Improve flavor set command to support updating flavor
For now, "flavor set" command only support to add flavor accesses, this change add support to updating flavor other attributes for this command. Change-Id: If32a46decebee62695f4e4f7f51c2fafbb64b5bf
This commit is contained in:
parent
cf3dbd365f
commit
3e3dc6a8a1
@ -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='<flavor>',
|
||||
help=_("Flavor to modify (name or UUID)")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
metavar='<project>',
|
||||
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='<flavor>',
|
||||
help=_("Flavor to modify (name or UUID)")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
metavar='<project>',
|
||||
help=_('Set flavor access to project (name or ID) '
|
||||
'(admin only)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
metavar='<name>',
|
||||
help=_('Set a new name to a flavor (admin only)')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--is-public',
|
||||
metavar='<is-public>',
|
||||
type=strutils.bool_from_string,
|
||||
help=_('Set a flavor to be public or private '
|
||||
'(admin only)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--disabled',
|
||||
metavar='<disabled>',
|
||||
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"""
|
||||
|
||||
|
@ -171,7 +171,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,
|
||||
|
@ -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'})
|
||||
|
@ -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})
|
||||
|
Loading…
x
Reference in New Issue
Block a user