Fix DNS Recordset CRUD

If a zone name is supplied to a recordset function
we should lookup the ID to use that in the URL,
as the name in the URL will return a 404.

The `name` parameter for a recordset needs to be the full FQDN
including the zone part. Fix the tests accordingly.

Looking up recordsets via name does not work tests for that behaviour
have been removed.

Also harmonised the naming of vars in the recordset
section to make this clearer.

Also add designate to the services deployed for functional tests

These issues with the DNS related cloud functions went undiscovered
for some time because even though there are tests for it,
those get skipped when designate isn't deployed.

Change-Id: I60d6400631f31cba89a6d07382c380006bd2ded2
Signed-off-by: Graham Hayes <gr@ham.ie>
Co-Authored-By: Jens Harbott <j.harbott@x-ion.de>
This commit is contained in:
Graham Hayes 2018-04-11 16:43:57 +01:00
parent 8ce681bc26
commit 60a3ef3eb9
4 changed files with 140 additions and 25 deletions

View File

@ -108,6 +108,7 @@
description: |
Run openstacksdk functional tests against a master devstack
required-projects:
- openstack/designate
- openstack/octavia
vars:
devstack_localrc:
@ -125,9 +126,11 @@
certificates:
cert_manager: local_cert_manager
devstack_plugins:
designate: https://git.openstack.org/openstack/designate
neutron: https://git.openstack.org/openstack/neutron
octavia: https://git.openstack.org/openstack/octavia
devstack_services:
designate: true
octavia: true
o-api: true
o-cw: true
@ -136,6 +139,7 @@
neutron-qos: true
neutron-trunk: true
tox_environment:
OPENSTACKSDK_HAS_DESIGNATE: 1
OPENSTACKSDK_HAS_OCTAVIA: 1
- job:

View File

@ -8469,8 +8469,12 @@ class OpenStackCloud(_normalize.Normalizer):
:returns: A list of recordsets.
"""
zone_obj = self.get_zone(zone)
if zone_obj is None:
raise OpenStackCloudException(
"Zone %s not found." % zone)
return self._dns_client.get(
"/zones/{zone_id}/recordsets".format(zone_id=zone),
"/zones/{zone_id}/recordsets".format(zone_id=zone_obj['id']),
error_message="Error fetching recordsets list")
def get_recordset(self, zone, name_or_id):
@ -8483,10 +8487,14 @@ class OpenStackCloud(_normalize.Normalizer):
found.
"""
zone_obj = self.get_zone(zone)
if zone_obj is None:
raise OpenStackCloudException(
"Zone %s not found." % zone)
try:
return self._dns_client.get(
"/zones/{zone_id}/recordsets/{recordset_id}".format(
zone_id=zone, recordset_id=name_or_id),
zone_id=zone_obj['id'], recordset_id=name_or_id),
error_message="Error fetching recordset")
except Exception:
return None
@ -8511,7 +8519,8 @@ class OpenStackCloud(_normalize.Normalizer):
:raises: OpenStackCloudException on operation error.
"""
if self.get_zone(zone) is None:
zone_obj = self.get_zone(zone)
if zone_obj is None:
raise OpenStackCloudException(
"Zone %s not found." % zone)
@ -8531,7 +8540,7 @@ class OpenStackCloud(_normalize.Normalizer):
body['ttl'] = ttl
return self._dns_client.post(
"/zones/{zone_id}/recordsets".format(zone_id=zone),
"/zones/{zone_id}/recordsets".format(zone_id=zone_obj['id']),
json=body,
error_message="Error creating recordset {name}".format(name=name))
@ -8577,19 +8586,19 @@ class OpenStackCloud(_normalize.Normalizer):
:raises: OpenStackCloudException on operation error.
"""
zone = self.get_zone(zone)
if zone is None:
zone_obj = self.get_zone(zone)
if zone_obj is None:
self.log.debug("Zone %s not found for deleting", zone)
return False
recordset = self.get_recordset(zone['id'], name_or_id)
recordset = self.get_recordset(zone_obj['id'], name_or_id)
if recordset is None:
self.log.debug("Recordset %s not found for deleting", name_or_id)
return False
self._dns_client.delete(
"/zones/{zone_id}/recordsets/{recordset_id}".format(
zone_id=zone['id'], recordset_id=name_or_id),
zone_id=zone_obj['id'], recordset_id=name_or_id),
error_message="Error deleting recordset {0}".format(name_or_id))
return True

