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>
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 show
from openstackclient.common import parseractions
from openstackclient.common import utils
@ -237,8 +238,79 @@ class ShowFlavor(show.ShowOne):
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
compute_client = self.app.client_manager.compute
flavor = utils.find_resource(compute_client.flavors,
parsed_args.flavor)._info.copy()
flavor.pop("links")
resource_flavor = utils.find_resource(compute_client.flavors,
parsed_args.flavor)
flavor = resource_flavor._info.copy()
flavor.pop("links", None)
flavor['properties'] = utils.format_dict(resource_flavor.get_keys())
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):
_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):
return {'property': 'value'}
return self._keys
class TestFlavor(compute_fakes.TestComputev2):
@ -272,3 +281,69 @@ class TestFlavorList(TestFlavor):
'property=\'value\''
), )
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_list = openstackclient.compute.v2.flavor:ListFlavor
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_show = openstackclient.compute.v2.host:ShowHost