diff --git a/moganclient/osc/v1/flavor.py b/moganclient/osc/v1/flavor.py index 32505fd..d765f5e 100644 --- a/moganclient/osc/v1/flavor.py +++ b/moganclient/osc/v1/flavor.py @@ -22,6 +22,7 @@ from osc_lib.cli import parseractions from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils +from oslo_utils import strutils from moganclient.common.i18n import _ @@ -164,50 +165,6 @@ class ListFlavor(command.Lister): ) for s in data)) -class SetFlavor(command.Command): - """Set baremetal flavor properties""" - - def get_parser(self, prog_name): - parser = super(SetFlavor, self).get_parser(prog_name) - parser.add_argument( - 'flavor', - metavar='', - help=_("Flavor to modify (name or UUID)") - ) - parser.add_argument( - '--project', - metavar='', - help=_('Set flavor access to project (name or ID) ' - '(admin only)'), - ) - return parser - - def take_action(self, parsed_args): - - bc_client = self.app.client_manager.baremetal_compute - data = utils.find_resource( - bc_client.flavor, - parsed_args.flavor, - ) - - result = 0 - if parsed_args.project: - try: - if data.is_public: - msg = _("Cannot set access for a public flavor") - raise exceptions.CommandError(msg) - else: - bc_client.flavor.add_tenant_access( - data, parsed_args.project) - except Exception as e: - LOG.error("Failed to set flavor access to project: %s", e) - result += 1 - - if result > 0: - raise exceptions.CommandError(_("Command Failed: One or more of" - " the operations failed")) - - class ShowFlavor(command.ShowOne): """Display baremetal flavor details""" @@ -226,12 +183,79 @@ class ShowFlavor(command.ShowOne): bc_client.flavor, parsed_args.flavor, ) - info = {} info.update(data._info) return zip(*sorted(info.items())) +class SetFlavor(command.Command): + """Set baremetal flavor properties""" + + def get_parser(self, prog_name): + parser = super(SetFlavor, self).get_parser(prog_name) + parser.add_argument( + 'flavor', + metavar='', + help=_("Flavor to modify (name or UUID)") + ) + parser.add_argument( + '--project', + metavar='', + help=_('Set flavor access to project (name or ID) ' + '(admin only)'), + ) + parser.add_argument( + '--name', + metavar='', + help=_('Set a new name to a flavor (admin only)') + ) + parser.add_argument( + '--is-public', + metavar='', + type=strutils.bool_from_string, + help=_('Set a flavor to be public or private ' + '(admin only)'), + ) + parser.add_argument( + '--disabled', + metavar='', + type=strutils.bool_from_string, + help=_('Set a flavor to be disabled or enabled ' + '(admin only)'), + ) + return parser + + def take_action(self, parsed_args): + + bc_client = self.app.client_manager.baremetal_compute + data = utils.find_resource( + bc_client.flavor, + parsed_args.flavor, + ) + updates = [] + if parsed_args.name: + updates.append({"op": "replace", + "path": "/name", + "value": parsed_args.name}) + if parsed_args.is_public is not None: + updates.append({"op": "replace", + "path": "/is_public", + "value": parsed_args.is_public}) + if parsed_args.disabled is not None: + updates.append({"op": "replace", + "path": "/disabled", + "value": parsed_args.disabled}) + if updates: + bc_client.flavor.update(data, updates) + if parsed_args.project: + if data.is_public: + msg = _("Cannot set access for a public flavor") + raise exceptions.CommandError(msg) + else: + bc_client.flavor.add_tenant_access( + data, parsed_args.project) + + class UnsetFlavor(command.Command): """Unset baremetal flavor properties""" diff --git a/moganclient/tests/unit/fakes.py b/moganclient/tests/unit/fakes.py index 9592d1d..0f8ee7f 100644 --- a/moganclient/tests/unit/fakes.py +++ b/moganclient/tests/unit/fakes.py @@ -178,7 +178,7 @@ class FakeFlavor(object): "description": "fake_description", "resources": {"BAREMETAL_GOLD": 1}, "resource_traits": {"BAREMETAL_GOLD": "FPGA"}, - "is_public": True, + "is_public": False, "disabled": False, "name": "flavor-name-" + uuidutils.generate_uuid(dashed=False), "updated_at": None, diff --git a/moganclient/tests/unit/osc/v1/test_flavor.py b/moganclient/tests/unit/osc/v1/test_flavor.py index 8bd739c..48c7df4 100644 --- a/moganclient/tests/unit/osc/v1/test_flavor.py +++ b/moganclient/tests/unit/osc/v1/test_flavor.py @@ -273,3 +273,41 @@ class TestFlavorShow(TestFlavor): mock_get.assert_called_once_with(expected_url) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) + + +@mock.patch.object(utils, 'find_resource') +@mock.patch.object(flavor_mgr.FlavorManager, '_update') +class TestFlavorSet(TestFlavor): + def setUp(self): + super(TestFlavorSet, self).setUp() + self.cmd = flavor.SetFlavor(self.app, None) + + @mock.patch.object(flavor_mgr.FlavorManager, '_create') + def test_flavor_set(self, mock_create, mock_update, mock_find): + mock_find.return_value = self.fake_flavor + arglist = [ + '--project', 'fake_project', + '--name', 'new_name', + '--disabled', 'false', + '--is-public', 'false', + self.fake_flavor.uuid, + ] + verifylist = [ + ('flavor', self.fake_flavor.uuid), + ('disabled', False), + ('is_public', False), + ('name', 'new_name'), + ('project', 'fake_project'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + expected_url = '/flavors/%s' % parsed_args.flavor + expected_args = [ + {'path': '/name', 'value': 'new_name', 'op': 'replace'}, + {'path': '/is_public', 'value': False, 'op': 'replace'}, + {'path': '/disabled', 'value': False, 'op': 'replace'}, + ] + mock_update.assert_called_once_with(expected_url, expected_args) + expected_url += '/access' + mock_create.assert_called_once_with( + expected_url, data={'tenant_id': 'fake_project'}) diff --git a/moganclient/v1/flavor.py b/moganclient/v1/flavor.py index 1750dbb..3331d49 100644 --- a/moganclient/v1/flavor.py +++ b/moganclient/v1/flavor.py @@ -50,6 +50,10 @@ class FlavorManager(base.ManagerWithFind): url = '/flavors' return self._list(url, response_key='flavors') + def update(self, flavor, data): + url = '/flavors/%s' % base.getid(flavor) + return self._update(url, data) + def add_tenant_access(self, flavor, project): url = '/flavors/%s/access' % base.getid(flavor) return self._create(url, data={'tenant_id': project})