Add the ability to set and unset flavor properties

Added flavor set and unset command which allow manage flavor
properties called extra_specs.

Command flavor show output was extended with these properties.

Closes-Bug: 1434137
Change-Id: Ie469bade802de18aab9d58eda3fff46064008163
This commit is contained in:
Marek Aufart 2015-03-17 15:38:24 +01:00 committed by Steve Martinelli
parent a8c44074f9
commit 621434451f
4 changed files with 193 additions and 4 deletions

View File

@ -123,3 +123,43 @@ Display flavor details
.. describe:: <flavor> .. describe:: <flavor>
Flavor to display (name or ID) Flavor to display (name or ID)
flavor set
----------
Set flavor properties
.. program:: flavor set
.. code:: bash
os flavor set
[--property <key=value> [...] ]
<flavor>
.. option:: --property <key=value>
Property to add or modify for this flavor (repeat option to set multiple properties)
.. describe:: <flavor>
Flavor to modify (name or ID)
flavor unset
------------
Unset flavor properties
.. program:: flavor unset
.. code:: bash
os flavor unset
[--property <key> [...] ]
<flavor>
.. option:: --property <key>
Property to remove from flavor (repeat option to remove multiple properties)
.. describe:: <flavor>
Flavor to modify (name or ID)

View File

@ -22,6 +22,7 @@ from cliff import command
from cliff import lister from cliff import lister
from cliff import show from cliff import show
from openstackclient.common import parseractions
from openstackclient.common import utils from openstackclient.common import utils
@ -237,8 +238,79 @@ class ShowFlavor(show.ShowOne):
def take_action(self, parsed_args): def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args) self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute compute_client = self.app.client_manager.compute
flavor = utils.find_resource(compute_client.flavors, resource_flavor = utils.find_resource(compute_client.flavors,
parsed_args.flavor)._info.copy() parsed_args.flavor)
flavor.pop("links") flavor = resource_flavor._info.copy()
flavor.pop("links", None)
flavor['properties'] = utils.format_dict(resource_flavor.get_keys())
return zip(*sorted(six.iteritems(flavor))) return zip(*sorted(six.iteritems(flavor)))
class SetFlavor(show.ShowOne):
"""Set flavor properties"""
log = logging.getLogger(__name__ + ".SetFlavor")
def get_parser(self, prog_name):
parser = super(SetFlavor, self).get_parser(prog_name)
parser.add_argument(
"--property",
metavar="<key=value>",
action=parseractions.KeyValueAction,
help='Property to add or modify for this flavor '
'(repeat option to set multiple properties)',
)
parser.add_argument(
"flavor",
metavar="<flavor>",
help="Flavor to modify (name or ID)",
)
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
resource_flavor = compute_client.flavors.find(name=parsed_args.flavor)
resource_flavor.set_keys(parsed_args.property)
flavor = resource_flavor._info.copy()
flavor['properties'] = utils.format_dict(resource_flavor.get_keys())
flavor.pop("links", None)
return zip(*sorted(six.iteritems(flavor)))
class UnsetFlavor(show.ShowOne):
"""Unset flavor properties"""
log = logging.getLogger(__name__ + ".UnsetFlavor")
def get_parser(self, prog_name):
parser = super(UnsetFlavor, self).get_parser(prog_name)
parser.add_argument(
"--property",
metavar="<key>",
action='append',
help='Property to remove from flavor '
'(repeat option to unset multiple properties)',
)
parser.add_argument(
"flavor",
metavar="<flavor>",
help="Flavor to modify (name or ID)",
)
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
resource_flavor = compute_client.flavors.find(name=parsed_args.flavor)
resource_flavor.unset_keys(parsed_args.property)
flavor = resource_flavor._info.copy()
flavor['properties'] = utils.format_dict(resource_flavor.get_keys())
flavor.pop("links", None)
return zip(*sorted(six.iteritems(flavor)))

View File

@ -22,8 +22,17 @@ from openstackclient.tests import fakes
class FakeFlavorResource(fakes.FakeResource): class FakeFlavorResource(fakes.FakeResource):
_keys = {'property': 'value'}
def set_keys(self, args):
self._keys.update(args)
def unset_keys(self, keys):
for key in keys:
self._keys.pop(key, None)
def get_keys(self): def get_keys(self):
return {'property': 'value'} return self._keys
class TestFlavor(compute_fakes.TestComputev2): class TestFlavor(compute_fakes.TestComputev2):
@ -272,3 +281,69 @@ class TestFlavorList(TestFlavor):
'property=\'value\'' 'property=\'value\''
), ) ), )
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
class TestFlavorSet(TestFlavor):
def setUp(self):
super(TestFlavorSet, self).setUp()
self.flavors_mock.find.return_value = FakeFlavorResource(
None,
copy.deepcopy(compute_fakes.FLAVOR),
loaded=True,
)
self.cmd = flavor.SetFlavor(self.app, None)
def test_flavor_set(self):
arglist = [
'--property', 'FOO="B A R"',
'baremetal'
]
verifylist = [
('property', {'FOO': '"B A R"'}),
('flavor', 'baremetal')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.flavors_mock.find.assert_called_with(name='baremetal')
self.assertEqual('properties', columns[2])
self.assertIn('FOO=\'"B A R"\'', data[2])
class TestFlavorUnset(TestFlavor):
def setUp(self):
super(TestFlavorUnset, self).setUp()
self.flavors_mock.find.return_value = FakeFlavorResource(
None,
copy.deepcopy(compute_fakes.FLAVOR),
loaded=True,
)
self.cmd = flavor.UnsetFlavor(self.app, None)
def test_flavor_unset(self):
arglist = [
'--property', 'property',
'baremetal'
]
verifylist = [
('property', ['property']),
('flavor', 'baremetal'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.flavors_mock.find.assert_called_with(name='baremetal')
self.assertEqual('properties', columns[2])
self.assertNotIn('property', data[2])

View File

@ -75,6 +75,8 @@ openstack.compute.v2 =
flavor_delete = openstackclient.compute.v2.flavor:DeleteFlavor flavor_delete = openstackclient.compute.v2.flavor:DeleteFlavor
flavor_list = openstackclient.compute.v2.flavor:ListFlavor flavor_list = openstackclient.compute.v2.flavor:ListFlavor
flavor_show = openstackclient.compute.v2.flavor:ShowFlavor flavor_show = openstackclient.compute.v2.flavor:ShowFlavor
flavor_set = openstackclient.compute.v2.flavor:SetFlavor
flavor_unset = openstackclient.compute.v2.flavor:UnsetFlavor
host_list = openstackclient.compute.v2.host:ListHost host_list = openstackclient.compute.v2.host:ListHost
host_show = openstackclient.compute.v2.host:ShowHost host_show = openstackclient.compute.v2.host:ShowHost