diff --git a/cratonclient/common/cliutils.py b/cratonclient/common/cliutils.py index be5f156..9914a67 100644 --- a/cratonclient/common/cliutils.py +++ b/cratonclient/common/cliutils.py @@ -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. diff --git a/cratonclient/formatters/table.py b/cratonclient/formatters/table.py index 4dc1190..6ae7b2d 100644 --- a/cratonclient/formatters/table.py +++ b/cratonclient/formatters/table.py @@ -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 " diff --git a/cratonclient/shell/v1/cells_shell.py b/cratonclient/shell/v1/cells_shell.py index 66c9d56..b8b6d4c 100644 --- a/cratonclient/shell/v1/cells_shell.py +++ b/cratonclient/shell/v1/cells_shell.py @@ -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='', - 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 + if args.fields and args.fields == DEFAULT_CELL_FIELDS: + args.fields = CELL_FIELDS + else: + raise exc.CommandError( + 'Cannot specify both --fields and --detail.' + ) 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])) - else: - fields = {x: cells.CELL_FIELDS[x] for x in default_fields} + + 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( diff --git a/cratonclient/shell/v1/clouds_shell.py b/cratonclient/shell/v1/clouds_shell.py index 5005dfa..0cc1f3c 100644 --- a/cratonclient/shell/v1/clouds_shell.py +++ b/cratonclient/shell/v1/clouds_shell.py @@ -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='', - 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='', 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])) - else: - fields = default_fields + if args.detail: + if args.fields and args.fields == DEFAULT_CLOUD_FIELDS: + args.fields = CLOUD_FIELDS + else: + 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( diff --git a/cratonclient/shell/v1/hosts_shell.py b/cratonclient/shell/v1/hosts_shell.py index 01f30cf..b804bd4 100644 --- a/cratonclient/shell/v1/hosts_shell.py +++ b/cratonclient/shell/v1/hosts_shell.py @@ -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='', - 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 + if args.fields and args.fields == DEFAULT_HOST_FIELDS: + args.fields = HOST_FIELDS + else: + raise exc.CommandError( + 'Cannot specify both --fields and --detail.' + ) 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])) - else: - fields = {x: hosts.HOST_FIELDS[x] for x in default_fields} + + 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)) diff --git a/cratonclient/shell/v1/projects_shell.py b/cratonclient/shell/v1/projects_shell.py index e7ac5e8..6e0e1be 100644 --- a/cratonclient/shell/v1/projects_shell.py +++ b/cratonclient/shell/v1/projects_shell.py @@ -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='', - 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) diff --git a/cratonclient/shell/v1/regions_shell.py b/cratonclient/shell/v1/regions_shell.py index 30fbef6..9f55e59 100644 --- a/cratonclient/shell/v1/regions_shell.py +++ b/cratonclient/shell/v1/regions_shell.py @@ -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='', - 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])) - else: - fields = default_fields + if args.detail: + if args.fields and args.fields == DEFAULT_REGION_FIELDS: + args.fields = REGION_FIELDS + else: + 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( diff --git a/cratonclient/tests/unit/formatters/test_table_formatter.py b/cratonclient/tests/unit/formatters/test_table_formatter.py index a4c5f23..74e53d8 100644 --- a/cratonclient/tests/unit/formatters/test_table_formatter.py +++ b/cratonclient/tests/unit/formatters/test_table_formatter.py @@ -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('') diff --git a/cratonclient/tests/unit/shell/base.py b/cratonclient/tests/unit/shell/base.py index f1180b5..0bfac05 100644 --- a/cratonclient/tests/unit/shell/base.py +++ b/cratonclient/tests/unit/shell/base.py @@ -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']) diff --git a/cratonclient/tests/unit/shell/v1/test_cells_shell.py b/cratonclient/tests/unit/shell/v1/test_cells_shell.py index 1f2c13b..1ea9cd2 100644 --- a/cratonclient/tests/unit/shell/v1/test_cells_shell.py +++ b/cratonclient/tests/unit/shell/v1/test_cells_shell.py @@ -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.""" diff --git a/cratonclient/tests/unit/shell/v1/test_clouds_shell.py b/cratonclient/tests/unit/shell/v1/test_clouds_shell.py index 5c4cd7d..1aad5e8 100644 --- a/cratonclient/tests/unit/shell/v1/test_clouds_shell.py +++ b/cratonclient/tests/unit/shell/v1/test_clouds_shell.py @@ -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.""" diff --git a/cratonclient/tests/unit/shell/v1/test_hosts_shell.py b/cratonclient/tests/unit/shell/v1/test_hosts_shell.py index 6132894..442bdd9 100644 --- a/cratonclient/tests/unit/shell/v1/test_hosts_shell.py +++ b/cratonclient/tests/unit/shell/v1/test_hosts_shell.py @@ -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.""" diff --git a/cratonclient/tests/unit/shell/v1/test_projects_shell.py b/cratonclient/tests/unit/shell/v1/test_projects_shell.py index 9f14b86..e4d2862 100644 --- a/cratonclient/tests/unit/shell/v1/test_projects_shell.py +++ b/cratonclient/tests/unit/shell/v1/test_projects_shell.py @@ -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.""" diff --git a/cratonclient/tests/unit/shell/v1/test_regions_shell.py b/cratonclient/tests/unit/shell/v1/test_regions_shell.py index a583d57..8df8d8b 100644 --- a/cratonclient/tests/unit/shell/v1/test_regions_shell.py +++ b/cratonclient/tests/unit/shell/v1/test_regions_shell.py @@ -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.""" diff --git a/cratonclient/v1/cells.py b/cratonclient/v1/cells.py index 6382b75..b161bab 100644 --- a/cratonclient/v1/cells.py +++ b/cratonclient/v1/cells.py @@ -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' -} diff --git a/cratonclient/v1/clouds.py b/cratonclient/v1/clouds.py index ab705f3..f823bc9 100644 --- a/cratonclient/v1/clouds.py +++ b/cratonclient/v1/clouds.py @@ -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' -} diff --git a/cratonclient/v1/hosts.py b/cratonclient/v1/hosts.py index 309d55c..bd135c3 100644 --- a/cratonclient/v1/hosts.py +++ b/cratonclient/v1/hosts.py @@ -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', -} diff --git a/cratonclient/v1/projects.py b/cratonclient/v1/projects.py index 371f873..ab5fd26 100644 --- a/cratonclient/v1/projects.py +++ b/cratonclient/v1/projects.py @@ -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' -} diff --git a/cratonclient/v1/regions.py b/cratonclient/v1/regions.py index eddef3a..cbcc4ae 100644 --- a/cratonclient/v1/regions.py +++ b/cratonclient/v1/regions.py @@ -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' -}