Skip to content

Commit 7b8873d

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Compute: Add description support for flavor"
2 parents ddcc25e + 4a68ba6 commit 7b8873d

5 files changed

Lines changed: 177 additions & 4 deletions

File tree

doc/source/cli/command-objects/flavor.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Create new flavor
2424
[--property <key=value> [...] ]
2525
[--project <project>]
2626
[--project-domain <project-domain>]
27+
[--description <description>]
2728
<flavor-name>
2829
2930
.. option:: --id <id>
@@ -76,6 +77,10 @@ Create new flavor
7677
Domain the project belongs to (name or ID).
7778
This can be used in case collisions between project names exist.
7879

80+
.. option:: --description <description>
81+
82+
Description to add for this flavor
83+
7984
.. _flavor_create-flavor-name:
8085
.. describe:: <flavor-name>
8186

@@ -148,6 +153,7 @@ Set flavor properties
148153
[--property <key=value> [...] ]
149154
[--project <project>]
150155
[--project-domain <project-domain>]
156+
[--description <description>]
151157
<flavor>
152158
153159
.. option:: --property <key=value>
@@ -168,6 +174,10 @@ Set flavor properties
168174
Remove all properties from this flavor (specify both --no-property and --property
169175
to remove the current properties before setting new properties.)
170176

177+
.. option:: --description <description>
178+
179+
Set description to this flavor
180+
171181
.. describe:: <flavor>
172182

173183
Flavor to modify (name or ID)

openstackclient/compute/v2/flavor.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import logging
1919

20+
from novaclient import api_versions
2021
from osc_lib.cli import parseractions
2122
from osc_lib.command import command
2223
from osc_lib import exceptions
@@ -134,6 +135,12 @@ def get_parser(self, prog_name):
134135
help=_("Allow <project> to access private flavor (name or ID) "
135136
"(Must be used with --private option)"),
136137
)
138+
parser.add_argument(
139+
'--description',
140+
metavar='<description>',
141+
help=_("Description for the flavor.(Supported by API versions "
142+
"'2.55' - '2.latest'")
143+
)
137144
identity_common.add_project_domain_option_to_parser(parser)
138145
return parser
139146

@@ -145,6 +152,11 @@ def take_action(self, parsed_args):
145152
msg = _("--project is only allowed with --private")
146153
raise exceptions.CommandError(msg)
147154

155+
if parsed_args.description:
156+
if compute_client.api_version < api_versions.APIVersion("2.55"):
157+
msg = _("--os-compute-api-version 2.55 or later is required")
158+
raise exceptions.CommandError(msg)
159+
148160
args = (
149161
parsed_args.name,
150162
parsed_args.ram,
@@ -154,7 +166,8 @@ def take_action(self, parsed_args):
154166
parsed_args.ephemeral,
155167
parsed_args.swap,
156168
parsed_args.rxtx_factor,
157-
parsed_args.public
169+
parsed_args.public,
170+
parsed_args.description
158171
)
159172

160173
flavor = compute_client.flavors.create(*args)
@@ -332,6 +345,12 @@ def get_parser(self, prog_name):
332345
help=_('Set flavor access to project (name or ID) '
333346
'(admin only)'),
334347
)
348+
parser.add_argument(
349+
'--description',
350+
metavar='<description>',
351+
help=_("Set description for the flavor.(Supported by API "
352+
"versions '2.55' - '2.latest'")
353+
)
335354
identity_common.add_project_domain_option_to_parser(parser)
336355

337356
return parser
@@ -380,6 +399,13 @@ def take_action(self, parsed_args):
380399
raise exceptions.CommandError(_("Command Failed: One or more of"
381400
" the operations failed"))
382401

402+
if parsed_args.description:
403+
if compute_client.api_version < api_versions.APIVersion("2.55"):
404+
msg = _("--os-compute-api-version 2.55 or later is required")
405+
raise exceptions.CommandError(msg)
406+
compute_client.flavors.update(flavor=parsed_args.flavor,
407+
description=parsed_args.description)
408+
383409

384410
class ShowFlavor(command.ShowOne):
385411
_description = _("Display flavor details")

openstackclient/tests/unit/compute/v2/fakes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,7 @@ def create_one_flavor(attrs=None):
765765
'rxtx_factor': 1.0,
766766
'OS-FLV-DISABLED:disabled': False,
767767
'os-flavor-access:is_public': True,
768+
'description': 'description',
768769
'OS-FLV-EXT-DATA:ephemeral': 0,
769770
'properties': {'property': 'value'},
770771
}

openstackclient/tests/unit/compute/v2/test_flavor.py

Lines changed: 133 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import mock
1717
from mock import call
1818

