Added Support of microverison 2.26
This microversion allows to create/delete/update server tags and to search servers by tags. Implements: blueprint tag-instances Change-Id: I66b6d4a763c507335f27a425bc3d4c2aae377c00
This commit is contained in:
parent
4187c69184
commit
ff9b97b2c6
@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1")
|
||||
# when client supported the max version, and bumped sequentially, otherwise
|
||||
# the client may break due to server side new version may include some
|
||||
# backward incompatible change.
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.25")
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.26")
|
||||
|
@ -316,6 +316,50 @@ class Base(base.Fixture):
|
||||
self.url(1234, 'os-server-password'),
|
||||
status_code=202,
|
||||
headers=self.json_headers)
|
||||
#
|
||||
# Server tags
|
||||
#
|
||||
|
||||
self.requests.register_uri('GET',
|
||||
self.url(1234, 'tags'),
|
||||
json={'tags': ['tag1', 'tag2']},
|
||||
headers=self.json_headers)
|
||||
|
||||
self.requests.register_uri('GET',
|
||||
self.url(1234, 'tags', 'tag'),
|
||||
status_code=204,
|
||||
headers=self.json_headers)
|
||||
|
||||
self.requests.register_uri('DELETE',
|
||||
self.url(1234, 'tags', 'tag'),
|
||||
status_code=204,
|
||||
headers=self.json_headers)
|
||||
|
||||
self.requests.register_uri('DELETE',
|
||||
self.url(1234, 'tags'),
|
||||
status_code=204,
|
||||
headers=self.json_headers)
|
||||
|
||||
def put_server_tag(request, context):
|
||||
body = jsonutils.loads(request.body)
|
||||
assert body is None
|
||||
context.status_code = 201
|
||||
return None
|
||||
|
||||
self.requests.register_uri('PUT',
|
||||
self.url(1234, 'tags', 'tag'),
|
||||
json=put_server_tag,
|
||||
headers=self.json_headers)
|
||||
|
||||
def put_server_tags(request, context):
|
||||
body = jsonutils.loads(request.body)
|
||||
assert list(body) == ['tags']
|
||||
return body
|
||||
|
||||
self.requests.register_uri('PUT',
|
||||
self.url(1234, 'tags'),
|
||||
json=put_server_tags,
|
||||
headers=self.json_headers)
|
||||
|
||||
|
||||
class V1(Base):
|
||||
|
@ -2221,6 +2221,24 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
def delete_servers_1234_migrations_1(self):
|
||||
return (202, {}, None)
|
||||
|
||||
def put_servers_1234_tags_tag(self, **kw):
|
||||
return (201, {}, None)
|
||||
|
||||
def put_servers_1234_tags(self, **kw):
|
||||
return (201, {}, None)
|
||||
|
||||
def get_servers_1234_tags(self, **kw):
|
||||
return (200, {}, {'tags': ['tag1', 'tag2']})
|
||||
|
||||
def delete_servers_1234_tags_tag(self, **kw):
|
||||
return (204, {}, None)
|
||||
|
||||
def delete_servers_1234_tags(self, **kw):
|
||||
return (204, {}, None)
|
||||
|
||||
def get_servers_1234_tags_tag(self, **kw):
|
||||
return (204, {}, None)
|
||||
|
||||
|
||||
class FakeSessionClient(fakes.FakeClient, client.Client):
|
||||
|
||||
|
@ -1148,3 +1148,45 @@ class ServersV225Test(ServersV219Test):
|
||||
s = self.cs.servers.get(1234)
|
||||
self.assertRaises(ValueError, s.live_migrate, 'hostname',
|
||||
'auto', 'True')
|
||||
|
||||
|
||||
class ServersV226Test(ServersV225Test):
|
||||
def setUp(self):
|
||||
super(ServersV219Test, self).setUp()
|
||||
self.cs.api_version = api_versions.APIVersion("2.26")
|
||||
|
||||
def test_tag_list(self):
|
||||
s = self.cs.servers.get(1234)
|
||||
ret = s.tag_list()
|
||||
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.assert_called('GET', '/servers/1234/tags')
|
||||
|
||||
def test_tag_delete(self):
|
||||
s = self.cs.servers.get(1234)
|
||||
ret = s.delete_tag('tag')
|
||||
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.assert_called('DELETE', '/servers/1234/tags/tag')
|
||||
|
||||
def test_tag_delete_all(self):
|
||||
s = self.cs.servers.get(1234)
|
||||
ret = s.delete_all_tags()
|
||||
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.assert_called('DELETE', '/servers/1234/tags')
|
||||
|
||||
def test_tag_add(self):
|
||||
s = self.cs.servers.get(1234)
|
||||
ret = s.add_tag('tag')
|
||||
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.assert_called('PUT', '/servers/1234/tags/tag')
|
||||
|
||||
def test_tags_set(self):
|
||||
s = self.cs.servers.get(1234)
|
||||
ret = s.set_tags(['tag1', 'tag2'])
|
||||
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.assert_called('PUT', '/servers/1234/tags')
|
||||
|
||||
def test_tag_exists(self):
|
||||
s = self.cs.servers.get(1234)
|
||||
ret = s.tag_exists('tag')
|
||||
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.assert_called('GET', '/servers/1234/tags/tag')
|
||||
|
@ -2775,6 +2775,52 @@ class ShellTest(utils.TestCase):
|
||||
self.run_command('list', api_version='2.10')
|
||||
self.assert_called('GET', '/servers/detail')
|
||||
|
||||
def test_server_tag_add(self):
|
||||
self.run_command('server-tag-add sample-server tag',
|
||||
api_version='2.26')
|
||||
self.assert_called('PUT', '/servers/1234/tags/tag', None)
|
||||
|
||||
def test_server_tag_set(self):
|
||||
self.run_command('server-tag-set sample-server tag1 tag2',
|
||||
api_version='2.26')
|
||||
self.assert_called('PUT', '/servers/1234/tags',
|
||||
{'tags': ['tag1', 'tag2']})
|
||||
|
||||
def test_server_tag_list(self):
|
||||
self.run_command('server-tag-list sample-server', api_version='2.26')
|
||||
self.assert_called('GET', '/servers/1234/tags')
|
||||
|
||||
def test_server_tag_delete(self):
|
||||
self.run_command('server-tag-delete sample-server tag',
|
||||
api_version='2.26')
|
||||
self.assert_called('DELETE', '/servers/1234/tags/tag')
|
||||
|
||||
def test_server_tag_delete_all(self):
|
||||
self.run_command('server-tag-delete-all sample-server',
|
||||
api_version='2.26')
|
||||
self.assert_called('DELETE', '/servers/1234/tags')
|
||||
|
||||
def test_server_tag_exists(self):
|
||||
self.run_command('server-tag-exists sample-server tag',
|
||||
api_version='2.26')
|
||||
self.assert_called('GET', '/servers/1234/tags/tag')
|
||||
|
||||
def test_list_v2_26_tags(self):
|
||||
self.run_command('list --tags tag1,tag2', api_version='2.26')
|
||||
self.assert_called('GET', '/servers/detail?tags=tag1%2Ctag2')
|
||||
|
||||
def test_list_v2_26_tags_any(self):
|
||||
self.run_command('list --tags-any tag1,tag2', api_version='2.26')
|
||||
self.assert_called('GET', '/servers/detail?tags-any=tag1%2Ctag2')
|
||||
|
||||
def test_list_v2_26_not_tags(self):
|
||||
self.run_command('list --not-tags tag1,tag2', api_version='2.26')
|
||||
self.assert_called('GET', '/servers/detail?not-tags=tag1%2Ctag2')
|
||||
|
||||
def test_list_v2_26_not_tags_any(self):
|
||||
self.run_command('list --not-tags-any tag1,tag2', api_version='2.26')
|
||||
self.assert_called('GET', '/servers/detail?not-tags-any=tag1%2Ctag2')
|
||||
|
||||
|
||||
class ShellWithSessionClientTest(ShellTest):
|
||||
|
||||
|
@ -526,6 +526,42 @@ class Server(base.Resource):
|
||||
"""Trigger crash dump in an instance"""
|
||||
return self.manager.trigger_crash_dump(self)
|
||||
|
||||
def tag_list(self):
|
||||
"""
|
||||
Get list of tags from an instance.
|
||||
"""
|
||||
return self.manager.tag_list(self)
|
||||
|
||||
def delete_tag(self, tag):
|
||||
"""
|
||||
Remove single tag from an instance.
|
||||
"""
|
||||
return self.manager.delete_tag(self, tag)
|
||||
|
||||
def delete_all_tags(self):
|
||||
"""
|
||||
Remove all tags from an instance.
|
||||
"""
|
||||
return self.manager.delete_all_tags(self)
|
||||
|
||||
def set_tags(self, tags):
|
||||
"""
|
||||
Set list of tags to an instance.
|
||||
"""
|
||||
return self.manager.set_tags(self, tags)
|
||||
|
||||
def add_tag(self, tag):
|
||||
"""
|
||||
Add single tag to an instance.
|
||||
"""
|
||||
return self.manager.add_tag(self, tag)
|
||||
|
||||
def tag_exists(self, tag):
|
||||
"""
|
||||
Check if an instance has specified tag.
|
||||
"""
|
||||
return self.manager.tag_exists(self, tag)
|
||||
|
||||
|
||||
class NetworkInterface(base.Resource):
|
||||
@property
|
||||
@ -1709,3 +1745,51 @@ class ServerManager(base.BootingManagerWithFind):
|
||||
url = '/servers/%s/remote-consoles' % base.getid(server)
|
||||
resp, body = self.api.client.post(url, body=body)
|
||||
return self.convert_into_with_meta(body, resp)
|
||||
|
||||
@api_versions.wraps('2.26')
|
||||
def tag_list(self, server):
|
||||
"""
|
||||
Get list of tags from an instance.
|
||||
"""
|
||||
resp, body = self.api.client.get(
|
||||
"/servers/%s/tags" % base.getid(server))
|
||||
return base.ListWithMeta(body['tags'], resp)
|
||||
|
||||
@api_versions.wraps('2.26')
|
||||
def delete_tag(self, server, tag):
|
||||
"""
|
||||
Remove single tag from an instance.
|
||||
"""
|
||||
return self._delete("/servers/%s/tags/%s" % (base.getid(server), tag))
|
||||
|
||||
@api_versions.wraps('2.26')
|
||||
def delete_all_tags(self, server):
|
||||
"""
|
||||
Remove all tags from an instance.
|
||||
"""
|
||||
return self._delete("/servers/%s/tags" % base.getid(server))
|
||||
|
||||
@api_versions.wraps('2.26')
|
||||
def set_tags(self, server, tags):
|
||||
"""
|
||||
Set list of tags to an instance.
|
||||
"""
|
||||
body = {"tags": tags}
|
||||
return self._update("/servers/%s/tags" % base.getid(server), body)
|
||||
|
||||
@api_versions.wraps('2.26')
|
||||
def add_tag(self, server, tag):
|
||||
"""
|
||||
Add single tag to an instance.
|
||||
"""
|
||||
return self._update(
|
||||
"/servers/%s/tags/%s" % (base.getid(server), tag), None)
|
||||
|
||||
@api_versions.wraps('2.26')
|
||||
def tag_exists(self, server, tag):
|
||||
"""
|
||||
Check if an instance has specified tag.
|
||||
"""
|
||||
resp, body = self.api.client.get(
|
||||
"/servers/%s/tags/%s" % (base.getid(server), tag))
|
||||
return self.convert_into_with_meta(body, resp)
|
||||
|
@ -1461,6 +1461,45 @@ def do_image_delete(cs, args):
|
||||
help=_("List only servers changed after a certain point of time."
|
||||
"The provided time should be an ISO 8061 formatted time."
|
||||
"ex 2016-03-04T06:27:59Z ."))
|
||||
@utils.arg(
|
||||
'--tags',
|
||||
dest='tags',
|
||||
metavar='<tags>',
|
||||
default=None,
|
||||
help=_("The given tags must all be present for a server to be included in "
|
||||
"the list result. Boolean expression in this case is 't1 AND t2'. "
|
||||
"Tags must be separated by commas: --tags <tag1,tag2>"),
|
||||
start_version="2.26")
|
||||
@utils.arg(
|
||||
'--tags-any',
|
||||
dest='tags-any',
|
||||
metavar='<tags-any>',
|
||||
default=None,
|
||||
help=_("If one of the given tags is present the server will be included "
|
||||
"in the list result. Boolean expression in this case is "
|
||||
"'t1 OR t2'. Tags must be separated by commas: "
|
||||
"--tags-any <tag1,tag2>"),
|
||||
start_version="2.26")
|
||||
@utils.arg(
|
||||
'--not-tags',
|
||||
dest='not-tags',
|
||||
metavar='<not-tags>',
|
||||
default=None,
|
||||
help=_("Only the servers that do not have any of the given tags will"
|
||||
"be included in the list results. Boolean expression in this case "
|
||||
"is 'NOT(t1 AND t2)'. Tags must be separated by commas: "
|
||||
"--not-tags <tag1,tag2>"),
|
||||
start_version="2.26")
|
||||
@utils.arg(
|
||||
'--not-tags-any',
|
||||
dest='not-tags-any',
|
||||
metavar='<not-tags-any>',
|
||||
default=None,
|
||||
help=_("Only the servers that do not have at least one of the given tags"
|
||||
"will be included in the list result. Boolean expression in this "
|
||||
"case is 'NOT(t1 OR t2)'. Tags must be separated by commas: "
|
||||
"--not-tags-any <tag1,tag2>"),
|
||||
start_version="2.26")
|
||||
def do_list(cs, args):
|
||||
"""List active servers."""
|
||||
imageid = None
|
||||
@ -1488,6 +1527,10 @@ def do_list(cs, args):
|
||||
'instance_name': args.instance_name,
|
||||
'changes-since': args.changes_since}
|
||||
|
||||
for arg in ('tags', "tags-any", 'not-tags', 'not-tags-any'):
|
||||
if arg in args:
|
||||
search_opts[arg] = getattr(args, arg)
|
||||
|
||||
filters = {'flavor': lambda f: f['id'],
|
||||
'security_groups': utils.format_security_groups}
|
||||
|
||||
@ -4956,3 +4999,56 @@ def do_virtual_interface_list(cs, args):
|
||||
server = _find_server(cs, args.server)
|
||||
interface_list = cs.virtual_interfaces.list(base.getid(server))
|
||||
_print_virtual_interface_list(cs, interface_list)
|
||||
|
||||
|
||||
@api_versions.wraps("2.26")
|
||||
@utils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
||||
def do_server_tag_list(cs, args):
|
||||
"""Get list of tags from a server."""
|
||||
server = _find_server(cs, args.server)
|
||||
tags = server.tag_list()
|
||||
utils.print_list(tags, 'name')
|
||||
|
||||
|
||||
@api_versions.wraps("2.26")
|
||||
@utils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
||||
@utils.arg('tag', metavar='<tag>', help=_('Tag to add.'))
|
||||
def do_server_tag_add(cs, args):
|
||||
"""Add single tag to a server."""
|
||||
server = _find_server(cs, args.server)
|
||||
server.add_tag(args.tag)
|
||||
|
||||
|
||||
@api_versions.wraps("2.26")
|
||||
@utils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
||||
@utils.arg('tags', metavar='<tags>', nargs='+', help=_('Tag(s) to set.'))
|
||||
def do_server_tag_set(cs, args):
|
||||
"""Set list of tags to a server."""
|
||||
server = _find_server(cs, args.server)
|
||||
server.set_tags(args.tags)
|
||||
|
||||
|
||||
@api_versions.wraps("2.26")
|
||||
@utils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
||||
@utils.arg('tag', metavar='<tag>', help=_('Tag to delete.'))
|
||||
def do_server_tag_delete(cs, args):
|
||||
"""Delete single tag from a server."""
|
||||
server = _find_server(cs, args.server)
|
||||
server.delete_tag(args.tag)
|
||||
|
||||
|
||||
@api_versions.wraps("2.26")
|
||||
@utils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
||||
def do_server_tag_delete_all(cs, args):
|
||||
"""Delete all tags from a server."""
|
||||
server = _find_server(cs, args.server)
|
||||
server.delete_all_tags()
|
||||
|
||||
|
||||
@api_versions.wraps("2.26")
|
||||
@utils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
||||
@utils.arg('tag', metavar='<tag>', help=_('Tag to check if it exists or not.'))
|
||||
def do_server_tag_exists(cs, args):
|
||||
"""Check if a server has specified tag."""
|
||||
server = _find_server(cs, args.server)
|
||||
server.tag_exists(args.tag)
|
||||
|
Loading…
Reference in New Issue
Block a user