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:
liusheng 2017-07-25 12:49:53 +08:00
parent cf3dbd365f
commit 3e3dc6a8a1
4 changed files with 112 additions and 46 deletions

View File

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

View File

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

View File

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

View File

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