diff --git a/openstackclient/common/extension.py b/openstackclient/common/extension.py index a1b17d33f7..f00bacaa95 100644 --- a/openstackclient/common/extension.py +++ b/openstackclient/common/extension.py @@ -22,15 +22,24 @@ from osc_lib import utils from openstackclient.i18n import _ - LOG = logging.getLogger(__name__) +def _get_extension_columns(item): + column_map = { + 'updated': 'updated_at', + } + hidden_columns = ['id', 'links', 'location'] + return utils.get_osc_show_columns_for_sdk_resource( + item, column_map, hidden_columns + ) + + class ListExtension(command.Lister): _description = _("List API extensions") def get_parser(self, prog_name): - parser = super(ListExtension, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( '--compute', action='store_true', @@ -70,7 +79,7 @@ class ListExtension(command.Lister): 'Alias', 'Description', 'Namespace', - 'Updated', + 'Updated At', 'Links', ) else: @@ -105,12 +114,12 @@ class ListExtension(command.Lister): LOG.warning(message) if parsed_args.volume or show_all: - volume_client = self.app.client_manager.volume + volume_client = self.app.client_manager.sdk_connection.volume try: - data += volume_client.list_extensions.show_all() + data += volume_client.extensions() except Exception: message = _( - "Extensions list not supported by " "Block Storage API" + "Extensions list not supported by Block Storage API" ) LOG.warning(message) @@ -120,7 +129,7 @@ class ListExtension(command.Lister): data += network_client.extensions() except Exception: message = _( - "Failed to retrieve extensions list " "from Network API" + "Failed to retrieve extensions list from Network API" ) LOG.warning(message) @@ -153,7 +162,12 @@ class ShowExtension(command.ShowOne): def take_action(self, parsed_args): client = self.app.client_manager.network - ext = str(parsed_args.extension) - obj = client.find_extension(ext, ignore_missing=False).to_dict() - return zip(*sorted(obj.items())) + extension = client.find_extension( + parsed_args.extension, + ignore_missing=False, + ) + + display_columns, columns = _get_extension_columns(extension) + data = utils.get_dict_properties(extension, columns) + return display_columns, data diff --git a/openstackclient/tests/unit/common/test_extension.py b/openstackclient/tests/unit/common/test_extension.py index 0771036f7a..d7cb29a722 100644 --- a/openstackclient/tests/unit/common/test_extension.py +++ b/openstackclient/tests/unit/common/test_extension.py @@ -20,7 +20,7 @@ from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes from openstackclient.tests.unit.network.v2 import fakes as network_fakes from openstackclient.tests.unit import utils from openstackclient.tests.unit import utils as tests_utils -from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes +from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes class TestExtension(utils.TestCommand): @@ -37,26 +37,16 @@ class TestExtension(utils.TestCommand): sdk_connection = mock.Mock() self.app.client_manager.sdk_connection = sdk_connection + self.compute_extensions_mock = sdk_connection.compute.extensions self.compute_extensions_mock.reset_mock() - volume_client = volume_fakes.FakeVolumeClient( - endpoint=fakes.AUTH_URL, - token=fakes.AUTH_TOKEN, - ) - self.app.client_manager.volume = volume_client - volume_client.list_extensions = mock.Mock() - self.volume_extensions_mock = volume_client.list_extensions + self.volume_extensions_mock = sdk_connection.volume.extensions self.volume_extensions_mock.reset_mock() - network_client = network_fakes.FakeNetworkV2Client( - endpoint=fakes.AUTH_URL, - token=fakes.AUTH_TOKEN, - ) - self.app.client_manager.network = network_client - network_client.extensions = mock.Mock() - self.network_extensions_mock = network_client.extensions - self.network_extensions_mock.reset_mock() + self.app.client_manager.network = mock.Mock() + self.network_client = self.app.client_manager.network + self.network_client.extensions = mock.Mock() class TestExtensionList(TestExtension): @@ -66,14 +56,14 @@ class TestExtensionList(TestExtension): 'Alias', 'Description', 'Namespace', - 'Updated', + 'Updated At', 'Links', ) volume_extension = volume_fakes.create_one_extension() identity_extension = identity_fakes.FakeExtension.create_one_extension() compute_extension = compute_fakes.create_one_extension() - network_extension = network_fakes.FakeExtension.create_one_extension() + network_extension = network_fakes.create_one_extension() def setUp(self): super().setUp() @@ -82,10 +72,8 @@ class TestExtensionList(TestExtension): self.identity_extension ] self.compute_extensions_mock.return_value = [self.compute_extension] - self.volume_extensions_mock.show_all.return_value = [ - self.volume_extension - ] - self.network_extensions_mock.return_value = [self.network_extension] + self.volume_extensions_mock.return_value = [self.volume_extension] + self.network_client.extensions.return_value = [self.network_extension] # Get the command object to test self.cmd = extension.ListExtension(self.app, None) @@ -134,8 +122,8 @@ class TestExtensionList(TestExtension): self._test_extension_list_helper(arglist, verifylist, datalist) self.identity_extensions_mock.list.assert_called_with() self.compute_extensions_mock.assert_called_with() - self.volume_extensions_mock.show_all.assert_called_with() - self.network_extensions_mock.assert_called_with() + self.volume_extensions_mock.assert_called_with() + self.network_client.extensions.assert_called_with() def test_extension_list_long(self): arglist = [ @@ -150,7 +138,7 @@ class TestExtensionList(TestExtension): self.identity_extension.alias, self.identity_extension.description, self.identity_extension.namespace, - self.identity_extension.updated, + '', self.identity_extension.links, ), ( @@ -158,31 +146,31 @@ class TestExtensionList(TestExtension): self.compute_extension.alias, self.compute_extension.description, self.compute_extension.namespace, - self.compute_extension.updated, + self.compute_extension.updated_at, self.compute_extension.links, ), ( self.volume_extension.name, self.volume_extension.alias, self.volume_extension.description, - self.volume_extension.namespace, - self.volume_extension.updated, + '', + self.volume_extension.updated_at, self.volume_extension.links, ), ( self.network_extension.name, self.network_extension.alias, self.network_extension.description, - self.network_extension.namespace, - self.network_extension.updated, + '', + self.network_extension.updated_at, self.network_extension.links, ), ) self._test_extension_list_helper(arglist, verifylist, datalist, True) self.identity_extensions_mock.list.assert_called_with() self.compute_extensions_mock.assert_called_with() - self.volume_extensions_mock.show_all.assert_called_with() - self.network_extensions_mock.assert_called_with() + self.volume_extensions_mock.assert_called_with() + self.network_client.extensions.assert_called_with() def test_extension_list_identity(self): arglist = [ @@ -216,7 +204,7 @@ class TestExtensionList(TestExtension): ), ) self._test_extension_list_helper(arglist, verifylist, datalist) - self.network_extensions_mock.assert_called_with() + self.network_client.extensions.assert_called_with() def test_extension_list_network_with_long(self): arglist = [ @@ -232,15 +220,15 @@ class TestExtensionList(TestExtension): self.network_extension.name, self.network_extension.alias, self.network_extension.description, - self.network_extension.namespace, - self.network_extension.updated, + '', + self.network_extension.updated_at, self.network_extension.links, ), ) self._test_extension_list_helper( arglist, verifylist, datalist, long=True ) - self.network_extensions_mock.assert_called_with() + self.network_client.extensions.assert_called_with() def test_extension_list_compute(self): arglist = [ @@ -282,7 +270,7 @@ class TestExtensionList(TestExtension): ) self._test_extension_list_helper(arglist, verifylist, datalist) self.compute_extensions_mock.assert_called_with() - self.network_extensions_mock.assert_called_with() + self.network_client.extensions.assert_called_with() def test_extension_list_volume(self): arglist = [ @@ -299,28 +287,24 @@ class TestExtensionList(TestExtension): ), ) self._test_extension_list_helper(arglist, verifylist, datalist) - self.volume_extensions_mock.show_all.assert_called_with() + self.volume_extensions_mock.assert_called_with() class TestExtensionShow(TestExtension): - extension_details = network_fakes.FakeExtension.create_one_extension() + extension_details = network_fakes.create_one_extension() columns = ( 'alias', 'description', - 'links', 'name', - 'namespace', - 'updated', + 'updated_at', ) data = ( extension_details.alias, extension_details.description, - extension_details.links, extension_details.name, - extension_details.namespace, - extension_details.updated, + extension_details.updated_at, ) def setUp(self): diff --git a/openstackclient/tests/unit/compute/v2/fakes.py b/openstackclient/tests/unit/compute/v2/fakes.py index aac9104d30..269d87fec8 100644 --- a/openstackclient/tests/unit/compute/v2/fakes.py +++ b/openstackclient/tests/unit/compute/v2/fakes.py @@ -21,6 +21,7 @@ import uuid from novaclient import api_versions from openstack.compute.v2 import aggregate as _aggregate from openstack.compute.v2 import availability_zone as _availability_zone +from openstack.compute.v2 import extension as _extension from openstack.compute.v2 import flavor as _flavor from openstack.compute.v2 import hypervisor as _hypervisor from openstack.compute.v2 import keypair as _keypair @@ -288,35 +289,33 @@ def create_agents(attrs=None, count=2): def create_one_extension(attrs=None): """Create a fake extension. - :param dict attrs: - A dictionary with all attributes - :return: - A FakeResource object with name, namespace, etc. + :param dict attrs: A dictionary with all attributes + :return: A fake openstack.compute.v2.extension.Extension object """ attrs = attrs or {} # Set default attributes. extension_info = { + 'alias': 'NMN', + 'description': 'description-' + uuid.uuid4().hex, + 'links': [ + { + "href": "https://github.com/openstack/compute-api", + "type": "text/html", + "rel": "describedby", + } + ], 'name': 'name-' + uuid.uuid4().hex, 'namespace': ( 'http://docs.openstack.org/compute/ext/multinic/api/v1.1' ), - 'description': 'description-' + uuid.uuid4().hex, - 'updated': '2014-01-07T12:00:0-00:00', - 'alias': 'NMN', - 'links': ( - '[{"href":' - '"https://github.com/openstack/compute-api", "type":' - ' "text/html", "rel": "describedby"}]' - ), + 'updated_at': '2014-01-07T12:00:0-00:00', } # Overwrite default attributes. extension_info.update(attrs) - extension = fakes.FakeResource( - info=copy.deepcopy(extension_info), loaded=True - ) + extension = _extension.Extension(**extension_info) return extension diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py index 06867707b0..c6c63a0224 100644 --- a/openstackclient/tests/unit/network/v2/fakes.py +++ b/openstackclient/tests/unit/network/v2/fakes.py @@ -23,6 +23,7 @@ from openstack.network.v2 import address_scope as _address_scope from openstack.network.v2 import agent as network_agent from openstack.network.v2 import auto_allocated_topology as allocated_topology from openstack.network.v2 import availability_zone as _availability_zone +from openstack.network.v2 import extension as _extension from openstack.network.v2 import flavor as _flavor from openstack.network.v2 import local_ip as _local_ip from openstack.network.v2 import local_ip_association as _local_ip_association @@ -101,21 +102,12 @@ class FakeNetworkV2Client(object): class TestNetworkV2(utils.TestCommand): def setUp(self): - super(TestNetworkV2, self).setUp() + super().setUp() self.namespace = argparse.Namespace() self.app.client_manager.session = mock.Mock() - - self.app.client_manager.network = FakeNetworkV2Client( - endpoint=fakes.AUTH_URL, - token=fakes.AUTH_TOKEN, - ) - - self.app.client_manager.sdk_connection = mock.Mock() - self.app.client_manager.sdk_connection.network = ( - self.app.client_manager.network - ) + self.app.client_manager.network = mock.Mock() self.app.client_manager.identity = ( identity_fakes_v3.FakeIdentityv3Client( @@ -125,37 +117,30 @@ class TestNetworkV2(utils.TestCommand): ) -class FakeExtension(object): - """Fake one or more extension.""" +def create_one_extension(attrs=None): + """Create a fake extension. - @staticmethod - def create_one_extension(attrs=None): - """Create a fake extension. + :param Dictionary attrs: + A dictionary with all attributes + :return: + An Extension object with name, namespace, etc. + """ + attrs = attrs or {} - :param Dictionary attrs: - A dictionary with all attributes - :return: - A FakeResource object with name, namespace, etc. - """ - attrs = attrs or {} + # Set default attributes. + extension_info = { + 'name': 'name-' + uuid.uuid4().hex, + 'description': 'description-' + uuid.uuid4().hex, + 'alias': 'Dystopian', + 'links': [], + 'updated_at': '2013-07-09T12:00:0-00:00', + } - # Set default attributes. - extension_info = { - 'name': 'name-' + uuid.uuid4().hex, - 'namespace': 'http://docs.openstack.org/network/', - 'description': 'description-' + uuid.uuid4().hex, - 'updated': '2013-07-09T12:00:0-00:00', - 'alias': 'Dystopian', - 'links': '[{"href":' '"https://github.com/os/network", "type"}]', - } + # Overwrite default attributes. + extension_info.update(attrs) - # Overwrite default attributes. - extension_info.update(attrs) - - extension = fakes.FakeResource( - info=copy.deepcopy(extension_info), loaded=True - ) - return extension + extension = _extension.Extension(**extension_info) + return extension class FakeNetworkQosPolicy(object): diff --git a/openstackclient/tests/unit/network/v2/test_router.py b/openstackclient/tests/unit/network/v2/test_router.py index e4bce6bbea..060d2c6557 100644 --- a/openstackclient/tests/unit/network/v2/test_router.py +++ b/openstackclient/tests/unit/network/v2/test_router.py @@ -485,7 +485,7 @@ class TestDeleteRouter(TestRouter): class TestListRouter(TestRouter): # The routers going to be listed up. routers = network_fakes.FakeRouter.create_routers(count=3) - _extensions = network_fakes.FakeExtension.create_one_extension() + extensions = network_fakes.create_one_extension() columns = ( 'ID', @@ -572,7 +572,7 @@ class TestListRouter(TestRouter): return_value=self.routers ) self.network.routers = mock.Mock(return_value=self.routers) - self.network.find_extension = mock.Mock(return_value=self._extensions) + self.network.find_extension = mock.Mock(return_value=self.extensions) self.network.find_router = mock.Mock(return_value=self.routers[0]) self._testagent = network_fakes.create_one_network_agent() self.network.get_agent = mock.Mock(return_value=self._testagent) diff --git a/openstackclient/tests/unit/volume/v2/fakes.py b/openstackclient/tests/unit/volume/v2/fakes.py index 23f6ffe252..6799a82b21 100644 --- a/openstackclient/tests/unit/volume/v2/fakes.py +++ b/openstackclient/tests/unit/volume/v2/fakes.py @@ -56,8 +56,6 @@ class FakeVolumeClient: self.cgsnapshots.resource_class = fakes.FakeResource(None, {}) self.consistencygroups = mock.Mock() self.consistencygroups.resource_class = fakes.FakeResource(None, {}) - self.extensions = mock.Mock() - self.extensions.resource_class = fakes.FakeResource(None, {}) self.limits = mock.Mock() self.limits.resource_class = fakes.FakeResource(None, {}) self.pools = mock.Mock() @@ -727,42 +725,6 @@ def get_consistency_group_snapshots(snapshots=None, count=2): return mock.Mock(side_effect=snapshots) -def create_one_extension(attrs=None): - """Create a fake extension. - - :param dict attrs: - A dictionary with all attributes - :return: - A FakeResource object with name, namespace, etc. - """ - attrs = attrs or {} - - # Set default attributes. - extension_info = { - 'name': 'name-' + uuid.uuid4().hex, - 'namespace': ( - 'http://docs.openstack.org/' - 'block-service/ext/scheduler-hints/api/v2' - ), - 'description': 'description-' + uuid.uuid4().hex, - 'updated': '2013-04-18T00:00:00+00:00', - 'alias': 'OS-SCH-HNT', - 'links': ( - '[{"href":' - '"https://github.com/openstack/block-api", "type":' - ' "text/html", "rel": "describedby"}]' - ), - } - - # Overwrite default attributes. - extension_info.update(attrs) - - extension = fakes.FakeResource( - info=copy.deepcopy(extension_info), loaded=True - ) - return extension - - def create_one_qos(attrs=None): """Create a fake Qos specification. diff --git a/openstackclient/tests/unit/volume/v3/fakes.py b/openstackclient/tests/unit/volume/v3/fakes.py index 1fb3484df8..454c90fbda 100644 --- a/openstackclient/tests/unit/volume/v3/fakes.py +++ b/openstackclient/tests/unit/volume/v3/fakes.py @@ -17,6 +17,7 @@ import uuid from cinderclient import api_versions from openstack.block_storage.v3 import availability_zone as _availability_zone from openstack.block_storage.v3 import block_storage_summary as _summary +from openstack.block_storage.v3 import extension as _extension from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes from openstackclient.tests.unit import fakes @@ -116,6 +117,37 @@ def create_availability_zones(attrs=None, count=2): return availability_zones +def create_one_extension(attrs=None): + """Create a fake extension. + + :param dict attrs: A dictionary with all attributes + :return: A fake + openstack.block_storage.v3.extension.Extension object + """ + attrs = attrs or {} + + # Set default attributes. + extension_info = { + 'alias': 'OS-SCH-HNT', + 'description': 'description-' + uuid.uuid4().hex, + 'links': [ + { + "href": "https://github.com/openstack/block-api", + "type": "text/html", + "rel": "describedby", + } + ], + 'name': 'name-' + uuid.uuid4().hex, + 'updated_at': '2013-04-18T00:00:00+00:00', + } + + # Overwrite default attributes. + extension_info.update(attrs) + + extension = _extension.Extension(**extension_info) + return extension + + def create_one_cluster(attrs=None): """Create a fake service cluster.