View File

@ -16,6 +16,8 @@ test_recordset
Functional tests for `shade` recordset methods.
"""
import random
import string
from testtools import content
@ -29,11 +31,73 @@ class TestRecordset(base.BaseFunctionalTestCase):
if not self.user_cloud.has_service('dns'):
self.skipTest('dns service not supported by cloud')
def test_recordsets(self):
def test_recordsets_with_zone_id(self):
'''Test DNS recordsets functionality'''
zone = 'example2.net.'
sub = ''.join(random.choice(string.ascii_lowercase) for _ in range(6))
zone = '%s.example2.net.' % sub
email = 'test@example2.net'
name = 'www'
name = 'www.%s' % zone
type_ = 'a'
description = 'Test recordset'
ttl = 3600
records = ['192.168.1.1']
self.addDetail('zone', content.text_content(zone))
self.addDetail('recordset', content.text_content(name))
# Create a zone to hold the tested recordset
zone_obj = self.user_cloud.create_zone(name=zone, email=email)
# Test we can create a recordset and we get it returned
created_recordset = self.user_cloud.create_recordset(zone_obj['id'],
name,
type_,
records,
description, ttl)
self.addCleanup(self.cleanup, zone, created_recordset['id'])
self.assertEqual(created_recordset['zone_id'], zone_obj['id'])
self.assertEqual(created_recordset['name'], name)
self.assertEqual(created_recordset['type'], type_.upper())
self.assertEqual(created_recordset['records'], records)
self.assertEqual(created_recordset['description'], description)
self.assertEqual(created_recordset['ttl'], ttl)
# Test that we can list recordsets
recordsets = self.user_cloud.list_recordsets(zone_obj['id'],)
self.assertIsNotNone(recordsets)
# Test we get the same recordset with the get_recordset method
get_recordset = self.user_cloud.get_recordset(zone_obj['id'],
created_recordset['id'])
self.assertEqual(get_recordset['id'], created_recordset['id'])
# Test we can update a field on the recordset and only that field
# is updated
updated_recordset = self.user_cloud.update_recordset(
zone_obj['id'],
created_recordset['id'],
ttl=7200)
self.assertEqual(updated_recordset['id'], created_recordset['id'])
self.assertEqual(updated_recordset['name'], name)
self.assertEqual(updated_recordset['type'], type_.upper())
self.assertEqual(updated_recordset['records'], records)
self.assertEqual(updated_recordset['description'], description)
self.assertEqual(updated_recordset['ttl'], 7200)
# Test we can delete and get True returned
deleted_recordset = self.user_cloud.delete_recordset(
zone, created_recordset['id'])
self.assertTrue(deleted_recordset)
def test_recordsets_with_zone_name(self):
'''Test DNS recordsets functionality'''
sub = ''.join(random.choice(string.ascii_lowercase) for _ in range(6))
zone = '%s.example2.net.' % sub
email = 'test@example2.net'
name = 'www.%s' % zone
type_ = 'a'
description = 'Test recordset'
ttl = 3600
@ -41,7 +105,6 @@ class TestRecordset(base.BaseFunctionalTestCase):
self.addDetail('zone', content.text_content(zone))
self.addDetail('recordset', content.text_content(name))
self.addCleanup(self.cleanup, zone, name)
# Create a zone to hold the tested recordset
zone_obj = self.user_cloud.create_zone(name=zone, email=email)
@ -50,8 +113,10 @@ class TestRecordset(base.BaseFunctionalTestCase):
created_recordset = self.user_cloud.create_recordset(zone, name, type_,
records,
description, ttl)
self.addCleanup(self.cleanup, zone, created_recordset['id'])
self.assertEqual(created_recordset['zone_id'], zone_obj['id'])
self.assertEqual(created_recordset['name'], name + '.' + zone)
self.assertEqual(created_recordset['name'], name)
self.assertEqual(created_recordset['type'], type_.upper())
self.assertEqual(created_recordset['records'], records)
self.assertEqual(created_recordset['description'], description)
@ -66,17 +131,14 @@ class TestRecordset(base.BaseFunctionalTestCase):
created_recordset['id'])
self.assertEqual(get_recordset['id'], created_recordset['id'])
# Test the get method also works by name
get_recordset = self.user_cloud.get_recordset(zone, name + '.' + zone)
self.assertEqual(get_recordset['id'], created_recordset['id'])
# Test we can update a field on the recordset and only that field
# is updated
updated_recordset = self.user_cloud.update_recordset(zone_obj['id'],
name + '.' + zone,
ttl=7200)
updated_recordset = self.user_cloud.update_recordset(
zone_obj['id'],
created_recordset['id'],
ttl=7200)
self.assertEqual(updated_recordset['id'], created_recordset['id'])
self.assertEqual(updated_recordset['name'], name + '.' + zone)
self.assertEqual(updated_recordset['name'], name)
self.assertEqual(updated_recordset['type'], type_.upper())
self.assertEqual(updated_recordset['records'], records)
self.assertEqual(updated_recordset['description'], description)
@ -84,10 +146,10 @@ class TestRecordset(base.BaseFunctionalTestCase):
# Test we can delete and get True returned
deleted_recordset = self.user_cloud.delete_recordset(
zone, name + '.' + zone)
zone, created_recordset['id'])
self.assertTrue(deleted_recordset)
def cleanup(self, zone_name, recordset_name):
def cleanup(self, zone_name, recordset_id):
self.user_cloud.delete_recordset(
zone_name, recordset_name + '.' + zone_name)
zone_name, recordset_id)
self.user_cloud.delete_zone(zone_name)

View File

@ -118,6 +118,14 @@ class TestRecordset(base.TestCase):
"links": {},
"metadata": {
'total_count': 1}}),
dict(method='GET',
uri=self.get_mock_url(
'dns', 'public', append=['v2', 'zones']),
json={
"zones": [zone],
"links": {},
"metadata": {
'total_count': 1}}),
dict(method='GET',
uri=self.get_mock_url(
'dns', 'public',
@ -146,6 +154,14 @@ class TestRecordset(base.TestCase):
"links": {},
"metadata": {
'total_count': 1}}),
dict(method='GET',
uri=self.get_mock_url(
'dns', 'public', append=['v2', 'zones']),
json={
"zones": [zone],
"links": {},
"metadata": {
'total_count': 1}}),
dict(method='GET',
uri=self.get_mock_url(
'dns', 'public',
@ -164,6 +180,14 @@ class TestRecordset(base.TestCase):
def test_get_recordset_by_id(self):
self.register_uris([
dict(method='GET',
uri=self.get_mock_url(
'dns', 'public', append=['v2', 'zones']),
json={
"zones": [zone],
"links": {},
"metadata": {
'total_count': 1}}),
dict(method='GET',
uri=self.get_mock_url(
'dns', 'public',
@ -176,12 +200,20 @@ class TestRecordset(base.TestCase):
def test_get_recordset_by_name(self):
self.register_uris([
dict(method='GET',
uri=self.get_mock_url(
'dns', 'public', append=['v2', 'zones']),
json={
"zones": [zone],
"links": {},
"metadata": {
'total_count': 1}}),
dict(method='GET',
uri=self.get_mock_url(
'dns', 'public',
append=['v2', 'zones', '1', 'recordsets',
new_recordset['name']]),
json=new_recordset),
json=new_recordset)
])
recordset = self.cloud.get_recordset('1', new_recordset['name'])
self.assertEqual(new_recordset['name'], recordset['name'])
@ -190,6 +222,14 @@ class TestRecordset(base.TestCase):
def test_get_recordset_not_found_returns_false(self):
recordset_name = "www.nonexistingrecord.net."
self.register_uris([
dict(method='GET',
uri=self.get_mock_url(
'dns', 'public', append=['v2', 'zones']),
json={
"zones": [zone],
"links": {},
"metadata": {
'total_count': 1}}),
dict(method='GET',
uri=self.get_mock_url(
'dns', 'public',