Merge "Migrate 'extension list' to SDK"

This commit is contained in:
Zuul 2023-09-05 19:30:04 +00:00 committed by Gerrit Code Review
commit 876c120a9c
7 changed files with 124 additions and 148 deletions
openstackclient
common
tests/unit

@ -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

@ -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):

@ -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

@ -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):

@ -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)

@ -57,8 +57,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()
@ -738,42 +736,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.

@ -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.