Compute: Add description support for flavor
Co-Authored-By: Fan Zhang <zh.f@outlook.com> Change-Id: I0dc80bee3ba6ff4ec8cc3fc113b6de7807e0bf2a Story: 2002196 Task: 21681
This commit is contained in:
parent
9766eb23e7
commit
4a68ba625c
@ -24,6 +24,7 @@ Create new flavor
|
||||
[--property <key=value> [...] ]
|
||||
[--project <project>]
|
||||
[--project-domain <project-domain>]
|
||||
[--description <description>]
|
||||
<flavor-name>
|
||||
|
||||
.. option:: --id <id>
|
||||
@ -76,6 +77,10 @@ Create new flavor
|
||||
Domain the project belongs to (name or ID).
|
||||
This can be used in case collisions between project names exist.
|
||||
|
||||
.. option:: --description <description>
|
||||
|
||||
Description to add for this flavor
|
||||
|
||||
.. _flavor_create-flavor-name:
|
||||
.. describe:: <flavor-name>
|
||||
|
||||
@ -148,6 +153,7 @@ Set flavor properties
|
||||
[--property <key=value> [...] ]
|
||||
[--project <project>]
|
||||
[--project-domain <project-domain>]
|
||||
[--description <description>]
|
||||
<flavor>
|
||||
|
||||
.. option:: --property <key=value>
|
||||
@ -168,6 +174,10 @@ Set flavor properties
|
||||
Remove all properties from this flavor (specify both --no-property and --property
|
||||
to remove the current properties before setting new properties.)
|
||||
|
||||
.. option:: --description <description>
|
||||
|
||||
Set description to this flavor
|
||||
|
||||
.. describe:: <flavor>
|
||||
|
||||
Flavor to modify (name or ID)
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from novaclient import api_versions
|
||||
from osc_lib.cli import parseractions
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
@ -134,6 +135,12 @@ class CreateFlavor(command.ShowOne):
|
||||
help=_("Allow <project> to access private flavor (name or ID) "
|
||||
"(Must be used with --private option)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar='<description>',
|
||||
help=_("Description for the flavor.(Supported by API versions "
|
||||
"'2.55' - '2.latest'")
|
||||
)
|
||||
identity_common.add_project_domain_option_to_parser(parser)
|
||||
return parser
|
||||
|
||||
@ -145,6 +152,11 @@ class CreateFlavor(command.ShowOne):
|
||||
msg = _("--project is only allowed with --private")
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
if parsed_args.description:
|
||||
if compute_client.api_version < api_versions.APIVersion("2.55"):
|
||||
msg = _("--os-compute-api-version 2.55 or later is required")
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
args = (
|
||||
parsed_args.name,
|
||||
parsed_args.ram,
|
||||
@ -154,7 +166,8 @@ class CreateFlavor(command.ShowOne):
|
||||
parsed_args.ephemeral,
|
||||
parsed_args.swap,
|
||||
parsed_args.rxtx_factor,
|
||||
parsed_args.public
|
||||
parsed_args.public,
|
||||
parsed_args.description
|
||||
)
|
||||
|
||||
flavor = compute_client.flavors.create(*args)
|
||||
@ -332,6 +345,12 @@ class SetFlavor(command.Command):
|
||||
help=_('Set flavor access to project (name or ID) '
|
||||
'(admin only)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar='<description>',
|
||||
help=_("Set description for the flavor.(Supported by API "
|
||||
"versions '2.55' - '2.latest'")
|
||||
)
|
||||
identity_common.add_project_domain_option_to_parser(parser)
|
||||
|
||||
return parser
|
||||
@ -380,6 +399,13 @@ class SetFlavor(command.Command):
|
||||
raise exceptions.CommandError(_("Command Failed: One or more of"
|
||||
" the operations failed"))
|
||||
|
||||
if parsed_args.description:
|
||||
if compute_client.api_version < api_versions.APIVersion("2.55"):
|
||||
msg = _("--os-compute-api-version 2.55 or later is required")
|
||||
raise exceptions.CommandError(msg)
|
||||
compute_client.flavors.update(flavor=parsed_args.flavor,
|
||||
description=parsed_args.description)
|
||||
|
||||
|
||||
class ShowFlavor(command.ShowOne):
|
||||
_description = _("Display flavor details")
|
||||
|
@ -765,6 +765,7 @@ class FakeFlavor(object):
|
||||
'rxtx_factor': 1.0,
|
||||
'OS-FLV-DISABLED:disabled': False,
|
||||
'os-flavor-access:is_public': True,
|
||||
'description': 'description',
|
||||
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||
'properties': {'property': 'value'},
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
import mock
|
||||
from mock import call
|
||||
|
||||
import novaclient
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
|
||||
@ -50,6 +51,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
columns = (
|
||||
'OS-FLV-DISABLED:disabled',
|
||||
'OS-FLV-EXT-DATA:ephemeral',
|
||||
'description',
|
||||
'disk',
|
||||
'id',
|
||||
'name',
|
||||
@ -63,6 +65,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
data = (
|
||||
flavor.disabled,
|
||||
flavor.ephemeral,
|
||||
flavor.description,
|
||||
flavor.disk,
|
||||
flavor.id,
|
||||
flavor.name,
|
||||
@ -101,7 +104,8 @@ class TestFlavorCreate(TestFlavor):
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
True
|
||||
True,
|
||||
None,
|
||||
)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.flavors_mock.create.assert_called_once_with(*default_args)
|
||||
@ -120,6 +124,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
'--vcpus', str(self.flavor.vcpus),
|
||||
'--rxtx-factor', str(self.flavor.rxtx_factor),
|
||||
'--public',
|
||||
'--description', str(self.flavor.description),
|
||||
'--property', 'property=value',
|
||||
self.flavor.name,
|
||||
]
|
||||
@ -132,6 +137,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
('vcpus', self.flavor.vcpus),
|
||||
('rxtx_factor', self.flavor.rxtx_factor),
|
||||
('public', True),
|
||||
('description', self.flavor.description),
|
||||
('property', {'property': 'value'}),
|
||||
('name', self.flavor.name),
|
||||
]
|
||||
@ -147,8 +153,13 @@ class TestFlavorCreate(TestFlavor):
|
||||
self.flavor.swap,
|
||||
self.flavor.rxtx_factor,
|
||||
self.flavor.is_public,
|
||||
self.flavor.description,
|
||||
)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.app.client_manager.compute.api_version = 2.55
|
||||
with mock.patch.object(novaclient.api_versions,
|
||||
'APIVersion',
|
||||
return_value=2.55):
|
||||
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()
|
||||
@ -168,6 +179,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
'--vcpus', str(self.flavor.vcpus),
|
||||
'--rxtx-factor', str(self.flavor.rxtx_factor),
|
||||
'--private',
|
||||
'--description', str(self.flavor.description),
|
||||
'--project', self.project.id,
|
||||
'--property', 'key1=value1',
|
||||
'--property', 'key2=value2',
|
||||
@ -181,6 +193,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
('vcpus', self.flavor.vcpus),
|
||||
('rxtx_factor', self.flavor.rxtx_factor),
|
||||
('public', False),
|
||||
('description', 'description'),
|
||||
('project', self.project.id),
|
||||
('property', {'key1': 'value1', 'key2': 'value2'}),
|
||||
('name', self.flavor.name),
|
||||
@ -197,8 +210,13 @@ class TestFlavorCreate(TestFlavor):
|
||||
self.flavor.swap,
|
||||
self.flavor.rxtx_factor,
|
||||
self.flavor.is_public,
|
||||
self.flavor.description,
|
||||
)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.app.client_manager.compute.api_version = 2.55
|
||||
with mock.patch.object(novaclient.api_versions,
|
||||
'APIVersion',
|
||||
return_value=2.55):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.flavors_mock.create.assert_called_once_with(*args)
|
||||
self.flavor_access_mock.add_tenant_access.assert_called_with(
|
||||
self.flavor.id,
|
||||
@ -234,6 +252,79 @@ class TestFlavorCreate(TestFlavor):
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
def test_flavor_create_with_description_api_newer(self):
|
||||
arglist = [
|
||||
'--id', self.flavor.id,
|
||||
'--ram', str(self.flavor.ram),
|
||||
'--disk', str(self.flavor.disk),
|
||||
'--ephemeral', str(self.flavor.ephemeral),
|
||||
'--swap', str(self.flavor.swap),
|
||||
'--vcpus', str(self.flavor.vcpus),
|
||||
'--rxtx-factor', str(self.flavor.rxtx_factor),
|
||||
'--private',
|
||||
'--description', 'fake description',
|
||||
self.flavor.name,
|
||||
]
|
||||
verifylist = [
|
||||
('id', self.flavor.id),
|
||||
('ram', self.flavor.ram),
|
||||
('disk', self.flavor.disk),
|
||||
('ephemeral', self.flavor.ephemeral),
|
||||
('swap', self.flavor.swap),
|
||||
('vcpus', self.flavor.vcpus),
|
||||
('rxtx_factor', self.flavor.rxtx_factor),
|
||||
('public', False),
|
||||
('description', 'fake description'),
|
||||
('name', self.flavor.name),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.app.client_manager.compute.api_version = 2.55
|
||||
with mock.patch.object(novaclient.api_versions,
|
||||
'APIVersion',
|
||||
return_value=2.55):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
args = (
|
||||
self.flavor.name,
|
||||
self.flavor.ram,
|
||||
self.flavor.vcpus,
|
||||
self.flavor.disk,
|
||||
self.flavor.id,
|
||||
self.flavor.ephemeral,
|
||||
self.flavor.swap,
|
||||
self.flavor.rxtx_factor,
|
||||
False,
|
||||
'fake description',
|
||||
)
|
||||
|
||||
self.flavors_mock.create.assert_called_once_with(*args)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
|
||||
def test_flavor_create_with_description_api_older(self):
|
||||
arglist = [
|
||||
'--id', self.flavor.id,
|
||||
'--ram', str(self.flavor.ram),
|
||||
'--vcpus', str(self.flavor.vcpus),
|
||||
'--description', 'description',
|
||||
self.flavor.name,
|
||||
]
|
||||
verifylist = [
|
||||
('ram', self.flavor.ram),
|
||||
('vcpus', self.flavor.vcpus),
|
||||
('description', 'description'),
|
||||
('name', self.flavor.name),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.app.client_manager.compute.api_version = 2.54
|
||||
with mock.patch.object(novaclient.api_versions,
|
||||
'APIVersion',
|
||||
return_value=2.55):
|
||||
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestFlavorDelete(TestFlavor):
|
||||
|
||||
@ -622,6 +713,42 @@ class TestFlavorSet(TestFlavor):
|
||||
self.flavor_access_mock.add_tenant_access.assert_not_called()
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_flavor_set_description_api_newer(self):
|
||||
arglist = [
|
||||
'--description', 'description',
|
||||
self.flavor.id,
|
||||
]
|
||||
verifylist = [
|
||||
('description', 'description'),
|
||||
('flavor', self.flavor.id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.app.client_manager.compute.api_version = 2.55
|
||||
with mock.patch.object(novaclient.api_versions,
|
||||
'APIVersion',
|
||||
return_value=2.55):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.flavors_mock.update.assert_called_with(
|
||||
flavor=self.flavor.id, description='description')
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_flavor_set_description_api_older(self):
|
||||
arglist = [
|
||||
'--description', 'description',
|
||||
self.flavor.id,
|
||||
]
|
||||
verifylist = [
|
||||
('description', 'description'),
|
||||
('flavor', self.flavor.id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.app.client_manager.compute.api_version = 2.54
|
||||
with mock.patch.object(novaclient.api_versions,
|
||||
'APIVersion',
|
||||
return_value=2.55):
|
||||
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestFlavorShow(TestFlavor):
|
||||
|
||||
@ -633,6 +760,7 @@ class TestFlavorShow(TestFlavor):
|
||||
'OS-FLV-DISABLED:disabled',
|
||||
'OS-FLV-EXT-DATA:ephemeral',
|
||||
'access_project_ids',
|
||||
'description',
|
||||
'disk',
|
||||
'id',
|
||||
'name',
|
||||
@ -648,6 +776,7 @@ class TestFlavorShow(TestFlavor):
|
||||
flavor.disabled,
|
||||
flavor.ephemeral,
|
||||
None,
|
||||
flavor.description,
|
||||
flavor.disk,
|
||||
flavor.id,
|
||||
flavor.name,
|
||||
@ -710,6 +839,7 @@ class TestFlavorShow(TestFlavor):
|
||||
private_flavor.disabled,
|
||||
private_flavor.ephemeral,
|
||||
self.flavor_access.tenant_id,
|
||||
private_flavor.description,
|
||||
private_flavor.disk,
|
||||
private_flavor.id,
|
||||
private_flavor.name,
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- Add ``--description`` option to ``flavor set`` command to update the
|
||||
description of the server.
|
||||
- Add ``--description`` option to ``flavor create`` command to set the
|
||||
description of the server.
|
Loading…
Reference in New Issue
Block a user