Merge "Adds an API test for list transfer requests sudo"
diff --git a/designate_tempest_plugin/common/constants.py b/designate_tempest_plugin/common/constants.py
index 84ee5ae..4f6c72b 100644
--- a/designate_tempest_plugin/common/constants.py
+++ b/designate_tempest_plugin/common/constants.py
@@ -19,6 +19,7 @@
DELETED = 'DELETED'
ACTIVE = 'ACTIVE'
UP = 'UP'
+CREATE = 'CREATE'
# Zone types
PRIMARY_ZONE_TYPE = 'PRIMARY'
diff --git a/designate_tempest_plugin/common/exceptions.py b/designate_tempest_plugin/common/exceptions.py
new file mode 100644
index 0000000..d3f343d
--- /dev/null
+++ b/designate_tempest_plugin/common/exceptions.py
@@ -0,0 +1,29 @@
+# Copyright 2021 Red Hat.
+#
+# 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.
+
+
+class InvalidStatusError(Exception):
+ """
+ Exception raise when an entity changes to an unexpected status.
+ """
+
+ def __init__(self, entity, entity_id, status, expected_status=None):
+ if expected_status:
+ message = ("{0} with ID {1} returned status {2} when {3} was "
+ "expected.".format(entity, entity_id,
+ status, expected_status))
+ else:
+ message = ("{0} with ID {1} returned unexpected status {2}".format(
+ entity, entity_id, status))
+ super(InvalidStatusError, self).__init__(message)
diff --git a/designate_tempest_plugin/common/waiters.py b/designate_tempest_plugin/common/waiters.py
index 2b7a3b6..6bc5dfa 100644
--- a/designate_tempest_plugin/common/waiters.py
+++ b/designate_tempest_plugin/common/waiters.py
@@ -18,6 +18,9 @@
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions as lib_exc
+from designate_tempest_plugin.common import constants as const
+from designate_tempest_plugin.common import exceptions
+
LOG = logging.getLogger(__name__)
@@ -35,6 +38,10 @@
LOG.info('Zone %s is 404ing', zone_id)
return
+ if zone['status'] == const.ERROR:
+ raise exceptions.InvalidStatusError('Zone', zone_id,
+ zone['status'])
+
if int(time.time()) - start >= client.build_timeout:
message = ('Zone %(zone_id)s failed to 404 within the required '
'time (%(timeout)s s). Current status: '
@@ -226,3 +233,35 @@
message = "(%s) %s" % (caller, message)
raise lib_exc.TimeoutException(message)
+
+
+def wait_for_ptr_status(client, fip_id, status):
+ """Waits for a PTR associated with FIP to reach given status."""
+ LOG.info('Waiting for PTR %s to reach %s', fip_id, status)
+
+ ptr = client.show_ptr_record(fip_id)
+ start = int(time.time())
+
+ while ptr['status'] != status:
+ time.sleep(client.build_interval)
+ ptr = client.show_ptr_record(fip_id)
+ status_curr = ptr['status']
+ if status_curr == status:
+ LOG.info('PTR %s reached %s', fip_id, status)
+ return
+
+ if int(time.time()) - start >= client.build_timeout:
+ message = ('PTR for FIP: %(fip_id)s failed to reach '
+ 'status=%(status)s within the required time '
+ '(%(timeout)s s). Current status: %(status_curr)s' %
+ {'fip_id': fip_id,
+ 'status': status,
+ 'status_curr': status_curr,
+ 'timeout': client.build_timeout})
+
+ caller = test_utils.find_test_caller()
+
+ if caller:
+ message = '(%s) %s' % (caller, message)
+
+ raise lib_exc.TimeoutException(message)
diff --git a/designate_tempest_plugin/data_utils.py b/designate_tempest_plugin/data_utils.py
index c9d3f6d..4b5d24d 100644
--- a/designate_tempest_plugin/data_utils.py
+++ b/designate_tempest_plugin/data_utils.py
@@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import random
+from string import ascii_lowercase
import netaddr
from oslo_log import log as logging
@@ -34,7 +35,7 @@
return an.format(netaddr.ipv6_compact)
-def rand_zone_name(name='', prefix=None, suffix='.com.'):
+def rand_zone_name(name='', prefix='rand', suffix='.com.'):
"""Generate a random zone name
:param str name: The name that you want to include
:param prefix: the exact text to start the string. Defaults to "rand"
@@ -96,8 +97,8 @@
quotas_dict['api_export_size'] = \
api_export_size or data_utils.rand_int_id(100, 999999)
else:
- LOG.warn("Leaving `api_export_size` out of quota data due to: "
- "https://bugs.launchpad.net/designate/+bug/1573141")
+ LOG.warning("Leaving `api_export_size` out of quota data due to: "
+ "https://bugs.launchpad.net/designate/+bug/1573141")
return quotas_dict
@@ -261,3 +262,22 @@
func = globals()["rand_{}_recordset".format(record_type.lower())]
return func(zone_name)
+
+
+def rand_string(size):
+ """Create random string of ASCII chars by size
+
+ :param int size - length os the string to be create
+ :return - random creates string of ASCII lover characters
+ """
+ return ''.join(random.choice(ascii_lowercase) for _ in range(size))
+
+
+def rand_domain_name(tld=None):
+ """Create random valid domain name
+
+ :param tld (optional) - TLD that will be used to random domain name
+ :return - valid domain name, for example: paka.zbabun.iuh
+ """
+ domain_tld = tld or rand_string(3)
+ return rand_string(4) + '.' + rand_string(6) + '.' + domain_tld + '.'
diff --git a/designate_tempest_plugin/services/dns/json/base.py b/designate_tempest_plugin/services/dns/json/base.py
index cbfb34f..d484ac9 100644
--- a/designate_tempest_plugin/services/dns/json/base.py
+++ b/designate_tempest_plugin/services/dns/json/base.py
@@ -82,7 +82,7 @@
"received not-int read_code %(read_code)r" %
{'expected_code': expected_code,
'read_code': read_code})
- LOG.warn(message)
+ LOG.warning(message)
return super(DnsClientBase, cls).expected_success(
expected_code=expected_code, read_code=int(read_code),
)
diff --git a/designate_tempest_plugin/services/dns/v2/json/ptr_client.py b/designate_tempest_plugin/services/dns/v2/json/ptr_client.py
index 1bd59b3..eed221b 100644
--- a/designate_tempest_plugin/services/dns/v2/json/ptr_client.py
+++ b/designate_tempest_plugin/services/dns/v2/json/ptr_client.py
@@ -24,7 +24,8 @@
@base.handle_errors
def set_ptr_record(self, floatingip_id, ptr_name=None,
- ttl=None, description=None, headers=None):
+ ttl=None, description=None, headers=None,
+ tld=None):
"""Set a PTR record for the given FloatingIP
:param floatingip_id: valid UUID of floating IP to be used.
@@ -32,13 +33,13 @@
:param ttl TTL or random valid value if not provided.
:param description Description or random if not provided.
:param headers (dict): The headers to use for the request.
+ :param tld, the TLD to be used in ptrdname generated value.
:return: created PTR dictionary.
"""
ptr = {
- 'ptrdname': ptr_name or dns_data_utils.rand_zone_name(),
+ 'ptrdname': ptr_name or dns_data_utils.rand_domain_name(tld),
'ttl': ttl or dns_data_utils.rand_ttl(),
- 'description': description or data_utils.rand_name(
- 'test-ptr')}
+ 'description': description or data_utils.rand_name('test-ptr')}
return self._update_request(
resource='reverse/floatingips/{}'.format(CONF.identity.region),
diff --git a/designate_tempest_plugin/tests/api/v2/test_enabled_api_version.py b/designate_tempest_plugin/tests/api/v2/test_enabled_api_version.py
index db98a9d..c5fcd69 100644
--- a/designate_tempest_plugin/tests/api/v2/test_enabled_api_version.py
+++ b/designate_tempest_plugin/tests/api/v2/test_enabled_api_version.py
@@ -51,8 +51,8 @@
versions = self.primary_client.list_enabled_api_versions()[1][
'versions']['values']
if user == 'not_auth_user':
- uri = CONF.identity.uri.split('identity')[0] + 'dns'
- response = requests.get(uri, verify=False)
+ response = requests.get(self.primary_client.base_url,
+ verify=False)
headers = {
k.lower(): v.lower() for k, v in response.headers.items()}
versions = self.deserialize(
diff --git a/designate_tempest_plugin/tests/api/v2/test_ptrs.py b/designate_tempest_plugin/tests/api/v2/test_ptrs.py
index e2ad98a..b094a5d 100644
--- a/designate_tempest_plugin/tests/api/v2/test_ptrs.py
+++ b/designate_tempest_plugin/tests/api/v2/test_ptrs.py
@@ -13,15 +13,22 @@
# under the License.
from oslo_log import log as logging
from tempest import config
+from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from designate_tempest_plugin.tests import base
+from designate_tempest_plugin.common import constants as const
+from designate_tempest_plugin.common import waiters
+from designate_tempest_plugin import data_utils as dns_data_utils
+
import tempest.test
CONF = config.CONF
LOG = logging.getLogger(__name__)
+TLD = dns_data_utils.rand_string(3)
+
class BasePtrTest(base.BaseDnsV2Test):
excluded_keys = ['created_at', 'updated_at', 'version', 'links',
@@ -29,7 +36,8 @@
class DesignatePtrRecord(BasePtrTest, tempest.test.BaseTestCase):
- credentials = ["primary"]
+
+ credentials = ['primary', 'admin', 'system_admin']
@classmethod
def setup_credentials(cls):
@@ -40,21 +48,37 @@
@classmethod
def setup_clients(cls):
super(DesignatePtrRecord, cls).setup_clients()
+ if CONF.enforce_scope.designate:
+ cls.admin_ptr_client = cls.os_system_admin.dns_v2.PtrClient()
+ else:
+ cls.admin_ptr_client = cls.os_admin.dns_v2.PtrClient()
cls.primary_ptr_client = cls.os_primary.dns_v2.PtrClient()
cls.primary_floating_ip_client = cls.os_primary.floating_ips_client
- def _set_ptr(self):
- fip = self.primary_floating_ip_client.create_floatingip(
- floating_network_id=CONF.network.public_network_id)['floatingip']
- fip_id = fip['id']
- self.addCleanup(self.primary_floating_ip_client.delete_floatingip,
- fip_id)
- ptr = self.primary_ptr_client.set_ptr_record(fip_id)
+ def _set_ptr(self, ptr_name=None, ttl=None, description=None,
+ headers=None, tld=TLD, fip_id=None):
+ if not fip_id:
+ fip = self.primary_floating_ip_client.create_floatingip(
+ floating_network_id=CONF.network.public_network_id)[
+ 'floatingip']
+ fip_id = fip['id']
+ self.addCleanup(
+ self.primary_floating_ip_client.delete_floatingip, fip_id)
+ ptr = self.primary_ptr_client.set_ptr_record(
+ fip_id, ptr_name=ptr_name, ttl=ttl, description=description,
+ headers=headers, tld=tld)
self.addCleanup(self.primary_ptr_client.unset_ptr_record, fip_id)
self.assertEqual('CREATE', ptr['action'])
self.assertEqual('PENDING', ptr['status'])
+ waiters.wait_for_ptr_status(
+ self.primary_ptr_client, fip_id=fip_id, status=const.ACTIVE)
return fip_id, ptr
+ def _unset_ptr(self, fip_id):
+ self.primary_ptr_client.unset_ptr_record(fip_id)
+ waiters.wait_for_ptr_status(
+ self.primary_ptr_client, fip_id=fip_id, status=const.DELETED)
+
@decorators.idempotent_id('2fb9d6ea-871d-11eb-9f9a-74e5f9e2a801')
def test_set_floatingip_ptr(self):
self._set_ptr()
@@ -66,6 +90,19 @@
floatingip_id=fip_id)
self.assertExpected(ptr, show_ptr, self.excluded_keys)
+ @decorators.idempotent_id('d3128a92-e3bd-11eb-a097-74e5f9e2a801')
+ def test_show_floatingip_ptr_impersonate_another_project(self):
+ fip_id, ptr = self._set_ptr()
+
+ LOG.info('As Admin user, show PTR record created by Primary'
+ ' user by including "x-auth-sudo-project-id" HTTP header'
+ ' in HTTP request.')
+ show_ptr = self.admin_ptr_client.show_ptr_record(
+ floatingip_id=fip_id,
+ headers={
+ 'x-auth-sudo-project-id': self.primary_ptr_client.project_id})
+ self.assertExpected(ptr, show_ptr, self.excluded_keys)
+
@decorators.idempotent_id('9187a9c6-87d4-11eb-9f9a-74e5f9e2a801')
def test_list_floatingip_ptr_records(self):
number_of_ptr_records = 3
@@ -81,14 +118,34 @@
'Failed - received PTR IDs: {} are not as'
' expected: {}'.format(created_ptr_ids, received_ptr_ids))
+ @decorators.idempotent_id('a108d6f2-e3c0-11eb-a097-74e5f9e2a801')
+ @decorators.skip_because(bug="1935977")
+ def test_list_floatingip_ptr_all_projects(self):
+ ptr = self._set_ptr()[1]
+ LOG.info('Created PTR is:{}'.format(ptr))
+
+ LOG.info('As Admin user, try to list PTR record for all projects '
+ 'by including "x-auth-all-projects" HTTP header.')
+ received_ptr_ids = [
+ item['id'] for item in self.admin_ptr_client.list_ptr_records(
+ headers={'x-auth-all-projects': True})]
+ self.assertGreater(
+ len(received_ptr_ids), 0,
+ 'Failed, "received_ptr_ids" should not be empty')
+ self.assertIn(
+ ptr['id'], received_ptr_ids,
+ 'Failed, expected ID was not found in "received_ptr_ids" list.')
+
@decorators.idempotent_id('499b5a7e-87e1-11eb-b412-74e5f9e2a801')
+ @decorators.skip_because(bug="1932026")
def test_unset_floatingip_ptr(self):
fip_id, ptr = self._set_ptr()
- self.primary_ptr_client.unset_ptr_record(fip_id)
+ self._unset_ptr(fip_id)
class DesignatePtrRecordNegative(BasePtrTest, tempest.test.BaseTestCase):
- credentials = ["primary"]
+
+ credentials = ['primary', 'admin']
@classmethod
def setup_credentials(cls):
@@ -101,24 +158,79 @@
super(DesignatePtrRecordNegative, cls).setup_clients()
cls.primary_ptr_client = cls.os_primary.dns_v2.PtrClient()
cls.primary_floating_ip_client = cls.os_primary.floating_ips_client
+ cls.admin_ptr_client = cls.os_admin.dns_v2.PtrClient()
def _set_ptr(self, ptr_name=None, ttl=None, description=None,
- headers=None):
- fip = self.primary_floating_ip_client.create_floatingip(
- floating_network_id=CONF.network.public_network_id)[
- 'floatingip']
- fip_id = fip['id']
- self.addCleanup(self.primary_floating_ip_client.delete_floatingip,
- fip_id)
+ headers=None, tld=TLD, fip_id=None):
+ if not fip_id:
+ fip = self.primary_floating_ip_client.create_floatingip(
+ floating_network_id=CONF.network.public_network_id)[
+ 'floatingip']
+ fip_id = fip['id']
+ self.addCleanup(
+ self.primary_floating_ip_client.delete_floatingip, fip_id)
ptr = self.primary_ptr_client.set_ptr_record(
fip_id, ptr_name=ptr_name, ttl=ttl, description=description,
- headers=headers)
+ headers=headers, tld=tld)
self.addCleanup(self.primary_ptr_client.unset_ptr_record, fip_id)
self.assertEqual('CREATE', ptr['action'])
self.assertEqual('PENDING', ptr['status'])
+ waiters.wait_for_ptr_status(
+ self.primary_ptr_client, fip_id=fip_id, status=const.ACTIVE)
return fip_id, ptr
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('8392db50-cdd0-11eb-a00f-74e5f9e2a801')
def test_set_floatingip_ptr_invalid_ttl(self):
LOG.info('Try to set PTR record using invalid TTL value')
with self.assertRaisesDns(lib_exc.BadRequest, 'invalid_object', 400):
self._set_ptr(ttl=-10)
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('0c9349ae-e2e8-11eb-a097-74e5f9e2a801')
+ def test_set_floatingip_ptr_not_existing_fip_id(self):
+ LOG.info('Try to set PTR record using not existing Floating IP')
+ with self.assertRaisesDns(lib_exc.NotFound, 'not_found', 404):
+ self._set_ptr(fip_id=data_utils.rand_uuid())
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('df217902-e3b2-11eb-a097-74e5f9e2a801')
+ def test_set_floatingip_ptr_huge_size_description(self):
+ LOG.info('Try to set PTR record using huge size description string')
+ with self.assertRaisesDns(lib_exc.BadRequest, 'invalid_object', 400):
+ self._set_ptr(description=dns_data_utils.rand_string(5000))
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('cb2264e2-e3b3-11eb-a097-74e5f9e2a801')
+ def test_set_floatingip_ptr_invalid_name(self):
+ invalid_names = ['', '@!(*&', 4564, dns_data_utils.rand_string(5000)]
+ for name in invalid_names:
+ LOG.info('Set PTR record using invalid name:{}'.format(name))
+ with self.assertRaisesDns(
+ lib_exc.BadRequest, 'invalid_object', 400):
+ self._set_ptr(description=dns_data_utils.rand_string(5000))
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('f616d216-51ac-11ec-8edf-201e8823901f')
+ def test_show_floatingip_ptr_impersonate_another_project_no_header(self):
+ fip_id, ptr = self._set_ptr()
+
+ LOG.info('As Admin user, show PTR record created by Primary'
+ ' user, without including "x-auth-sudo-project-id" '
+ 'HTTP header in request.')
+ with self.assertRaisesDns(lib_exc.NotFound, 'not_found', 404):
+ self.admin_ptr_client.show_ptr_record(floatingip_id=fip_id)
+
+ @decorators.attr(type='negative')
+ @decorators.idempotent_id('0d132ff0-51ad-11ec-8edf-201e8823901f')
+ @decorators.skip_because(bug="1935977")
+ def test_list_floatingip_ptr_all_projects_no_header(self):
+ ptr = self._set_ptr()[1]
+ LOG.info('Created PTR is:{}'.format(ptr))
+
+ LOG.info('As Admin user, try to list PTR record for all projects '
+ 'without including "x-auth-all-projects" HTTP header.')
+ received_ptr_ids = [
+ item['id'] for item in self.admin_ptr_client.list_ptr_records()]
+ self.assertEqual([], received_ptr_ids,
+ 'Failed, "received_ptr_ids" list should be empty')
diff --git a/designate_tempest_plugin/tests/scenario/v2/recordset_data.json b/designate_tempest_plugin/tests/scenario/v2/recordset_data.json
index 9f365a7..3168722 100644
--- a/designate_tempest_plugin/tests/scenario/v2/recordset_data.json
+++ b/designate_tempest_plugin/tests/scenario/v2/recordset_data.json
@@ -48,5 +48,37 @@
"name": "www",
"type": "TXT",
"records": ["\"Any Old Text Goes Here\""]
+ },
+ "SPF": {
+ "name": "*.sub",
+ "type": "SPF",
+ "records": ["\"v=spf1; a -all\""]
+ },
+ "NS": {
+ "name": "NS_Record",
+ "type": "NS",
+ "records": ["ns1.example.org."]
+ },
+ "PTR_IPV4": {
+ "name": "PTR_Record_IPV4",
+ "type": "PTR",
+ "records": ["34.216.184.93.in-addr.arpa."]
+ },
+ "PTR_IPV6":{
+ "name":"PTR_Record_IPV6",
+ "type":"PTR",
+ "records":[
+ "6.4.9.1.8.c.5.2.3.9.8.1.8.4.2.0.1.0.0.0.0.2.2.0.0.0.8.2.6.0.6.2.ip6.arpa."
+ ]
+ },
+ "CAA_Record": {
+ "name": "CAA_Record",
+ "type": "CAA",
+ "records": ["0 issue letsencrypt.org"]
+ },
+ "NAPTR_Record": {
+ "name": "NAPTR_Record",
+ "type": "NAPTR",
+ "records": ["0 0 S SIP+D2U !^.*$!sip:customer-service@example.com! _sip._udp.example.com."]
}
-}
+}
\ No newline at end of file
diff --git a/designate_tempest_plugin/tests/scenario/v2/test_blacklists.py b/designate_tempest_plugin/tests/scenario/v2/test_blacklists.py
index 1501300..27b3f7f 100644
--- a/designate_tempest_plugin/tests/scenario/v2/test_blacklists.py
+++ b/designate_tempest_plugin/tests/scenario/v2/test_blacklists.py
@@ -13,12 +13,14 @@
# under the License.
from oslo_log import log as logging
+from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from designate_tempest_plugin import data_utils as dns_data_utils
from designate_tempest_plugin.tests import base
+CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -28,7 +30,7 @@
class BlacklistE2E(BaseBlacklistsTest):
- credentials = ["admin", 'primary']
+ credentials = ["admin", 'primary', 'system_admin']
@classmethod
def setup_credentials(cls):
@@ -39,8 +41,13 @@
@classmethod
def setup_clients(cls):
super(BlacklistE2E, cls).setup_clients()
- cls.admin_blacklist_client = cls.os_admin.dns_v2.BlacklistsClient()
- cls.admin_zone_client = cls.os_admin.dns_v2.ZonesClient()
+ if CONF.enforce_scope.designate:
+ cls.admin_blacklist_client = (
+ cls.os_system_admin.dns_v2.BlacklistsClient())
+ cls.admin_zone_client = cls.os_system_admin.dns_v2.ZonesClient()
+ else:
+ cls.admin_blacklist_client = cls.os_admin.dns_v2.BlacklistsClient()
+ cls.admin_zone_client = cls.os_admin.dns_v2.ZonesClient()
cls.primary_zone_client = cls.os_primary.dns_v2.ZonesClient()
@decorators.idempotent_id('22b1ee72-d8d2-11eb-bcdc-74e5f9e2a801')
@@ -94,9 +101,11 @@
'supposed to be blocked')
zone = self.admin_zone_client.create_zone(
name='blacklistnameregextest2' +
- dns_data_utils.rand_zone_name())[1]
+ dns_data_utils.rand_zone_name(),
+ project_id=self.primary_zone_client.project_id)[1]
self.addCleanup(
self.wait_zone_delete, self.admin_zone_client, zone['id'])
- zone = self.admin_zone_client.create_zone(name=zone_name)[1]
+ zone = self.admin_zone_client.create_zone(
+ name=zone_name, project_id=self.primary_zone_client.project_id)[1]
self.addCleanup(
self.wait_zone_delete, self.admin_zone_client, zone['id'])
diff --git a/designate_tempest_plugin/tests/scenario/v2/test_recordsets.py b/designate_tempest_plugin/tests/scenario/v2/test_recordsets.py
index 0808f56..4c40c28 100644
--- a/designate_tempest_plugin/tests/scenario/v2/test_recordsets.py
+++ b/designate_tempest_plugin/tests/scenario/v2/test_recordsets.py
@@ -27,10 +27,16 @@
@ddt.ddt
class RecordsetsTest(base.BaseDnsV2Test):
+
+ credentials = ["admin", "system_admin", "primary"]
+
@classmethod
def setup_clients(cls):
super(RecordsetsTest, cls).setup_clients()
-
+ if CONF.enforce_scope.designate:
+ cls.admin_client = cls.os_system_admin.dns_v2.RecordsetClient()
+ else:
+ cls.admin_client = cls.os_admin.dns_v2.RecordsetClient()
cls.client = cls.os_primary.dns_v2.ZonesClient()
cls.recordset_client = cls.os_primary.dns_v2.RecordsetClient()
@@ -98,3 +104,21 @@
self.assertRaises(lib_exc.NotFound,
lambda: self.recordset_client.show_recordset(
self.zone['id'], recordset['id']))
+
+ @decorators.idempotent_id('1e78a742-66ee-11ec-8dc3-201e8823901f')
+ def test_create_soa_record_not_permitted(self):
+ # SOA record is automatically created for a zone, no user
+ # should be able to create a SOA record.
+ soa_record = ("s1.devstack.org. admin.example.net. 1510721487 3510"
+ " 600 86400 3600")
+ LOG.info('Primary tries to create a Recordset on '
+ 'the existing zone')
+ self.assertRaises(
+ lib_exc.BadRequest,
+ self.recordset_client.create_recordset,
+ self.zone['id'], soa_record)
+ LOG.info('Admin tries to create a Recordset on the existing zone')
+ self.assertRaises(
+ lib_exc.BadRequest,
+ self.admin_client.create_recordset,
+ self.zone['id'], soa_record)
diff --git a/setup.cfg b/setup.cfg
index 3cf22d8..728e365 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,12 +1,12 @@
[metadata]
name = designate-tempest-plugin
summary = OpenStack DNS As A Service (Designate) Functional Tests
-description-file =
+description_file =
README.rst
author = OpenStack
-author-email = openstack-discuss@lists.openstack.org
-home-page = https://docs.openstack.org/designate-tempest-plugin/latest/
-python-requires = >=3.6
+author_email = openstack-discuss@lists.openstack.org
+home_page = https://docs.openstack.org/designate-tempest-plugin/latest/
+python_requires = >=3.6
classifier =
Environment :: OpenStack
Environment :: No Input/Output (Daemon)