Compute: Add description support for server

This patch adds functionality to configure server's description with:
1 server create
2 server set
3 server unset
4 server rebuild

Change-Id: Ic06d97b29e51828b29d7ac5172645c288e4ada9e
Story: 2002005
Task: 19640
This commit is contained in:
Chen 2018-05-15 15:25:40 +08:00 committed by Dean Troyer
parent 0a2b01fb40
commit c77a9621be
4 changed files with 288 additions and 1 deletions

View File

@ -125,7 +125,8 @@ unlock,server unlock,Unlock a server.
unpause,server unpause,Unpause a server. unpause,server unpause,Unpause a server.
unrescue,server unrescue,Restart the server from normal boot disk again. unrescue,server unrescue,Restart the server from normal boot disk again.
unshelve,server unshelve,Unshelve a server. unshelve,server unshelve,Unshelve a server.
update,server set / unset,Update the name or the description for a server. update,server set / unset --description,Update or unset the description for a server.
update,server set --name,Update the name for a server.
usage,usage show,Show usage data for a single tenant. usage,usage show,Show usage data for a single tenant.
usage-list,usage list,List usage data for all tenants. usage-list,usage list,List usage data for all tenants.
version-list,,List all API versions. version-list,,List all API versions.

1 add-fixed-ip server add fixed ip Add new IP address on a network to server.
125 unpause server unpause Unpause a server.
126 unrescue server unrescue Restart the server from normal boot disk again.
127 unshelve server unshelve Unshelve a server.
128 update server set / unset server set / unset --description Update the name or the description for a server. Update or unset the description for a server.
129 update server set --name Update the name for a server.
130 usage usage show Show usage data for a single tenant.
131 usage-list usage list List usage data for all tenants.
132 version-list List all API versions.

View File

@ -502,6 +502,12 @@ class CreateServer(command.ShowOne):
metavar='<user-data>', metavar='<user-data>',
help=_('User data file to serve from the metadata server'), help=_('User data file to serve from the metadata server'),
) )
parser.add_argument(
'--description',
metavar='<description>',
help=_('Set description for the server (supported by '
'--os-compute-api-version 2.19 or above)'),
)
parser.add_argument( parser.add_argument(
'--availability-zone', '--availability-zone',
metavar='<zone-name>', metavar='<zone-name>',
@ -712,6 +718,12 @@ class CreateServer(command.ShowOne):
"exception": e} "exception": e}
) )
if parsed_args.description:
if compute_client.api_version < api_versions.APIVersion("2.19"):
msg = _("Description is not supported for "
"--os-compute-api-version less than 2.19")
raise exceptions.CommandError(msg)
block_device_mapping_v2 = [] block_device_mapping_v2 = []
if volume: if volume:
block_device_mapping_v2 = [{'uuid': volume, block_device_mapping_v2 = [{'uuid': volume,
@ -872,6 +884,9 @@ class CreateServer(command.ShowOne):
scheduler_hints=hints, scheduler_hints=hints,
config_drive=config_drive) config_drive=config_drive)
if parsed_args.description:
boot_kwargs['description'] = parsed_args.description
LOG.debug('boot_args: %s', boot_args) LOG.debug('boot_args: %s', boot_args)
LOG.debug('boot_kwargs: %s', boot_kwargs) LOG.debug('boot_kwargs: %s', boot_kwargs)
@ -1529,6 +1544,12 @@ class RebuildServer(command.ShowOne):
help=_('Set a property on the rebuilt instance ' help=_('Set a property on the rebuilt instance '
'(repeat option to set multiple values)'), '(repeat option to set multiple values)'),
) )
parser.add_argument(
'--description',
metavar='<description>',
help=_('New description for the server (supported by '
'--os-compute-api-version 2.19 or above'),
)
parser.add_argument( parser.add_argument(
'--wait', '--wait',
action='store_true', action='store_true',
@ -1557,6 +1578,12 @@ class RebuildServer(command.ShowOne):
kwargs = {} kwargs = {}
if parsed_args.property: if parsed_args.property:
kwargs['meta'] = parsed_args.property kwargs['meta'] = parsed_args.property
if parsed_args.description:
if server.api_version < api_versions.APIVersion("2.19"):
msg = _("Description is not supported for "
"--os-compute-api-version less than 2.19")
raise exceptions.CommandError(msg)
kwargs['description'] = parsed_args.description
server = server.rebuild(image, parsed_args.password, **kwargs) server = server.rebuild(image, parsed_args.password, **kwargs)
if parsed_args.wait: if parsed_args.wait:
@ -1968,6 +1995,12 @@ class SetServer(command.Command):
choices=['active', 'error'], choices=['active', 'error'],
help=_('New server state (valid value: active, error)'), help=_('New server state (valid value: active, error)'),
) )
parser.add_argument(
'--description',
metavar='<description>',
help=_('New server description (supported by '
'--os-compute-api-version 2.19 or above)'),
)
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
@ -1999,6 +2032,13 @@ class SetServer(command.Command):
msg = _("Passwords do not match, password unchanged") msg = _("Passwords do not match, password unchanged")
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
if parsed_args.description:
if server.api_version < api_versions.APIVersion("2.19"):
msg = _("Description is not supported for "
"--os-compute-api-version less than 2.19")
raise exceptions.CommandError(msg)
server.update(description=parsed_args.description)
class ShelveServer(command.Command): class ShelveServer(command.Command):
_description = _("Shelve server(s)") _description = _("Shelve server(s)")
@ -2358,6 +2398,13 @@ class UnsetServer(command.Command):
help=_('Property key to remove from server ' help=_('Property key to remove from server '
'(repeat option to remove multiple values)'), '(repeat option to remove multiple values)'),
) )
parser.add_argument(
'--description',
dest='description',
action='store_true',
help=_('Unset server description (supported by '
'--os-compute-api-version 2.19 or above)'),
)
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
@ -2373,6 +2420,16 @@ class UnsetServer(command.Command):
parsed_args.property, parsed_args.property,
) )
if parsed_args.description:
if compute_client.api_version < api_versions.APIVersion("2.19"):
msg = _("Description is not supported for "
"--os-compute-api-version less than 2.19")
raise exceptions.CommandError(msg)
compute_client.servers.update(
server,
description="",
)
class UnshelveServer(command.Command): class UnshelveServer(command.Command):
_description = _("Unshelve server(s)") _description = _("Unshelve server(s)")

