summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/command-objects/flavor.rst5
-rw-r--r--functional/tests/compute/v2/test_flavor.py14
-rw-r--r--openstackclient/compute/v2/flavor.py21
-rw-r--r--openstackclient/tests/compute/v2/fakes.py1
-rw-r--r--openstackclient/tests/compute/v2/test_flavor.py20
-rw-r--r--releasenotes/notes/bug-1596798-b22fd587bdca8b36.yaml4
6 files changed, 53 insertions, 12 deletions
diff --git a/doc/source/command-objects/flavor.rst b/doc/source/command-objects/flavor.rst
index a886b9ff..9ea504c1 100644
--- a/doc/source/command-objects/flavor.rst
+++ b/doc/source/command-objects/flavor.rst
@@ -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)
diff --git a/functional/tests/compute/v2/test_flavor.py b/functional/tests/compute/v2/test_flavor.py
index 2bb075bd..6edb1fdf 100644
--- a/functional/tests/compute/v2/test_flavor.py
+++ b/functional/tests/compute/v2/test_flavor.py
@@ -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'])
+ # 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 set --property a=b --property c=d ' + 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("a='b', 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 ' + self.NAME
+ 'flavor unset --property a --property c ' + self.NAME
)
self.assertEqual('', raw_output)
raw_output = self.openstack('flavor show ' + self.NAME + opts)
- self.assertEqual("c='d'\n", raw_output)
+ self.assertEqual("e='f', g='h'\n", raw_output)
diff --git a/openstackclient/compute/v2/flavor.py b/openstackclient/compute/v2/flavor.py
index 01d7da75..000df598 100644
--- a/openstackclient/compute/v2/flavor.py
+++ b/openstackclient/compute/v2/flavor.py
@@ -122,6 +122,13 @@ class CreateFlavor(command.ShowOne):
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>',
help=_("Allow <project> to access private flavor (name or ID) "
@@ -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):
diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py
index b7f17fbc..a7a66d5e 100644
--- a/openstackclient/tests/compute/v2/fakes.py
+++ b/openstackclient/tests/compute/v2/fakes.py
@@ -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.
diff --git a/openstackclient/tests/compute/v2/test_flavor.py b/openstackclient/tests/compute/v2/test_flavor.py
index da76b6d7..20ae8706 100644
--- a/openstackclient/tests/compute/v2/test_flavor.py
+++ b/openstackclient/tests/compute/v2/test_flavor.py
@@ -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)
diff --git a/releasenotes/notes/bug-1596798-b22fd587bdca8b36.yaml b/releasenotes/notes/bug-1596798-b22fd587bdca8b36.yaml
new file mode 100644
index 00000000..6ab833da
--- /dev/null
+++ b/releasenotes/notes/bug-1596798-b22fd587bdca8b36.yaml
@@ -0,0 +1,4 @@
+---
+features:
+ - Add ``--property`` option to ``flavor create`` command.
+ [Bug `1596798 <https://bugs.launchpad.net/bugs/1596798>`_]