Merge "Add network tags client"
This commit is contained in:
commit
5bf47220a0
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Define v2.0 ``tags_client`` for the network service as a library
|
||||
interface, allowing other projects to use this module as a stable
|
||||
library without maintenance changes.
|
||||
|
||||
* tags_client(v2.0)
|
@ -83,6 +83,7 @@ class BaseNetworkTest(tempest.test.BaseTestCase):
|
||||
cls.os_primary.security_group_rules_client)
|
||||
cls.network_versions_client = cls.os_primary.network_versions_client
|
||||
cls.service_providers_client = cls.os_primary.service_providers_client
|
||||
cls.tags_client = cls.os_primary.tags_client
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
|
90
tempest/api/network/test_tags.py
Normal file
90
tempest/api/network/test_tags.py
Normal file
@ -0,0 +1,90 @@
|
||||
# Copyright 2017 AT&T Corporation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 tempest.api.network import base
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
from tempest import test
|
||||
|
||||
|
||||
class TagsTest(base.BaseNetworkTest):
|
||||
"""Tests the following operations in the tags API:
|
||||
|
||||
Update all tags.
|
||||
Delete all tags.
|
||||
Check tag existence.
|
||||
Create a tag.
|
||||
List tags.
|
||||
Remove a tag.
|
||||
|
||||
v2.0 of the Neutron API is assumed. The tag extension allows users to set
|
||||
tags on their networks. The extension supports networks only.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(TagsTest, cls).skip_checks()
|
||||
if not test.is_extension_enabled('tag', 'network'):
|
||||
msg = "tag extension not enabled."
|
||||
raise cls.skipException(msg)
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TagsTest, cls).resource_setup()
|
||||
cls.network = cls.create_network()
|
||||
|
||||
@decorators.idempotent_id('ee76bfaf-ac94-4d74-9ecc-4bbd4c583cb1')
|
||||
def test_create_list_show_update_delete_tags(self):
|
||||
# Validate that creating a tag on a network resource works.
|
||||
tag_name = data_utils.rand_name(self.__class__.__name__ + '-Tag')
|
||||
self.tags_client.create_tag('networks', self.network['id'], tag_name)
|
||||
self.addCleanup(self.tags_client.delete_all_tags, 'networks',
|
||||
self.network['id'])
|
||||
self.tags_client.check_tag_existence('networks', self.network['id'],
|
||||
tag_name)
|
||||
|
||||
# Validate that listing tags on a network resource works.
|
||||
retrieved_tags = self.tags_client.list_tags(
|
||||
'networks', self.network['id'])['tags']
|
||||
self.assertEqual([tag_name], retrieved_tags)
|
||||
|
||||
# Generate 3 new tag names.
|
||||
replace_tags = [data_utils.rand_name(
|
||||
self.__class__.__name__ + '-Tag') for _ in range(3)]
|
||||
|
||||
# Replace the current tag with the 3 new tags and validate that the
|
||||
# network resource has the 3 new tags.
|
||||
updated_tags = self.tags_client.update_all_tags(
|
||||
'networks', self.network['id'], replace_tags)['tags']
|
||||
self.assertEqual(3, len(updated_tags))
|
||||
self.assertEqual(set(replace_tags), set(updated_tags))
|
||||
|
||||
# Delete the first tag and check that it has been removed.
|
||||
self.tags_client.delete_tag(
|
||||
'networks', self.network['id'], replace_tags[0])
|
||||
self.assertRaises(lib_exc.NotFound,
|
||||
self.tags_client.check_tag_existence, 'networks',
|
||||
self.network['id'], replace_tags[0])
|
||||
for i in range(1, 3):
|
||||
self.tags_client.check_tag_existence(
|
||||
'networks', self.network['id'], replace_tags[i])
|
||||
|
||||
# Delete all the remaining tags and check that they have been removed.
|
||||
self.tags_client.delete_all_tags('networks', self.network['id'])
|
||||
for i in range(1, 3):
|
||||
self.assertRaises(lib_exc.NotFound,
|
||||
self.tags_client.check_tag_existence, 'networks',
|
||||
self.network['id'], replace_tags[i])
|
@ -79,6 +79,7 @@ class Manager(clients.ServiceClients):
|
||||
self.security_groups_client = self.network.SecurityGroupsClient()
|
||||
self.network_versions_client = self.network.NetworkVersionsClient()
|
||||
self.service_providers_client = self.network.ServiceProvidersClient()
|
||||
self.tags_client = self.network.TagsClient()
|
||||
|
||||
def _set_image_clients(self):
|
||||
if CONF.service_available.glance:
|
||||
|
@ -31,11 +31,12 @@ from tempest.lib.services.network.service_providers_client import \
|
||||
ServiceProvidersClient
|
||||
from tempest.lib.services.network.subnetpools_client import SubnetpoolsClient
|
||||
from tempest.lib.services.network.subnets_client import SubnetsClient
|
||||
from tempest.lib.services.network.tags_client import TagsClient
|
||||
from tempest.lib.services.network.versions_client import NetworkVersionsClient
|
||||
|
||||
__all__ = ['AgentsClient', 'ExtensionsClient', 'FloatingIPsClient',
|
||||
'MeteringLabelRulesClient', 'MeteringLabelsClient',
|
||||
'NetworksClient', 'PortsClient', 'QuotasClient', 'RoutersClient',
|
||||
'SecurityGroupRulesClient', 'SecurityGroupsClient',
|
||||
'ServiceProvidersClient', 'SubnetpoolsClient', 'SubnetsClient',
|
||||
'NetworkVersionsClient']
|
||||
'NetworksClient', 'NetworkVersionsClient', 'PortsClient',
|
||||
'QuotasClient', 'RoutersClient', 'SecurityGroupRulesClient',
|
||||
'SecurityGroupsClient', 'ServiceProvidersClient',
|
||||
'SubnetpoolsClient', 'SubnetsClient', 'TagsClient']
|
||||
|
88
tempest/lib/services/network/tags_client.py
Normal file
88
tempest/lib/services/network/tags_client.py
Normal file
@ -0,0 +1,88 @@
|
||||
# Copyright 2017 AT&T Corporation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 oslo_serialization import jsonutils as json
|
||||
|
||||
from tempest.lib.common import rest_client
|
||||
from tempest.lib.services.network import base
|
||||
|
||||
|
||||
class TagsClient(base.BaseNetworkClient):
|
||||
|
||||
def create_tag(self, resource_type, resource_id, tag):
|
||||
"""Adds a tag on the resource.
|
||||
|
||||
For more information, please refer to the official API reference:
|
||||
http://developer.openstack.org/api-ref/networking/v2/index.html#add-a-tag
|
||||
"""
|
||||
# NOTE(felipemonteiro): Cannot use ``update_resource`` method because
|
||||
# this API requires self.put but returns 201 instead of 200 expected
|
||||
# by ``update_resource``.
|
||||
uri = '%s/%s/%s/tags/%s' % (
|
||||
self.uri_prefix, resource_type, resource_id, tag)
|
||||
resp, _ = self.put(uri, json.dumps({}))
|
||||
self.expected_success(201, resp.status)
|
||||
return rest_client.ResponseBody(resp)
|
||||
|
||||
def check_tag_existence(self, resource_type, resource_id, tag):
|
||||
"""Confirm that a given tag is set on the resource.
|
||||
|
||||
For more information, please refer to the official API reference:
|
||||
http://developer.openstack.org/api-ref/networking/v2/index.html#confirm-a-tag
|
||||
"""
|
||||
# TODO(felipemonteiro): Use the "check_resource" method in
|
||||
# ``BaseNetworkClient`` once it has been implemented.
|
||||
uri = '%s/%s/%s/tags/%s' % (
|
||||
self.uri_prefix, resource_type, resource_id, tag)
|
||||
resp, _ = self.get(uri)
|
||||
self.expected_success(204, resp.status)
|
||||
return rest_client.ResponseBody(resp)
|
||||
|
||||
def update_all_tags(self, resource_type, resource_id, tags):
|
||||
"""Replace all tags on the resource.
|
||||
|
||||
For more information, please refer to the official API reference:
|
||||
http://developer.openstack.org/api-ref/networking/v2/index.html#replace-all-tags
|
||||
"""
|
||||
uri = '/%s/%s/tags' % (resource_type, resource_id)
|
||||
put_body = {"tags": tags}
|
||||
return self.update_resource(uri, put_body)
|
||||
|
||||
def delete_tag(self, resource_type, resource_id, tag):
|
||||
"""Removes a tag on the resource.
|
||||
|
||||
For more information, please refer to the official API reference:
|
||||
http://developer.openstack.org/api-ref/networking/v2/index.html#remove-a-tag
|
||||
"""
|
||||
uri = '/%s/%s/tags/%s' % (resource_type, resource_id, tag)
|
||||
return self.delete_resource(uri)
|
||||
|
||||
def delete_all_tags(self, resource_type, resource_id):
|
||||
"""Removes all tags on the resource.
|
||||
|
||||
For more information, please refer to the official API reference:
|
||||
http://developer.openstack.org/api-ref/networking/v2/index.html#remove-all-tags
|
||||
"""
|
||||
uri = '/%s/%s/tags' % (resource_type, resource_id)
|
||||
return self.delete_resource(uri)
|
||||
|
||||
def list_tags(self, resource_type, resource_id):
|
||||
"""Retrieves the tags for a resource.
|
||||
|
||||
For more information, please refer to the official API reference:
|
||||
http://developer.openstack.org/api-ref/networking/v2/index.html#obtain-tag-list
|
||||
"""
|
||||
uri = '/%s/%s/tags' % (resource_type, resource_id)
|
||||
return self.list_resources(uri)
|
123
tempest/tests/lib/services/network/test_tags_client.py
Normal file
123
tempest/tests/lib/services/network/test_tags_client.py
Normal file
@ -0,0 +1,123 @@
|
||||
# Copyright 2017 AT&T Corporation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 tempest.lib.services.network import tags_client
|
||||
from tempest.tests.lib import fake_auth_provider
|
||||
from tempest.tests.lib.services import base
|
||||
|
||||
|
||||
class TestTagsClient(base.BaseServiceTest):
|
||||
|
||||
FAKE_TAGS = {
|
||||
"tags": [
|
||||
"red",
|
||||
"blue"
|
||||
]
|
||||
}
|
||||
|
||||
FAKE_RESOURCE_TYPE = 'network'
|
||||
|
||||
FAKE_RESOURCE_ID = '7a8f904b-c1ed-4446-a87d-60440c02934b'
|
||||
|
||||
def setUp(self):
|
||||
super(TestTagsClient, self).setUp()
|
||||
fake_auth = fake_auth_provider.FakeAuthProvider()
|
||||
self.client = tags_client.TagsClient(
|
||||
fake_auth, 'network', 'regionOne')
|
||||
|
||||
def _test_update_all_tags(self, bytes_body=False):
|
||||
self.check_service_client_function(
|
||||
self.client.update_all_tags,
|
||||
'tempest.lib.common.rest_client.RestClient.put',
|
||||
self.FAKE_TAGS,
|
||||
bytes_body,
|
||||
resource_type=self.FAKE_RESOURCE_TYPE,
|
||||
resource_id=self.FAKE_RESOURCE_ID,
|
||||
tags=self.FAKE_TAGS)
|
||||
|
||||
def _test_check_tag_existence(self, bytes_body=False):
|
||||
self.check_service_client_function(
|
||||
self.client.check_tag_existence,
|
||||
'tempest.lib.common.rest_client.RestClient.get',
|
||||
{},
|
||||
bytes_body,
|
||||
resource_type=self.FAKE_RESOURCE_TYPE,
|
||||
resource_id=self.FAKE_RESOURCE_ID,
|
||||
tag=self.FAKE_TAGS['tags'][0],
|
||||
status=204)
|
||||
|
||||
def _test_create_tag(self, bytes_body=False):
|
||||
self.check_service_client_function(
|
||||
self.client.create_tag,
|
||||
'tempest.lib.common.rest_client.RestClient.put',
|
||||
{},
|
||||
bytes_body,
|
||||
resource_type=self.FAKE_RESOURCE_TYPE,
|
||||
resource_id=self.FAKE_RESOURCE_ID,
|
||||
tag=self.FAKE_TAGS['tags'][0],
|
||||
status=201)
|
||||
|
||||
def _test_list_tags(self, bytes_body=False):
|
||||
self.check_service_client_function(
|
||||
self.client.list_tags,
|
||||
'tempest.lib.common.rest_client.RestClient.get',
|
||||
self.FAKE_TAGS,
|
||||
bytes_body,
|
||||
resource_type=self.FAKE_RESOURCE_TYPE,
|
||||
resource_id=self.FAKE_RESOURCE_ID)
|
||||
|
||||
def test_update_all_tags_with_str_body(self):
|
||||
self._test_update_all_tags()
|
||||
|
||||
def test_update_all_tags_with_bytes_body(self):
|
||||
self._test_update_all_tags(bytes_body=True)
|
||||
|
||||
def test_delete_all_tags(self):
|
||||
self.check_service_client_function(
|
||||
self.client.delete_all_tags,
|
||||
'tempest.lib.common.rest_client.RestClient.delete',
|
||||
{},
|
||||
resource_type=self.FAKE_RESOURCE_TYPE,
|
||||
resource_id=self.FAKE_RESOURCE_ID,
|
||||
status=204)
|
||||
|
||||
def test_check_tag_existence_with_str_body(self):
|
||||
self._test_check_tag_existence()
|
||||
|
||||
def test_check_tag_existence_with_bytes_body(self):
|
||||
self._test_check_tag_existence(bytes_body=True)
|
||||
|
||||
def test_create_tag_with_str_body(self):
|
||||
self._test_create_tag()
|
||||
|
||||
def test_create_tag_with_bytes_body(self):
|
||||
self._test_create_tag(bytes_body=True)
|
||||
|
||||
def test_list_tags_with_str_body(self):
|
||||
self._test_list_tags()
|
||||
|
||||
def test_list_tags_with_bytes_body(self):
|
||||
self._test_list_tags(bytes_body=True)
|
||||
|
||||
def test_delete_tag(self):
|
||||
self.check_service_client_function(
|
||||
self.client.delete_tag,
|
||||
'tempest.lib.common.rest_client.RestClient.delete',
|
||||
{},
|
||||
resource_type=self.FAKE_RESOURCE_TYPE,
|
||||
resource_id=self.FAKE_RESOURCE_ID,
|
||||
tag=self.FAKE_TAGS['tags'][0],
|
||||
status=204)
|
Loading…
Reference in New Issue
Block a user