Migrate Server table

This migrates the data in the server table to
  the pool_attributes table. In addition, this
  makes all the changes for the code to use the
  nameserver pool_attribute in the default pool
  instead of a server.

  Paritally-implements: blueprint server-pools-storage

  What's left to do:
  - Remove the old server table and rest of the
    server api code

Change-Id: I7e93ab53966cf71d7c8ced38fce55f76aec12e71
This commit is contained in:
Betsy Luzader 2014-11-20 16:18:08 -06:00
parent 5b65e05776
commit 3ab3853c2f
18 changed files with 563 additions and 510 deletions

View File

@ -19,7 +19,7 @@ from designate.openstack.common import log as logging
from designate import schema
from designate.api.v1 import load_values
from designate.central import rpcapi as central_rpcapi
from designate.objects import Domain
from designate import objects
LOG = logging.getLogger(__name__)
@ -29,6 +29,19 @@ domains_schema = schema.Schema('v1', 'domains')
servers_schema = schema.Schema('v1', 'servers')
def _poolattribute_to_server(pool_attribute):
server_values = {
'id': pool_attribute.id,
'created_at': pool_attribute.created_at,
'updated_at': pool_attribute.updated_at,
'version': pool_attribute.version,
'name': pool_attribute.value
}
server = objects.Server(**server_values)
return server
@blueprint.route('/schemas/domain', methods=['GET'])
def get_domain_schema():
return flask.jsonify(domain_schema.raw)
@ -49,7 +62,7 @@ def create_domain():
domain_schema.validate(values)
central_api = central_rpcapi.CentralAPI.get_instance()
domain = central_api.create_domain(context, Domain(**values))
domain = central_api.create_domain(context, objects.Domain(**values))
response = flask.jsonify(domain_schema.filter(domain))
response.status_int = 201
@ -117,6 +130,12 @@ def get_domain_servers(domain_id):
context = flask.request.environ.get('context')
central_api = central_rpcapi.CentralAPI.get_instance()
servers = central_api.get_domain_servers(context, domain_id)
nameservers = central_api.get_domain_servers(context, domain_id)
servers = objects.ServerList()
for ns in nameservers:
servers.append(_poolattribute_to_server(ns))
return flask.jsonify(servers_schema.filter({'servers': servers}))

View File

@ -14,17 +14,37 @@
# License for the specific language governing permissions and limitations
# under the License.
import flask
from oslo.config import cfg
from designate.openstack.common import log as logging
from designate import exceptions
from designate import schema
from designate import objects
from designate.central import rpcapi as central_rpcapi
from designate.objects import Server
LOG = logging.getLogger(__name__)
blueprint = flask.Blueprint('servers', __name__)
server_schema = schema.Schema('v1', 'server')
servers_schema = schema.Schema('v1', 'servers')
default_pool_id = cfg.CONF['service:central'].default_pool_id
# Servers are no longer used. They have been replaced by nameservers, which
# is stored as a PoolAttribute. However, the v1 server API calls still need
# to work
def _poolattribute_to_server(pool_attribute):
server_values = {
'id': pool_attribute.id,
'created_at': pool_attribute.created_at,
'updated_at': pool_attribute.updated_at,
'version': pool_attribute.version,
'name': pool_attribute.value
}
server = objects.Server(**server_values)
return server
@blueprint.route('/schemas/server', methods=['GET'])
@ -41,10 +61,40 @@ def get_servers_schema():
def create_server():
context = flask.request.environ.get('context')
values = flask.request.json
server_schema.validate(values)
central_api = central_rpcapi.CentralAPI.get_instance()
server = central_api.create_server(context, server=Server(**values))
# Validate against the original server schema
server_schema.validate(values)
# Create a PoolAttribute object
pa_values = {
'pool_id': default_pool_id,
'key': 'name_server',
'value': values['name']
}
nameserver = objects.NameServer(**pa_values)
# Get the default pool
pool = central_api.get_pool(context, default_pool_id)
# Add the new PoolAttribute to the pool as a nameserver
pool.nameservers.append(nameserver)
try:
# Update the pool
updated_pool = central_api.update_pool(context, pool)
except exceptions.DuplicatePoolAttribute:
raise exceptions.DuplicateServer()
# Go through the pool.nameservers to find the right one to get the ID
for ns in updated_pool.nameservers:
if ns.value == pa_values['value']:
created_nameserver = ns
break
# Convert the PoolAttribute to a Server so we can validate with the
# original schema and display
server = _poolattribute_to_server(created_nameserver)
response = flask.jsonify(server_schema.filter(server))
response.status_int = 201
@ -58,7 +108,14 @@ def get_servers():
context = flask.request.environ.get('context')
central_api = central_rpcapi.CentralAPI.get_instance()
servers = central_api.find_servers(context)
# Get the default pool
pool = central_api.get_pool(context, default_pool_id)
servers = objects.ServerList()
for ns in pool.nameservers:
servers.append(_poolattribute_to_server(ns))
return flask.jsonify(servers_schema.filter({'servers': servers}))
@ -68,7 +125,24 @@ def get_server(server_id):
context = flask.request.environ.get('context')
central_api = central_rpcapi.CentralAPI.get_instance()
server = central_api.get_server(context, server_id)
# Get the default pool
pool = central_api.get_pool(context, default_pool_id)
# Create an empty PoolAttribute object
nameserver = objects.NameServer()
# Get the desired nameserver from the pool
for ns in pool.nameservers:
if ns.id == server_id:
nameserver = ns
break
# If the nameserver wasn't found, raise an exception
if nameserver.id != server_id:
raise exceptions.ServerNotFound
server = _poolattribute_to_server(nameserver)
return flask.jsonify(server_schema.filter(server))
@ -80,19 +154,37 @@ def update_server(server_id):
central_api = central_rpcapi.CentralAPI.get_instance()
# Fetch the existing resource
server = central_api.get_server(context, server_id)
# Get the default pool
pool = central_api.get_pool(context, default_pool_id)
# Prepare a dict of fields for validation
# Get the Nameserver from the pool
index = -1
nameservers = pool.nameservers
for ns in nameservers:
if ns.id == server_id:
index = nameservers.index(ns)
break
if index == -1:
raise exceptions.ServerNotFound
# Get the nameserver from the pool so we can update it
nameserver = nameservers.pop(index)
# Update it with the new values
nameserver.update({'value': values['name']})
# Change it to a server, so we can use the original validation. We want
# to make sure we don't change anything in v1
server = _poolattribute_to_server(nameserver)
server_data = server_schema.filter(server)
server_data.update(values)
# Validate the new set of data
server_schema.validate(server_data)
# Update and persist the resource
server.update(values)
server = central_api.update_server(context, server)
# Now that it's been validated, add it back to the pool and persist it
pool.nameservers.append(nameserver)
central_api.update_pool(context, pool)
return flask.jsonify(server_schema.filter(server))
@ -102,6 +194,25 @@ def delete_server(server_id):
context = flask.request.environ.get('context')
central_api = central_rpcapi.CentralAPI.get_instance()
central_api.delete_server(context, server_id)
# Get the default pool
pool = central_api.get_pool(context, default_pool_id)
# Get the Nameserver from the pool
index = -1
nameservers = pool.nameservers
for ns in nameservers:
if ns.id == server_id:
index = nameservers.index(ns)
break
if index == -1:
raise exceptions.ServerNotFound
# Remove the nameserver from the pool so it will be deleted
nameservers.pop(index)
# Update the pool without the deleted server
central_api.update_pool(context, pool)
return flask.Response(status=200)

