Compute: Add tags support for server
Change-Id: If065602792958ff0145ae9f2e05f5b7a3177905c Story: 2002006 Task: 19641
This commit is contained in:
parent
6216025e9d
commit
2f76bfa3a6
@ -828,6 +828,18 @@ class CreateServer(command.ShowOne):
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
help=_('Wait for build to complete'),
|
help=_('Wait for build to complete'),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--tag',
|
||||||
|
metavar='<tag>',
|
||||||
|
action='append',
|
||||||
|
default=[],
|
||||||
|
dest='tags',
|
||||||
|
help=_(
|
||||||
|
'Tags for the server. '
|
||||||
|
'Specify multiple times to add multiple tags. '
|
||||||
|
'(supported by --os-compute-api-version 2.52 or above)'
|
||||||
|
),
|
||||||
|
)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -1141,6 +1153,16 @@ class CreateServer(command.ShowOne):
|
|||||||
if parsed_args.description:
|
if parsed_args.description:
|
||||||
boot_kwargs['description'] = parsed_args.description
|
boot_kwargs['description'] = parsed_args.description
|
||||||
|
|
||||||
|
if parsed_args.tags:
|
||||||
|
if compute_client.api_version < api_versions.APIVersion('2.52'):
|
||||||
|
msg = _(
|
||||||
|
'--os-compute-api-version 2.52 or greater is required to '
|
||||||
|
'support the --tag option'
|
||||||
|
)
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
boot_kwargs['tags'] = parsed_args.tags
|
||||||
|
|
||||||
if parsed_args.host:
|
if parsed_args.host:
|
||||||
if compute_client.api_version < api_versions.APIVersion("2.74"):
|
if compute_client.api_version < api_versions.APIVersion("2.74"):
|
||||||
msg = _("Specifying --host is not supported for "
|
msg = _("Specifying --host is not supported for "
|
||||||
@ -1408,6 +1430,30 @@ class ListServer(command.Lister):
|
|||||||
help=_('Only display unlocked servers. '
|
help=_('Only display unlocked servers. '
|
||||||
'Requires ``--os-compute-api-version`` 2.73 or greater.'),
|
'Requires ``--os-compute-api-version`` 2.73 or greater.'),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--tags',
|
||||||
|
metavar='<tag>',
|
||||||
|
action='append',
|
||||||
|
default=[],
|
||||||
|
dest='tags',
|
||||||
|
help=_(
|
||||||
|
'Only list servers with the specified tag. '
|
||||||
|
'Specify multiple times to filter on multiple tags. '
|
||||||
|
'(supported by --os-compute-api-version 2.26 or above)'
|
||||||
|
),
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--not-tags',
|
||||||
|
metavar='<tag>',
|
||||||
|
action='append',
|
||||||
|
default=[],
|
||||||
|
dest='not_tags',
|
||||||
|
help=_(
|
||||||
|
'Only list servers without the specified tag. '
|
||||||
|
'Specify multiple times to filter on multiple tags. '
|
||||||
|
'(supported by --os-compute-api-version 2.26 or above)'
|
||||||
|
),
|
||||||
|
)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -1463,6 +1509,27 @@ class ListServer(command.Lister):
|
|||||||
'changes-before': parsed_args.changes_before,
|
'changes-before': parsed_args.changes_before,
|
||||||
'changes-since': parsed_args.changes_since,
|
'changes-since': parsed_args.changes_since,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if parsed_args.tags:
|
||||||
|
if compute_client.api_version < api_versions.APIVersion('2.26'):
|
||||||
|
msg = _(
|
||||||
|
'--os-compute-api-version 2.26 or greater is required to '
|
||||||
|
'support the --tag option'
|
||||||
|
)
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
search_opts['tags'] = parsed_args.tags
|
||||||
|
|
||||||
|
if parsed_args.not_tags:
|
||||||
|
if compute_client.api_version < api_versions.APIVersion('2.26'):
|
||||||
|
msg = _(
|
||||||
|
'--os-compute-api-version 2.26 or greater is required to '
|
||||||
|
'support the --not-tag option'
|
||||||
|
)
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
search_opts['not-tags'] = parsed_args.not_tags
|
||||||
|
|
||||||
support_locked = (compute_client.api_version >=
|
support_locked = (compute_client.api_version >=
|
||||||
api_versions.APIVersion('2.73'))
|
api_versions.APIVersion('2.73'))
|
||||||
if not support_locked and (parsed_args.locked or parsed_args.unlocked):
|
if not support_locked and (parsed_args.locked or parsed_args.unlocked):
|
||||||
@ -2795,6 +2862,18 @@ class SetServer(command.Command):
|
|||||||
help=_('New server description (supported by '
|
help=_('New server description (supported by '
|
||||||
'--os-compute-api-version 2.19 or above)'),
|
'--os-compute-api-version 2.19 or above)'),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--tag',
|
||||||
|
metavar='<tag>',
|
||||||
|
action='append',
|
||||||
|
default=[],
|
||||||
|
dest='tags',
|
||||||
|
help=_(
|
||||||
|
'Tag for the server. '
|
||||||
|
'Specify multiple times to add multiple tags. '
|
||||||
|
'(supported by --os-compute-api-version 2.26 or above)'
|
||||||
|
),
|
||||||
|
)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -2833,6 +2912,17 @@ class SetServer(command.Command):
|
|||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
server.update(description=parsed_args.description)
|
server.update(description=parsed_args.description)
|
||||||
|
|
||||||
|
if parsed_args.tags:
|
||||||
|
if server.api_version < api_versions.APIVersion('2.26'):
|
||||||
|
msg = _(
|
||||||
|
'--os-compute-api-version 2.26 or greater is required to '
|
||||||
|
'support the --tag option'
|
||||||
|
)
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
for tag in parsed_args.tags:
|
||||||
|
server.add_tag(tag=tag)
|
||||||
|
|
||||||
|
|
||||||
class ShelveServer(command.Command):
|
class ShelveServer(command.Command):
|
||||||
_description = _("Shelve server(s)")
|
_description = _("Shelve server(s)")
|
||||||
@ -3174,7 +3264,7 @@ class UnrescueServer(command.Command):
|
|||||||
|
|
||||||
|
|
||||||
class UnsetServer(command.Command):
|
class UnsetServer(command.Command):
|
||||||
_description = _("Unset server properties")
|
_description = _("Unset server properties and tags")
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(UnsetServer, self).get_parser(prog_name)
|
parser = super(UnsetServer, self).get_parser(prog_name)
|
||||||
@ -3198,6 +3288,18 @@ class UnsetServer(command.Command):
|
|||||||
help=_('Unset server description (supported by '
|
help=_('Unset server description (supported by '
|
||||||
'--os-compute-api-version 2.19 or above)'),
|
'--os-compute-api-version 2.19 or above)'),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--tag',
|
||||||
|
metavar='<tag>',
|
||||||
|
action='append',
|
||||||
|
default=[],
|
||||||
|
dest='tags',
|
||||||
|
help=_(
|
||||||
|
'Tag to remove from the server. '
|
||||||
|
'Specify multiple times to remove multiple tags. '
|
||||||
|
'(supported by --os-compute-api-version 2.26 or later'
|
||||||
|
),
|
||||||
|
)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -3223,6 +3325,17 @@ class UnsetServer(command.Command):
|
|||||||
description="",
|
description="",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if parsed_args.tags:
|
||||||
|
if compute_client.api_version < api_versions.APIVersion('2.26'):
|
||||||
|
msg = _(
|
||||||
|
'--os-compute-api-version 2.26 or greater is required to '
|
||||||
|
'support the --tag option'
|
||||||
|
)
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
for tag in parsed_args.tags:
|
||||||
|
compute_client.servers.delete_tag(server, tag=tag)
|
||||||
|
|
||||||
|
|
||||||
class UnshelveServer(command.Command):
|
class UnshelveServer(command.Command):
|
||||||
_description = _("Unshelve server(s)")
|
_description = _("Unshelve server(s)")
|
||||||
|
@ -2434,6 +2434,87 @@ class TestServerCreate(TestServer):
|
|||||||
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||||
parsed_args)
|
parsed_args)
|
||||||
|
|
||||||
|
def test_server_create_with_tag(self):
|
||||||
|
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
||||||
|
'2.52')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--image', 'image1',
|
||||||
|
'--flavor', 'flavor1',
|
||||||
|
'--tag', 'tag1',
|
||||||
|
'--tag', 'tag2',
|
||||||
|
self.new_server.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('image', 'image1'),
|
||||||
|
('flavor', 'flavor1'),
|
||||||
|
('tags', ['tag1', 'tag2']),
|
||||||
|
('config_drive', False),
|
||||||
|
('server_name', self.new_server.name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
# Set expected values
|
||||||
|
kwargs = {
|
||||||
|
'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': [],
|
||||||
|
'admin_pass': None,
|
||||||
|
'nics': 'auto',
|
||||||
|
'scheduler_hints': {},
|
||||||
|
'config_drive': None,
|
||||||
|
'tags': ['tag1', 'tag2'],
|
||||||
|
}
|
||||||
|
# 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_tag_pre_v252(self):
|
||||||
|
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
||||||
|
'2.51')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--image', 'image1',
|
||||||
|
'--flavor', 'flavor1',
|
||||||
|
'--tag', 'tag1',
|
||||||
|
'--tag', 'tag2',
|
||||||
|
self.new_server.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('image', 'image1'),
|
||||||
|
('flavor', 'flavor1'),
|
||||||
|
('tags', ['tag1', 'tag2']),
|
||||||
|
('config_drive', False),
|
||||||
|
('server_name', self.new_server.name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
ex = self.assertRaises(
|
||||||
|
exceptions.CommandError,
|
||||||
|
self.cmd.take_action,
|
||||||
|
parsed_args)
|
||||||
|
self.assertIn(
|
||||||
|
'--os-compute-api-version 2.52 or greater is required',
|
||||||
|
str(ex))
|
||||||
|
|
||||||
def test_server_create_with_host_v274(self):
|
def test_server_create_with_host_v274(self):
|
||||||
|
|
||||||
# Explicit host is supported for nova api version 2.74 or above
|
# Explicit host is supported for nova api version 2.74 or above
|
||||||
@ -3206,6 +3287,7 @@ class TestServerList(TestServer):
|
|||||||
|
|
||||||
self.search_opts['changes-before'] = '2016-03-05T06:27:59Z'
|
self.search_opts['changes-before'] = '2016-03-05T06:27:59Z'
|
||||||
self.search_opts['deleted'] = True
|
self.search_opts['deleted'] = True
|
||||||
|
|
||||||
self.servers_mock.list.assert_called_with(**self.kwargs)
|
self.servers_mock.list.assert_called_with(**self.kwargs)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
@ -3298,6 +3380,92 @@ class TestServerList(TestServer):
|
|||||||
'UNKNOWN', '', '', '')
|
'UNKNOWN', '', '', '')
|
||||||
self.assertEqual(expected_row, partial_server)
|
self.assertEqual(expected_row, partial_server)
|
||||||
|
|
||||||
|
def test_server_list_with_tag(self):
|
||||||
|
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
||||||
|
'2.26')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--tag', 'tag1',
|
||||||
|
'--tag', 'tag2',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('tags', ['tag1', 'tag2']),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.search_opts['tags'] = ['tag1', 'tag2']
|
||||||
|
|
||||||
|
self.servers_mock.list.assert_called_with(**self.kwargs)
|
||||||
|
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(tuple(self.data), tuple(data))
|
||||||
|
|
||||||
|
def test_server_list_with_tag_pre_v225(self):
|
||||||
|
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
||||||
|
'2.25')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--tag', 'tag1',
|
||||||
|
'--tag', 'tag2',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('tags', ['tag1', 'tag2']),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
ex = self.assertRaises(
|
||||||
|
exceptions.CommandError,
|
||||||
|
self.cmd.take_action,
|
||||||
|
parsed_args)
|
||||||
|
self.assertIn(
|
||||||
|
'--os-compute-api-version 2.26 or greater is required',
|
||||||
|
str(ex))
|
||||||
|
|
||||||
|
def test_server_list_with_not_tag(self):
|
||||||
|
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
||||||
|
'2.26')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--not-tag', 'tag1',
|
||||||
|
'--not-tag', 'tag2',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('not_tags', ['tag1', 'tag2']),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.search_opts['not-tags'] = ['tag1', 'tag2']
|
||||||
|
|
||||||
|
self.servers_mock.list.assert_called_with(**self.kwargs)
|
||||||
|
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(tuple(self.data), tuple(data))
|
||||||
|
|
||||||
|
def test_server_list_with_not_tag_pre_v226(self):
|
||||||
|
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
||||||
|
'2.25')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--not-tag', 'tag1',
|
||||||
|
'--not-tag', 'tag2',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('not_tags', ['tag1', 'tag2']),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
ex = self.assertRaises(
|
||||||
|
exceptions.CommandError,
|
||||||
|
self.cmd.take_action,
|
||||||
|
parsed_args)
|
||||||
|
self.assertIn(
|
||||||
|
'--os-compute-api-version 2.26 or greater is required',
|
||||||
|
str(ex))
|
||||||
|
|
||||||
|
|
||||||
class TestServerLock(TestServer):
|
class TestServerLock(TestServer):
|
||||||
|
|
||||||
@ -5388,6 +5556,8 @@ class TestServerSet(TestServer):
|
|||||||
'update': None,
|
'update': None,
|
||||||
'reset_state': None,
|
'reset_state': None,
|
||||||
'change_password': None,
|
'change_password': None,
|
||||||
|
'add_tag': None,
|
||||||
|
'set_tags': None,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.fake_servers = self.setup_servers_mock(2)
|
self.fake_servers = self.setup_servers_mock(2)
|
||||||
@ -5528,6 +5698,50 @@ class TestServerSet(TestServer):
|
|||||||
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||||
parsed_args)
|
parsed_args)
|
||||||
|
|
||||||
|
def test_server_set_with_tag(self):
|
||||||
|
self.fake_servers[0].api_version = api_versions.APIVersion('2.26')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--tag', 'tag1',
|
||||||
|
'--tag', 'tag2',
|
||||||
|
'foo_vm',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('tags', ['tag1', 'tag2']),
|
||||||
|
('server', 'foo_vm'),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.fake_servers[0].add_tag.assert_has_calls([
|
||||||
|
mock.call(tag='tag1'),
|
||||||
|
mock.call(tag='tag2'),
|
||||||
|
])
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
def test_server_set_with_tag_pre_v226(self):
|
||||||
|
self.fake_servers[0].api_version = api_versions.APIVersion('2.25')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--tag', 'tag1',
|
||||||
|
'--tag', 'tag2',
|
||||||
|
'foo_vm',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('tags', ['tag1', 'tag2']),
|
||||||
|
('server', 'foo_vm'),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
ex = self.assertRaises(
|
||||||
|
exceptions.CommandError,
|
||||||
|
self.cmd.take_action,
|
||||||
|
parsed_args)
|
||||||
|
self.assertIn(
|
||||||
|
'--os-compute-api-version 2.26 or greater is required',
|
||||||
|
str(ex))
|
||||||
|
|
||||||
|
|
||||||
class TestServerShelve(TestServer):
|
class TestServerShelve(TestServer):
|
||||||
|
|
||||||
@ -5853,6 +6067,52 @@ class TestServerUnset(TestServer):
|
|||||||
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
|
||||||
parsed_args)
|
parsed_args)
|
||||||
|
|
||||||
|
def test_server_unset_with_tag(self):
|
||||||
|
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
||||||
|
'2.26')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--tag', 'tag1',
|
||||||
|
'--tag', 'tag2',
|
||||||
|
'foo_vm',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('tags', ['tag1', 'tag2']),
|
||||||
|
('server', 'foo_vm'),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
self.servers_mock.delete_tag.assert_has_calls([
|
||||||
|
mock.call(self.fake_server, tag='tag1'),
|
||||||
|
mock.call(self.fake_server, tag='tag2'),
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_server_unset_with_tag_pre_v226(self):
|
||||||
|
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
||||||
|
'2.25')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--tag', 'tag1',
|
||||||
|
'--tag', 'tag2',
|
||||||
|
'foo_vm',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('tags', ['tag1', 'tag2']),
|
||||||
|
('server', 'foo_vm'),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
ex = self.assertRaises(
|
||||||
|
exceptions.CommandError,
|
||||||
|
self.cmd.take_action,
|
||||||
|
parsed_args)
|
||||||
|
self.assertIn(
|
||||||
|
'--os-compute-api-version 2.26 or greater is required',
|
||||||
|
str(ex))
|
||||||
|
|
||||||
|
|
||||||
class TestServerUnshelve(TestServer):
|
class TestServerUnshelve(TestServer):
|
||||||
|
|
||||||
|
14
releasenotes/notes/server-add-tag-63f9cd01dbd82d1b.yaml
Normal file
14
releasenotes/notes/server-add-tag-63f9cd01dbd82d1b.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Add ``--tag`` option to ``server create`` command to add tags when creating
|
||||||
|
a server.
|
||||||
|
Only available starting with ``--os-compute-api-version 2.52``.
|
||||||
|
- Add ``--tag`` option to ``server set`` command to add a tag to an
|
||||||
|
existing server.
|
||||||
|
Only available starting with ``--os-compute-api-version 2.26``.
|
||||||
|
- Add ``--tag`` options to ``server unset`` command to remove a tag from an
|
||||||
|
existing server.
|
||||||
|
Only available starting with ``--os-compute-api-version 2.26``.
|
||||||
|
- Add ``--tags`` and ``--not-tags`` options to ``server list`` command to
|
||||||
|
list instances with and without the specified tag(s), respectively.
|
||||||
|
Only available starting with ``--os-compute-api-version 2.26``.
|
Loading…
Reference in New Issue
Block a user