Merge "Make column ordering consistent and predictable"

This commit is contained in:
Jenkins 2017-03-03 17:40:37 +00:00 committed by Gerrit Code Review
commit 9694c6aacb
19 changed files with 244 additions and 209 deletions

View File

@ -51,6 +51,27 @@ def add_arg(func, *args, **kwargs):
func.arguments.insert(0, (args, kwargs))
def field_labels_from(attributes):
"""Generate a list of slightly more human readable field names.
This takes the list of fields/attributes on the object and makes them
easier to read.
:param list attributes:
The attribute names to convert. For example, ``["parent_id"]``.
:returns:
List of field names. For example ``["Parent Id"]``
:rtype:
list
Example:
>>> field_labels_from(["id", "name", "cloud_id"])
["Id", "Name", "Cloud Id"]
"""
return [field.replace('_', ' ').title() for field in attributes]
def print_list(objs, fields, formatters=None, sortby_index=0,
mixed_case_fields=None, field_labels=None):
"""Print a list or objects as a table, one row per object.

View File

@ -18,6 +18,7 @@ from oslo_utils import encodeutils
import prettytable
import six
from cratonclient.common import cliutils
from cratonclient.formatters import base
@ -28,7 +29,7 @@ class Formatter(base.Formatter):
"""Set-up after initialization."""
self.fields = []
self.formatters = {}
self.sortby_index = 0
self.sortby_index = None
self.mixed_case_fields = set([])
self.field_labels = []
self.dict_property = "Property"
@ -71,7 +72,7 @@ class Formatter(base.Formatter):
if fields is not None:
self.fields = fields
if field_labels is None:
self.field_labels = self.fields
self.field_labels = cliutils.field_labels_from(self.fields)
elif len(field_labels) != len(self.fields):
raise ValueError(
"Field labels list %(labels)s has different number "

View File

@ -16,7 +16,21 @@ from __future__ import print_function
from cratonclient.common import cliutils
from cratonclient import exceptions as exc
from cratonclient.v1 import cells
DEFAULT_CELL_FIELDS = [
'id',
'name',
'cloud_id',
'region_id',
'created_at',
]
CELL_FIELDS = DEFAULT_CELL_FIELDS + [
'updated_at',
'note',
'variables',
'project_id',
]
@cliutils.arg('id',
@ -52,7 +66,7 @@ def do_cell_show(cc, args):
@cliutils.arg('--fields',
nargs='+',
metavar='<fields>',
default=[],
default=DEFAULT_CELL_FIELDS,
help='Space-separated list of fields to display. '
'Only these fields will be fetched from the server. '
'Can not be used when "--detail" is specified')
@ -73,7 +87,6 @@ def do_cell_show(cc, args):
def do_cell_list(cc, args):
"""Print list of cells which are registered with the Craton service."""
params = {}
default_fields = ['id', 'name']
if args.cloud is not None:
params['cloud_id'] = args.cloud
if args.limit is not None:
@ -85,27 +98,29 @@ def do_cell_list(cc, args):
if args.all is True:
params['limit'] = 100
if args.fields and args.detail:
raise exc.CommandError('Cannot specify both --fields and --detail.')
if args.detail:
fields = cells.CELL_FIELDS
params['detail'] = args.detail
elif args.fields:
try:
fields = {x: cells.CELL_FIELDS[x] for x in args.fields}
except KeyError as keyerr:
raise exc.CommandError('Invalid field "{}"'.format(keyerr.args[0]))
if args.fields and args.fields == DEFAULT_CELL_FIELDS:
args.fields = CELL_FIELDS
else:
fields = {x: cells.CELL_FIELDS[x] for x in default_fields}
raise exc.CommandError(
'Cannot specify both --fields and --detail.'
)
params['detail'] = args.detail
fields = args.fields
for field in fields:
if field not in CELL_FIELDS:
raise exc.CommandError(
'Invalid field "{}"'.format(field)
)
sort_key = args.sort_key and args.sort_key.lower()
if sort_key is not None:
if sort_key not in cells.CELL_FIELDS:
if sort_key not in CELL_FIELDS:
raise exc.CommandError(
('"--sort-key" value was "{}" but should '
'be one of: {}').format(
args.sort_key,
', '.join(cells.CELL_FIELDS.keys())
', '.join(CELL_FIELDS)
)
)
params['sort_key'] = sort_key
@ -117,7 +132,7 @@ def do_cell_list(cc, args):
params['autopaginate'] = args.all
listed_cells = cc.cells.list(**params)
args.formatter.configure(fields=list(fields)).handle(listed_cells)
args.formatter.configure(fields=fields).handle(listed_cells)
@cliutils.arg('-n', '--name',
@ -141,7 +156,7 @@ def do_cell_list(cc, args):
def do_cell_create(cc, args):
"""Register a new cell with the Craton service."""
fields = {k: v for (k, v) in vars(args).items()
if k in cells.CELL_FIELDS and not (v is None)}
if k in CELL_FIELDS and not (v is None)}
cell = cc.cells.create(**fields)
args.formatter.configure(wrap=72).handle(cell)
@ -168,7 +183,7 @@ def do_cell_create(cc, args):
def do_cell_update(cc, args):
"""Update a cell that is registered with the Craton service."""
fields = {k: v for (k, v) in vars(args).items()
if k in cells.CELL_FIELDS and not (v is None)}
if k in CELL_FIELDS and not (v is None)}
cell_id = fields.pop('id')
if not fields:
raise exc.CommandError(

View File

@ -14,7 +14,18 @@ from __future__ import print_function
from cratonclient.common import cliutils
from cratonclient import exceptions as exc
from cratonclient.v1 import clouds
DEFAULT_CLOUD_FIELDS = [
'id',
'name',
'created_at',
]
CLOUD_FIELDS = DEFAULT_CLOUD_FIELDS + [
'updated_at',
'note',
'project_id',
]
@cliutils.arg('-n', '--name',
@ -26,7 +37,7 @@ from cratonclient.v1 import clouds
def do_cloud_create(cc, args):
"""Register a new cloud with the Craton service."""
fields = {k: v for (k, v) in vars(args).items()
if k in clouds.CLOUD_FIELDS and not (v is None)}
if k in CLOUD_FIELDS and not (v is None)}
cloud = cc.clouds.create(**fields)
args.formatter.configure(wrap=72).handle(cloud)
@ -35,7 +46,7 @@ def do_cloud_create(cc, args):
@cliutils.arg('--fields',
nargs='+',
metavar='<fields>',
default=[],
default=DEFAULT_CLOUD_FIELDS,
help='Comma-separated list of fields to display. '
'Only these fields will be fetched from the server. '
'Can not be used when "--detail" is specified')
@ -45,6 +56,10 @@ def do_cloud_create(cc, args):
help='Retrieve and show all clouds. This will override '
'the provided value for --limit and automatically '
'retrieve each page of results.')
@cliutils.arg('--detail',
action='store_true',
default=False,
help='Show detailed information about all clouds.')
@cliutils.arg('--limit',
metavar='<limit>',
type=int,
@ -56,7 +71,6 @@ def do_cloud_create(cc, args):
def do_cloud_list(cc, args):
"""List all clouds."""
params = {}
default_fields = ['id', 'name']
if args.limit is not None:
if args.limit < 0:
raise exc.CommandError('Invalid limit specified. Expected '
@ -66,13 +80,22 @@ def do_cloud_list(cc, args):
if args.all is True:
params['limit'] = 100
if args.fields:
try:
fields = {x: clouds.CLOUD_FIELDS[x] for x in args.fields}
except KeyError as err:
raise exc.CommandError('Invalid field "{}"'.format(err.args[0]))
if args.detail:
if args.fields and args.fields == DEFAULT_CLOUD_FIELDS:
args.fields = CLOUD_FIELDS
else:
fields = default_fields
raise exc.CommandError(
'Cannot specify both --fields and --detail.'
)
params['detail'] = args.detail
fields = args.fields
for field in args.fields:
if field not in CLOUD_FIELDS:
raise exc.CommandError(
'Invalid field "{}"'.format(field)
)
params['marker'] = args.marker
params['autopaginate'] = args.all
@ -102,7 +125,7 @@ def do_cloud_show(cc, args):
def do_cloud_update(cc, args):
"""Update a cloud that is registered with the Craton service."""
fields = {k: v for (k, v) in vars(args).items()
if k in clouds.CLOUD_FIELDS and not (v is None)}
if k in CLOUD_FIELDS and not (v is None)}
item_id = fields.pop('id')
if not fields:
raise exc.CommandError(

View File

@ -16,7 +16,28 @@ from __future__ import print_function
from cratonclient.common import cliutils
from cratonclient import exceptions as exc
from cratonclient.v1 import hosts
DEFAULT_HOST_FIELDS = [
'id',
'name',
'active',
'device_type',
'ip_address',
'cloud_id',
'region_id',
'cell_id',
'created_at',
]
HOST_FIELDS = DEFAULT_HOST_FIELDS + [
'updated_at',
'note',
'variables',
'labels',
'parent_id',
'project_id',
]
@cliutils.arg('id',
@ -57,7 +78,7 @@ def do_host_show(cc, args):
@cliutils.arg('--fields',
nargs='+',
metavar='<fields>',
default=[],
default=DEFAULT_HOST_FIELDS,
help='Space-separated list of fields to display. '
'Only these fields will be fetched from the server. '
'Can not be used when "--detail" is specified')
@ -94,7 +115,6 @@ def do_host_show(cc, args):
def do_host_list(cc, args):
"""Print list of hosts which are registered with the Craton service."""
params = {}
default_fields = ['id', 'name', 'device_type', 'active', 'cell_id']
if args.cell is not None:
params['cell_id'] = args.cell
if args.cloud is not None:
@ -116,26 +136,29 @@ def do_host_list(cc, args):
if args.all is True:
params['limit'] = 100
if args.fields and args.detail:
raise exc.CommandError('Cannot specify both --fields and --detail.')
if args.detail:
fields = hosts.HOST_FIELDS
params['detail'] = args.detail
elif args.fields:
try:
fields = {x: hosts.HOST_FIELDS[x] for x in args.fields}
except KeyError as keyerr:
raise exc.CommandError('Invalid field "{}"'.format(keyerr.args[0]))
if args.fields and args.fields == DEFAULT_HOST_FIELDS:
args.fields = HOST_FIELDS
else:
fields = {x: hosts.HOST_FIELDS[x] for x in default_fields}
raise exc.CommandError(
'Cannot specify both --fields and --detail.'
)
params['detail'] = args.detail
fields = args.fields
for field in args.fields:
if field not in HOST_FIELDS:
raise exc.CommandError(
'Invalid field "{}"'.format(field)
)
sort_key = args.sort_key and args.sort_key.lower()
if sort_key is not None:
if sort_key not in hosts.HOST_FIELDS:
if sort_key not in HOST_FIELDS:
raise exc.CommandError(
'{0} is an invalid key for sorting, valid values for '
'--sort-key are: {1}'.format(
args.sort_key, hosts.HOST_FIELDS.keys()
args.sort_key, HOST_FIELDS
)
)
params['sort_key'] = sort_key
@ -147,7 +170,7 @@ def do_host_list(cc, args):
params['autopaginate'] = args.all
host_list = cc.hosts.list(**params)
args.formatter.configure(fields=list(fields)).handle(host_list)
args.formatter.configure(fields=fields).handle(host_list)
@cliutils.arg('-n', '--name',
@ -191,7 +214,7 @@ def do_host_list(cc, args):
def do_host_create(cc, args):
"""Register a new host with the Craton service."""
fields = {k: v for (k, v) in vars(args).items()
if k in hosts.HOST_FIELDS and (v or v is False)}
if k in HOST_FIELDS and (v or v is False)}
host = cc.hosts.create(**fields)
args.formatter.configure(wrap=72).handle(host)
@ -232,7 +255,7 @@ def do_host_create(cc, args):
def do_host_update(cc, args):
"""Update a host that is registered with the Craton service."""
fields = {k: v for (k, v) in vars(args).items()
if k in hosts.HOST_FIELDS and (v or v is False)}
if k in HOST_FIELDS and (v or v is False)}
item_id = fields.pop('id')
host = cc.hosts.update(item_id, **fields)
print("Host {0} has been successfully updated.".format(host.id))

View File

@ -16,7 +16,17 @@ from __future__ import print_function
from cratonclient.common import cliutils
from cratonclient import exceptions as exc
from cratonclient.v1 import projects
DEFAULT_PROJECT_FIELDS = [
'id',
'name',
]
PROJECT_FIELDS = DEFAULT_PROJECT_FIELDS + [
'created_at',
'updated_at',
]
@cliutils.arg('id',
@ -38,7 +48,7 @@ def do_project_show(cc, args):
@cliutils.arg('--fields',
nargs='+',
metavar='<fields>',
default=[],
default=DEFAULT_PROJECT_FIELDS,
help='Space-separated list of fields to display. '
'Only these fields will be fetched from the server. '
'Can not be used when "--detail" is specified')
@ -59,7 +69,6 @@ def do_project_show(cc, args):
def do_project_list(cc, args):
"""Print list of projects which are registered with the Craton service."""
params = {}
default_fields = ['id', 'name']
if args.limit is not None:
if args.limit < 0:
raise exc.CommandError('Invalid limit specified. Expected '
@ -69,20 +78,24 @@ def do_project_list(cc, args):
if args.all is True:
params['limit'] = 100
if args.fields and args.detail:
raise exc.CommandError('Cannot specify both --fields and --detail.')
if args.detail:
if args.fields and args.fields == DEFAULT_PROJECT_FIELDS:
args.fields = PROJECT_FIELDS
else:
raise exc.CommandError(
'Cannot specify both --fields and --detail.'
)
fields = args.fields
for field in fields:
if field not in PROJECT_FIELDS:
raise exc.CommandError(
'Invalid field "{}"'.format(field)
)
if args.name:
params['name'] = args.name
if args.detail:
fields = projects.PROJECT_FIELDS
elif args.fields:
try:
fields = {x: projects.PROJECT_FIELDS[x] for x in args.fields}
except KeyError as keyerr:
raise exc.CommandError('Invalid field "{}"'.format(keyerr.args[0]))
else:
fields = {x: projects.PROJECT_FIELDS[x] for x in default_fields}
params['marker'] = args.marker
params['autopaginate'] = args.all
@ -97,7 +110,7 @@ def do_project_list(cc, args):
def do_project_create(cc, args):
"""Register a new project with the Craton service."""
fields = {k: v for (k, v) in vars(args).items()
if k in projects.PROJECT_FIELDS and not (v is None)}
if k in PROJECT_FIELDS and not (v is None)}
project = cc.projects.create(**fields)
args.formatter.configure(wrap=72).handle(project)

View File

@ -14,7 +14,19 @@ from __future__ import print_function
from cratonclient.common import cliutils
from cratonclient import exceptions as exc
from cratonclient.v1 import regions
DEFAULT_REGION_FIELDS = [
'id',
'name',
'cloud_id',
]
REGION_FIELDS = DEFAULT_REGION_FIELDS + [
'project_id',
'note',
'created_at',
'updated_at',
]
@cliutils.arg('-n', '--name',
@ -32,7 +44,7 @@ from cratonclient.v1 import regions
def do_region_create(cc, args):
"""Register a new region with the Craton service."""
fields = {k: v for (k, v) in vars(args).items()
if k in regions.REGION_FIELDS and not (v is None)}
if k in REGION_FIELDS and not (v is None)}
region = cc.regions.create(**fields)
args.formatter.configure(wrap=72).handle(region)
@ -45,10 +57,14 @@ def do_region_create(cc, args):
@cliutils.arg('--fields',
nargs='+',
metavar='<fields>',
default=[],
default=DEFAULT_REGION_FIELDS,
help='Space-separated list of fields to display. '
'Only these fields will be fetched from the server. '
'Can not be used when "--detail" is specified')
@cliutils.arg('--detail',
action='store_true',
default=False,
help='Show detailed information about the regions.')
@cliutils.arg('--all',
action='store_true',
default=False,
@ -66,7 +82,6 @@ def do_region_create(cc, args):
def do_region_list(cc, args):
"""List all regions."""
params = {}
default_fields = ['id', 'name']
if args.cloud is not None:
params['cloud_id'] = args.cloud
if args.limit is not None:
@ -78,13 +93,21 @@ def do_region_list(cc, args):
if args.all is True:
params['limit'] = 100
if args.fields:
try:
fields = {x: regions.REGION_FIELDS[x] for x in args.fields}
except KeyError as err:
raise exc.CommandError('Invalid field "{}"'.format(err.args[0]))
if args.detail:
if args.fields and args.fields == DEFAULT_REGION_FIELDS:
args.fields = REGION_FIELDS
else:
fields = default_fields
raise exc.CommandError(
'Cannot specify both --fields and --detail.'
)
params['detail'] = args.detail
fields = args.fields
for field in args.fields:
if field not in REGION_FIELDS:
raise exc.CommandError(
'Invalid field "{}"'.format(field)
)
params['marker'] = args.marker
params['autopaginate'] = args.all
@ -120,7 +143,7 @@ def do_region_show(cc, args):
def do_region_update(cc, args):
"""Update a region that is registered with the Craton service."""
fields = {k: v for (k, v) in vars(args).items()
if k in regions.REGION_FIELDS and not (v is None)}
if k in REGION_FIELDS and not (v is None)}
item_id = fields.pop('id')
if not fields:
raise exc.CommandError(

View File

@ -31,7 +31,7 @@ class TestTableFormatter(base.FormatterTestCase):
"""Verify we set up defaults for our PrettyTable formatter."""
self.assertEqual([], self.formatter.fields)
self.assertEqual({}, self.formatter.formatters)
self.assertEqual(0, self.formatter.sortby_index)
self.assertIsNone(self.formatter.sortby_index)
self.assertEqual(set([]), self.formatter.mixed_case_fields)
self.assertEqual([], self.formatter.field_labels)
self.assertEqual("Property", self.formatter.dict_property)
@ -63,14 +63,14 @@ class TestTableFormatter(base.FormatterTestCase):
# Assert defaults remain unchanged
self.assertEqual([], self.formatter.fields)
self.assertEqual([], self.formatter.field_labels)
self.assertEqual(0, self.formatter.sortby_index)
self.assertIsNone(self.formatter.sortby_index)
# Case 1: Just fields
def test_configure_fields_only(self):
"""Verify the logic for configuring fields."""
self.formatter.configure(fields=['id', 'name'])
self.assertListEqual(['id', 'name'], self.formatter.fields)
self.assertListEqual(['id', 'name'], self.formatter.field_labels)
self.assertListEqual(['Id', 'Name'], self.formatter.field_labels)
# Case 2: fields + field_labels
def test_configure_fields_and_field_labels(self):
@ -167,6 +167,7 @@ class TestTableFormatter(base.FormatterTestCase):
def test_sortby_kwargs(self):
"""Verify sortby_kwargs relies on sortby_index."""
self.formatter.field_labels = ['id', 'created_at']
self.formatter.sortby_index = 0
self.assertDictEqual({'sortby': 'id'}, self.formatter.sortby_kwargs())
self.formatter.sortby_index = 1
@ -219,10 +220,10 @@ class TestTableFormatter(base.FormatterTestCase):
self.formatter.handle_generator(crud.Resource(mock.Mock(), info)
for info in info_list)
PrettyTable.assert_called_once_with(['id', 'Name'])
PrettyTable.assert_called_once_with(['Id', 'Name'])
self.assertListEqual(
[mock.call([i, 'Test Resource']) for i in range(15)],
mocktable.add_row.call_args_list,
)
mocktable.get_string.assert_called_once_with(sortby='id')
mocktable.get_string.assert_called_once_with()
self.print_.assert_called_once_with('')

View File

@ -99,3 +99,8 @@ class TestShellCommandUsingPrintList(TestShellCommand):
kwargs = self.formatter.configure.call_args[1]
self.assertListEqual(expected_fields,
sorted(kwargs['fields']))
def assertFieldsEqualTo(self, expected_fields):
"""Assert the sorted fields parameter is equal expected_fields."""
kwargs = self.formatter.configure.call_args[1]
self.assertListEqual(expected_fields, kwargs['fields'])

View File

@ -17,7 +17,6 @@ import mock
from cratonclient import exceptions
from cratonclient.shell.v1 import cells_shell
from cratonclient.tests.unit.shell import base
from cratonclient.v1 import cells
class TestDoShellShow(base.TestShellCommandUsingPrintDict):
@ -54,7 +53,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
kwargs.setdefault('limit', None)
kwargs.setdefault('sort_key', None)
kwargs.setdefault('sort_dir', 'asc')
kwargs.setdefault('fields', [])
kwargs.setdefault('fields', cells_shell.DEFAULT_CELL_FIELDS)
kwargs.setdefault('marker', None)
kwargs.setdefault('all', False)
return super(TestDoCellList, self).args_for(**kwargs)
@ -71,7 +70,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(cells_shell.DEFAULT_CELL_FIELDS)
def test_with_cloud_id(self):
"""Verify the behaviour of do_cell_list with mostly default values."""
@ -86,7 +85,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(cells_shell.DEFAULT_CELL_FIELDS)
def test_negative_limit(self):
"""Ensure we raise an exception for negative limits."""
@ -108,7 +107,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(cells_shell.DEFAULT_CELL_FIELDS)
def test_valid_sort_key(self):
"""Verify that we pass on our sort key."""
@ -123,7 +122,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(cells_shell.DEFAULT_CELL_FIELDS)
def test_invalid_sort_key(self):
"""Verify that do not we pass on our sort key."""
@ -145,7 +144,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedFieldsEqualTo(sorted(list(cells.CELL_FIELDS)))
self.assertFieldsEqualTo(cells_shell.CELL_FIELDS)
def test_raises_exception_with_detail_and_fields(self):
"""Verify that we fail when users specify --detail and --fields."""
@ -169,7 +168,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedFieldsEqualTo(['id', 'name', 'note'])
self.assertFieldsEqualTo(['id', 'name', 'note'])
def test_invalid_fields(self):
"""Verify that we error out with invalid fields."""

View File

@ -196,7 +196,7 @@ class TestDoCloudList(base.TestShellCommandUsingPrintList):
"""Generate the default argument list for cloud-list."""
kwargs.setdefault('detail', False)
kwargs.setdefault('limit', None)
kwargs.setdefault('fields', [])
kwargs.setdefault('fields', clouds_shell.DEFAULT_CLOUD_FIELDS)
kwargs.setdefault('marker', None)
kwargs.setdefault('all', False)
return super(TestDoCloudList, self).args_for(**kwargs)
@ -206,7 +206,7 @@ class TestDoCloudList(base.TestShellCommandUsingPrintList):
args = self.args_for()
clouds_shell.do_cloud_list(self.craton_client, args)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(clouds_shell.DEFAULT_CLOUD_FIELDS)
def test_negative_limit(self):
"""Ensure we raise an exception for negative limits."""
@ -222,13 +222,13 @@ class TestDoCloudList(base.TestShellCommandUsingPrintList):
marker=None,
autopaginate=False,
)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(clouds_shell.DEFAULT_CLOUD_FIELDS)
def test_fields(self):
"""Verify that we print out specific fields."""
args = self.args_for(fields=['id', 'name', 'note'])
clouds_shell.do_cloud_list(self.craton_client, args)
self.assertSortedFieldsEqualTo(['id', 'name', 'note'])
self.assertFieldsEqualTo(['id', 'name', 'note'])
def test_invalid_fields(self):
"""Verify that we error out with invalid fields."""

View File

@ -46,7 +46,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
kwargs.setdefault('limit', None)
kwargs.setdefault('sort_key', None)
kwargs.setdefault('sort_dir', 'asc')
kwargs.setdefault('fields', [])
kwargs.setdefault('fields', hosts_shell.DEFAULT_HOST_FIELDS)
kwargs.setdefault('marker', None)
kwargs.setdefault('all', False)
kwargs.setdefault('vars', None)
@ -67,9 +67,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedPrintListFieldsEqualTo([
'active', 'cell_id', 'device_type', 'id', 'name'
])
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
def test_with_cell_id(self):
"""Verify that we include the cell_id in the params."""
@ -84,9 +82,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedPrintListFieldsEqualTo([
'active', 'cell_id', 'device_type', 'id', 'name',
])
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
def test_with_cloud_id(self):
"""Verify that we include the cell_id in the params."""
@ -101,9 +97,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedPrintListFieldsEqualTo([
'active', 'cell_id', 'device_type', 'id', 'name',
])
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
def test_with_detail(self):
"""Verify the behaviour of specifying --detail."""
@ -118,22 +112,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedPrintListFieldsEqualTo([
'active',
'cell_id',
'cloud_id',
'created_at',
'device_type',
'id',
'ip_address',
'labels',
'name',
'note',
'parent_id',
'project_id',
'region_id',
'updated_at',
])
self.assertFieldsEqualTo(hosts_shell.HOST_FIELDS)
def test_with_limit(self):
"""Verify the behaviour with --limit specified."""
@ -148,9 +127,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedPrintListFieldsEqualTo([
'active', 'cell_id', 'device_type', 'id', 'name'
])
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
def test_negative_limit_raises_command_error(self):
"""Verify that we forbid negative limit values."""
@ -172,9 +149,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedPrintListFieldsEqualTo([
'active', 'cell_id', 'device_type', 'id', 'name'
])
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
def test_with_label(self):
"""Verify the behaviour with --label specified."""
@ -189,9 +164,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedPrintListFieldsEqualTo([
'active', 'cell_id', 'device_type', 'id', 'name'
])
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
def test_with_device_type(self):
"""Verify the behaviour with --device-type specified."""
@ -206,9 +179,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedPrintListFieldsEqualTo([
'active', 'cell_id', 'device_type', 'id', 'name'
])
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
def test_with_ip(self):
"""Verify the behaviour with --ip specified."""
@ -223,9 +194,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedPrintListFieldsEqualTo([
'active', 'cell_id', 'device_type', 'id', 'name'
])
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
def test_fields(self):
"""Verify that we can specify custom fields."""

View File

@ -19,7 +19,6 @@ import mock
from cratonclient import exceptions
from cratonclient.shell.v1 import projects_shell
from cratonclient.tests.unit.shell import base
from cratonclient.v1 import projects
class TestDoShellShow(base.TestShellCommandUsingPrintDict):
@ -53,7 +52,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
kwargs.setdefault('name', None)
kwargs.setdefault('limit', None)
kwargs.setdefault('detail', False)
kwargs.setdefault('fields', [])
kwargs.setdefault('fields', projects_shell.DEFAULT_PROJECT_FIELDS)
kwargs.setdefault('marker', None)
kwargs.setdefault('all', False)
return super(TestDoProjectList, self).args_for(**kwargs)
@ -68,7 +67,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
marker=None,
autopaginate=False,
)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(projects_shell.DEFAULT_PROJECT_FIELDS)
def test_negative_limit(self):
"""Ensure we raise an exception for negative limits."""
@ -89,7 +88,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(projects_shell.DEFAULT_PROJECT_FIELDS)
def test_detail(self):
"""Verify the behaviour of specifying --detail."""
@ -101,7 +100,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
marker=None,
autopaginate=False,
)
self.assertSortedFieldsEqualTo(sorted(list(projects.PROJECT_FIELDS)))
self.assertFieldsEqualTo(projects_shell.PROJECT_FIELDS)
def test_list_name(self):
"""Verify the behaviour of specifying --detail."""
@ -114,13 +113,13 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(projects_shell.DEFAULT_PROJECT_FIELDS)
def test_raises_exception_with_detail_and_fields(self):
"""Verify that we fail when users specify --detail and --fields."""
args = self.args_for(
detail=True,
fields=['id', 'name'],
fields=['name', 'id'],
)
self.assertRaisesCommandErrorWith(projects_shell.do_project_list, args)
@ -128,7 +127,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
def test_fields(self):
"""Verify that we print out specific fields."""
args = self.args_for(fields=['id', 'name'])
args = self.args_for(fields=['name', 'id'])
projects_shell.do_project_list(self.craton_client, args)
@ -136,7 +135,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
autopaginate=False,
marker=None,
)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(['name', 'id'])
def test_invalid_fields(self):
"""Verify that we error out with invalid fields."""

View File

@ -204,7 +204,7 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
kwargs.setdefault('detail', False)
kwargs.setdefault('cloud', None)
kwargs.setdefault('limit', None)
kwargs.setdefault('fields', [])
kwargs.setdefault('fields', regions_shell.DEFAULT_REGION_FIELDS)
kwargs.setdefault('marker', None)
kwargs.setdefault('all', False)
return super(TestDoRegionList, self).args_for(**kwargs)
@ -214,7 +214,7 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
args = self.args_for()
regions_shell.do_region_list(self.craton_client, args)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(regions_shell.DEFAULT_REGION_FIELDS)
def test_with_cloud_id(self):
"""Test region-list with default values."""
@ -225,7 +225,7 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
marker=None,
autopaginate=False,
)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(regions_shell.DEFAULT_REGION_FIELDS)
def test_negative_limit(self):
"""Ensure we raise an exception for negative limits."""
@ -241,13 +241,13 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
marker=None,
autopaginate=False,
)
self.assertSortedFieldsEqualTo(['id', 'name'])
self.assertFieldsEqualTo(regions_shell.DEFAULT_REGION_FIELDS)
def test_fields(self):
"""Verify that we print out specific fields."""
args = self.args_for(fields=['id', 'name', 'note'])
args = self.args_for(fields=['name', 'id', 'note'])
regions_shell.do_region_list(self.craton_client, args)
self.assertSortedFieldsEqualTo(['id', 'name', 'note'])
self.assertFieldsEqualTo(['name', 'id', 'note'])
def test_invalid_fields(self):
"""Verify that we error out with invalid fields."""

View File

@ -27,15 +27,3 @@ class CellManager(crud.CRUDClient):
key = 'cell'
base_path = '/cells'
resource_class = Cell
CELL_FIELDS = {
'id': 'ID',
'region_id': 'Region ID',
'project_id': 'Project ID',
'cloud_id': 'Cloud ID',
'name': 'Name',
'note': 'Note',
'created_at': 'Created At',
'updated_at': 'Updated At'
}

View File

@ -27,12 +27,3 @@ class CloudManager(crud.CRUDClient):
key = 'cloud'
base_path = '/clouds'
resource_class = Cloud
CLOUD_FIELDS = {
'id': 'ID',
'project_id': 'Project ID',
'name': 'Name',
'note': 'Note',
'created_at': 'Created At',
'updated_at': 'Updated At'
}

View File

@ -27,21 +27,3 @@ class HostManager(crud.CRUDClient):
key = 'host'
base_path = '/hosts'
resource_class = Host
HOST_FIELDS = {
'id': 'ID',
'name': 'Name',
'device_type': 'Device Type',
'project_id': 'Project ID',
'cloud_id': 'Cloud ID',
'region_id': 'Region ID',
'cell_id': 'Cell ID',
'ip_address': 'IP Address',
'active': 'Active',
'note': 'Note',
'created_at': 'Created At',
'updated_at': 'Updated At',
'labels': 'Labels',
'parent_id': 'Parent ID',
}

View File

@ -27,11 +27,3 @@ class ProjectManager(crud.CRUDClient):
key = 'project'
base_path = '/projects'
resource_class = Project
PROJECT_FIELDS = {
'id': 'ID',
'name': 'Name',
'created_at': 'Created At',
'updated_at': 'Updated At'
}

View File

@ -28,13 +28,3 @@ class RegionManager(crud.CRUDClient):
base_path = '/regions'
resource_class = Region
project_id = 0
REGION_FIELDS = {
'id': 'ID',
'project_id': 'Project ID',
'cloud_id': 'Cloud ID',
'name': 'Name',
'note': 'Note',
'created_at': 'Created At',
'updated_at': 'Updated At'
}