diff options
author | Jenkins <jenkins@review.openstack.org> | 2016-05-04 10:18:50 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2016-05-04 10:18:51 +0000 |
commit | db4677fd3acd74e0dada7730acd2648c39e443ce (patch) | |
tree | 2dc6f44423a602c3bd75891d6f29da1eb72007f4 | |
parent | 71680abacf6cb32066cba6042b13fa267f7c9433 (diff) | |
parent | dceb77ff4437f32f5b2e8aafa904759a815c17bd (diff) | |
download | python-novaclient-db4677fd3acd74e0dada7730acd2648c39e443ce.tar.gz |
Merge "Clean the duplicated columns for "nova network-list""
-rw-r--r-- | novaclient/tests/unit/v2/test_shell.py | 14 | ||||
-rw-r--r-- | novaclient/v2/shell.py | 109 |
2 files changed, 88 insertions, 35 deletions
diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py index 17ce6d67..92257d61 100644 --- a/novaclient/tests/unit/v2/test_shell.py +++ b/novaclient/tests/unit/v2/test_shell.py @@ -1082,6 +1082,13 @@ class ShellTest(utils.TestCase): self.assertRaises(exceptions.CommandError, self.run_command, 'list --changes-since 0123456789') + def test_list_fields_redundant(self): + output, __ = self.run_command('list --fields id,status,status') + header = output.splitlines()[1] + self.assertEqual(1, header.count('ID')) + self.assertEqual(0, header.count('Id')) + self.assertEqual(1, header.count('Status')) + def test_meta_parsing(self): meta = ['key1=meta1', 'key2=meta2'] ref = {'key1': 'meta1', 'key2': 'meta2'} @@ -2169,6 +2176,13 @@ class ShellTest(utils.TestCase): self.run_command, 'network-list --fields vlan,project_id,invalid') + def test_network_list_redundant_fields(self): + output, __ = self.run_command( + 'network-list --fields label,project_id,project_id') + header = output.splitlines()[1] + self.assertEqual(1, header.count('Label')) + self.assertEqual(1, header.count('Project Id')) + def test_network_show(self): self.run_command('network-show 1') self.assert_called('GET', '/os-networks') diff --git a/novaclient/v2/shell.py b/novaclient/v2/shell.py index baef1db5..5eec6f7a 100644 --- a/novaclient/v2/shell.py +++ b/novaclient/v2/shell.py @@ -963,24 +963,9 @@ def do_network_list(cs, args): """Print a list of available networks.""" network_list = cs.networks.list() columns = ['ID', 'Label', 'Cidr'] - - formatters = {} - field_titles = [] - non_existent_fields = [] - if args.fields: - for field in args.fields.split(','): - if network_list and not hasattr(network_list[0], field): - non_existent_fields.append(field) - continue - field_title, formatter = utils.make_field_formatter(field, {}) - field_titles.append(field_title) - formatters[field_title] = formatter - if non_existent_fields: - raise exceptions.CommandError( - _("Non-existent fields are specified: %s") - % non_existent_fields) - - columns = columns + field_titles + columns += _get_list_table_columns_and_formatters( + args.fields, network_list, + exclude_fields=(c.lower() for c in columns))[0] utils.print_list(network_list, columns) @@ -1545,28 +1530,17 @@ def do_list(cs, args): _translate_extended_states(servers) formatters = {} - field_titles = [] - non_existent_fields = [] - if args.fields: - for field in args.fields.split(','): - if servers and not hasattr(servers[0], field): - non_existent_fields.append(field) - continue - field_title, formatter = utils.make_field_formatter(field, - filters) - field_titles.append(field_title) - formatters[field_title] = formatter - if non_existent_fields: - raise exceptions.CommandError( - _("Non-existent fields are specified: %s") - % non_existent_fields) + + cols, fmts = _get_list_table_columns_and_formatters( + args.fields, servers, exclude_fields=('id',), filters=filters) if args.minimal: columns = [ id_col, 'Name'] - elif field_titles: - columns = [id_col] + field_titles + elif cols: + columns = [id_col] + cols + formatters.update(fmts) else: columns = [ id_col, @@ -1590,6 +1564,71 @@ def do_list(cs, args): formatters, sortby_index=sortby_index) +def _get_list_table_columns_and_formatters(fields, objs, exclude_fields=(), + filters=None): + """Check and add fields to output columns. + + If there is any value in fields that not an attribute of obj, + CommandError will be raised. + + If fields has duplicate values (case sensitive), we will make them unique + and ignore duplicate ones. + + If exclude_fields is specified, any field both in fields and + exclude_fields will be ignored. + + :param fields: A list of string contains the fields to be printed. + :param objs: An list of object which will be used to check if field is + valid or not. Note, we don't check fields if obj is None or + empty. + :param exclude_fields: A tuple of string which contains the fields to be + excluded. + :param filters: A dictionary defines how to get value from fields, this + is useful when field's value is a complex object such as + dictionary. + + :return: columns, formatters. + columns is a list of string which will be used as table header. + formatters is a dictionary specifies how to display the value + of the field. + They can be [], {}. + :raise: novaclient.exceptions.CommandError + """ + if not fields: + return [], {} + + if not objs: + obj = None + elif isinstance(objs, list): + obj = objs[0] + else: + obj = objs + + columns = [] + formatters = {} + + non_existent_fields = [] + exclude_fields = set(exclude_fields) + + for field in fields.split(','): + if not hasattr(obj, field): + non_existent_fields.append(field) + continue + if field in exclude_fields: + continue + field_title, formatter = utils.make_field_formatter(field, + filters) + columns.append(field_title) + formatters[field_title] = formatter + exclude_fields.add(field) + + if non_existent_fields: + raise exceptions.CommandError( + _("Non-existent fields are specified: %s") % non_existent_fields) + + return columns, formatters + + @utils.arg( '--hard', dest='reboot_type', |