19+
import novaclient
1920
from osc_lib import exceptions
2021
from osc_lib import utils
2122

@@ -50,6 +51,7 @@ class TestFlavorCreate(TestFlavor):
5051
columns = (
5152
'OS-FLV-DISABLED:disabled',
5253
'OS-FLV-EXT-DATA:ephemeral',
54+
'description',
5355
'disk',
5456
'id',
5557
'name',
@@ -63,6 +65,7 @@ class TestFlavorCreate(TestFlavor):
6365
data = (
6466
flavor.disabled,
6567
flavor.ephemeral,
68+
flavor.description,
6669
flavor.disk,
6770
flavor.id,
6871
flavor.name,
@@ -101,7 +104,8 @@ def test_flavor_create_default_options(self):
101104
0,
102105
0,
103106
1.0,
104-
True
107+
True,
108+
None,
105109
)
106110
columns, data = self.cmd.take_action(parsed_args)
107111
self.flavors_mock.create.assert_called_once_with(*default_args)
@@ -120,6 +124,7 @@ def test_flavor_create_all_options(self):
120124
'--vcpus', str(self.flavor.vcpus),
121125
'--rxtx-factor', str(self.flavor.rxtx_factor),
122126
'--public',
127+
'--description', str(self.flavor.description),
123128
'--property', 'property=value',
124129
self.flavor.name,
125130
]
@@ -132,6 +137,7 @@ def test_flavor_create_all_options(self):
132137
('vcpus', self.flavor.vcpus),
133138
('rxtx_factor', self.flavor.rxtx_factor),
134139
('public', True),
140+
('description', self.flavor.description),
135141
('property', {'property': 'value'}),
136142
('name', self.flavor.name),
137143
]
@@ -147,8 +153,13 @@ def test_flavor_create_all_options(self):
147153
self.flavor.swap,
148154
self.flavor.rxtx_factor,
149155
self.flavor.is_public,
156+
self.flavor.description,
150157
)
151-
columns, data = self.cmd.take_action(parsed_args)
158+
self.app.client_manager.compute.api_version = 2.55
159+
with mock.patch.object(novaclient.api_versions,
160+
'APIVersion',
161+
return_value=2.55):
162+
columns, data = self.cmd.take_action(parsed_args)
152163
self.flavors_mock.create.assert_called_once_with(*args)
153164
self.flavor.set_keys.assert_called_once_with({'property': 'value'})
154165
self.flavor.get_keys.assert_called_once_with()
@@ -168,6 +179,7 @@ def test_flavor_create_other_options(self):
168179
'--vcpus', str(self.flavor.vcpus),
169180
'--rxtx-factor', str(self.flavor.rxtx_factor),
170181
'--private',
182+
'--description', str(self.flavor.description),
171183
'--project', self.project.id,
172184
'--property', 'key1=value1',
173185
'--property', 'key2=value2',
@@ -181,6 +193,7 @@ def test_flavor_create_other_options(self):
181193
('vcpus', self.flavor.vcpus),
182194
('rxtx_factor', self.flavor.rxtx_factor),
183195
('public', False),
196+
('description', 'description'),
184197
('project', self.project.id),
185198
('property', {'key1': 'value1', 'key2': 'value2'}),
186199
('name', self.flavor.name),
@@ -197,8 +210,13 @@ def test_flavor_create_other_options(self):
197210
self.flavor.swap,
198211
self.flavor.rxtx_factor,
199212
self.flavor.is_public,
213+
self.flavor.description,
200214
)
201-
columns, data = self.cmd.take_action(parsed_args)
215+
self.app.client_manager.compute.api_version = 2.55
216+
with mock.patch.object(novaclient.api_versions,
217+
'APIVersion',
218+
return_value=2.55):
219+
columns, data = self.cmd.take_action(parsed_args)
202220
self.flavors_mock.create.assert_called_once_with(*args)
203221
self.flavor_access_mock.add_tenant_access.assert_called_with(
204222
self.flavor.id,
@@ -234,6 +252,79 @@ def test_flavor_create_no_options(self):
234252
arglist,
235253
verifylist)
236254

