From e1cf238c5da444581090b05997139397fccf8462 Mon Sep 17 00:00:00 2001 From: ericxiett Date: Thu, 11 Nov 2021 08:07:18 +0000 Subject: [PATCH] Get device profile by name in cyborgclient This patch adds the support that getting the device profile by its name. Implements: blueprint show-device-profile-with-name Change-Id: I3587dce1555bf7a337661e2662165c171ddea57a --- cyborgclient/exceptions.py | 2 +- cyborgclient/osc/plugin.py | 4 +- cyborgclient/osc/v2/device_profile.py | 23 +++++------ .../tests/unit/osc/v2/test_device_profile.py | 40 +++++++++++++++++-- 4 files changed, 51 insertions(+), 18 deletions(-) diff --git a/cyborgclient/exceptions.py b/cyborgclient/exceptions.py index 25aeb8b..efe5f33 100644 --- a/cyborgclient/exceptions.py +++ b/cyborgclient/exceptions.py @@ -224,7 +224,7 @@ class NotAcceptable(HTTPClientError): acceptable according to the Accept headers sent in the request. """ status_code = 406 - message = _("Not Acceptable") + message = _("Not Acceptable %(message)s") class ProxyAuthenticationRequired(HTTPClientError): diff --git a/cyborgclient/osc/plugin.py b/cyborgclient/osc/plugin.py index 89ba0b1..4a3cbd5 100644 --- a/cyborgclient/osc/plugin.py +++ b/cyborgclient/osc/plugin.py @@ -75,7 +75,8 @@ def create_connection(prof=None, cloud_region=None, **kwargs): # If we got the CloudRegion from python-openstackclient and it doesn't # already have a default microversion set, set it here. microversion_key = _make_key(API_NAME, 'default_microversion') - cloud_region.config.setdefault(microversion_key, CURRENT_API_VERSION) + api_version = kwargs.get('api_version', CURRENT_API_VERSION) + cloud_region.config.setdefault(microversion_key, api_version) user_agent = kwargs.pop('user_agent', None) app_name = kwargs.pop('app_name', None) @@ -93,6 +94,7 @@ def make_client(instance): """Returns a accelerator proxy""" conn = create_connection( cloud_region=instance._cli_options, + api_version=instance._api_version[API_NAME] ) LOG.debug('Connection: %s', conn) diff --git a/cyborgclient/osc/v2/device_profile.py b/cyborgclient/osc/v2/device_profile.py index 86d5b90..f05b750 100644 --- a/cyborgclient/osc/v2/device_profile.py +++ b/cyborgclient/osc/v2/device_profile.py @@ -20,7 +20,6 @@ from openstack import exceptions as sdk_exc from osc_lib.command import command from osc_lib import utils as oscutils from oslo_serialization import jsonutils -from oslo_utils import uuidutils from cyborgclient.common import utils from cyborgclient import exceptions as exc @@ -162,8 +161,10 @@ class ShowDeviceProfile(command.ShowOne): parser = super(ShowDeviceProfile, self).get_parser(prog_name) parser.add_argument( "device_profile", - metavar="", - help=_("UUID of the device_profile.") + metavar="", + help=_("Name or UUID of the device_profile." + " The name field requires at least" + " ``--os-accelerator-api-version 2.2``.") ) return parser @@ -174,11 +175,8 @@ class ShowDeviceProfile(command.ShowOne): parsed_args.device_profile) -def _show_device_profile(acc_client, uuid): +def _show_device_profile(acc_client, name_or_uuid): """Show detailed info about device_profile.""" - if not uuidutils.is_uuid_like(uuid): - raise exc.CommandError(_('Only UUID of device_profile allowed. ' - 'Invalid input: %s') % uuid) columns = ( "created_at", @@ -189,12 +187,13 @@ def _show_device_profile(acc_client, uuid): "description", ) try: - device_profile = acc_client.get_device_profile(uuid) + device_profile = acc_client.get_device_profile(name_or_uuid) except sdk_exc.ResourceNotFound: - raise exc.CommandError(_('device_profile not found: %s') % uuid) - formatters = { - 'data': utils.json_formatter, - } + raise exc.CommandError(_('device_profile %s not found') % name_or_uuid) + except sdk_exc.HttpException as e: + raise exc.NotAcceptable(message=e.details) + + formatters = {'data': utils.json_formatter} data = device_profile.to_dict() return columns, oscutils.get_dict_properties(data, columns, formatters=formatters) diff --git a/cyborgclient/tests/unit/osc/v2/test_device_profile.py b/cyborgclient/tests/unit/osc/v2/test_device_profile.py index da5935d..2647343 100644 --- a/cyborgclient/tests/unit/osc/v2/test_device_profile.py +++ b/cyborgclient/tests/unit/osc/v2/test_device_profile.py @@ -12,6 +12,10 @@ # import copy +from openstack import exceptions as sdk_exc +from osc_lib import utils as oscutils + +from cyborgclient.common import utils from cyborgclient import exceptions as exc from cyborgclient.osc.v2 import device_profile as osc_device_profile from cyborgclient.tests.unit.osc.v2 import fakes as acc_fakes @@ -101,15 +105,43 @@ class TestDeviceProfileShow(TestDeviceProfile): super(TestDeviceProfileShow, self).setUp() self.cmd = osc_device_profile.ShowDeviceProfile(self.app, None) - def test_device_profile_show_with_name(self): + def test_device_profile_show_with_name_before_v22(self): + exc_msg = 'The minimal required API version should be 2.2' + self.mock_acc_client.get_device_profile.side_effect = \ + sdk_exc.HttpException(details=exc_msg) + arg_list = [acc_fakes.device_profile_name] verify_list = [] parsed_args = self.check_parser(self.cmd, arg_list, verify_list) - result = self.assertRaises(exc.CommandError, + result = self.assertRaises(exc.NotAcceptable, self.cmd.take_action, parsed_args) - self.assertIn("Only UUID of device_profile allowed. " - "Invalid input: fake_devprof_name", str(result)) + self.assertIn(exc_msg, str(result)) + + def test_device_profile_show_with_name(self): + fake_dp = acc_fakes.FakeAcceleratorResource( + None, + copy.deepcopy(acc_fakes.DEVICE_PROFILE), + loaded=True) + self.mock_acc_client.get_device_profile.return_value = fake_dp + + arg_list = [acc_fakes.device_profile_name] + verify_list = [] + parsed_args = self.check_parser(self.cmd, arg_list, verify_list) + result = self.cmd.take_action(parsed_args) + columns = ( + "created_at", + "updated_at", + "uuid", + "name", + "groups", + "description", + ) + formatters = {'data': utils.json_formatter} + expected = oscutils.get_dict_properties(acc_fakes.DEVICE_PROFILE, + columns, + formatters=formatters) + self.assertEqual(result, (columns, expected)) class TestDeviceProfileCreate(TestDeviceProfile):