View File

@ -1736,6 +1736,90 @@ class TestServerCreate(TestServer):
self.cmd.take_action, self.cmd.take_action,
parsed_args) parsed_args)
def test_server_create_with_description_api_newer(self):
# Description is supported for nova api version 2.19 or above
self.app.client_manager.compute.api_version = 2.19
arglist = [
'--image', 'image1',
'--flavor', 'flavor1',
'--description', 'description1',
self.new_server.name,
]
verifylist = [
('image', 'image1'),
('flavor', 'flavor1'),
('description', 'description1'),
('config_drive', False),
('server_name', self.new_server.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object(api_versions,
'APIVersion',
return_value=2.19):
# In base command class ShowOne in cliff, abstract method
# take_action() returns a two-part tuple with a tuple of
# column names and a tuple of data to be shown.
columns, data = self.cmd.take_action(parsed_args)
# Set expected values
kwargs = dict(
meta=None,
files={},
reservation_id=None,
min_count=1,
max_count=1,
security_groups=[],
userdata=None,
key_name=None,
availability_zone=None,
block_device_mapping_v2=[],
nics='auto',
scheduler_hints={},
config_drive=None,
description='description1',
)
# ServerManager.create(name, image, flavor, **kwargs)
self.servers_mock.create.assert_called_with(
self.new_server.name,
self.image,
self.flavor,
**kwargs
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist(), data)
self.assertFalse(self.images_mock.called)
self.assertFalse(self.flavors_mock.called)
def test_server_create_with_description_api_older(self):
# Description is not supported for nova api version below 2.19
self.app.client_manager.compute.api_version = 2.18
arglist = [
'--image', 'image1',
'--flavor', 'flavor1',
'--description', 'description1',
self.new_server.name,
]
verifylist = [
('image', 'image1'),
('flavor', 'flavor1'),
('description', 'description1'),
('config_drive', False),
('server_name', self.new_server.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object(api_versions,
'APIVersion',
return_value=2.19):
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
parsed_args)
class TestServerDelete(TestServer): class TestServerDelete(TestServer):
@ -2493,6 +2577,55 @@ class TestServerRebuild(TestServer):
self.images_mock.get.assert_called_with(self.image.id) self.images_mock.get.assert_called_with(self.image.id)
self.server.rebuild.assert_called_with(self.image, password) self.server.rebuild.assert_called_with(self.image, password)
def test_rebuild_with_description_api_older(self):
# Description is not supported for nova api version below 2.19
self.server.api_version = 2.18
description = 'description1'
arglist = [
self.server.id,
'--description', description
]
verifylist = [
('server', self.server.id),
('description', description)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object(api_versions,
'APIVersion',
return_value=2.19):
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
parsed_args)
def test_rebuild_with_description_api_newer(self):
# Description is supported for nova api version 2.19 or above
self.server.api_version = 2.19
description = 'description1'
arglist = [
self.server.id,
'--description', description
]
verifylist = [
('server', self.server.id),
('description', description)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object(api_versions,
'APIVersion',
return_value=2.19):
# Get the command object to test
self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id)
self.images_mock.get.assert_called_with(self.image.id)
self.server.rebuild.assert_called_with(self.image, None,
description=description)
@mock.patch.object(common_utils, 'wait_for_status', return_value=True) @mock.patch.object(common_utils, 'wait_for_status', return_value=True)
def test_rebuild_with_wait_ok(self, mock_wait_for_status): def test_rebuild_with_wait_ok(self, mock_wait_for_status):
arglist = [ arglist = [
@ -3140,6 +3273,10 @@ class TestServerSet(TestServer):
def setUp(self): def setUp(self):
super(TestServerSet, self).setUp() super(TestServerSet, self).setUp()
self.attrs = {
'api_version': None,
}
self.methods = { self.methods = {
'update': None, 'update': None,
'reset_state': None, 'reset_state': None,
@ -3242,6 +3379,48 @@ class TestServerSet(TestServer):
mock.sentinel.fake_pass) mock.sentinel.fake_pass)
self.assertIsNone(result) self.assertIsNone(result)
def test_server_set_with_description_api_newer(self):
# Description is supported for nova api version 2.19 or above
self.fake_servers[0].api_version = 2.19
arglist = [
'--description', 'foo_description',
'foo_vm',
]
verifylist = [
('description', 'foo_description'),
('server', 'foo_vm'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object(api_versions,
'APIVersion',
return_value=2.19):
result = self.cmd.take_action(parsed_args)
self.fake_servers[0].update.assert_called_once_with(
description='foo_description')
self.assertIsNone(result)
def test_server_set_with_description_api_older(self):
# Description is not supported for nova api version below 2.19
self.fake_servers[0].api_version = 2.18
arglist = [
'--description', 'foo_description',
'foo_vm',
]
verifylist = [
('description', 'foo_description'),
('server', 'foo_vm'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object(api_versions,
'APIVersion',
return_value=2.19):
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
parsed_args)
class TestServerShelve(TestServer): class TestServerShelve(TestServer):
@ -3523,6 +3702,50 @@ class TestServerUnset(TestServer):
self.fake_server, ['key1', 'key2']) self.fake_server, ['key1', 'key2'])
self.assertIsNone(result) self.assertIsNone(result)
def test_server_unset_with_description_api_newer(self):
# Description is supported for nova api version 2.19 or above
self.app.client_manager.compute.api_version = 2.19
arglist = [
'--description',
'foo_vm',
]
verifylist = [
('description', True),
('server', 'foo_vm'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object(api_versions,
'APIVersion',
return_value=2.19):
result = self.cmd.take_action(parsed_args)
self.servers_mock.update.assert_called_once_with(
self.fake_server, description="")
self.assertIsNone(result)
def test_server_unset_with_description_api_older(self):
# Description is not supported for nova api version below 2.19
self.app.client_manager.compute.api_version = 2.18
arglist = [
'--description',
'foo_vm',
]
verifylist = [
('description', True),
('server', 'foo_vm'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object(api_versions,
'APIVersion',
return_value=2.19):
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
parsed_args)
class TestServerUnshelve(TestServer): class TestServerUnshelve(TestServer):

View File

@ -0,0 +1,6 @@
---
features:
- |
Add ``--description`` option to ``server create``, ``server rebuild``,
``server set`` and ``server unset`` commands.
[Bug `2002005 <https://storyboard.openstack.org/#!/story/2002005>`_]