255+
def test_flavor_create_with_description_api_newer(self):
256+
arglist = [
257+
'--id', self.flavor.id,
258+
'--ram', str(self.flavor.ram),
259+
'--disk', str(self.flavor.disk),
260+
'--ephemeral', str(self.flavor.ephemeral),
261+
'--swap', str(self.flavor.swap),
262+
'--vcpus', str(self.flavor.vcpus),
263+
'--rxtx-factor', str(self.flavor.rxtx_factor),
264+
'--private',
265+
'--description', 'fake description',
266+
self.flavor.name,
267+
]
268+
verifylist = [
269+
('id', self.flavor.id),
270+
('ram', self.flavor.ram),
271+
('disk', self.flavor.disk),
272+
('ephemeral', self.flavor.ephemeral),
273+
('swap', self.flavor.swap),
274+
('vcpus', self.flavor.vcpus),
275+
('rxtx_factor', self.flavor.rxtx_factor),
276+
('public', False),
277+
('description', 'fake description'),
278+
('name', self.flavor.name),
279+
]
280+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
281+
self.app.client_manager.compute.api_version = 2.55
282+
with mock.patch.object(novaclient.api_versions,
283+
'APIVersion',
284+
return_value=2.55):
285+
columns, data = self.cmd.take_action(parsed_args)
286+
287+
args = (
288+
self.flavor.name,
289+
self.flavor.ram,
290+
self.flavor.vcpus,
291+
self.flavor.disk,
292+
self.flavor.id,
293+
self.flavor.ephemeral,
294+
self.flavor.swap,
295+
self.flavor.rxtx_factor,
296+
False,
297+
'fake description',
298+
)
299+
300+
self.flavors_mock.create.assert_called_once_with(*args)
301+
302+
self.assertEqual(self.columns, columns)
303+
self.assertEqual(self.data, data)
304+
305+
def test_flavor_create_with_description_api_older(self):
306+
arglist = [
307+
'--id', self.flavor.id,
308+
'--ram', str(self.flavor.ram),
309+
'--vcpus', str(self.flavor.vcpus),
310+
'--description', 'description',
311+
self.flavor.name,
312+
]
313+
verifylist = [
314+
('ram', self.flavor.ram),
315+
('vcpus', self.flavor.vcpus),
316+
('description', 'description'),
317+
('name', self.flavor.name),
318+
]
319+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
320+
321+
self.app.client_manager.compute.api_version = 2.54
322+
with mock.patch.object(novaclient.api_versions,
323+
'APIVersion',
324+
return_value=2.55):
325+
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
326+
parsed_args)
327+
237328

238329
class TestFlavorDelete(TestFlavor):
239330

@@ -622,6 +713,42 @@ def test_flavor_set_nothing(self):
622713
self.flavor_access_mock.add_tenant_access.assert_not_called()
623714
self.assertIsNone(result)
624715

716+
def test_flavor_set_description_api_newer(self):
717+
arglist = [
718+
'--description', 'description',
719+
self.flavor.id,
720+
]
721+
verifylist = [
722+
('description', 'description'),
723+
('flavor', self.flavor.id),
724+
]
725+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
726+
self.app.client_manager.compute.api_version = 2.55
727+
with mock.patch.object(novaclient.api_versions,
728+
'APIVersion',
729+
return_value=2.55):
730+
result = self.cmd.take_action(parsed_args)
731+
self.flavors_mock.update.assert_called_with(
732+
flavor=self.flavor.id, description='description')
733+
self.assertIsNone(result)
734+
735+
def test_flavor_set_description_api_older(self):
736+
arglist = [
737+
'--description', 'description',
738+
self.flavor.id,
739+
]
740+
verifylist = [
741+
('description', 'description'),
742+
('flavor', self.flavor.id),
743+
]
744+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
745+
self.app.client_manager.compute.api_version = 2.54
746+
with mock.patch.object(novaclient.api_versions,
747+
'APIVersion',
748+
return_value=2.55):
749+
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
750+
parsed_args)
751+
625752

626753
class TestFlavorShow(TestFlavor):
627754

@@ -633,6 +760,7 @@ class TestFlavorShow(TestFlavor):
633760
'OS-FLV-DISABLED:disabled',
634761
'OS-FLV-EXT-DATA:ephemeral',
635762
'access_project_ids',
763+
'description',
636764
'disk',
637765
'id',
638766
'name',
@@ -648,6 +776,7 @@ class TestFlavorShow(TestFlavor):
648776
flavor.disabled,
649777
flavor.ephemeral,
650778
None,
779+
flavor.description,
651780
flavor.disk,
652781
flavor.id,
653782
flavor.name,
@@ -710,6 +839,7 @@ def test_private_flavor_show(self):
710839
private_flavor.disabled,
711840
private_flavor.ephemeral,
712841
self.flavor_access.tenant_id,
842+
private_flavor.description,
713843
private_flavor.disk,
714844
private_flavor.id,
715845
private_flavor.name,
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- Add ``--description`` option to ``flavor set`` command to update the
4+
description of the server.
5+
- Add ``--description`` option to ``flavor create`` command to set the
6+
description of the server.

0 commit comments

Comments
 (0)