Add "--property" option to "flavor create" command
Add "--property" option to "flavor create" command to support adding properties to a new falvor. Change-Id: I4f06b364375d5a81584fe41122d48e9568fa712a Closes-Bug: #1596798
This commit is contained in:
parent
9e47688e5e
commit
dbed97a24d
@ -21,6 +21,7 @@ Create new flavor
|
||||
[--vcpus <num-cpu>]
|
||||
[--rxtx-factor <factor>]
|
||||
[--public | --private]
|
||||
[--property <key=value> [...] ]
|
||||
[--project <project>]
|
||||
[--project-domain <project-domain>]
|
||||
<flavor-name>
|
||||
@ -61,6 +62,10 @@ Create new flavor
|
||||
|
||||
Flavor is not available to other projects
|
||||
|
||||
.. option:: --property <key=value>
|
||||
|
||||
Property to add for this flavor (repeat option to set multiple properties)
|
||||
|
||||
.. option:: --project <project>
|
||||
|
||||
Allow <project> to access private flavor (name or ID)
|
||||
|
@ -25,7 +25,8 @@ class FlavorTests(test.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
opts = cls.get_show_opts(cls.FIELDS)
|
||||
raw_output = cls.openstack('flavor create ' + cls.NAME + opts)
|
||||
raw_output = cls.openstack(
|
||||
'flavor create --property a=b --property c=d ' + cls.NAME + opts)
|
||||
expected = cls.NAME + '\n'
|
||||
cls.assertOutput(expected, raw_output)
|
||||
|
||||
@ -47,19 +48,22 @@ class FlavorTests(test.TestCase):
|
||||
|
||||
def test_flavor_properties(self):
|
||||
opts = self.get_show_opts(['properties'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
'flavor set --property a=b --property c=d ' + self.NAME
|
||||
)
|
||||
self.assertEqual('', raw_output)
|
||||
|
||||
# check the properties we added in create command.
|
||||
raw_output = self.openstack('flavor show ' + self.NAME + opts)
|
||||
self.assertEqual("a='b', c='d'\n", raw_output)
|
||||
|
||||
raw_output = self.openstack(
|
||||
'flavor unset --property a ' + self.NAME
|
||||
'flavor set --property e=f --property g=h ' + self.NAME
|
||||
)
|
||||
self.assertEqual('', raw_output)
|
||||
|
||||
raw_output = self.openstack('flavor show ' + self.NAME + opts)
|
||||
self.assertEqual("c='d'\n", raw_output)
|
||||
self.assertEqual("a='b', c='d', e='f', g='h'\n", raw_output)
|
||||
|
||||
raw_output = self.openstack(
|
||||
'flavor unset --property a --property c ' + self.NAME
|
||||
)
|
||||
self.assertEqual('', raw_output)
|
||||
|
||||
raw_output = self.openstack('flavor show ' + self.NAME + opts)
|
||||
self.assertEqual("e='f', g='h'\n", raw_output)
|
||||
|
@ -121,6 +121,13 @@ class CreateFlavor(command.ShowOne):
|
||||
action="store_false",
|
||||
help=_("Flavor is not available to other projects")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--property",
|
||||
metavar="<key=value>",
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_("Property to add for this flavor "
|
||||
"(repeat option to set multiple properties)")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
metavar='<project>',
|
||||
@ -150,8 +157,7 @@ class CreateFlavor(command.ShowOne):
|
||||
parsed_args.public
|
||||
)
|
||||
|
||||
flavor = compute_client.flavors.create(*args)._info.copy()
|
||||
flavor.pop("links")
|
||||
flavor = compute_client.flavors.create(*args)
|
||||
|
||||
if parsed_args.project:
|
||||
try:
|
||||
@ -166,8 +172,17 @@ class CreateFlavor(command.ShowOne):
|
||||
msg = _("Failed to add project %(project)s access to "
|
||||
"flavor: %(e)s")
|
||||
LOG.error(msg % {'project': parsed_args.project, 'e': e})
|
||||
if parsed_args.property:
|
||||
try:
|
||||
flavor.set_keys(parsed_args.property)
|
||||
except Exception as e:
|
||||
LOG.error(_("Failed to set flavor property: %s"), e)
|
||||
|
||||
return zip(*sorted(six.iteritems(flavor)))
|
||||
flavor_info = flavor._info.copy()
|
||||
flavor_info.pop("links")
|
||||
flavor_info['properties'] = utils.format_dict(flavor.get_keys())
|
||||
|
||||
return zip(*sorted(six.iteritems(flavor_info)))
|
||||
|
||||
|
||||
class DeleteFlavor(command.Command):
|
||||
|
@ -716,6 +716,7 @@ class FakeFlavor(object):
|
||||
'OS-FLV-DISABLED:disabled': False,
|
||||
'os-flavor-access:is_public': True,
|
||||
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||
'properties': {'property': 'value'},
|
||||
}
|
||||
|
||||
# Overwrite default attributes.
|
||||
|
@ -56,6 +56,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
'id',
|
||||
'name',
|
||||
'os-flavor-access:is_public',
|
||||
'properties',
|
||||
'ram',
|
||||
'rxtx_factor',
|
||||
'swap',
|
||||
@ -68,6 +69,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
flavor.id,
|
||||
flavor.name,
|
||||
flavor.is_public,
|
||||
utils.format_dict(flavor.properties),
|
||||
flavor.ram,
|
||||
flavor.rxtx_factor,
|
||||
flavor.swap,
|
||||
@ -116,7 +118,6 @@ class TestFlavorCreate(TestFlavor):
|
||||
def test_flavor_create_all_options(self):
|
||||
|
||||
arglist = [
|
||||
self.flavor.name,
|
||||
'--id', self.flavor.id,
|
||||
'--ram', str(self.flavor.ram),
|
||||
'--disk', str(self.flavor.disk),
|
||||
@ -125,9 +126,10 @@ class TestFlavorCreate(TestFlavor):
|
||||
'--vcpus', str(self.flavor.vcpus),
|
||||
'--rxtx-factor', str(self.flavor.rxtx_factor),
|
||||
'--public',
|
||||
'--property', 'property=value',
|
||||
self.flavor.name,
|
||||
]
|
||||
verifylist = [
|
||||
('name', self.flavor.name),
|
||||
('id', self.flavor.id),
|
||||
('ram', self.flavor.ram),
|
||||
('disk', self.flavor.disk),
|
||||
@ -136,6 +138,8 @@ class TestFlavorCreate(TestFlavor):
|
||||
('vcpus', self.flavor.vcpus),
|
||||
('rxtx_factor', self.flavor.rxtx_factor),
|
||||
('public', True),
|
||||
('property', {'property': 'value'}),
|
||||
('name', self.flavor.name),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
@ -152,6 +156,8 @@ class TestFlavorCreate(TestFlavor):
|
||||
)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.flavors_mock.create.assert_called_once_with(*args)
|
||||
self.flavor.set_keys.assert_called_once_with({'property': 'value'})
|
||||
self.flavor.get_keys.assert_called_once_with()
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
@ -160,7 +166,6 @@ class TestFlavorCreate(TestFlavor):
|
||||
|
||||
self.flavor.is_public = False
|
||||
arglist = [
|
||||
self.flavor.name,
|
||||
'--id', self.flavor.id,
|
||||
'--ram', str(self.flavor.ram),
|
||||
'--disk', str(self.flavor.disk),
|
||||
@ -170,9 +175,11 @@ class TestFlavorCreate(TestFlavor):
|
||||
'--rxtx-factor', str(self.flavor.rxtx_factor),
|
||||
'--private',
|
||||
'--project', identity_fakes.project_id,
|
||||
'--property', 'key1=value1',
|
||||
'--property', 'key2=value2',
|
||||
self.flavor.name,
|
||||
]
|
||||
verifylist = [
|
||||
('name', self.flavor.name),
|
||||
('id', self.flavor.id),
|
||||
('ram', self.flavor.ram),
|
||||
('disk', self.flavor.disk),
|
||||
@ -182,6 +189,8 @@ class TestFlavorCreate(TestFlavor):
|
||||
('rxtx_factor', self.flavor.rxtx_factor),
|
||||
('public', False),
|
||||
('project', identity_fakes.project_id),
|
||||
('property', {'key1': 'value1', 'key2': 'value2'}),
|
||||
('name', self.flavor.name),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
@ -202,6 +211,9 @@ class TestFlavorCreate(TestFlavor):
|
||||
self.flavor.id,
|
||||
identity_fakes.project_id,
|
||||
)
|
||||
self.flavor.set_keys.assert_called_with(
|
||||
{'key1': 'value1', 'key2': 'value2'})
|
||||
self.flavor.get_keys.assert_called_with()
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
|
4
releasenotes/notes/bug-1596798-b22fd587bdca8b36.yaml
Normal file
4
releasenotes/notes/bug-1596798-b22fd587bdca8b36.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- Add ``--property`` option to ``flavor create`` command.
|
||||
[Bug `1596798 <https://bugs.launchpad.net/bugs/1596798>`_]
|
Loading…
Reference in New Issue
Block a user