View File

@ -38,5 +38,5 @@ class NameServerView(base_view.BaseView):
"""Basic view of a nameserver"""
return {
"id": nameserver["id"],
"name": nameserver["name"]
"name": nameserver["value"]
}

View File

@ -47,7 +47,7 @@ class PoolsView(base_view.BaseView):
if 'nameservers' in result:
result['nameservers'] = objects.NameServerList(
objects=[objects.NameServer(key='nameserver', value=r)
objects=[objects.NameServer(key='name_server', value=r)
for r in result['nameservers']])
if 'attributes' in result:

View File

@ -217,7 +217,7 @@ class IPABackend(base.Backend):
LOG.debug('Create Domain %r' % domain)
ipareq = {'method': 'dnszone_add', 'id': 0}
params = [domain['name']]
servers = self.central_service.find_servers(self.admin_context)
servers = self.central_service.get_domain_servers(self.admin_context)
# just use the first one for zone creation - add the others
# later, below - use force because designate assumes the NS
# already exists somewhere, is resolvable, and already has

View File

@ -410,8 +410,8 @@ class Service(service.RPCService):
return domain
# SOA Recordset Methods
def _build_soa_record(self, zone, servers):
return "%s %s. %d %d %d %d %d" % (servers[0]['name'],
def _build_soa_record(self, zone, nameservers):
return "%s %s. %d %d %d %d %d" % (nameservers[0]['value'],
zone['email'].replace("@", "."),
zone['serial'],
zone['refresh'],
@ -420,11 +420,16 @@ class Service(service.RPCService):
zone['minimum'])
def _create_soa(self, context, zone):
# Need elevated context to get the servers
elevated_context = context.elevated()
elevated_context.all_tenants = True
servers = self.find_servers(elevated_context)
soa_values = [self._build_soa_record(zone, servers)]
# Get the nameservers
nameservers = self.storage.find_pool_attributes(
context=elevated_context,
criterion={'pool_id': zone.pool_id, 'key': 'name_server'}
)
soa_values = [self._build_soa_record(zone, nameservers)]
recordlist = objects.RecordList(objects=[
objects.Record(data=r, managed=True) for r in soa_values])
values = {
@ -439,23 +444,23 @@ class Service(service.RPCService):
def _update_soa(self, context, zone):
servers = self.get_domain_servers(context, zone['id'])
nameservers = self.get_domain_servers(context, zone['id'])
soa = self.find_recordset(context,
criterion={'domain_id': zone['id'],
'type': "SOA"})
soa.records[0].data = self._build_soa_record(zone, servers)
soa.records[0].data = self._build_soa_record(zone, nameservers)
self._update_recordset_in_storage(context, zone, soa,
increment_serial=False)
# NS Recordset Methods
def _create_ns(self, context, zone, servers):
def _create_ns(self, context, zone, nameservers):
# Create an NS record for each server
ns_values = []
for s in servers:
ns_values.append(s.name)
for s in nameservers:
ns_values.append(s.value)
recordlist = objects.RecordList(objects=[
objects.Record(data=r, managed=True) for r in ns_values])
values = {
@ -480,25 +485,33 @@ class Service(service.RPCService):
r.data = new_name
self._update_recordset_in_storage(context, zone, ns)
def _add_ns(self, context, zone, server):
def _add_ns(self, context, zone, nameserver):
# Get NS recordset
ns = self.find_recordset(context,
criterion={'domain_id': zone['id'],
'type': "NS"})
# Add new record to recordset
ns_record = objects.Record(data=server.name)
# If the zone doesn't have an NS recordset yet, create one
try:
ns = self.find_recordset(context,
criterion={'domain_id': zone['id'],
'type': "NS"})
except exceptions.RecordSetNotFound:
nameservers = objects.PoolAttributeList()
nameservers.append(nameserver)
self._create_ns(context, zone, nameservers)
return
# Add new record to recordset based on the new nameserver
ns_record = objects.Record(data=nameserver.value)
ns.records.append(ns_record)
self._update_recordset_in_storage(context, zone, ns)
def _delete_ns(self, context, zone, server):
def _delete_ns(self, context, zone, nameserver):
ns = self.find_recordset(context,
criterion={'domain_id': zone['id'],
'type': "NS"})
records = ns.records
for r in records:
if r.data == server.name:
if r.data == nameserver.value:
ns.records.remove(r)
self._update_recordset_in_storage(context, zone, ns)
@ -564,122 +577,6 @@ class Service(service.RPCService):
self.quota.reset_quotas(context, tenant_id)
# Server Methods
@notification('dns.server.create')
def create_server(self, context, server):
policy.check('create_server', context)
elevated_context = context.elevated()
elevated_context.all_tenants = True
zones = self.find_domains(elevated_context)
server = self._create_server_in_storage(context, server, zones)
for zone in zones:
self.pool_manager_api.update_domain(elevated_context, zone)
return server
@transaction
def _create_server_in_storage(self, context, server, zones):
server = self.storage.create_server(context, server)
elevated_context = context.elevated()
elevated_context.all_tenants = True
# Add NS recordsets for all zones.
for zone in zones:
self._add_ns(elevated_context, zone, server)
return server
def find_servers(self, context, criterion=None, marker=None, limit=None,
sort_key=None, sort_dir=None):
policy.check('find_servers', context)
return self.storage.find_servers(context, criterion, marker, limit,
sort_key, sort_dir)
def get_server(self, context, server_id):
policy.check('get_server', context, {'server_id': server_id})
return self.storage.get_server(context, server_id)
@notification('dns.server.update')
def update_server(self, context, server):
target = {
'server_id': server.obj_get_original_value('id'),
}
policy.check('update_server', context, target)
elevated_context = context.elevated()
elevated_context.all_tenants = True
zones = self.find_domains(elevated_context)
server = self._update_server_in_storage(context, server, zones)
for zone in zones:
self.pool_manager_api.update_domain(elevated_context, zone)
return server
@transaction
def _update_server_in_storage(self, context, server, zones):
orig_server_name = server.obj_get_original_value('name')
new_server_name = server.name
server = self.storage.update_server(context, server)
elevated_context = context.elevated()
elevated_context.all_tenants = True
# Update NS recordsets for all zones.
for zone in zones:
self._update_ns(elevated_context, zone, orig_server_name,
new_server_name)
return server
@notification('dns.server.delete')
def delete_server(self, context, server_id):
policy.check('delete_server', context, {'server_id': server_id})
elevated_context = context.elevated()
elevated_context.all_tenants = True
zones = self.find_domains(elevated_context)
server = self._delete_server_in_storage(context, server_id, zones)
for zone in zones:
self.pool_manager_api.update_domain(elevated_context, zone)
return server
@transaction
def _delete_server_in_storage(self, context, server_id, zones):
# don't delete last of servers
servers = self.storage.find_servers(context)
if len(servers) == 1 and server_id == servers[0].id:
raise exceptions.LastServerDeleteNotAllowed(
"Not allowed to delete last of servers")
server = self.storage.delete_server(context, server_id)
elevated_context = context.elevated()
elevated_context.all_tenants = True
# Delete NS recordsets for all zones.
for zone in zones:
self._delete_ns(elevated_context, zone, server)
return server
# TLD Methods
@notification('dns.tld.create')
@transaction
@ -803,7 +700,6 @@ class Service(service.RPCService):
@synchronized_domain(new_domain=True)
def create_domain(self, context, domain):
# TODO(kiall): Refactor this method into *MUCH* smaller chunks.
# Default to creating in the current users tenant
if domain.tenant_id is None:
domain.tenant_id = context.tenant
@ -856,11 +752,16 @@ class Service(service.RPCService):
# NOTE(kiall): Fetch the servers before creating the domain, this way
# we can prevent domain creation if no servers are
# configured.
servers = self.storage.find_servers(context)
elevated_context = context.elevated()
elevated_context.all_tenants = True
nameservers = self.storage.find_pool_attributes(
context=elevated_context,
criterion={'pool_id': domain.pool_id, 'key': 'name_server'}
)
if len(servers) == 0:
LOG.critical(_LC('No servers configured. '
'Please create at least one server'))
if len(nameservers) == 0:
LOG.critical(_LC('No nameservers configured. '
'Please create at least one nameserver'))
raise exceptions.NoServersConfigured()
domain = self._create_domain_in_storage(context, domain)
@ -888,12 +789,12 @@ class Service(service.RPCService):
domain.serial = utils.increment_serial()
domain = self.storage.create_domain(context, domain)
servers = self.storage.find_servers(context)
nameservers = self.get_domain_servers(context, domain['id'])
# Create the SOA and NS recordsets for the new domain. The SOA
# record will always be the first 'created_at' record for a domain.
self._create_soa(context, domain)
self._create_ns(context, domain, servers)
self._create_ns(context, domain, nameservers)
if domain.obj_attr_is_set('recordsets'):
for rrset in domain.recordsets:
@ -914,20 +815,31 @@ class Service(service.RPCService):
return domain
def get_domain_servers(self, context, domain_id, criterion=None):
domain = self.storage.get_domain(context, domain_id)
def get_domain_servers(self, context, domain_id=None, criterion=None):
target = {
'domain_id': domain_id,
'domain_name': domain.name,
'tenant_id': domain.tenant_id
}
if domain_id is None:
policy.check('get_domain_servers', context)
pool_id = cfg.CONF['service:central'].default_pool_id
else:
domain = self.storage.get_domain(context, domain_id)
target = {
'domain_id': domain_id,
'domain_name': domain.name,
'tenant_id': domain.tenant_id
}
pool_id = domain.pool_id
policy.check('get_domain_servers', context, target)
policy.check('get_domain_servers', context, target)
# TODO(kiall): Once we allow domains to be allocated on 1 of N server
# pools, return the filtered list here.
return self.storage.find_servers(context, criterion)
nameservers = self.storage.find_pool_attributes(
context=context,
criterion={
'pool_id': pool_id,
'key': 'name_server'
}
)
return nameservers
def find_domains(self, context, criterion=None, marker=None, limit=None,
sort_key=None, sort_dir=None):
@ -1986,8 +1898,57 @@ class Service(service.RPCService):
policy.check('update_pool', context)
# If there is a nameserver, then additional steps need to be done
# Since these are treated as mutable objects, we're only going to
# be comparing the nameserver.value which is the FQDN
if pool.obj_attr_is_set('nameservers'):
elevated_context = context.elevated()
elevated_context.all_tenants = True
# Get all existing nameserver FQDNs and put them in a set
existing_ns = \
set([ns.value for ns in self.storage.find_pool_attributes(
context=context,
criterion={'pool_id': pool.id, 'key': 'name_server'}
)])
# Get all nameserver FQDNs from the request and put them in a set
request_ns = set([ns.value for ns in pool.nameservers.objects])
# Get the new ones to be created
create_ns = request_ns.difference(existing_ns)
# Get the ones to be deleted
delete_ns = existing_ns.difference(request_ns)
# Ignore the ones that are in both sets, as those haven't changed
updated_pool = self.storage.update_pool(context, pool)
# After the update, handle new nameservers
for ns in create_ns:
# Create new NS recordsets for every zone
zones = self.find_domains(
context=elevated_context,
criterion={'pool_id': pool.id})
for z in zones:
self._add_ns(elevated_context, z,
objects.PoolAttribute(value=ns))
# Then handle the nameservers to delete
for ns in delete_ns:
# Cannot delete the last nameserver, so verify that first.
nameservers = pool.nameservers
if len(nameservers) == 0:
raise exceptions.LastServerDeleteNotAllowed(
"Not allowed to delete last of servers"
)
# Delete the NS recordsets for every zone
zones = self.find_domains(
context=elevated_context,
criterion={'pool_id': pool.id})
for z in zones:
self._delete_ns(elevated_context, z,
objects.PoolAttribute(value=ns))
return updated_pool
@notification('dns.pool.delete')
@ -1996,7 +1957,19 @@ class Service(service.RPCService):
policy.check('delete_pool', context)
pool = self.storage.delete_pool(context, pool_id)
# Make sure that there are no existing zones in the pool
elevated_context = context.elevated()
elevated_context.all_tenants = True
zones = self.find_domains(
context=elevated_context,
criterion={'pool_id': pool_id})
# If there are existing zones, do not delete the pool
LOG.debug("Zones is None? %r " % zones)
if len(zones) == 0:
pool = self.storage.delete_pool(context, pool_id)
else:
raise exceptions.InvalidOperation('pool must not contain zones')
return pool

View File

@ -42,8 +42,6 @@
"attributes": {
"type": "object",
"description": "Pool attributes as name value pairs",
"additionalProperties": false,
"required": ["scope"],
"properties": {
"scope": {
"type": "string",

View File

@ -397,7 +397,7 @@ class Storage(DriverPlugin):
"""
Update a recordset
:param context: RPC Context
:param context: RPC Context.
:param recordset: RecordSet to update
"""
@ -406,7 +406,7 @@ class Storage(DriverPlugin):
"""
Delete a recordset
:param context: RPC Context
:param context: RPC Context.
:param recordset_id: RecordSet ID to delete
"""
@ -469,7 +469,7 @@ class Storage(DriverPlugin):
"""
Update a record
:param context: RPC Context
:param context: RPC Context.
:param record: Record to update
"""
@ -478,7 +478,7 @@ class Storage(DriverPlugin):
"""
Delete a record
:param context: RPC Context
:param context: RPC Context.
:param record_id: Record ID to delete
"""
@ -567,7 +567,7 @@ class Storage(DriverPlugin):
"""
Find all Pools
:param context: RPC Context
:param context: RPC Context.
:param criterion: Criteria by which to filter
:param marker: Resource ID used by paging. The next page will start
at the next resource after the marker
@ -590,9 +590,8 @@ class Storage(DriverPlugin):
"""
Get a Pool via the id
:param context: RPC Context
:param context: RPC Context.
:param pool_id: The ID of the pool to get
:return: The requested pool
"""
@abc.abstractmethod
@ -600,9 +599,8 @@ class Storage(DriverPlugin):
"""
Update the specified pool
:param context: RPC Context
:param pool_id: The ID of the pool to be updated
:return: The updated pool
:param context: RPC Context.
:param pool: Pool to update.
"""
@abc.abstractmethod
@ -610,10 +608,71 @@ class Storage(DriverPlugin):
"""
Delete the pool with the matching id
:param context: RPC Context
:param context: RPC Context.
:param pool_id: The ID of the pool to be deleted
"""
@abc.abstractmethod
def create_pool_attribute(self, context, pool_id, pool_attribute):
"""
Create a PoolAttribute.
:param context: RPC Context.
:param pool_id: The ID of the pool to which the attribute belongs.
:param pool_attribute: PoolAttribute object with the values created.
"""
@abc.abstractmethod
def find_pool_attributes(self, context, criterion=None, marker=None,
limit=None, sort_key=None, sort_dir=None):
"""
Find all PoolAttributes
:param context: RPC Context
:param criterion: Criteria by which to filer
:param marker: Resource ID used by paging. The next page will start
at the next resource after the marker
:param limit: Integer limit of objects on the page
:param sort_key: Key used to sort the returned list
:param sort_dir: Directions to sort after using sort_key
"""
@abc.abstractmethod
def find_pool_attribute(self, context, criterion):
"""
Find a single PoolAttribute
:param context: RPC Context.
:param criterion: Criteria to filter by.
"""
@abc.abstractmethod
def get_pool_attribute(self, context, pool_attribute_id):
"""
Get a PoolAttribute via the ID
:param context: RPC Context.
:param pool_attribute_id: The ID of the PoolAttribute to get
"""
@abc.abstractmethod
def update_pool_attribute(self, context, pool_attribute):
"""
Update the specified pool
:param context: RPC Context.
:param pool_attribute: PoolAttribute to update
"""
@abc.abstractmethod
def delete_pool_attribute(self, context, pool_attribute_id):
"""
Delete the pool with the matching id
:param context: RPC Context.
:param pool_attribute_id: The ID of the PoolAttribute to be deleted
"""
def ping(self, context):
"""Ping the Storage connection"""
return {

View File

@ -634,10 +634,11 @@ class SQLAlchemyStorage(sqlalchemy_base.SQLAlchemy, storage_base.Storage):
def get_pool(self, context, pool_id):
pool = self._find_pools(context, {'id': pool_id}, one=True)
pool.attributes = self._find_pool_attributes(
context, {'pool_id': pool_id, 'key': '!nameserver'})
context, {'pool_id': pool_id, 'key': '!name_server'})
pool.nameservers = self._find_pool_attributes(
context, {'pool_id': pool_id, 'key': 'nameserver'})
context, {'pool_id': pool_id, 'key': 'name_server'})
pool.obj_reset_changes(['attributes', 'nameservers'])
return pool
def find_pools(self, context, criterion=None, marker=None,
@ -647,9 +648,9 @@ class SQLAlchemyStorage(sqlalchemy_base.SQLAlchemy, storage_base.Storage):
sort_dir=sort_dir)
for pool in pools:
pool.attributes = self._find_pool_attributes(
context, {'pool_id': pool.id, 'key': '!nameserver'})
context, {'pool_id': pool.id, 'key': '!name_server'})
pool.nameservers = self._find_pool_attributes(
context, {'pool_id': pool.id, 'key': 'nameserver'})
context, {'pool_id': pool.id, 'key': 'name_server'})
pool.obj_reset_changes(['attributes', 'nameservers'])
return pools
@ -657,9 +658,9 @@ class SQLAlchemyStorage(sqlalchemy_base.SQLAlchemy, storage_base.Storage):
def find_pool(self, context, criterion):
pool = self._find_pools(context, criterion, one=True)
pool.attributes = self._find_pool_attributes(
context, {'pool_id': pool.id, 'key': '!nameserver'})
context, {'pool_id': pool.id, 'key': '!name_server'})
pool.nameservers = self._find_pool_attributes(
context, {'pool_id': pool.id, 'key': 'nameserver'})
context, {'pool_id': pool.id, 'key': 'name_server'})
pool.obj_reset_changes(['attributes', 'nameservers'])
return pool
@ -714,7 +715,11 @@ class SQLAlchemyStorage(sqlalchemy_base.SQLAlchemy, storage_base.Storage):
self.create_pool_attribute(
context, pool.id, attribute)
return pool
# Call get_pool to get the ids of all the attributes/nameservers
# refreshed in the pool object
updated_pool = self.get_pool(context, pool.id)
return updated_pool
def delete_pool(self, context, pool_id):
pool = self._find_pools(context, {'id': pool_id}, one=True)

View File

@ -0,0 +1,73 @@
# Copyright (c) 2014 Rackspace Hosting
#
# Author: Betsy Luzader <betsy.luzader@rackspace.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.
from oslo.config import cfg
from sqlalchemy.schema import Table, MetaData
from sqlalchemy.sql import select
meta = MetaData()
# Get the default pool_id from the config file
default_pool_id = cfg.CONF['service:central'].default_pool_id.replace('-', '')
def upgrade(migrate_engine):
meta.bind = migrate_engine
# Load the database tables
servers_table = Table('servers', meta, autoload=True)
pool_attrib_table = Table('pool_attributes', meta, autoload=True)
# Read in all the servers to migrate to pool_attributes table
servers = select(
columns=[
servers_table.c.id,
servers_table.c.created_at,
servers_table.c.updated_at,
servers_table.c.version,
servers_table.c.name
]
).execute().fetchall()
for server in servers:
pool_attrib_table.insert().execute(
id=server.id,
created_at=server.created_at,
updated_at=server.updated_at,
version=server.version,
key='name_server',
value=server.name,
pool_id=default_pool_id
)
def downgrade(migrate_engine):
meta.bind = migrate_engine
# servers_table = Table('servers', meta, autoload=True)
pool_attrib_table = Table('pool_attributes', meta, autoload=True)
pool_attributes = select(
columns=[
pool_attrib_table.c.key,
pool_attrib_table.c.pool_id
]
).execute().fetchall()
for p in pool_attributes:
pool_attrib_table.delete().\
where(p.pool_id == default_pool_id).\
where(p.key == 'name_server').execute()

View File

@ -38,6 +38,7 @@ from designate import exceptions
from designate.network_api import fake as fake_network_api
from designate import network_api
from designate import objects
from designate import storage
from designate.manage import database as manage_database
from designate.sqlalchemy import utils as sqlalchemy_utils
@ -55,6 +56,7 @@ cfg.CONF.import_opt('cache_driver', 'designate.pool_manager',
cfg.CONF.import_opt('connection',
'designate.pool_manager.cache.impl_sqlalchemy',
group='pool_manager_cache:sqlalchemy')
pool_id = cfg.CONF['service:central'].default_pool_id
class NotifierFixture(fixtures.Fixture):
@ -249,14 +251,23 @@ class TestCase(base.BaseTestCase):
}]
pool_attributes_fixtures = [
{'pool_id': 'bbaa1d0b-619f-41ed-8c26-2b61c42e7a4b',
{'pool_id': pool_id,
'key': 'name_server',
'value': 'ns1.example.com.'},
{'pool_id': 'a7f5a834-dbfd-4ecc-83cd-550785b183c9',
{'pool_id': pool_id,
'key': 'scope',
'value': 'public'}
]
pool_attribute_nameserver_fixtures = [
{'pool_id': pool_id,
'key': 'name_server',
'value': 'ns1.example.org'},
{'pool_id': pool_id,
'key': 'name_server',
'value': 'ns2.example.org'},
]
pool_manager_status_fixtures = [{
'server_id': '1d7a26e6-e604-4aa0-bbc5-d01081bf1f45',
'status': 'SUCCESS',
@ -349,6 +360,8 @@ class TestCase(base.BaseTestCase):
self.central_service = self.start_service('central')
self.admin_context = self.get_admin_context()
storage_driver = cfg.CONF['service:central'].storage_driver
self.storage = storage.get_storage(storage_driver)
def _setup_pool_manager_cache(self):
@ -502,6 +515,13 @@ class TestCase(base.BaseTestCase):
_values.update(values)
return _values
def get_pool_attribute_nameserver_fixtures(self, fixture=0, values=None):
values = values or {}
_values = copy.copy(self.pool_attribute_nameserver_fixtures[fixture])
_values.update(values)
return _values
def get_pool_manager_status_fixture(self, fixture=0, values=None):
values = values or {}
@ -523,7 +543,7 @@ class TestCase(base.BaseTestCase):
_nameserver_values = self.get_nameserver_fixture(
fixture=fixture, values=None)
_values['nameservers'] = objects.NameServerList(
objects=[objects.NameServer(key='nameserver', value=r)
objects=[objects.NameServer(key='name_server', value=r)
for r in _nameserver_values])
return _values
@ -556,13 +576,31 @@ class TestCase(base.BaseTestCase):
_values.update(values)
return _values
def create_server(self, **kwargs):
def create_nameserver(self, **kwargs):
context = kwargs.pop('context', self.admin_context)
fixture = kwargs.pop('fixture', 0)
values = self.get_server_fixture(fixture=fixture, values=kwargs)
return self.central_service.create_server(
context, objects.Server(**values))
values = self.get_pool_attribute_nameserver_fixtures(fixture=fixture,
values=kwargs)
nameserver = objects.PoolAttribute(**values)
# Get the default pool
pool = self.central_service.get_pool(self.admin_context, pool_id)
# Add the new PoolAttribute to the pool as a nameserver
pool.nameservers.append(nameserver)
# Update the pool
self.central_service.update_pool(self.admin_context, pool)
# Get the new PoolAttribute from the db in order to return it
created_nameserver = self.storage.find_pool_attribute(
context=context,
criterion=values
)
return created_nameserver
def create_tld(self, **kwargs):
context = kwargs.pop('context', self.admin_context)
@ -600,9 +638,15 @@ class TestCase(base.BaseTestCase):
fixture = kwargs.pop('fixture', 0)
try:
# We always need a server to create a domain..
self.create_server()
except exceptions.DuplicateServer:
# We always need a server to create a server
nameservers = self.storage.find_pool_attributes(
context=self.admin_context,
criterion={'pool_id': pool_id,
'key': 'name_server'}
)
if len(nameservers) == 0:
self.create_nameserver()
except exceptions.DuplicatePoolAttribute:
pass
values = self.get_domain_fixture(fixture=fixture, values=kwargs)

View File

@ -31,7 +31,7 @@ LOG = logging.getLogger(__name__)
class ApiV1DomainsTest(ApiV1Test):
def test_create_domain(self):
# Create a server
self.create_server()
self.create_nameserver()
# Create a domain
fixture = self.get_domain_fixture(0)
@ -44,7 +44,7 @@ class ApiV1DomainsTest(ApiV1Test):
def test_create_domain_junk(self):
# Create a server
self.create_server()
self.create_nameserver()
# Create a domain
fixture = self.get_domain_fixture(0)
@ -95,8 +95,8 @@ class ApiV1DomainsTest(ApiV1Test):
self.post('domains', data=fixture, status_code=400)
def test_create_domain_utf_description(self):
# Create a server
self.create_server()
# Create a nameserver
self.create_nameserver()
# Create a domain
fixture = self.get_domain_fixture(0)
@ -109,7 +109,7 @@ class ApiV1DomainsTest(ApiV1Test):
def test_create_domain_description_too_long(self):
# Create a server
self.create_server()
self.create_nameserver()
# Create a domain
fixture = self.get_domain_fixture(0)
@ -124,7 +124,7 @@ class ApiV1DomainsTest(ApiV1Test):
created_at = datetime.datetime(2014, 6, 22, 21, 50, 0)
updated_at = datetime.datetime(2014, 6, 22, 21, 50, 0)
serial = 1234567
self.create_server()
self.create_nameserver()
# Create a domain
fixture = self.get_domain_fixture(0)

View File

@ -18,6 +18,7 @@ from oslo import messaging
from designate.openstack.common import log as logging
from designate import exceptions
from designate import objects
from designate.central import service as central_service
from designate.tests.test_api.test_v1 import ApiV1Test
@ -31,6 +32,7 @@ class ApiV1ServersTest(ApiV1Test):
# All Server Checks should be performed as an admin, so..
# Override to policy to make everyone an admin.
self.policy({'admin': '@'})
def test_create_server(self):
@ -63,7 +65,7 @@ class ApiV1ServersTest(ApiV1Test):
# Ensure it fails with a 400
self.post('servers', data=fixture, status_code=400)
@patch.object(central_service.Service, 'create_server',
@patch.object(central_service.Service, 'update_pool',
side_effect=messaging.MessagingTimeout())
def test_create_server_timeout(self, _):
# Create a server
@ -71,7 +73,7 @@ class ApiV1ServersTest(ApiV1Test):
self.post('servers', data=fixture, status_code=504)
@patch.object(central_service.Service, 'create_server',
@patch.object(central_service.Service, 'update_pool',
side_effect=exceptions.DuplicateServer())
def test_create_server_duplicate(self, _):
# Create a server
@ -85,8 +87,8 @@ class ApiV1ServersTest(ApiV1Test):
self.assertIn('servers', response.json)
self.assertEqual(0, len(response.json['servers']))
# Create a server
self.create_server()
# Create the nameserver
self.create_nameserver()
response = self.get('servers')
@ -94,34 +96,42 @@ class ApiV1ServersTest(ApiV1Test):
self.assertEqual(1, len(response.json['servers']))
# Create a second server
self.create_server(fixture=1)
self.create_nameserver(fixture=1)
response = self.get('servers')
self.assertIn('servers', response.json)
self.assertEqual(2, len(response.json['servers']))
@patch.object(central_service.Service, 'find_servers',
@patch.object(central_service.Service, 'get_pool',
side_effect=messaging.MessagingTimeout())
def test_get_servers_timeout(self, _):
self.get('servers', status_code=504)
def test_get_server(self):
# Create a server
server = self.create_server()
nameserver = self.create_nameserver()
response = self.get('servers/%s' % server['id'])
response = self.get('servers/%s' % nameserver['id'])
self.assertIn('id', response.json)
self.assertEqual(response.json['id'], server['id'])
self.assertEqual(response.json['id'], nameserver['id'])
@patch.object(central_service.Service, 'get_server',
@patch.object(central_service.Service, 'get_pool',
side_effect=messaging.MessagingTimeout())
def test_get_server_timeout(self, _):
# Create a server
server = self.create_server()
# # Create a server
# nameserver = self.create_nameserver()
self.get('servers/%s' % server['id'], status_code=504)
fixture = self.get_server_fixture(0)
values = {
'key': 'name_server',
'value': fixture['name'],
'id': '2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980'
}
nameserver = objects.PoolAttribute(**values)
self.get('servers/%s' % nameserver['id'], status_code=504)
def test_get_server_with_invalid_id(self):
self.get('servers/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff98GH',
@ -133,7 +143,7 @@ class ApiV1ServersTest(ApiV1Test):
def test_update_server(self):
# Create a server
server = self.create_server()
server = self.create_nameserver()
data = {'name': 'test.example.org.'}
@ -145,46 +155,26 @@ class ApiV1ServersTest(ApiV1Test):
self.assertIn('name', response.json)
self.assertEqual(response.json['name'], 'test.example.org.')
def test_update_server_missing(self):
data = {'name': 'test.example.org.'}
self.put('servers/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980', data=data,
status_code=404)
def test_update_server_junk(self):
# Create a server
server = self.create_server()
server = self.create_nameserver()
data = {'name': 'test.example.org.', 'junk': 'Junk Field'}
self.put('servers/%s' % server['id'], data=data, status_code=400)
@patch.object(central_service.Service, 'update_server',
side_effect=messaging.MessagingTimeout())
def test_update_server_timeout(self, _):
# Create a server
server = self.create_server()
data = {'name': 'test.example.org.'}
self.put('servers/%s' % server['id'], data=data, status_code=504)
@patch.object(central_service.Service, 'update_server',
side_effect=exceptions.DuplicateServer())
def test_update_server_duplicate(self, _):
server = self.create_server()
data = {'name': 'test.example.org.'}
self.put('servers/%s' % server['id'], data=data, status_code=409)
def test_update_server_missing(self):
data = {'name': 'test.example.org.'}
self.get('servers/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980', data=data,
status_code=404)
def test_delete_server(self):
# Create a server
server = self.create_server()
server = self.create_nameserver()
# Create a second server so that we can delete the first
# because the last remaining server is not allowed to be deleted
server2 = self.create_server(fixture=1)
server2 = self.create_nameserver(fixture=1)
# Now delete the server
self.delete('servers/%s' % server['id'])
@ -195,18 +185,10 @@ class ApiV1ServersTest(ApiV1Test):
# Also, verify we cannot delete last remaining server
self.delete('servers/%s' % server2['id'], status_code=400)
@patch.object(central_service.Service, 'delete_server',
side_effect=messaging.MessagingTimeout())
def test_delete_server_timeout(self, _):
# Create a server
server = self.create_server()
self.delete('servers/%s' % server['id'], status_code=504)
def test_delete_server_with_invalid_id(self):
self.delete('servers/9fdadfb1-cf96-4259-ac6b-bb7b6d2ff98GH',
status_code=404)
def test_delete_server_missing(self):
self.delete('servers/9fdadfb1-cf96-4259-ac6b-bb7b6d2ff980',
self.delete('servers/9fdadfb1-cf96-4259-ac6b-bb7b6d2ff980',
status_code=404)

View File

@ -44,7 +44,7 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
self.assertEqual(None, fip_record['ptrdname'])
def test_get_floatingip_with_record(self):
self.create_server()
self.create_nameserver()
fixture = self.get_ptr_fixture()
@ -110,7 +110,7 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
self.assertEqual(None, fip_record['description'])
def test_list_floatingip_with_record(self):
self.create_server()
self.create_nameserver()
fixture = self.get_ptr_fixture()
@ -138,7 +138,7 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
self.assertEqual(fixture['ptrdname'], fip_record['ptrdname'])
def test_set_floatingip(self):
self.create_server()
self.create_nameserver()
fixture = self.get_ptr_fixture()
fip = self.network_api.fake.allocate_floatingip('tenant')
@ -184,7 +184,7 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
url, {})
def test_unset_floatingip(self):
self.create_server()
self.create_nameserver()
fixture = self.get_ptr_fixture()
context = self.get_context(tenant='a')
@ -229,7 +229,7 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
self.assertEqual(None, fip['ptrdname'])
def test_unset_floatingip_not_allocated(self):
self.create_server()
self.create_nameserver()
fixture = self.get_ptr_fixture()
context = self.get_context(tenant='a')

View File

@ -16,10 +16,14 @@
from mock import patch
from oslo import messaging
from designate.openstack.common import log as logging
from designate.central import service as central_service
from designate.tests.test_api.test_v2 import ApiV2TestCase
LOG = logging.getLogger(__name__)
class ApiV2NameServersTest(ApiV2TestCase):
def setUp(self):
super(ApiV2NameServersTest, self).setUp()
@ -49,10 +53,10 @@ class ApiV2NameServersTest(ApiV2TestCase):
self.assertEqual(servers[0]['id'],
response.json['nameservers'][0]['id'])
self.assertEqual(servers[0]['name'],
self.assertEqual(servers[0]['value'],
response.json['nameservers'][0]['name'])
self.create_server(name='nsx.mydomain.com.')
self.create_nameserver(value='nsx.mydomain.com.')
response = self.client.get(url)

View File

@ -18,16 +18,20 @@ from mock import patch
from oslo import messaging
from designate import exceptions
from designate.openstack.common import log as logging
from designate.central import service as central_service
from designate.tests.test_api.test_v2 import ApiV2TestCase
LOG = logging.getLogger(__name__)
class ApiV2ZonesTest(ApiV2TestCase):
def setUp(self):
super(ApiV2ZonesTest, self).setUp()
# Create a server
self.create_server()
self.create_nameserver()
# Create the default TLDs
self.create_default_tlds()

View File

@ -186,92 +186,6 @@ class CentralServiceTest(CentralTestCase):
self.central_service._is_valid_ttl(
context, values['ttl'])
# Server Tests
def test_create_server(self):
values = dict(
name='ns1.example.org.'
)
# Create a server
server = self.central_service.create_server(
self.admin_context, server=objects.Server(**values))
# Ensure all values have been set correctly
self.assertIsNotNone(server['id'])
self.assertEqual(server['name'], values['name'])
def test_find_servers(self):
# Ensure we have no servers to start with.
servers = self.central_service.find_servers(self.admin_context)
self.assertEqual(len(servers), 0)
# Create a single server (using default values)
self.create_server()
# Ensure we can retrieve the newly created server
servers = self.central_service.find_servers(self.admin_context)
self.assertEqual(len(servers), 1)
self.assertEqual(servers[0]['name'], 'ns1.example.org.')
# Create a second server
self.create_server(name='ns2.example.org.')
# Ensure we can retrieve both servers
servers = self.central_service.find_servers(self.admin_context)
self.assertEqual(len(servers), 2)
self.assertEqual(servers[0]['name'], 'ns1.example.org.')
self.assertEqual(servers[1]['name'], 'ns2.example.org.')
def test_get_server(self):
# Create a server
server_name = 'ns%d.example.org.' % random.randint(10, 1000)
expected_server = self.create_server(name=server_name)
# Retrieve it, and ensure it's the same
server = self.central_service.get_server(
self.admin_context, expected_server['id'])
self.assertEqual(server['id'], expected_server['id'])
self.assertEqual(server['name'], expected_server['name'])
def test_update_server(self):
# Create a server
server = self.create_server(name='ns1.example.org.')
# Update the Object
server.name = 'ns2.example.org.'
# Perform the update
self.central_service.update_server(self.admin_context, server)
# Fetch the server again
server = self.central_service.get_server(self.admin_context, server.id)
# Ensure the new value took
self.assertEqual('ns2.example.org.', server.name)
def test_delete_server(self):
# Create a server
server = self.create_server()
# Create a second server
server2 = self.create_server(fixture=1)
# Delete one server
self.central_service.delete_server(self.admin_context, server['id'])
# Fetch the server again, ensuring an exception is raised
self.assertRaises(
exceptions.ServerNotFound,
self.central_service.get_server,
self.admin_context, server['id'])
# Try to delete last remaining server - expect exception
self.assertRaises(
exceptions.LastServerDeleteNotAllowed,
self.central_service.delete_server, self.admin_context,
server2['id'])
# TLD Tests
def test_create_tld(self):
# Create a TLD with one label
@ -458,7 +372,7 @@ class CentralServiceTest(CentralTestCase):
# Domain Tests
def _test_create_domain(self, values):
# Create a server
self.create_server()
self.create_nameserver()
# Reset the list of notifications
self.reset_notifications()
@ -629,7 +543,7 @@ class CentralServiceTest(CentralTestCase):
)
# Create a server
self.create_server()
self.create_nameserver()
# Create a zone that is blacklisted
domain = self.central_service.create_domain(
@ -665,7 +579,7 @@ class CentralServiceTest(CentralTestCase):
def test_create_domain_invalid_tld_fail(self):
# Create a server
self.create_server()
self.create_nameserver()
# add a tld for com
self.create_tld(fixture=0)
@ -700,7 +614,7 @@ class CentralServiceTest(CentralTestCase):
values['ttl'] = 0
# Create a server
self.create_server()
self.create_nameserver()
with testtools.ExpectedException(exceptions.InvalidTTL):
self.central_service.create_domain(
@ -714,7 +628,7 @@ class CentralServiceTest(CentralTestCase):
values['ttl'] = -100
# Create a server
self.create_server()
self.create_nameserver()
# Create domain with random TTL
domain = self.central_service.create_domain(
@ -1856,7 +1770,7 @@ class CentralServiceTest(CentralTestCase):
self.central_service.count_records(self.get_context())
def test_get_floatingip_no_record(self):
self.create_server()
self.create_nameserver()
context = self.get_context(tenant='a')
@ -1871,7 +1785,7 @@ class CentralServiceTest(CentralTestCase):
self.assertEqual(None, fip_ptr['ptrdname'])
def test_get_floatingip_with_record(self):
self.create_server()
self.create_nameserver()
context = self.get_context(tenant='a')
@ -1899,7 +1813,7 @@ class CentralServiceTest(CentralTestCase):
context, fip['region'], fip['id'])
def test_get_floatingip_deallocated_and_invalidate(self):
self.create_server()
self.create_nameserver()
context_a = self.get_context(tenant='a')
elevated_a = context_a.elevated()
@ -1978,7 +1892,7 @@ class CentralServiceTest(CentralTestCase):
self.assertEqual(None, fips[0]['description'])
def test_list_floatingips_with_record(self):
self.create_server()
self.create_nameserver()
context = self.get_context(tenant='a')
@ -1999,7 +1913,7 @@ class CentralServiceTest(CentralTestCase):
self.assertEqual(fip_ptr['description'], fips[0]['description'])
def test_list_floatingips_deallocated_and_invalidate(self):
self.create_server()
self.create_nameserver()
context_a = self.get_context(tenant='a')
elevated_a = context_a.elevated()
@ -2056,7 +1970,7 @@ class CentralServiceTest(CentralTestCase):
self.central_service.find_record(elevated_a, criterion)
def test_set_floatingip(self):
self.create_server()
self.create_nameserver()
context = self.get_context(tenant='a')
@ -2073,7 +1987,7 @@ class CentralServiceTest(CentralTestCase):
self.assertIsNotNone(fip_ptr['ttl'])
def test_set_floatingip_removes_old_record(self):
self.create_server()
self.create_nameserver()
context_a = self.get_context(tenant='a')
elevated_a = context_a.elevated()
@ -2146,7 +2060,7 @@ class CentralServiceTest(CentralTestCase):
context, fip['region'], fip['id'], fixture)
def test_unset_floatingip(self):
self.create_server()
self.create_nameserver()
context = self.get_context(tenant='a')
@ -2324,8 +2238,8 @@ class CentralServiceTest(CentralTestCase):
# Anytime a zone is created, an NS recordset should be
# automatically be created, with a record for each server
# Create a server
server = self.create_server(name='ns1.example.org.')
# Create a nameserver
nameserver = self.create_nameserver(value='ns1.example.org.')
# Create a zone
zone = self.create_domain(name='example3.org.')
@ -2339,20 +2253,14 @@ class CentralServiceTest(CentralTestCase):
self.assertIsNotNone(ns.id)
self.assertEqual('NS', ns.type)
self.assertIsNotNone(ns.records)
self.assertEqual(ns.records[0].data, server.name)
self.assertEqual(ns.records[0].data, nameserver.value)
def test_update_ns(self):
def test_add_ns(self):
# Anytime a server is created, the NS recordset for each zone
# should be automatically updated to contain the new server
# Create a server
server1 = self.create_server(name='ns1.example.net.')
servers = self.central_service.find_servers(self.admin_context)
if len(servers) == 0:
LOG.debug("There are no servers")
for s in servers:
LOG.debug("Server name is %s" % s.name)
nameserver1 = self.create_nameserver(value='ns1.example.net.')
# Create a zone
zone = self.create_domain(name='example3.net.')
@ -2363,18 +2271,14 @@ class CentralServiceTest(CentralTestCase):
self.admin_context,
criterion={'domain_id': zone['id'], 'type': "NS"})
records = ns_rs.records
for r in records:
LOG.debug("Record data is %s" % r.data)
# Ensure all values have been set correctly
self.assertIsNotNone(ns_rs.id)
self.assertEqual('NS', ns_rs.type)
self.assertIsNotNone(ns_rs.records)
self.assertEqual(ns_rs.records[0].data, server1.name)
self.assertEqual(ns_rs.records[0].data, nameserver1.value)
# Create another server
server2 = self.create_server(name='ns2.example.net.')
nameserver2 = self.create_nameserver(value='ns2.example.net.')
# Get the NS recordset again
ns_rs = self.central_service.find_recordset(
@ -2384,12 +2288,11 @@ class CentralServiceTest(CentralTestCase):
# Get zone again to check serial number
updated_zone = self.central_service.get_domain(self.admin_context,
zone.id)
new_serial = updated_zone.serial
# Ensure another record was added to the recordset
self.assertEqual(ns_rs.records[0].data, server1.name)
self.assertEqual(ns_rs.records[2].data, server2.name)
self.assertEqual(ns_rs.records[0].data, nameserver1.value)
self.assertEqual(ns_rs.records[1].data, nameserver2.value)
self.assertThat(new_serial, GreaterThan(original_serial))
# Pool Tests
@ -2519,7 +2422,7 @@ class CentralServiceTest(CentralTestCase):
nameserver_values = self.get_nameserver_fixture(fixture=1)
pool_nameservers = pool.nameservers = objects.NameServerList(
objects=[objects.NameServer(key='nameserver', value=r)
objects=[objects.NameServer(key='name_server', value=r)
for r in nameserver_values])
# Update pool

View File

@ -274,128 +274,6 @@ class StorageTestCase(object):
uuid = 'caf771fc-6b05-4891-bee1-c2a48621f57b'
self.storage.delete_quota(self.admin_context, uuid)
# Server Tests
def test_create_server(self):
values = {
'name': 'ns1.example.org.'
}
result = self.storage.create_server(
self.admin_context, server=objects.Server(**values))
self.assertIsNotNone(result['id'])
self.assertIsNotNone(result['created_at'])
self.assertIsNone(result['updated_at'])
self.assertEqual(result['name'], values['name'])
def test_create_server_duplicate(self):
# Create the Initial Server
self.create_server()
with testtools.ExpectedException(exceptions.DuplicateServer):
self.create_server()
def test_find_servers(self):
actual = self.storage.find_servers(self.admin_context)
self.assertEqual(0, len(actual))
# Create a single server
server = self.create_server()
actual = self.storage.find_servers(self.admin_context)
self.assertEqual(1, len(actual))
self.assertEqual(server['name'], actual[0]['name'])
def test_find_servers_paging(self):
# Create 10 Servers
created = [self.create_server(name='ns%d.example.org.' % i)
for i in xrange(10)]
# Ensure we can page through the results.
self._ensure_paging(created, self.storage.find_servers)
def test_find_servers_criterion(self):
server_one = self.create_server(fixture=0)
server_two = self.create_server(fixture=1)
criterion = dict(
name=server_one['name']
)
results = self.storage.find_servers(self.admin_context, criterion)
self.assertEqual(len(results), 1)
self.assertEqual(results[0]['name'], server_one['name'])
criterion = dict(
name=server_two['name']
)
results = self.storage.find_servers(self.admin_context, criterion)
self.assertEqual(len(results), 1)
self.assertEqual(results[0]['name'], server_two['name'])
def test_get_server(self):
# Create a server
expected = self.create_server()
actual = self.storage.get_server(self.admin_context, expected['id'])
self.assertEqual(str(actual['name']), str(expected['name']))
def test_get_server_missing(self):
with testtools.ExpectedException(exceptions.ServerNotFound):
uuid = 'caf771fc-6b05-4891-bee1-c2a48621f57b'
self.storage.get_server(self.admin_context, uuid)
def test_update_server(self):
# Create a server
server = self.create_server(name='ns1.example.org.')
# Update the Object
server.name = 'ns2.example.org.'
# Perform the update
server = self.storage.update_server(self.admin_context, server)
# Ensure the new value took
self.assertEqual('ns2.example.org.', server.name)
# Ensure the version column was incremented
self.assertEqual(2, server.version)
def test_update_server_duplicate(self):
# Create two servers
server_one = self.create_server(fixture=0)
server_two = self.create_server(fixture=1)
# Update the S2 object to be a duplicate of S1
server_two.name = server_one.name
with testtools.ExpectedException(exceptions.DuplicateServer):
self.storage.update_server(self.admin_context, server_two)
def test_update_server_missing(self):
server = objects.Server(id='caf771fc-6b05-4891-bee1-c2a48621f57b')
with testtools.ExpectedException(exceptions.ServerNotFound):
self.storage.update_server(self.admin_context, server)
def test_delete_server(self):
server = self.create_server()
self.storage.delete_server(self.admin_context, server['id'])
with testtools.ExpectedException(exceptions.ServerNotFound):
self.storage.get_server(self.admin_context, server['id'])
def test_delete_server_missing(self):
with testtools.ExpectedException(exceptions.ServerNotFound):
uuid = 'caf771fc-6b05-4891-bee1-c2a48621f57b'
self.storage.delete_server(self.admin_context, uuid)
# TSIG Key Tests
def test_create_tsigkey(self):
values = self.get_tsigkey_fixture()