Adds zone client's methods and tests to Designate tempest plugin
Change-Id: Ib1037238da64518c332952d8c88fd767d4d9607b
Depends-On: I58930c40243068e97ff8f6f1684cfbe5565ac7f1
Partially-Implements: blueprint designate-tempest-plugin
diff --git a/designate_tempest_plugin/services/dns/json/base.py b/designate_tempest_plugin/services/dns/json/base.py
index f2574d6..3c2f3c1 100644
--- a/designate_tempest_plugin/services/dns/json/base.py
+++ b/designate_tempest_plugin/services/dns/json/base.py
@@ -91,6 +91,7 @@
def _show_request(self, resource, uuid, params=None):
"""Gets a specific object of the specified type.
+ :param resource: The name of the REST resource, e.g., 'zones'.
:param uuid: Unique identifier of the object in UUID format.
:param params: A Python dict that represents the query paramaters to
include in the request URI.
@@ -104,6 +105,40 @@
return resp, self.deserialize(body)
+ def _list_request(self, resource, params=None):
+ """Gets a list of specific objects.
+ :param resource: The name of the REST resource, e.g., 'zones'.
+ :param params: A Python dict that represents the query paramaters to
+ include in the request URI.
+ :returns: Serialized object as a dictionary.
+ """
+ uri = self._get_uri(resource, params=params)
+
+ resp, body = self.get(uri)
+
+ self.expected_success(200, resp['status'])
+
+ return resp, self.deserialize(body)
+
+ def _update_request(self, resource, uuid, object_dict, params=None):
+ """Update a specified object.
+ :param resource: The name of the REST resource, e.g., 'zones'
+ :param uuid: Unique identifier of the object in UUID format.
+ :param object_dict: A Python dict that represents an object of the
+ specified type.
+ :param params: A Python dict that represents the query paramaters to
+ include in the request URI.
+ :returns: Serialized object as a dictionary.
+ """
+ body = self.serialize(object_dict)
+ uri = self._get_uri(resource, uuid=uuid, params=params)
+
+ resp, body = self.patch(uri, body=body)
+
+ self.expected_success(200, resp['status'])
+
+ return resp, self.deserialize(body)
+
def _delete_request(self, resource, uuid, params=None):
"""Delete specified object.
:param resource: The name of the REST resource, e.g., 'zones'.
diff --git a/designate_tempest_plugin/services/dns/v2/json/zones_client.py b/designate_tempest_plugin/services/dns/v2/json/zones_client.py
index 6f5cb95..da77979 100644
--- a/designate_tempest_plugin/services/dns/v2/json/zones_client.py
+++ b/designate_tempest_plugin/services/dns/v2/json/zones_client.py
@@ -64,6 +64,15 @@
return self._show_request('zones', uuid, params=params)
@base.handle_errors
+ def list_zones(self, params=None):
+ """Gets a list of zones.
+ :param params: A Python dict that represents the query paramaters to
+ include in the request URI.
+ :return: Serialized zones as a list.
+ """
+ return self._list_request('zones', params=params)
+
+ @base.handle_errors
def delete_zone(self, uuid, params=None):
"""Deletes a zone having the specified UUID.
:param uuid: The unique identifier of the zone.
@@ -72,3 +81,32 @@
:return: A tuple with the server response and the response body.
"""
return self._delete_request('zones', uuid, params=params)
+
+ @base.handle_errors
+ def update_zone(self, uuid, email=None, ttl=None,
+ description=None, wait_until=False, params=None):
+ """Update a zone with the specified parameters.
+ :param uuid: The unique identifier of the zone.
+ :param email: The email for the zone.
+ Default: Random Value
+ :param ttl: The ttl for the zone.
+ Default: Random Value
+ :param description: A description of the zone.
+ Default: Random Value
+ :param wait_until: Block until the zone reaches the desiered status
+ :param params: A Python dict that represents the query paramaters to
+ include in the request URI.
+ :return: A tuple with the server response and the updated zone.
+ """
+ zone = {
+ 'email': email or dns_data_utils.rand_email(),
+ 'ttl': ttl or dns_data_utils.rand_ttl(),
+ 'description': description or data_utils.rand_name('test-zone'),
+ }
+
+ resp, body = self._update_request('zones', uuid, zone, params=params)
+
+ if wait_until:
+ waiters.wait_for_zone_status(self, body['id'], wait_until)
+
+ return resp, body
\ No newline at end of file
diff --git a/designate_tempest_plugin/tests/api/v2/base.py b/designate_tempest_plugin/tests/api/v2/base.py
index d05d9d0..f7634c1 100644
--- a/designate_tempest_plugin/tests/api/v2/base.py
+++ b/designate_tempest_plugin/tests/api/v2/base.py
@@ -28,4 +28,4 @@
# rest the actual roles.
# NOTE(kiall) primary will result in a manager @ cls.os, alt will have
# cls.os_alt, and admin will have cls.os_adm.
- credentials = ['primary']
+ credentials = ['primary', 'alt', 'admin']
diff --git a/designate_tempest_plugin/tests/api/v2/test_zones.py b/designate_tempest_plugin/tests/api/v2/test_zones.py
index 345ff60..8bdebba 100644
--- a/designate_tempest_plugin/tests/api/v2/test_zones.py
+++ b/designate_tempest_plugin/tests/api/v2/test_zones.py
@@ -75,6 +75,50 @@
waiters.wait_for_zone_404(self.client, zone['id'])
+ @test.attr(type='smoke')
+ @test.idempotent_id('5bfa3cfe-5bc8-443b-bf48-cfba44cbb247')
+ def test_list_zones(self):
+ LOG.info('Create a zone')
+ _, zone = self.client.create_zone()
+ self.addCleanup(self.client.delete_zone, zone['id'])
+
+ LOG.info('Ensure we respond with CREATE+PENDING')
+ self.assertEqual('CREATE', zone['action'])
+ self.assertEqual('PENDING', zone['status'])
+
+ waiters.wait_for_zone_status(
+ self.client, zone['id'], 'ACTIVE')
+
+ LOG.info('List zones')
+ _, body = self.client.list_zones()
+
+ self.assertTrue(len(body['zones']) > 0)
+
+ @test.attr(type='smoke')
+ @test.idempotent_id('123f51cb-19d5-48a9-aacc-476742c02141')
+ def test_update_zone(self):
+ LOG.info('Create a zone')
+ _, zone = self.client.create_zone()
+ self.addCleanup(self.client.delete_zone, zone['id'])
+
+ LOG.info('Ensure we respond with CREATE+PENDING')
+ self.assertEqual('CREATE', zone['action'])
+ self.assertEqual('PENDING', zone['status'])
+
+ waiters.wait_for_zone_status(
+ self.client, zone['id'], 'ACTIVE')
+
+ LOG.info('Update the zone')
+ resp, body = self.client.update_zone(zone['id'])
+
+ self.assertEqual('UPDATE', body['action'])
+ self.assertEqual('PENDING', body['status'])
+
+ waiters.wait_for_zone_status(
+ self.client, body['id'], 'ACTIVE')
+
+ self.assertEqual(202, resp.status)
+
class ZonesAdminTest(BaseZonesTest):
credentials = ['primary', 'admin']
@@ -98,3 +142,69 @@
LOG.info('Ensure the fetched response matches the created zone')
self._assertExpected(zone, body)
+
+
+class ZoneOwnershipTest(BaseZonesTest):
+
+ @classmethod
+ def setup_clients(cls):
+ super(ZoneOwnershipTest, cls).setup_clients()
+
+ cls.client = cls.os.zones_client
+ cls.alt_client = cls.os_alt.zones_client
+
+ @test.attr(type='smoke')
+ @test.idempotent_id('5d28580a-a012-4b57-b211-e077b1a01340')
+ def test_no_create_duplicate_domain(self):
+ LOG.info('Create a zone as a default user')
+ _, zone = self.client.create_zone()
+ self.addCleanup(self.client.delete_zone, zone['id'])
+
+ LOG.info('Ensure we respond with CREATE+PENDING')
+ self.assertEqual('CREATE', zone['action'])
+ self.assertEqual('PENDING', zone['status'])
+
+ waiters.wait_for_zone_status(
+ self.client, zone['id'], 'ACTIVE')
+
+ LOG.info('Create a zone as an alt user with existing domain')
+ self.assertRaises(lib_exc.Conflict,
+ self.alt_client.create_zone, name=zone['name'])
+
+ @test.attr(type='smoke')
+ @test.idempotent_id('a48776fd-b1aa-4a25-9f09-d1d34cfbb175')
+ def test_no_create_subdomain_by_alt_user(self):
+ LOG.info('Create a zone as a default user')
+ _, zone = self.client.create_zone()
+ self.addCleanup(self.client.delete_zone, zone['id'])
+
+ LOG.info('Ensure we respond with CREATE+PENDING')
+ self.assertEqual('CREATE', zone['action'])
+ self.assertEqual('PENDING', zone['status'])
+
+ waiters.wait_for_zone_status(
+ self.client, zone['id'], 'ACTIVE')
+
+ LOG.info('Create a zone as an alt user with existing subdomain')
+ self.assertRaises(lib_exc.Forbidden,
+ self.alt_client.create_zone, name='sub.' + zone['name'])
+ self.assertRaises(lib_exc.Forbidden,
+ self.alt_client.create_zone, name='sub.sub.' + zone['name'])
+
+ @test.attr(type='smoke')
+ @test.idempotent_id('f1723d48-c082-43cd-94bf-ebeb5b8c9458')
+ def test_no_create_superdomain_by_alt_user(self):
+ LOG.info('Create a zone as a default user')
+ _, zone = self.client.create_zone(name='a.b.' + "example.com.")
+ self.addCleanup(self.client.delete_zone, zone['id'])
+
+ LOG.info('Ensure we respond with CREATE+PENDING')
+ self.assertEqual('CREATE', zone['action'])
+ self.assertEqual('PENDING', zone['status'])
+
+ waiters.wait_for_zone_status(
+ self.client, zone['id'], 'ACTIVE')
+
+ LOG.info('Create a zone as an alt user with existing superdomain')
+ self.assertRaises(lib_exc.Forbidden,
+ self.alt_client.create_zone, name='example.com.')