summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authortianhui <tianhui@awcloud.com>2018-05-18 18:59:37 +0800
committerStephen Finucane <sfinucan@redhat.com>2020-10-14 09:53:26 +0100
commit2f76bfa3a69b6867491a6c5f0bf3c7e9f62743ca (patch)
tree7b7483efa69ea906964bb125dbb410fad0e8cc70 /openstackclient
parent6216025e9da0b1689ddc4a494eaf562f15b28b32 (diff)
downloadpython-openstackclient-2f76bfa3a69b6867491a6c5f0bf3c7e9f62743ca.tar.gz
Compute: Add tags support for server
Change-Id: If065602792958ff0145ae9f2e05f5b7a3177905c Story: 2002006 Task: 19641
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/compute/v2/server.py115
-rw-r--r--openstackclient/tests/unit/compute/v2/test_server.py260
2 files changed, 374 insertions, 1 deletions
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index 89ea0067..09842f88 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -828,6 +828,18 @@ class CreateServer(command.ShowOne):
action='store_true',
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
def take_action(self, parsed_args):
@@ -1141,6 +1153,16 @@ class CreateServer(command.ShowOne):
if 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 compute_client.api_version < api_versions.APIVersion("2.74"):
msg = _("Specifying --host is not supported for "
@@ -1408,6 +1430,30 @@ class ListServer(command.Lister):
help=_('Only display unlocked servers. '
'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
def take_action(self, parsed_args):
@@ -1463,6 +1509,27 @@ class ListServer(command.Lister):
'changes-before': parsed_args.changes_before,
'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 >=
api_versions.APIVersion('2.73'))
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 '
'--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
def take_action(self, parsed_args):
@@ -2833,6 +2912,17 @@ class SetServer(command.Command):
raise exceptions.CommandError(msg)
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):
_description = _("Shelve server(s)")
@@ -3174,7 +3264,7 @@ class UnrescueServer(command.Command):
class UnsetServer(command.Command):
- _description = _("Unset server properties")
+ _description = _("Unset server properties and tags")
def get_parser(self, prog_name):
parser = super(UnsetServer, self).get_parser(prog_name)
@@ -3198,6 +3288,18 @@ class UnsetServer(command.Command):
help=_('Unset server description (supported by '
'--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
def take_action(self, parsed_args):
@@ -3223,6 +3325,17 @@ class UnsetServer(command.Command):
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):
_description = _("Unshelve server(s)")
diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py
index 5f1d5d06..544e0137 100644
--- a/openstackclient/tests/unit/compute/v2/test_server.py
+++ b/openstackclient/tests/unit/compute/v2/test_server.py
@@ -2434,6 +2434,87 @@ class TestServerCreate(TestServer):
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
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):
# 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['deleted'] = True
+
self.servers_mock.list.assert_called_with(**self.kwargs)
self.assertEqual(self.columns, columns)
@@ -3298,6 +3380,92 @@ class TestServerList(TestServer):
'UNKNOWN', '', '', '')
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):
@@ -5388,6 +5556,8 @@ class TestServerSet(TestServer):
'update': None,
'reset_state': None,
'change_password': None,
+ 'add_tag': None,
+ 'set_tags': None,
}
self.fake_servers = self.setup_servers_mock(2)
@@ -5528,6 +5698,50 @@ class TestServerSet(TestServer):
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
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):
@@ -5853,6 +6067,52 @@ class TestServerUnset(TestServer):
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
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):