From 9c3ae09c320e3a0df4e64ac85f7b965db3b39d97 Mon Sep 17 00:00:00 2001 From: liusheng Date: Tue, 10 Oct 2017 11:14:21 +0800 Subject: [PATCH] Don't show empty columns if no column data for non-admin users For listing flavor and showing flavor commands by non-admin users, it will show empty columns of "resources" and "resource_aggregates" fields, because they are invisible for common users. It's better to avoid show the empty columns. Change-Id: If85a9f5711859030234f4159c9011459bbe4287b Closes-Bug: #1722438 --- moganclient/common/utils.py | 10 ++++++ moganclient/osc/v1/flavor.py | 34 +++++++++++--------- moganclient/tests/unit/osc/v1/test_flavor.py | 16 +++++++++ 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/moganclient/common/utils.py b/moganclient/common/utils.py index e21f63e..c3aacb4 100644 --- a/moganclient/common/utils.py +++ b/moganclient/common/utils.py @@ -63,3 +63,13 @@ def flavor_formatter(bc_client, flavor_id): flavor = bc_client.flavor.get(flavor_id) return '%s (%s)' % (flavor.name, flavor_id) return '' + + +def clean_listing_columns(headers, columns, data_sample): + col_headers = [] + cols = [] + for header, col in zip(headers, columns): + if hasattr(data_sample, col): + col_headers.append(header) + cols.append(col) + return tuple(col_headers), tuple(cols) diff --git a/moganclient/osc/v1/flavor.py b/moganclient/osc/v1/flavor.py index 51a16ec..e4f77dc 100644 --- a/moganclient/osc/v1/flavor.py +++ b/moganclient/osc/v1/flavor.py @@ -25,6 +25,7 @@ from osc_lib import utils from oslo_utils import strutils from moganclient.common.i18n import _ +from moganclient.common import utils as cli_utils LOG = logging.getLogger(__name__) @@ -98,14 +99,12 @@ class CreateFlavor(command.ShowOne): disabled=parsed_args.disabled, ) - data._info.update( - { - 'resources': utils.format_dict( - data._info.get('resources', {})), - 'resource_aggregates': utils.format_dict( - data._info.get('resource_aggregates', {})), - }, - ) + if 'resources' in data._info: + data._info.update({'resources': utils.format_dict( + data._info.get('resources', {}))}) + if 'resource_aggregates' in data._info: + data._info.update({'resource_aggregates': utils.format_dict( + data._info.get('resource_aggregates', {}))}) info.update(data._info) return zip(*sorted(info.items())) @@ -197,9 +196,14 @@ class ListFlavor(command.Lister): ) data = bc_client.flavor.list() + if not data: + return (), () + column_headers, columns = cli_utils.clean_listing_columns( + column_headers, columns, data[0]) formatters = {'resources': utils.format_dict, 'resource_aggregates': utils.format_dict } + return (column_headers, (utils.get_item_properties( s, columns, formatters=formatters) for s in data)) @@ -224,14 +228,12 @@ class ShowFlavor(command.ShowOne): parsed_args.flavor, ) - data._info.update( - { - 'resources': utils.format_dict( - data._info.get('resources', {})), - 'resource_aggregates': utils.format_dict( - data._info.get('resource_aggregates', {})), - }, - ) + if 'resources' in data._info: + data._info.update({'resources': utils.format_dict( + data._info.get('resources', {}))}) + if 'resource_aggregates' in data._info: + data._info.update({'resource_aggregates': utils.format_dict( + data._info.get('resource_aggregates', {}))}) info = {} info.update(data._info) return zip(*sorted(info.items())) diff --git a/moganclient/tests/unit/osc/v1/test_flavor.py b/moganclient/tests/unit/osc/v1/test_flavor.py index da41b15..d2751ca 100644 --- a/moganclient/tests/unit/osc/v1/test_flavor.py +++ b/moganclient/tests/unit/osc/v1/test_flavor.py @@ -214,6 +214,22 @@ class TestFlavorList(TestFlavor): self.assertEqual(self.list_columns, columns) self.assertEqual(self.list_data, tuple(data)) + def test_flavor_list_non_admin(self, mock_list): + arglist = [] + verifylist = [] + fake_flavor = fakes.FakeFlavor.create_one_flavor() + delattr(fake_flavor, 'resource_aggregates') + delattr(fake_flavor, 'resources') + mock_list.return_value = [fake_flavor] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + mock_list.assert_called_once_with('/flavors', response_key='flavors') + column_headers = ('UUID', 'Name', 'Is Public', 'Description') + self.assertEqual(column_headers, columns) + columns_data = ((fake_flavor.uuid, fake_flavor.name, + fake_flavor.is_public, fake_flavor.description),) + self.assertEqual(columns_data, tuple(data)) + @mock.patch.object(flavor_mgr.FlavorManager, '_get') class TestFlavorShow(TestFlavor):