Add tag API
Change-Id: I4e8325866ef63e424d5c6a93138e731001731568 Implements: blueprint role-decomposition
This commit is contained in:
parent
da2b335d35
commit
520e230690
|
@ -0,0 +1,139 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2015 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
|
||||
from nailgun.api.v1.handlers import base
|
||||
from nailgun.api.v1.handlers.base import handle_errors
|
||||
from nailgun.api.v1.handlers.base import serialize
|
||||
from nailgun.api.v1.handlers.base import validate
|
||||
from nailgun.api.v1.validators.tag import TagValidator
|
||||
from nailgun import errors
|
||||
from nailgun import objects
|
||||
from nailgun.objects.serializers.tag import TagSerializer
|
||||
|
||||
|
||||
class TagMixIn(object):
|
||||
|
||||
def _get_object_or_404(self, obj_type, obj_id):
|
||||
obj_cls = {
|
||||
'releases': objects.Release,
|
||||
'clusters': objects.Cluster,
|
||||
}[obj_type]
|
||||
return obj_cls, self.get_object_or_404(obj_cls, obj_id)
|
||||
|
||||
|
||||
class TagHandler(base.SingleHandler, TagMixIn):
|
||||
|
||||
validator = TagValidator
|
||||
|
||||
def _check_tag(self, obj_cls, obj, tag_name):
|
||||
if tag_name not in obj_cls.get_own_tags(obj):
|
||||
raise self.http(
|
||||
404,
|
||||
"Tag '{}' is not found for the {} {}".format(
|
||||
tag_name, obj_cls.__name__.lower(), obj.id))
|
||||
|
||||
@handle_errors
|
||||
@validate
|
||||
@serialize
|
||||
def GET(self, obj_type, obj_id, tag_name):
|
||||
"""Retrieve tag
|
||||
|
||||
:http:
|
||||
* 200 (OK)
|
||||
* 404 (no such object found)
|
||||
"""
|
||||
obj_cls, obj = self._get_object_or_404(obj_type, obj_id)
|
||||
self._check_tag(obj_cls, obj, tag_name)
|
||||
return TagSerializer.serialize_from_obj(obj_cls, obj, tag_name)
|
||||
|
||||
@handle_errors
|
||||
@validate
|
||||
@serialize
|
||||
def PUT(self, obj_type, obj_id, tag_name):
|
||||
"""Update tag
|
||||
|
||||
:http:
|
||||
* 200 (OK)
|
||||
* 400 (wrong data specified)
|
||||
* 404 (no such object found)
|
||||
"""
|
||||
obj_cls, obj = self._get_object_or_404(obj_type, obj_id)
|
||||
self._check_tag(obj_cls, obj, tag_name)
|
||||
data = self.checked_data(
|
||||
self.validator.validate_update, instance_cls=obj_cls, instance=obj)
|
||||
obj_cls.update_tag(obj, data)
|
||||
return TagSerializer.serialize_from_obj(obj_cls, obj, tag_name)
|
||||
|
||||
@handle_errors
|
||||
def DELETE(self, obj_type, obj_id, tag_name):
|
||||
"""Remove tag
|
||||
|
||||
:http:
|
||||
* 204 (object successfully deleted)
|
||||
* 400 (cannot delete object)
|
||||
* 404 (no such object found)
|
||||
"""
|
||||
obj_cls, obj = self._get_object_or_404(obj_type, obj_id)
|
||||
self._check_tag(obj_cls, obj, tag_name)
|
||||
obj_cls.remove_tag(obj, tag_name)
|
||||
raise self.http(204)
|
||||
|
||||
|
||||
class TagCollectionHandler(base.CollectionHandler, TagMixIn):
|
||||
|
||||
validator = TagValidator
|
||||
|
||||
@handle_errors
|
||||
@validate
|
||||
def POST(self, obj_type, obj_id):
|
||||
"""Create tag for release or cluster
|
||||
|
||||
:http:
|
||||
* 201 (object successfully created)
|
||||
* 400 (invalid object data specified)
|
||||
* 409 (object with such parameters already exists)
|
||||
* 404 (no such object found)
|
||||
"""
|
||||
obj_cls, obj = self._get_object_or_404(obj_type, obj_id)
|
||||
try:
|
||||
data = self.checked_data(
|
||||
self.validator.validate_create,
|
||||
instance_cls=obj_cls,
|
||||
instance=obj)
|
||||
except errors.AlreadyExists as exc:
|
||||
raise self.http(409, exc.message)
|
||||
|
||||
tag_name = data['name']
|
||||
obj_cls.update_tag(obj, data)
|
||||
raise self.http(
|
||||
201, TagSerializer.serialize_from_obj(obj_cls, obj, tag_name))
|
||||
|
||||
@handle_errors
|
||||
@validate
|
||||
@serialize
|
||||
def GET(self, obj_type, obj_id):
|
||||
"""Retrieve tag list of release or cluster
|
||||
|
||||
:http:
|
||||
* 200 (OK)
|
||||
* 404 (no such object found)
|
||||
"""
|
||||
obj_cls, obj = self._get_object_or_404(obj_type, obj_id)
|
||||
tag_names = six.iterkeys(obj_cls.get_tags_metadata(obj))
|
||||
return [TagSerializer.serialize_from_obj(obj_cls, obj, tag_name)
|
||||
for tag_name in tag_names]
|
|
@ -112,6 +112,9 @@ from nailgun.api.v1.handlers.release import ReleaseNetworksHandler
|
|||
from nailgun.api.v1.handlers.role import RoleCollectionHandler
|
||||
from nailgun.api.v1.handlers.role import RoleHandler
|
||||
|
||||
from nailgun.api.v1.handlers.tag import TagCollectionHandler
|
||||
from nailgun.api.v1.handlers.tag import TagHandler
|
||||
|
||||
from nailgun.api.v1.handlers.tasks import TaskCollectionHandler
|
||||
from nailgun.api.v1.handlers.tasks import TaskHandler
|
||||
|
||||
|
@ -171,6 +174,12 @@ urls = (
|
|||
'(?P<role_name>[a-zA-Z0-9-_]+)/?$',
|
||||
RoleHandler,
|
||||
|
||||
r'/(?P<obj_type>releases|clusters)/(?P<obj_id>\d+)/tags/?$',
|
||||
TagCollectionHandler,
|
||||
r'/(?P<obj_type>releases|clusters)/(?P<obj_id>\d+)/tags/'
|
||||
'(?P<tag_name>[a-zA-Z0-9-_]+)/?$',
|
||||
TagHandler,
|
||||
|
||||
r'/releases/(?P<obj_id>\d+)/deployment_graphs/?$',
|
||||
ReleaseDeploymentGraphCollectionHandler,
|
||||
r'/releases/(?P<obj_id>\d+)/deployment_graphs/'
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
TAG_META_INFO = {
|
||||
"type": "object",
|
||||
"required": ["has_primary"],
|
||||
"properties": {
|
||||
"has_primary": {
|
||||
"type": "boolean",
|
||||
"description": ("During orchestration this role"
|
||||
" will be splitted into primary-role and role.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SCHEMA = {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "Tag",
|
||||
"description": "Serialized Tag object",
|
||||
"type": "object",
|
||||
"required": ['name'],
|
||||
"properties": {
|
||||
"name": {"type": "string", "pattern": "^[a-zA-Z0-9_-]+$"},
|
||||
"meta": TAG_META_INFO
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2015 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nailgun.api.v1.validators.base import BasicValidator
|
||||
from nailgun.api.v1.validators.json_schema import tag
|
||||
from nailgun import errors
|
||||
|
||||
|
||||
class TagValidator(BasicValidator):
|
||||
|
||||
@classmethod
|
||||
def validate(cls, data, instance=None):
|
||||
parsed = super(TagValidator, cls).validate(data)
|
||||
cls.validate_schema(parsed, tag.SCHEMA)
|
||||
return parsed
|
||||
|
||||
@classmethod
|
||||
def validate_update(cls, data, instance_cls, instance):
|
||||
parsed = cls.validate(data, instance=instance)
|
||||
return parsed
|
||||
|
||||
@classmethod
|
||||
def validate_create(cls, data, instance_cls, instance):
|
||||
parsed = cls.validate(data, instance=instance)
|
||||
|
||||
tag_name = parsed['name']
|
||||
if tag_name in instance_cls.get_own_tags(instance):
|
||||
raise errors.AlreadyExists(
|
||||
"Tag with name '{}' already "
|
||||
"exists for {} {}".format(
|
||||
tag_name, instance_cls.__name__.lower(), instance.id))
|
||||
|
||||
return parsed
|
|
@ -408,6 +408,27 @@ class Cluster(NailgunObject):
|
|||
instance.volumes_metadata.changed()
|
||||
return bool(result)
|
||||
|
||||
@classmethod
|
||||
def update_tag(cls, instance, tag):
|
||||
"""Update existing Cluster instance with specified tag.
|
||||
|
||||
Previous ones are deleted.
|
||||
|
||||
:param instance: a Cluster instance
|
||||
:param role: a tag dict
|
||||
:returns: None
|
||||
"""
|
||||
instance.tags_metadata[tag['name']] = tag['meta']
|
||||
|
||||
@classmethod
|
||||
def remove_tag(cls, instance, tag_name):
|
||||
for role, meta in six.iteritems(cls.get_own_roles(instance)):
|
||||
tags = meta.get('tags', [])
|
||||
if tag_name in tags:
|
||||
tags.remove(tag_name)
|
||||
instance.roles_metadata.changed()
|
||||
return bool(instance.tags_metadata.pop(tag_name, None))
|
||||
|
||||
@classmethod
|
||||
def _create_public_map(cls, instance, roles_metadata=None):
|
||||
if instance.network_config.configuration_template is not None:
|
||||
|
@ -824,6 +845,10 @@ class Cluster(NailgunObject):
|
|||
def get_own_roles(cls, instance):
|
||||
return instance.roles_metadata
|
||||
|
||||
@classmethod
|
||||
def get_own_tags(cls, instance):
|
||||
return instance.tags_metadata
|
||||
|
||||
@classmethod
|
||||
def set_primary_tag(cls, instance, nodes, tag):
|
||||
"""Method for assigning primary attribute for specific tag.
|
||||
|
|
|
@ -139,6 +139,27 @@ class Release(NailgunObject):
|
|||
instance.volumes_metadata.changed()
|
||||
return bool(result)
|
||||
|
||||
@classmethod
|
||||
def update_tag(cls, instance, tag):
|
||||
"""Update existing Cluster instance with specified tag.
|
||||
|
||||
Previous ones are deleted.
|
||||
|
||||
:param instance: a Cluster instance
|
||||
:param role: a tag dict
|
||||
:returns: None
|
||||
"""
|
||||
instance.tags_metadata[tag['name']] = tag['meta']
|
||||
|
||||
@classmethod
|
||||
def remove_tag(cls, instance, tag_name):
|
||||
for role, meta in six.iteritems(cls.get_own_roles(instance)):
|
||||
tags = meta.get('tags', [])
|
||||
if tag_name in tags:
|
||||
tags.remove(tag_name)
|
||||
instance.roles_metadata.changed()
|
||||
return bool(instance.tags_metadata.pop(tag_name, None))
|
||||
|
||||
@classmethod
|
||||
def is_deployable(cls, instance):
|
||||
"""Returns whether a given release deployable or not.
|
||||
|
@ -317,6 +338,14 @@ class Release(NailgunObject):
|
|||
def get_own_roles(cls, instance):
|
||||
return instance.roles_metadata
|
||||
|
||||
@classmethod
|
||||
def get_tags_metadata(cls, instance):
|
||||
return cls.get_own_tags(instance)
|
||||
|
||||
@classmethod
|
||||
def get_own_tags(cls, instance):
|
||||
return instance.tags_metadata
|
||||
|
||||
@classmethod
|
||||
def _check_relation(cls, a, b, relation):
|
||||
"""Helper function to check commutative property for relations"""
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2015 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nailgun.objects.serializers.base import BasicSerializer
|
||||
|
||||
|
||||
class TagSerializer(BasicSerializer):
|
||||
|
||||
@classmethod
|
||||
def serialize_from_obj(cls, obj_cls, obj, tag_name):
|
||||
tag_meta = obj_cls.get_tags_metadata(obj)[tag_name]
|
||||
|
||||
return {'name': tag_name, 'meta': tag_meta}
|
|
@ -262,6 +262,65 @@ class EnvironmentManager(object):
|
|||
expect_errors=expect_errors
|
||||
)
|
||||
|
||||
def get_all_tags(self, obj_type, obj_id, expect_errors=False):
|
||||
return self.app.get(
|
||||
reverse(
|
||||
'TagCollectionHandler',
|
||||
kwargs={'obj_id': obj_id, 'obj_type': obj_type}
|
||||
),
|
||||
headers=self.default_headers,
|
||||
expect_errors=expect_errors
|
||||
)
|
||||
|
||||
def get_tag(self, obj_type, obj_id, tag_name, expect_errors=False):
|
||||
return self.app.get(
|
||||
reverse(
|
||||
'TagHandler',
|
||||
kwargs={'obj_id': obj_id,
|
||||
'obj_type': obj_type,
|
||||
'tag_name': tag_name}
|
||||
),
|
||||
headers=self.default_headers,
|
||||
expect_errors=expect_errors
|
||||
)
|
||||
|
||||
def update_tag(self, obj_type, obj_id, tag_name, data,
|
||||
expect_errors=False):
|
||||
return self.app.put(
|
||||
reverse(
|
||||
'TagHandler',
|
||||
kwargs={'obj_id': obj_id,
|
||||
'obj_type': obj_type,
|
||||
'tag_name': tag_name}
|
||||
),
|
||||
jsonutils.dumps(data),
|
||||
headers=self.default_headers,
|
||||
expect_errors=expect_errors
|
||||
)
|
||||
|
||||
def delete_tag(self, obj_type, obj_id, tag_name, expect_errors=False):
|
||||
return self.app.delete(
|
||||
reverse(
|
||||
'TagHandler',
|
||||
kwargs={'obj_id': obj_id,
|
||||
'obj_type': obj_type,
|
||||
'tag_name': tag_name}
|
||||
),
|
||||
headers=self.default_headers,
|
||||
expect_errors=expect_errors
|
||||
)
|
||||
|
||||
def create_tag(self, obj_type, obj_id, data, expect_errors=False):
|
||||
return self.app.post(
|
||||
reverse(
|
||||
'TagCollectionHandler',
|
||||
kwargs={'obj_id': obj_id, 'obj_type': obj_type}
|
||||
),
|
||||
jsonutils.dumps(data),
|
||||
headers=self.default_headers,
|
||||
expect_errors=expect_errors
|
||||
)
|
||||
|
||||
def create_cluster(self, api=True, exclude=None, **kwargs):
|
||||
cluster_data = {
|
||||
'name': 'cluster-api-' + str(randint(0, 1000000)),
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2015 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nailgun.test import base
|
||||
|
||||
|
||||
class TestReleaseTagsHandler(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestReleaseTagsHandler, self).setUp()
|
||||
self.release = self.env.create_release()
|
||||
self.tag_data = {'name': 'my_tag', 'meta': {'has_primary': False}}
|
||||
|
||||
def test_get_all_tags(self):
|
||||
owner_type, owner_id = 'releases', self.release.id
|
||||
resp = self.env.get_all_tags(owner_type, owner_id)
|
||||
|
||||
self.assertEqual(
|
||||
len(self.release.tags_metadata.keys()),
|
||||
len(resp.json))
|
||||
|
||||
def test_create_tag(self):
|
||||
owner_type, owner_id = 'releases', self.release.id
|
||||
resp = self.env.create_tag(owner_type, owner_id, self.tag_data)
|
||||
self.assertEqual(resp.json['meta'], self.tag_data['meta'])
|
||||
|
||||
resp = self.env.get_all_tags(owner_type, owner_id)
|
||||
|
||||
created_tag = next((
|
||||
tag
|
||||
for tag in resp.json if tag['name'] == self.tag_data['name']))
|
||||
self.assertEqual(created_tag, self.tag_data)
|
||||
|
||||
def test_update_tag(self):
|
||||
has_primary = True
|
||||
owner_type, owner_id = 'releases', self.release.id
|
||||
|
||||
resp = self.env.create_tag(owner_type, owner_id, self.tag_data)
|
||||
|
||||
data = resp.json
|
||||
data['meta']['has_primary'] = has_primary
|
||||
|
||||
resp = self.env.update_tag(owner_type, owner_id, data['name'], data)
|
||||
self.assertTrue(resp.json['meta']['has_primary'])
|
||||
|
||||
def test_update_tag_not_present(self):
|
||||
owner_type, owner_id = 'releases', self.release.id
|
||||
self.env.create_tag(owner_type, owner_id, self.tag_data)
|
||||
tag_name = 'blah_tag'
|
||||
resp = self.env.update_tag(owner_type,
|
||||
owner_id,
|
||||
tag_name,
|
||||
self.tag_data,
|
||||
expect_errors=True)
|
||||
self.assertEqual(404, resp.status_code)
|
||||
self.assertIn('is not found for the release', resp.body)
|
||||
|
||||
def test_delete_tag(self):
|
||||
owner_type, owner_id = 'releases', self.release.id
|
||||
self.env.create_tag(owner_type, owner_id, self.tag_data)
|
||||
delete_resp = self.env.delete_tag(
|
||||
owner_type, owner_id, self.tag_data['name'])
|
||||
|
||||
self.assertEqual(delete_resp.status_code, 204)
|
||||
|
||||
def test_delete_tag_not_present(self):
|
||||
owner_type, owner_id = 'releases', self.release.id
|
||||
self.env.create_tag(owner_type, owner_id, self.tag_data)
|
||||
tag_name = 'blah_tag'
|
||||
delete_resp = self.env.delete_tag(
|
||||
owner_type, owner_id, tag_name, expect_errors=True)
|
||||
self.assertEqual(delete_resp.status_code, 404)
|
||||
self.assertIn('is not found for the release', delete_resp.body)
|
||||
|
||||
def test_get_tag(self):
|
||||
owner_type, owner_id = 'releases', self.release.id
|
||||
self.env.create_tag(owner_type, owner_id, self.tag_data)
|
||||
tag = self.env.get_tag(owner_type, owner_id, self.tag_data['name'])
|
||||
|
||||
self.assertEqual(tag.status_code, 200)
|
||||
self.assertEqual(tag.json['name'], self.tag_data['name'])
|
||||
|
||||
def test_get_tag_not_present(self):
|
||||
owner_type, owner_id = 'releases', self.release.id
|
||||
self.env.create_tag(owner_type, owner_id, self.tag_data)
|
||||
tag_name = 'blah_tag'
|
||||
resp = self.env.get_tag(
|
||||
owner_type, owner_id, tag_name, expect_errors=True)
|
||||
self.assertEqual(resp.status_code, 404)
|
||||
self.assertIn('is not found for the release', resp.body)
|
||||
|
||||
def test_create_tag_with_special_symbols(self):
|
||||
owner_type, owner_id = 'releases', self.release.id
|
||||
self.tag_data['name'] = '@#$%^&*()'
|
||||
resp = self.env.create_tag(
|
||||
owner_type, owner_id, self.tag_data, expect_errors=True)
|
||||
|
||||
self.assertEqual(resp.status_code, 400)
|
||||
|
||||
|
||||
class TestClusterTagsHandler(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestClusterTagsHandler, self).setUp()
|
||||
self.cluster = self.env.create_cluster(api=False)
|
||||
self.tag_data = {'name': 'my_tag', 'meta': {'has_primary': False}}
|
||||
|
||||
def test_get_all_tags(self):
|
||||
owner_type, owner_id = 'clusters', self.cluster.id
|
||||
resp = self.env.get_all_tags(owner_type, owner_id)
|
||||
|
||||
self.assertEqual(
|
||||
len(self.cluster.release.tags_metadata.keys() +
|
||||
self.cluster.tags_metadata.keys()),
|
||||
len(resp.json))
|
||||
|
||||
def test_create_tag(self):
|
||||
owner_type, owner_id = 'clusters', self.cluster.id
|
||||
resp = self.env.create_tag(owner_type, owner_id, self.tag_data)
|
||||
self.assertEqual(resp.json['meta'], self.tag_data['meta'])
|
||||
|
||||
resp = self.env.get_all_tags(owner_type, owner_id)
|
||||
|
||||
created_tag = next((
|
||||
tag
|
||||
for tag in resp.json if tag['name'] == self.tag_data['name']))
|
||||
self.assertEqual(created_tag, self.tag_data)
|
||||
|
||||
def test_update_tag(self):
|
||||
changed_name = 'Another name'
|
||||
owner_type, owner_id = 'clusters', self.cluster.id
|
||||
|
||||
resp = self.env.create_tag(owner_type, owner_id, self.tag_data)
|
||||
|
||||
data = resp.json
|
||||
data['meta']['name'] = changed_name
|
||||
|
||||
resp = self.env.update_tag(owner_type, owner_id, data['name'], data)
|
||||
self.assertEqual(resp.json['meta']['name'], changed_name)
|
||||
|
||||
def test_get_tag(self):
|
||||
owner_type, owner_id = 'clusters', self.cluster.id
|
||||
self.env.create_tag(owner_type, owner_id, self.tag_data)
|
||||
tag = self.env.get_tag(owner_type, owner_id, self.tag_data['name'])
|
||||
|
||||
self.assertEqual(tag.status_code, 200)
|
||||
self.assertEqual(tag.json['name'], self.tag_data['name'])
|
||||
|
||||
def test_delete_tag(self):
|
||||
owner_type, owner_id = 'clusters', self.cluster.id
|
||||
self.env.create_tag(owner_type, owner_id, self.tag_data)
|
||||
delete_resp = self.env.delete_tag(
|
||||
owner_type, owner_id, self.tag_data['name'])
|
||||
|
||||
self.assertEqual(delete_resp.status_code, 204)
|
||||
|
||||
def test_error_tag_not_present(self):
|
||||
owner_type, owner_id = 'clusters', self.cluster.id
|
||||
tag_name = 'blah_tag'
|
||||
resp = self.env.get_tag(
|
||||
owner_type, owner_id, tag_name, expect_errors=True)
|
||||
|
||||
self.assertEqual(resp.status_code, 404)
|
||||
self.assertIn("is not found for the cluster",
|
||||
resp.json_body['message'])
|
Loading…
Reference in New Issue