Verify DNS changes when updating RRSet

Change-Id: Ic4379b95cdc2fa9d62cfe0394ff7329533f38374
This commit is contained in:
Endre Karlson 2015-05-28 19:42:35 +02:00
parent d5c63b6ddb
commit 48435d84ae
6 changed files with 124 additions and 3 deletions

View File

@ -31,6 +31,9 @@ if is_service_enabled designate; then
echo_summary "Initializing Designate"
init_designate
echo "Configuring Tempest options for Designate"
configure_designate_tempest
echo_summary "Starting Designate"
start_designate

View File

@ -206,6 +206,30 @@ function configure_designate {
configure_designate_backend
}
# Configure the needed tempest options
function configure_designate_tempest() {
if is_service_enabled tempest; then
nameservers=$DESIGNATE_SERVICE_HOST:$DESIGNATE_SERVICE_PORT_DNS
case $DESIGNATE_BACKEND_DRIVER in
bind9|powerdns)
nameservers="$DESIGNATE_SERVICE_HOST:$DESIGNATE_SERVICE_PORT_DNS"
;;
akamai)
nameservers="$DESIGNATE_AKAMAI_NAMESERVERS"
;;
dynect)
nameservers="$DESIGNATE_DYNECT_NAMESERVERS"
;;
esac
if [ ! -z "$DESIGNATE_NAMESERVERS" ]; then
nameservers=$DESIGNATE_NAMESERVERS
fi
iniset $TEMPEST_CONFIG designate nameservers $nameservers
fi
}
# create_designate_accounts - Set up common required designate accounts
# Tenant User Roles

View File

@ -13,10 +13,11 @@ 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 dns.rdatatype
from tempest_lib import exceptions
from functionaltests.common import datagen
from functionaltests.common import dnsclient
from functionaltests.common import utils
from functionaltests.api.v2.base import DesignateV2Test
from functionaltests.api.v2.clients.recordset_client import RecordsetClient
@ -38,6 +39,29 @@ class RecordsetTest(DesignateV2Test):
.list_recordsets(self.zone.id)
self.assertEqual(resp.status, 200)
def assert_dns(self, model):
results = dnsclient.query_servers(model.name, model.type)
model_data = model.to_dict()
if model.type == 'AAAA':
model_data['records'] = utils.shorten_ipv6_addrs(
model_data['records'])
for answer in results:
data = {
"type": dns.rdatatype.to_text(answer.rdtype),
"name": str(answer.canonical_name),
# DNSPython wraps TXT values in "" so '+all v=foo' becomes
# '"+all" "+v=foo"'
"records": [i.to_text().replace('"', '')
for i in answer.rrset.items]
}
if answer.rrset.ttl != 0:
data['ttl'] = answer.rrset.ttl
self.assertEqual(model_data, data)
@utils.parameterized({
'A': dict(
make_recordset=lambda z: datagen.random_a_recordset(z.name)),
@ -72,6 +96,8 @@ class RecordsetTest(DesignateV2Test):
RecordsetClient.as_user('default').wait_for_recordset(
self.zone.id, recordset_id)
self.assert_dns(post_model)
put_model = make_recordset(self.zone)
del put_model.name # don't try to update the name
resp, put_resp_model = RecordsetClient.as_user('default') \
@ -85,6 +111,9 @@ class RecordsetTest(DesignateV2Test):
RecordsetClient.as_user('default').wait_for_recordset(
self.zone.id, recordset_id)
put_model.name = post_model.name
self.assert_dns(put_model)
resp, delete_resp_model = RecordsetClient.as_user('default') \
.delete_recordset(self.zone.id, recordset_id)
self.assertEqual(resp.status, 202, "on delete response")

View File

@ -60,6 +60,11 @@ cfg.CONF.register_opts([
], group='noauth')
cfg.CONF.register_opts([
cfg.ListOpt('nameservers', default=["127.0.0.1:53"])
], group="designate")
def find_config_file():
return os.environ.get(
'TEMPEST_CONFIG', '/opt/stack/tempest/etc/tempest.conf')

View File

@ -0,0 +1,48 @@
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Author: Endre Karlson <endre.karlson@hp.com>
#
# 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 os
import dns.resolver
from oslo_config import cfg
from functionaltests.common import utils
def query(name, type_, server="127.0.0.1", port=53, timeout=3):
resolver = dns.resolver.Resolver()
resolver.nameservers = [server]
resolver.port = int(port)
resolver.timeout = timeout
try:
return resolver.query(name, type_)
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
return False
def query_servers(name, type_, servers=None, timeout=3):
servers = servers or os.environ.get("DESIGNATE_SERVERS",
cfg.CONF.designate.nameservers)
results = []
for srv in servers:
server, port = srv.split(":")
port = port or 53
result = utils.wait_for_condition(
lambda: query(name, type_, server, port))
results.append(result)
return results

View File

@ -18,6 +18,8 @@ import functools
import time
import types
import netaddr
def def_method(f, *args, **kwargs):
@functools.wraps(f)
@ -88,8 +90,9 @@ def parameterized(data):
def wait_for_condition(condition, interval=1, timeout=40):
end_time = time.time() + timeout
while time.time() < end_time:
if condition():
return
result = condition()
if result:
return result
time.sleep(interval)
raise Exception("Timed out after {0} seconds".format(timeout))
@ -110,3 +113,12 @@ def memoized(func):
cache[args] = value
return value
return wrapper
def shorten_ipv6_addrs(addrs):
"""Shorten ipv6 addresses"""
new_addrs = []
for a in addrs:
an = netaddr.IPAddress(a, version=6)
new_addrs.append(an.format(netaddr.ipv6_compact))
return new_addrs