Replace API_v2 views with Adapters
* Copied old base view into /admin/ * Removed all v2/ views * Controllers moved to Adapters * Validation Error Middleware now in use for validation errors * Updated tests to remove wrapper object * Updated Docs to remove wrapper * Moved Quota Docs to /admin/ Change-Id: I345552bb271222d41321523acc9c4100cbe4878e Partially-Implements: blueprint validation-cleanup APIImpact: Removes wrapping object on APIv2 single resource gets (i.e. get zone by id moves from {zone:{<zone_info>}} to {<zone_info>})
This commit is contained in:
parent
19c574989b
commit
129b00e819
@ -15,7 +15,7 @@
|
||||
# under the License.
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.api.v2.views import base as base_view
|
||||
from designate.api.admin.views import base as base_view
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -15,7 +15,7 @@
|
||||
# under the License.
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.api.v2.views import base as base_view
|
||||
from designate.api.admin.views import base as base_view
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -17,20 +17,16 @@
|
||||
import pecan
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate import schema
|
||||
from designate import utils
|
||||
from designate.api.v2.controllers import rest
|
||||
from designate.api.v2.views import blacklists as blacklists_view
|
||||
from designate.objects import Blacklist
|
||||
from designate.objects.adapters import DesignateAdapter
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BlacklistsController(rest.RestController):
|
||||
_view = blacklists_view.BlacklistsView()
|
||||
_resource_schema = schema.Schema('v2', 'blacklist')
|
||||
_collection_schema = schema.Schema('v2', 'blacklists')
|
||||
SORT_KEYS = ['created_at', 'id', 'updated_at', 'pattern']
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@ -41,9 +37,10 @@ class BlacklistsController(rest.RestController):
|
||||
request = pecan.request
|
||||
context = request.environ['context']
|
||||
|
||||
blacklist = self.central_api.get_blacklist(context, blacklist_id)
|
||||
|
||||
return self._view.show(context, request, blacklist)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.get_blacklist(context, blacklist_id),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def get_all(self, **params):
|
||||
@ -59,10 +56,11 @@ class BlacklistsController(rest.RestController):
|
||||
criterion = dict((k, params[k]) for k in accepted_filters
|
||||
if k in params)
|
||||
|
||||
blacklist = self.central_api.find_blacklists(
|
||||
context, criterion, marker, limit, sort_key, sort_dir)
|
||||
|
||||
return self._view.list(context, request, blacklist)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.find_blacklists(
|
||||
context, criterion, marker, limit, sort_key, sort_dir),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def post_all(self):
|
||||
@ -70,26 +68,25 @@ class BlacklistsController(rest.RestController):
|
||||
request = pecan.request
|
||||
response = pecan.response
|
||||
context = request.environ['context']
|
||||
|
||||
body = request.body_dict
|
||||
|
||||
# Validate the request conforms to the schema
|
||||
self._resource_schema.validate(body)
|
||||
blacklist = DesignateAdapter.parse('API_v2', body, Blacklist())
|
||||
|
||||
# Convert from APIv2 -> Central format
|
||||
values = self._view.load(context, request, body)
|
||||
blacklist.validate()
|
||||
|
||||
# Create the blacklist
|
||||
blacklist = self.central_api.create_blacklist(
|
||||
context, Blacklist(**values))
|
||||
context, blacklist)
|
||||
|
||||
response.status_int = 201
|
||||
|
||||
response.headers['Location'] = self._view._get_resource_href(
|
||||
request, blacklist)
|
||||
blacklist = DesignateAdapter.render(
|
||||
'API_v2', blacklist, request=request)
|
||||
|
||||
response.headers['Location'] = blacklist['links']['self']
|
||||
|
||||
# Prepare and return the response body
|
||||
return self._view.show(context, request, blacklist)
|
||||
return blacklist
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@pecan.expose(template='json:', content_type='application/json-patch+json')
|
||||
@ -101,27 +98,21 @@ class BlacklistsController(rest.RestController):
|
||||
body = request.body_dict
|
||||
response = pecan.response
|
||||
|
||||
if request.content_type == 'application/json-patch+json':
|
||||
raise NotImplemented('json-patch not implemented')
|
||||
|
||||
# Fetch the existing blacklist entry
|
||||
blacklist = self.central_api.get_blacklist(context, blacklist_id)
|
||||
|
||||
# Convert to APIv2 Format
|
||||
blacklist_data = self._view.show(context, request, blacklist)
|
||||
blacklist = DesignateAdapter.parse('API_v2', body, blacklist)
|
||||
|
||||
if request.content_type == 'application/json-patch+json':
|
||||
raise NotImplemented('json-patch not implemented')
|
||||
else:
|
||||
blacklist_data = utils.deep_dict_merge(blacklist_data, body)
|
||||
blacklist.validate()
|
||||
|
||||
# Validate the new set of data
|
||||
self._resource_schema.validate(blacklist_data)
|
||||
|
||||
# Update and persist the resource
|
||||
blacklist.update(self._view.load(context, request, body))
|
||||
blacklist = self.central_api.update_blacklist(context, blacklist)
|
||||
blacklist = self.central_api.update_blacklist(context, blacklist)
|
||||
|
||||
response.status_int = 200
|
||||
|
||||
return self._view.show(context, request, blacklist)
|
||||
return DesignateAdapter.render('API_v2', blacklist, request=request)
|
||||
|
||||
@pecan.expose(template=None, content_type='application/json')
|
||||
@utils.validate_uuid('blacklist_id')
|
||||
|
@ -18,10 +18,9 @@ import re
|
||||
import pecan
|
||||
|
||||
from designate import exceptions
|
||||
from designate import schema
|
||||
from designate import objects
|
||||
from designate.objects.adapters import DesignateAdapter
|
||||
from designate.api.v2.controllers import rest
|
||||
from designate.api.v2.views import floatingips as floatingips_views
|
||||
|
||||
|
||||
FIP_REGEX = '^(?P<region>[A-Za-z0-9\\.\\-_]{1,100}):' \
|
||||
@ -41,9 +40,6 @@ def fip_key_to_data(key):
|
||||
|
||||
|
||||
class FloatingIPController(rest.RestController):
|
||||
_view = floatingips_views.FloatingIPView()
|
||||
_resource_schema = schema.Schema('v2', 'floatingip')
|
||||
_collection_schema = schema.Schema('v2', 'floatingips')
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def get_all(self, **params):
|
||||
@ -51,8 +47,10 @@ class FloatingIPController(rest.RestController):
|
||||
request = pecan.request
|
||||
context = request.environ['context']
|
||||
|
||||
fips = self.central_api.list_floatingips(context)
|
||||
return self._view.list(context, request, fips)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.list_floatingips(context),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def patch_one(self, fip_key):
|
||||
@ -61,21 +59,25 @@ class FloatingIPController(rest.RestController):
|
||||
"""
|
||||
request = pecan.request
|
||||
context = request.environ['context']
|
||||
body = request.body_dict
|
||||
try:
|
||||
body = request.body_dict
|
||||
except Exception as e:
|
||||
if e.message != 'TODO: Unsupported Content Type':
|
||||
raise
|
||||
else:
|
||||
# Got a blank body
|
||||
body = dict()
|
||||
|
||||
region, id_ = fip_key_to_data(fip_key)
|
||||
|
||||
# Validate the request conforms to the schema
|
||||
self._resource_schema.validate(body)
|
||||
fip = DesignateAdapter.parse('API_v2', body, objects.FloatingIP())
|
||||
|
||||
fip = self.central_api.update_floatingip(
|
||||
context,
|
||||
region,
|
||||
id_,
|
||||
objects.FloatingIP().from_dict(body['floatingip']))
|
||||
fip.validate()
|
||||
|
||||
fip = self.central_api.update_floatingip(context, region, id_, fip)
|
||||
|
||||
if fip:
|
||||
return self._view.show(context, request, fip)
|
||||
return DesignateAdapter.render('API_v2', fip, request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def get_one(self, fip_key):
|
||||
@ -87,6 +89,7 @@ class FloatingIPController(rest.RestController):
|
||||
|
||||
region, id_ = fip_key_to_data(fip_key)
|
||||
|
||||
fip = self.central_api.get_floatingip(context, region, id_)
|
||||
|
||||
return self._view.show(context, request, fip)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.get_floatingip(context, region, id_),
|
||||
request=request)
|
||||
|
@ -18,20 +18,22 @@ import pecan
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.api.v2.controllers import rest
|
||||
from designate.api.v2.views import limits as limits_view
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LimitsController(rest.RestController):
|
||||
_view = limits_view.LimitsView()
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def get_all(self):
|
||||
request = pecan.request
|
||||
context = pecan.request.environ['context']
|
||||
|
||||
absolute_limits = self.central_api.get_absolute_limits(context)
|
||||
|
||||
return self._view.show(context, request, absolute_limits)
|
||||
return {
|
||||
"max_zones": absolute_limits['domains'],
|
||||
"max_zone_recordsets": absolute_limits['domain_recordsets'],
|
||||
"max_zone_records": absolute_limits['domain_records'],
|
||||
"max_recordset_records": absolute_limits['recordset_records']
|
||||
}
|
||||
|
@ -15,20 +15,16 @@
|
||||
import pecan
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate import schema
|
||||
from designate import utils
|
||||
from designate.api.v2.controllers import rest
|
||||
from designate.api.v2.views import pools as pools_view
|
||||
from designate.objects import Pool
|
||||
from designate.objects.adapters import DesignateAdapter
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PoolsController(rest.RestController):
|
||||
_view = pools_view.PoolsView()
|
||||
_resource_schema = schema.Schema('v2', 'pool')
|
||||
_collection_schema = schema.Schema('v2', 'pools')
|
||||
SORT_KEYS = ['created_at', 'id', 'updated_at', 'name']
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@ -38,8 +34,10 @@ class PoolsController(rest.RestController):
|
||||
request = pecan.request
|
||||
context = request.environ['context']
|
||||
|
||||
pool = self.central_api.get_pool(context, pool_id)
|
||||
return self._view.show(context, request, pool)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.get_pool(context, pool_id),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def get_all(self, **params):
|
||||
@ -55,10 +53,11 @@ class PoolsController(rest.RestController):
|
||||
criterion = dict((k, params[k]) for k in accepted_filters
|
||||
if k in params)
|
||||
|
||||
pools = self.central_api.find_pools(
|
||||
context, criterion, marker, limit, sort_key, sort_dir)
|
||||
|
||||
return self._view.list(context, request, pools)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.find_pools(
|
||||
context, criterion, marker, limit, sort_key, sort_dir),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def post_all(self):
|
||||
@ -68,20 +67,18 @@ class PoolsController(rest.RestController):
|
||||
context = request.environ['context']
|
||||
body = request.body_dict
|
||||
|
||||
# Validate the request conforms to the schema
|
||||
self._resource_schema.validate(body)
|
||||
pool = DesignateAdapter.parse('API_v2', body, Pool())
|
||||
|
||||
# Convert from APIv2 -> Central format
|
||||
values = self._view.load(context, request, body)
|
||||
pool.validate()
|
||||
|
||||
# Create the pool
|
||||
pool = self.central_api.create_pool(context, Pool(**values))
|
||||
pool = self.central_api.create_pool(context, pool)
|
||||
pool = DesignateAdapter.render('API_v2', pool, request=request)
|
||||
response.status_int = 201
|
||||
|
||||
response.headers['Location'] = self._view._get_resource_href(request,
|
||||
pool)
|
||||
response.headers['Location'] = pool['links']['self']
|
||||
# Prepare and return the response body
|
||||
return self._view.show(context, request, pool)
|
||||
return pool
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@pecan.expose(template='json:', content_type='application/json-patch+json')
|
||||
@ -93,27 +90,21 @@ class PoolsController(rest.RestController):
|
||||
body = request.body_dict
|
||||
response = pecan.response
|
||||
|
||||
if request.content_type == 'application/json-patch+json':
|
||||
raise NotImplemented('json-patch not implemented')
|
||||
|
||||
# Fetch the existing pool
|
||||
pool = self.central_api.get_pool(context, pool_id)
|
||||
|
||||
# Convert to APIv2 Format
|
||||
pool_data = self._view.show(context, request, pool)
|
||||
pool = DesignateAdapter.parse('API_v2', body, pool)
|
||||
|
||||
if request.content_type == 'application/json-patch+json':
|
||||
raise NotImplemented('json-patch not implemented')
|
||||
else:
|
||||
pool_data = utils.deep_dict_merge(pool_data, body)
|
||||
pool.validate()
|
||||
|
||||
# Validate the new set of data
|
||||
self._resource_schema.validate(pool_data)
|
||||
|
||||
# Update and persist the resource
|
||||
pool.update(self._view.load(context, request, body))
|
||||
pool = self.central_api.update_pool(context, pool)
|
||||
pool = self.central_api.update_pool(context, pool)
|
||||
|
||||
response.status_int = 200
|
||||
|
||||
return self._view.show(context, request, pool)
|
||||
return DesignateAdapter.render('API_v2', pool, request=request)
|
||||
|
||||
@pecan.expose(template=None, content_type='application/json')
|
||||
@utils.validate_uuid('pool_id')
|
||||
|
@ -17,21 +17,16 @@ import pecan
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate import exceptions
|
||||
from designate import schema
|
||||
from designate import utils
|
||||
from designate.api.v2.controllers import rest
|
||||
from designate.api.v2.views import recordsets as recordsets_view
|
||||
from designate.objects import RecordSet
|
||||
from designate.objects import Record
|
||||
|
||||
from designate.objects import RecordSetList
|
||||
from designate.objects.adapters import DesignateAdapter
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RecordSetsController(rest.RestController):
|
||||
_view = recordsets_view.RecordSetsView()
|
||||
_resource_schema = schema.Schema('v2', 'recordset')
|
||||
_collection_schema = schema.Schema('v2', 'recordsets')
|
||||
SORT_KEYS = ['created_at', 'id', 'updated_at', 'domain_id', 'tenant_id',
|
||||
'name', 'type', 'ttl', 'records']
|
||||
|
||||
@ -42,10 +37,11 @@ class RecordSetsController(rest.RestController):
|
||||
request = pecan.request
|
||||
context = request.environ['context']
|
||||
|
||||
recordset = self.central_api.get_recordset(context, zone_id,
|
||||
recordset_id)
|
||||
|
||||
return self._view.show(context, request, recordset)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.get_recordset(
|
||||
context, zone_id, recordset_id),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@utils.validate_uuid('zone_id')
|
||||
@ -82,10 +78,16 @@ class RecordSetsController(rest.RestController):
|
||||
context, criterion={'data': data, 'domain_id': zone_id})
|
||||
recordsets_with_data.update(
|
||||
[record.recordset_id for record in records])
|
||||
recordsets = [recordset for recordset in recordsets
|
||||
if recordset.id in recordsets_with_data]
|
||||
|
||||
return self._view.list(context, request, recordsets, [zone_id])
|
||||
new_rsets = RecordSetList()
|
||||
|
||||
for recordset in recordsets:
|
||||
if recordset.id in recordsets_with_data:
|
||||
new_rsets.append(recordset)
|
||||
|
||||
recordsets = new_rsets
|
||||
|
||||
return DesignateAdapter.render('API_v2', recordsets, request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@utils.validate_uuid('zone_id')
|
||||
@ -97,31 +99,32 @@ class RecordSetsController(rest.RestController):
|
||||
|
||||
body = request.body_dict
|
||||
|
||||
# Validate the request conforms to the schema
|
||||
self._resource_schema.validate(body)
|
||||
recordset = DesignateAdapter.parse('API_v2', body, RecordSet())
|
||||
|
||||
# Convert from APIv2 -> Central format
|
||||
values = self._view.load(context, request, body)
|
||||
recordset.validate()
|
||||
|
||||
# SOA recordsets cannot be created manually
|
||||
if values['type'] == 'SOA':
|
||||
if recordset.type == 'SOA':
|
||||
raise exceptions.BadRequest(
|
||||
"Creating a SOA recordset is not allowed")
|
||||
|
||||
# Create the recordset
|
||||
recordset = self.central_api.create_recordset(
|
||||
context, zone_id, RecordSet(**values))
|
||||
context, zone_id, recordset)
|
||||
|
||||
# Prepare the response headers
|
||||
if recordset['status'] == 'PENDING':
|
||||
response.status_int = 202
|
||||
else:
|
||||
response.status_int = 201
|
||||
response.headers['Location'] = self._view._get_resource_href(
|
||||
request, recordset, [zone_id])
|
||||
|
||||
recordset = DesignateAdapter.render(
|
||||
'API_v2', recordset, request=request)
|
||||
|
||||
response.headers['Location'] = recordset['links']['self']
|
||||
|
||||
# Prepare and return the response body
|
||||
return self._view.show(context, request, recordset)
|
||||
return recordset
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@utils.validate_uuid('zone_id', 'recordset_id')
|
||||
@ -149,41 +152,10 @@ class RecordSetsController(rest.RestController):
|
||||
'Updating a root zone NS record is not allowed')
|
||||
|
||||
# Convert to APIv2 Format
|
||||
recordset_data = self._view.show(context, request, recordset)
|
||||
recordset_data = utils.deep_dict_merge(recordset_data, body)
|
||||
new_recordset = self._view.load(context, request, body)
|
||||
|
||||
# Validate the new set of data
|
||||
self._resource_schema.validate(recordset_data)
|
||||
recordset = DesignateAdapter.parse('API_v2', body, recordset)
|
||||
|
||||
# Get original list of Records
|
||||
original_records = set()
|
||||
for record in recordset.records:
|
||||
original_records.add(record.data)
|
||||
# Get new list of Records
|
||||
new_records = set()
|
||||
if 'records' in new_recordset:
|
||||
for record in new_recordset['records']:
|
||||
new_records.add(record.data)
|
||||
# Get differences of Records
|
||||
records_to_add = new_records.difference(original_records)
|
||||
records_to_rm = original_records.difference(new_records)
|
||||
|
||||
# Update all items except records
|
||||
record_update = False
|
||||
if 'records' in new_recordset:
|
||||
record_update = True
|
||||
del new_recordset['records']
|
||||
recordset.update(new_recordset)
|
||||
|
||||
# Remove deleted records if we have provided a records array
|
||||
if record_update:
|
||||
recordset.records[:] = [record for record in recordset.records
|
||||
if record.data not in records_to_rm]
|
||||
|
||||
# Add new records
|
||||
for record in records_to_add:
|
||||
recordset.records.append(Record(data=record))
|
||||
recordset.validate()
|
||||
|
||||
# Persist the resource
|
||||
recordset = self.central_api.update_recordset(context, recordset)
|
||||
@ -193,7 +165,7 @@ class RecordSetsController(rest.RestController):
|
||||
else:
|
||||
response.status_int = 200
|
||||
|
||||
return self._view.show(context, request, recordset)
|
||||
return DesignateAdapter.render('API_v2', recordset, request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@utils.validate_uuid('zone_id', 'recordset_id')
|
||||
@ -214,4 +186,4 @@ class RecordSetsController(rest.RestController):
|
||||
context, zone_id, recordset_id)
|
||||
response.status_int = 202
|
||||
|
||||
return self._view.show(context, request, recordset)
|
||||
return DesignateAdapter.render('API_v2', recordset, request=request)
|
||||
|
@ -19,7 +19,6 @@ from stevedore import named
|
||||
|
||||
from designate.api.v2.controllers import limits
|
||||
from designate.api.v2.controllers import reverse
|
||||
from designate.api.v2.controllers import schemas
|
||||
from designate.api.v2.controllers import tlds
|
||||
from designate.api.v2.controllers import blacklists
|
||||
from designate.api.v2.controllers import errors
|
||||
@ -52,7 +51,6 @@ class RootController(object):
|
||||
setattr(controller, path.split('.')[-1], ext.obj)
|
||||
|
||||
limits = limits.LimitsController()
|
||||
schemas = schemas.SchemasController()
|
||||
reverse = reverse.ReverseController()
|
||||
tlds = tlds.TldsController()
|
||||
zones = zones.ZonesController()
|
||||
|
@ -1,40 +0,0 @@
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@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 pecan
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate import exceptions
|
||||
from designate import utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SchemasController(object):
|
||||
@pecan.expose(template='json:', content_type='application/schema+json')
|
||||
def _default(self, *remainder):
|
||||
if len(remainder) == 0:
|
||||
pecan.abort(404)
|
||||
|
||||
try:
|
||||
schema_name = os.path.join(*remainder)
|
||||
schema_json = utils.load_schema('v2', schema_name)
|
||||
except exceptions.ResourceNotFound:
|
||||
pecan.abort(404)
|
||||
|
||||
return schema_json
|
@ -15,20 +15,16 @@
|
||||
import pecan
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate import schema
|
||||
from designate import utils
|
||||
from designate.api.v2.controllers import rest
|
||||
from designate.api.v2.views import tlds as tlds_view
|
||||
from designate.objects import Tld
|
||||
from designate.objects.adapters import DesignateAdapter
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TldsController(rest.RestController):
|
||||
_view = tlds_view.TldsView()
|
||||
_resource_schema = schema.Schema('v2', 'tld')
|
||||
_collection_schema = schema.Schema('v2', 'tlds')
|
||||
SORT_KEYS = ['created_at', 'id', 'updated_at', 'name']
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@ -39,8 +35,10 @@ class TldsController(rest.RestController):
|
||||
request = pecan.request
|
||||
context = request.environ['context']
|
||||
|
||||
tld = self.central_api.get_tld(context, tld_id)
|
||||
return self._view.show(context, request, tld)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.get_tld(context, tld_id),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def get_all(self, **params):
|
||||
@ -56,10 +54,11 @@ class TldsController(rest.RestController):
|
||||
criterion = dict((k, params[k]) for k in accepted_filters
|
||||
if k in params)
|
||||
|
||||
tlds = self.central_api.find_tlds(
|
||||
context, criterion, marker, limit, sort_key, sort_dir)
|
||||
|
||||
return self._view.list(context, request, tlds)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.find_tlds(
|
||||
context, criterion, marker, limit, sort_key, sort_dir),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def post_all(self):
|
||||
@ -69,20 +68,19 @@ class TldsController(rest.RestController):
|
||||
context = request.environ['context']
|
||||
body = request.body_dict
|
||||
|
||||
# Validate the request conforms to the schema
|
||||
self._resource_schema.validate(body)
|
||||
tld = DesignateAdapter.parse('API_v2', body, Tld())
|
||||
|
||||
# Convert from APIv2 -> Central format
|
||||
values = self._view.load(context, request, body)
|
||||
tld.validate()
|
||||
|
||||
# Create the tld
|
||||
tld = self.central_api.create_tld(context, Tld(**values))
|
||||
tld = self.central_api.create_tld(context, tld)
|
||||
response.status_int = 201
|
||||
|
||||
response.headers['Location'] = self._view._get_resource_href(request,
|
||||
tld)
|
||||
tld = DesignateAdapter.render('API_v2', tld, request=request)
|
||||
|
||||
response.headers['Location'] = tld['links']['self']
|
||||
# Prepare and return the response body
|
||||
return self._view.show(context, request, tld)
|
||||
return tld
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@pecan.expose(template='json:', content_type='application/json-patch+json')
|
||||
@ -93,28 +91,21 @@ class TldsController(rest.RestController):
|
||||
context = request.environ['context']
|
||||
body = request.body_dict
|
||||
response = pecan.response
|
||||
if request.content_type == 'application/json-patch+json':
|
||||
raise NotImplemented('json-patch not implemented')
|
||||
|
||||
# Fetch the existing tld
|
||||
tld = self.central_api.get_tld(context, tld_id)
|
||||
|
||||
# Convert to APIv2 Format
|
||||
tld_data = self._view.show(context, request, tld)
|
||||
tld = DesignateAdapter.parse('API_v2', body, tld)
|
||||
|
||||
if request.content_type == 'application/json-patch+json':
|
||||
raise NotImplemented('json-patch not implemented')
|
||||
else:
|
||||
tld_data = utils.deep_dict_merge(tld_data, body)
|
||||
tld.validate()
|
||||
|
||||
# Validate the new set of data
|
||||
self._resource_schema.validate(tld_data)
|
||||
|
||||
# Update and persist the resource
|
||||
tld.update(self._view.load(context, request, body))
|
||||
tld = self.central_api.update_tld(context, tld)
|
||||
tld = self.central_api.update_tld(context, tld)
|
||||
|
||||
response.status_int = 200
|
||||
|
||||
return self._view.show(context, request, tld)
|
||||
return DesignateAdapter.render('API_v2', tld, request=request)
|
||||
|
||||
@pecan.expose(template=None, content_type='application/json')
|
||||
@utils.validate_uuid('tld_id')
|
||||
|
@ -17,20 +17,15 @@
|
||||
import pecan
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate import schema
|
||||
from designate import utils
|
||||
from designate.api.v2.controllers import rest
|
||||
from designate.api.v2.views import tsigkeys as tsigkeys_view
|
||||
from designate.objects import TsigKey
|
||||
|
||||
from designate.objects.adapters import DesignateAdapter
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TsigKeysController(rest.RestController):
|
||||
_view = tsigkeys_view.TsigKeysView()
|
||||
_resource_schema = schema.Schema('v2', 'tsigkey')
|
||||
_collection_schema = schema.Schema('v2', 'tsigkeys')
|
||||
SORT_KEYS = ['created_at', 'id', 'updated_at', 'name']
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@ -41,9 +36,10 @@ class TsigKeysController(rest.RestController):
|
||||
request = pecan.request
|
||||
context = request.environ['context']
|
||||
|
||||
tsigkey = self.central_api.get_tsigkey(context, tsigkey_id)
|
||||
|
||||
return self._view.show(context, request, tsigkey)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.get_tsigkey(context, tsigkey_id),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def get_all(self, **params):
|
||||
@ -59,10 +55,11 @@ class TsigKeysController(rest.RestController):
|
||||
criterion = dict((k, params[k]) for k in accepted_filters
|
||||
if k in params)
|
||||
|
||||
tsigkey = self.central_api.find_tsigkeys(
|
||||
context, criterion, marker, limit, sort_key, sort_dir)
|
||||
|
||||
return self._view.list(context, request, tsigkey)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.find_tsigkeys(
|
||||
context, criterion, marker, limit, sort_key, sort_dir),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def post_all(self):
|
||||
@ -70,26 +67,22 @@ class TsigKeysController(rest.RestController):
|
||||
request = pecan.request
|
||||
response = pecan.response
|
||||
context = request.environ['context']
|
||||
|
||||
body = request.body_dict
|
||||
|
||||
# Validate the request conforms to the schema
|
||||
self._resource_schema.validate(body)
|
||||
tsigkey = DesignateAdapter.parse('API_v2', body, TsigKey())
|
||||
|
||||
# Convert from APIv2 -> Central format
|
||||
values = self._view.load(context, request, body)
|
||||
tsigkey.validate()
|
||||
|
||||
# Create the tsigkey
|
||||
tsigkey = self.central_api.create_tsigkey(
|
||||
context, TsigKey(**values))
|
||||
context, tsigkey)
|
||||
|
||||
tsigkey = DesignateAdapter.render('API_v2', tsigkey, request=request)
|
||||
|
||||
response.headers['Location'] = tsigkey['links']['self']
|
||||
response.status_int = 201
|
||||
|
||||
response.headers['Location'] = self._view._get_resource_href(
|
||||
request, tsigkey)
|
||||
|
||||
# Prepare and return the response body
|
||||
return self._view.show(context, request, tsigkey)
|
||||
return tsigkey
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@pecan.expose(template='json:', content_type='application/json-patch+json')
|
||||
@ -101,27 +94,23 @@ class TsigKeysController(rest.RestController):
|
||||
body = request.body_dict
|
||||
response = pecan.response
|
||||
|
||||
if request.content_type == 'application/json-patch+json':
|
||||
raise NotImplemented('json-patch not implemented')
|
||||
|
||||
# Fetch the existing tsigkey entry
|
||||
tsigkey = self.central_api.get_tsigkey(context, tsigkey_id)
|
||||
|
||||
# Convert to APIv2 Format
|
||||
tsigkey_data = self._view.show(context, request, tsigkey)
|
||||
tsigkey = DesignateAdapter.parse('API_v2', body, tsigkey)
|
||||
|
||||
if request.content_type == 'application/json-patch+json':
|
||||
raise NotImplemented('json-patch not implemented')
|
||||
else:
|
||||
tsigkey_data = utils.deep_dict_merge(tsigkey_data, body)
|
||||
# Validate the new set of data
|
||||
tsigkey.validate()
|
||||
|
||||
# Validate the new set of data
|
||||
self._resource_schema.validate(tsigkey_data)
|
||||
|
||||
# Update and persist the resource
|
||||
tsigkey.update(self._view.load(context, request, body))
|
||||
tsigkey = self.central_api.update_tsigkey(context, tsigkey)
|
||||
# Update and persist the resource
|
||||
tsigkey = self.central_api.update_tsigkey(context, tsigkey)
|
||||
|
||||
response.status_int = 200
|
||||
|
||||
return self._view.show(context, request, tsigkey)
|
||||
return DesignateAdapter.render('API_v2', tsigkey, request=request)
|
||||
|
||||
@pecan.expose(template=None, content_type='application/json')
|
||||
@utils.validate_uuid('tsigkey_id')
|
||||
|
@ -20,22 +20,19 @@ from oslo.config import cfg
|
||||
|
||||
from designate import exceptions
|
||||
from designate import utils
|
||||
from designate import schema
|
||||
from designate import dnsutils
|
||||
from designate.api.v2.controllers import rest
|
||||
from designate.api.v2.controllers import recordsets
|
||||
from designate.api.v2.controllers.zones import tasks
|
||||
from designate.api.v2.views import zones as zones_view
|
||||
from designate import objects
|
||||
from designate.objects.adapters import DesignateAdapter
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class ZonesController(rest.RestController):
|
||||
_view = zones_view.ZonesView()
|
||||
_resource_schema = schema.Schema('v2', 'zone')
|
||||
_collection_schema = schema.Schema('v2', 'zones')
|
||||
|
||||
SORT_KEYS = ['created_at', 'id', 'updated_at', 'name', 'tenant_id',
|
||||
'serial', 'ttl', 'status']
|
||||
|
||||
@ -65,9 +62,10 @@ class ZonesController(rest.RestController):
|
||||
|
||||
def _get_json(self, request, context, zone_id):
|
||||
"""'Normal' zone get"""
|
||||
zone = self.central_api.get_domain(context, zone_id)
|
||||
|
||||
return self._view.show(context, request, zone)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.get_domain(context, zone_id),
|
||||
request=request)
|
||||
|
||||
def _get_zonefile(self, request, context, zone_id):
|
||||
"""Export zonefile"""
|
||||
@ -110,13 +108,15 @@ class ZonesController(rest.RestController):
|
||||
|
||||
# Extract any filter params.
|
||||
accepted_filters = ('name', 'email', 'status', )
|
||||
|
||||
criterion = self._apply_filter_params(
|
||||
params, accepted_filters, {})
|
||||
|
||||
zones = self.central_api.find_domains(
|
||||
context, criterion, marker, limit, sort_key, sort_dir)
|
||||
|
||||
return self._view.list(context, request, zones)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.find_domains(
|
||||
context, criterion, marker, limit, sort_key, sort_dir),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def post_all(self):
|
||||
@ -134,29 +134,27 @@ class ZonesController(rest.RestController):
|
||||
|
||||
def _post_json(self, request, response, context):
|
||||
"""'Normal' zone creation"""
|
||||
body = request.body_dict
|
||||
zone = request.body_dict
|
||||
|
||||
# We need to check the zone type before validating the schema since if
|
||||
# it's the type is SECONDARY we need to set the email to the mgmt email
|
||||
zone = body.get('zone')
|
||||
|
||||
if isinstance(zone, dict):
|
||||
if 'type' not in zone:
|
||||
zone['type'] = 'PRIMARY'
|
||||
|
||||
if zone['type'] == 'SECONDARY':
|
||||
mgmt_email = CONF['service:central'].managed_resource_email
|
||||
body['zone']['email'] = mgmt_email
|
||||
zone['email'] = mgmt_email
|
||||
|
||||
# Validate the request conforms to the schema
|
||||
self._resource_schema.validate(body)
|
||||
zone = DesignateAdapter.parse('API_v2', zone, objects.Domain())
|
||||
|
||||
# Convert from APIv2 -> Central format
|
||||
values = self._view.load(context, request, body)
|
||||
zone.validate()
|
||||
|
||||
# TODO(ekarlso): Fix this once setter or so works.
|
||||
masters = values.pop('masters', [])
|
||||
zone = objects.Domain.from_dict(values)
|
||||
zone.set_masters(masters)
|
||||
# # TODO(ekarlso): Fix this once setter or so works.
|
||||
# masters = values.pop('masters', [])
|
||||
# zone = objects.Domain.from_dict(values)
|
||||
# zone.set_masters(masters)
|
||||
|
||||
# Create the zone
|
||||
zone = self.central_api.create_domain(context, zone)
|
||||
@ -169,11 +167,12 @@ class ZonesController(rest.RestController):
|
||||
else:
|
||||
response.status_int = 201
|
||||
|
||||
response.headers['Location'] = self._view._get_resource_href(request,
|
||||
zone)
|
||||
|
||||
# Prepare and return the response body
|
||||
return self._view.show(context, request, zone)
|
||||
zone = DesignateAdapter.render('API_v2', zone, request=request)
|
||||
|
||||
response.headers['Location'] = zone['links']['self']
|
||||
|
||||
return zone
|
||||
|
||||
def _post_zonefile(self, request, response, context):
|
||||
"""Import Zone"""
|
||||
@ -206,9 +205,11 @@ class ZonesController(rest.RestController):
|
||||
else:
|
||||
response.status_int = 201
|
||||
|
||||
response.headers['Location'] = self._view._get_resource_href(request,
|
||||
zone)
|
||||
return self._view.show(context, request, zone)
|
||||
zone = DesignateAdapter.render('API_v2', zone, request=request)
|
||||
|
||||
response.headers['Location'] = zone['links']['self']
|
||||
|
||||
return zone
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@pecan.expose(template='json:', content_type='application/json-patch+json')
|
||||
@ -230,9 +231,6 @@ class ZonesController(rest.RestController):
|
||||
if zone.action == "DELETE":
|
||||
raise exceptions.BadRequest('Can not update a deleting zone')
|
||||
|
||||
# Convert to APIv2 Format
|
||||
zone_data = self._view.show(context, request, zone)
|
||||
|
||||
if request.content_type == 'application/json-patch+json':
|
||||
# Possible pattern:
|
||||
#
|
||||
@ -248,23 +246,16 @@ class ZonesController(rest.RestController):
|
||||
# 3) ...?
|
||||
raise NotImplemented('json-patch not implemented')
|
||||
else:
|
||||
zone_data = utils.deep_dict_merge(zone_data, body)
|
||||
|
||||
# Validate the new set of data
|
||||
self._resource_schema.validate(zone_data)
|
||||
|
||||
# Unpack the values
|
||||
values = self._view.load(context, request, body)
|
||||
|
||||
zone.set_masters(values.pop('masters', []))
|
||||
# Update the zone object with the new values
|
||||
zone = DesignateAdapter.parse('API_v2', body, zone)
|
||||
|
||||
zone.validate()
|
||||
# If masters are specified then we set zone.transferred_at to None
|
||||
# which will cause a new transfer
|
||||
if 'attributes' in zone.obj_what_changed():
|
||||
zone.transferred_at = None
|
||||
|
||||
# Update and persist the resource
|
||||
zone.update(values)
|
||||
|
||||
if zone.type == 'SECONDARY' and 'email' in zone.obj_what_changed():
|
||||
msg = "Changed email is not allowed."
|
||||
@ -279,7 +270,7 @@ class ZonesController(rest.RestController):
|
||||
else:
|
||||
response.status_int = 200
|
||||
|
||||
return self._view.show(context, request, zone)
|
||||
return DesignateAdapter.render('API_v2', zone, request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@utils.validate_uuid('zone_id')
|
||||
@ -292,4 +283,4 @@ class ZonesController(rest.RestController):
|
||||
zone = self.central_api.delete_domain(context, zone_id)
|
||||
response.status_int = 202
|
||||
|
||||
return self._view.show(context, request, zone)
|
||||
return DesignateAdapter.render('API_v2', zone, request=request)
|
||||
|
@ -16,21 +16,17 @@
|
||||
import pecan
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate import schema
|
||||
from designate import utils
|
||||
from designate.api.v2.controllers import rest
|
||||
from designate.api.v2.views.zones.tasks import transfer_accepts as \
|
||||
zone_transfer_accepts_view
|
||||
from designate.objects import ZoneTransferAccept
|
||||
from designate.objects.adapters import DesignateAdapter
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TransferAcceptsController(rest.RestController):
|
||||
_view = zone_transfer_accepts_view.ZoneTransferAcceptsView()
|
||||
_resource_schema = schema.Schema('v2', 'transfer_accept')
|
||||
_collection_schema = schema.Schema('v2', 'transfer_accepts')
|
||||
|
||||
SORT_KEYS = ['created_at', 'id', 'updated_at']
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@ -41,11 +37,11 @@ class TransferAcceptsController(rest.RestController):
|
||||
request = pecan.request
|
||||
context = request.environ['context']
|
||||
|
||||
transfer_accepts = \
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.get_zone_transfer_accept(
|
||||
context, transfer_accept_id)
|
||||
|
||||
return self._view.show(context, request, transfer_accepts)
|
||||
context, transfer_accept_id),
|
||||
request=request)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def post_all(self):
|
||||
@ -55,18 +51,19 @@ class TransferAcceptsController(rest.RestController):
|
||||
context = request.environ['context']
|
||||
body = request.body_dict
|
||||
|
||||
# Validate the request conforms to the schema
|
||||
self._resource_schema.validate(body)
|
||||
zone_transfer_accept = DesignateAdapter.parse(
|
||||
'API_v2', body, ZoneTransferAccept())
|
||||
|
||||
zone_transfer_accept.validate()
|
||||
|
||||
# Convert from APIv2 -> Central format
|
||||
values = self._view.load(context, request, body)
|
||||
# Create the zone_transfer_request
|
||||
zone_transfer_accept = self.central_api.create_zone_transfer_accept(
|
||||
context, ZoneTransferAccept(**values))
|
||||
context, zone_transfer_accept)
|
||||
response.status_int = 201
|
||||
|
||||
response.headers['Location'] = self._view._get_resource_href(
|
||||
request,
|
||||
zone_transfer_accept)
|
||||
zone_transfer_accept = DesignateAdapter.render(
|
||||
'API_v2', zone_transfer_accept, request=request)
|
||||
|
||||
response.headers['Location'] = zone_transfer_accept['links']['self']
|
||||
# Prepare and return the response body
|
||||
return self._view.show(context, request, zone_transfer_accept)
|
||||
return zone_transfer_accept
|
||||
|
@ -16,20 +16,15 @@
|
||||
import pecan
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate import schema
|
||||
from designate import utils
|
||||
from designate.api.v2.controllers import rest
|
||||
from designate.api.v2.views.zones.tasks import transfer_requests as \
|
||||
zone_transfer_requests_view
|
||||
from designate.objects import ZoneTransferRequest
|
||||
|
||||
from designate.objects.adapters import DesignateAdapter
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TransferRequestsController(rest.RestController):
|
||||
_view = zone_transfer_requests_view.ZoneTransferRequestsView()
|
||||
_resource_schema = schema.Schema('v2', 'transfer_request')
|
||||
_collection_schema = schema.Schema('v2', 'transfer_requests')
|
||||
|
||||
SORT_KEYS = ['created_at', 'id', 'updated_at']
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@ -40,11 +35,12 @@ class TransferRequestsController(rest.RestController):
|
||||
request = pecan.request
|
||||
context = request.environ['context']
|
||||
|
||||
transfer_request = \
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.get_zone_transfer_request(
|
||||
context, transfer_request_id)
|
||||
|
||||
return self._view.show(context, request, transfer_request)
|
||||
context, transfer_request_id),
|
||||
request=request,
|
||||
context=context)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def get_all(self, **params):
|
||||
@ -58,10 +54,12 @@ class TransferRequestsController(rest.RestController):
|
||||
# Extract any filter params.
|
||||
criterion = self._apply_filter_params(params, ('status',), {})
|
||||
|
||||
zone_transfer_requests = self.central_api.find_zone_transfer_requests(
|
||||
context, criterion, marker, limit, sort_key, sort_dir)
|
||||
|
||||
return self._view.list(context, request, zone_transfer_requests)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2',
|
||||
self.central_api.find_zone_transfer_requests(
|
||||
context, criterion, marker, limit, sort_key, sort_dir),
|
||||
request=request,
|
||||
context=context)
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@utils.validate_uuid('zone_id')
|
||||
@ -70,27 +68,33 @@ class TransferRequestsController(rest.RestController):
|
||||
request = pecan.request
|
||||
response = pecan.response
|
||||
context = request.environ['context']
|
||||
body = request.body_dict
|
||||
try:
|
||||
body = request.body_dict
|
||||
except Exception as e:
|
||||
if e.message != 'TODO: Unsupported Content Type':
|
||||
raise
|
||||
else:
|
||||
# Got a blank body
|
||||
body = dict()
|
||||
|
||||
if body['transfer_request'] is not None:
|
||||
body['transfer_request']['zone_id'] = zone_id
|
||||
body['zone_id'] = zone_id
|
||||
|
||||
# Validate the request conforms to the schema
|
||||
self._resource_schema.validate(body)
|
||||
zone_transfer_request = DesignateAdapter.parse(
|
||||
'API_v2', body, ZoneTransferRequest())
|
||||
|
||||
# Convert from APIv2 -> Central format
|
||||
values = self._view.load(context, request, body)
|
||||
zone_transfer_request.validate()
|
||||
|
||||
# Create the zone_transfer_request
|
||||
zone_transfer_request = self.central_api.create_zone_transfer_request(
|
||||
context, ZoneTransferRequest(**values))
|
||||
context, zone_transfer_request)
|
||||
response.status_int = 201
|
||||
|
||||
response.headers['Location'] = self._view._get_resource_href(
|
||||
request,
|
||||
zone_transfer_request)
|
||||
zone_transfer_request = DesignateAdapter.render(
|
||||
'API_v2', zone_transfer_request, request=request, context=context)
|
||||
|
||||
response.headers['Location'] = zone_transfer_request['links']['self']
|
||||
# Prepare and return the response body
|
||||
return self._view.show(context, request, zone_transfer_request)
|
||||
return zone_transfer_request
|
||||
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
@pecan.expose(template='json:', content_type='application/json-patch+json')
|
||||
@ -102,30 +106,25 @@ class TransferRequestsController(rest.RestController):
|
||||
body = request.body_dict
|
||||
response = pecan.response
|
||||
|
||||
# Fetch the existing zone_transfer_request
|
||||
zt_request = self.central_api.get_zone_transfer_request(
|
||||
context, zone_transfer_request_id)
|
||||
|
||||
# Convert to APIv2 Format
|
||||
zt_request_data = self._view.show(context,
|
||||
request, zt_request)
|
||||
|
||||
if request.content_type == 'application/json-patch+json':
|
||||
raise NotImplemented('json-patch not implemented')
|
||||
else:
|
||||
zt_request_data = utils.deep_dict_merge(
|
||||
zt_request_data, body)
|
||||
|
||||
# Validate the request conforms to the schema
|
||||
self._resource_schema.validate(zt_request_data)
|
||||
# Fetch the existing zone_transfer_request
|
||||
zone_transfer_request = self.central_api.get_zone_transfer_request(
|
||||
context, zone_transfer_request_id)
|
||||
|
||||
zt_request.update(self._view.load(context, request, body))
|
||||
zt_request = self.central_api.update_zone_transfer_request(
|
||||
context, zt_request)
|
||||
zone_transfer_request = DesignateAdapter.parse(
|
||||
'API_v2', body, zone_transfer_request)
|
||||
|
||||
zone_transfer_request.validate()
|
||||
|
||||
zone_transfer_request = self.central_api.update_zone_transfer_request(
|
||||
context, zone_transfer_request)
|
||||
|
||||
response.status_int = 200
|
||||
|
||||
return self._view.show(context, request, zt_request)
|
||||
return DesignateAdapter.render(
|
||||
'API_v2', zone_transfer_request, request=request, context=context)
|
||||
|
||||
@pecan.expose(template=None, content_type='application/json')
|
||||
@utils.validate_uuid('zone_transfer_request_id')
|
||||
|
@ -1,45 +0,0 @@
|
||||
# Copyright 2014 Rackspace
|
||||
#
|
||||
# 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_log import log as logging
|
||||
|
||||
from designate.api.v2.views import base as base_view
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BlacklistsView(base_view.BaseView):
|
||||
"""Model a Blacklist API response as a python dictionary"""
|
||||
|
||||
_resource_name = 'blacklist'
|
||||
_collection_name = 'blacklists'
|
||||
|
||||
def show_basic(self, context, request, blacklist):
|
||||
"""Detailed view of a blacklisted zone"""
|
||||
return {
|
||||
"id": blacklist['id'],
|
||||
"pattern": blacklist['pattern'],
|
||||
"description": blacklist['description'],
|
||||
"created_at": blacklist['created_at'],
|
||||
"updated_at": blacklist['updated_at'],
|
||||
"links": self._get_resource_links(request, blacklist)
|
||||
}
|
||||
|
||||
def load(self, context, request, body):
|
||||
"""Extract a "central" compatible dict from an API call"""
|
||||
valid_keys = ('pattern', 'description')
|
||||
return self._load(context, request, body, valid_keys)
|
@ -1,38 +0,0 @@
|
||||
# Copyright 2013 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.
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.api.v2.views import base as base_view
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FloatingIPView(base_view.BaseView):
|
||||
"""Model a FloatingIP PTR record as a python dict"""
|
||||
_resource_name = 'floatingip'
|
||||
_collection_name = 'floatingips'
|
||||
|
||||
def _get_base_href(self, parents=None):
|
||||
return '%s/v2/reverse/floatingips' % self.base_uri
|
||||
|
||||
def show_basic(self, context, request, item):
|
||||
item = item.to_dict()
|
||||
item['id'] = ":".join([item['region'], item['id']])
|
||||
del item['region']
|
||||
item['links'] = self._get_resource_links(
|
||||
request, item, [item['id']])
|
||||
return item
|
@ -1,40 +0,0 @@
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@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.
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.api.v2.views import base as base_view
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LimitsView(base_view.BaseView):
|
||||
"""Model a Limits API response as a python dictionary"""
|
||||
|
||||
_resource_name = 'limits'
|
||||
_collection_name = 'limits'
|
||||
|
||||
def show_basic(self, context, request, absolute_limits):
|
||||
"""Basic view of the limits"""
|
||||
|
||||
return {
|
||||
"absolute": {
|
||||
"max_zones": absolute_limits['domains'],
|
||||
"max_zone_recordsets": absolute_limits['domain_recordsets'],
|
||||
"max_zone_records": absolute_limits['domain_records'],
|
||||
"max_recordset_records": absolute_limits['recordset_records']
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@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.
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate import objects
|
||||
from designate.api.v2.views import base as base_view
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RecordSetsView(base_view.BaseView):
|
||||
"""Model a Zone API response as a python dictionary"""
|
||||
|
||||
_resource_name = 'recordset'
|
||||
_collection_name = 'recordsets'
|
||||
|
||||
def _get_base_href(self, parents=None):
|
||||
assert len(parents) == 1
|
||||
|
||||
href = "%s/v2/zones/%s/recordsets" % (self.base_uri, parents[0])
|
||||
|
||||
return href.rstrip('?')
|
||||
|
||||
def show_basic(self, context, request, recordset):
|
||||
"""Basic view of a recordset"""
|
||||
|
||||
return {
|
||||
"id": recordset['id'],
|
||||
"zone_id": recordset['domain_id'],
|
||||
"name": recordset['name'],
|
||||
"type": recordset['type'],
|
||||
"ttl": recordset['ttl'],
|
||||
"records": [r.data for r in recordset['records']],
|
||||
"action": recordset.action,
|
||||
"status": recordset.status,
|
||||
"description": recordset['description'],
|
||||
"version": recordset['version'],
|
||||
"created_at": recordset['created_at'],
|
||||
"updated_at": recordset['updated_at'],
|
||||
"links": self._get_resource_links(request, recordset,
|
||||
[recordset['domain_id']])
|
||||
}
|
||||
|
||||
def load(self, context, request, body):
|
||||
"""Extract a "central" compatible dict from an API call"""
|
||||
valid_keys = ('name', 'type', 'ttl', 'description', 'records')
|
||||
|
||||
result = self._load(context, request, body, valid_keys)
|
||||
|
||||
if 'records' in result:
|
||||
result['records'] = objects.RecordList(objects=[
|
||||
objects.Record(data=r) for r in result['records']
|
||||
])
|
||||
|
||||
return result
|
@ -1,43 +0,0 @@
|
||||
# Copyright (c) 2014 Rackspace Hosting
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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_log import log as logging
|
||||
|
||||
from designate.api.v2.views import base as base_view
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TldsView(base_view.BaseView):
|
||||
"""Model a TLD API response as a python dictionary"""
|
||||
|
||||
_resource_name = 'tld'
|
||||
_collection_name = 'tlds'
|
||||
|
||||
def show_basic(self, context, request, tld):
|
||||
"""Basic view of a tld"""
|
||||
return {
|
||||
"id": tld['id'],
|
||||
"name": tld['name'],
|
||||
"description": tld['description'],
|
||||
"created_at": tld['created_at'],
|
||||
"updated_at": tld['updated_at'],
|
||||
"links": self._get_resource_links(request, tld)
|
||||
}
|
||||
|
||||
def load(self, context, request, body):
|
||||
"""Extract a "central" compatible dict from an API call"""
|
||||
valid_keys = ('name', 'description')
|
||||
return self._load(context, request, body, valid_keys)
|
@ -1,50 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@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.
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.api.v2.views import base as base_view
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TsigKeysView(base_view.BaseView):
|
||||
"""Model a TsigKey API response as a python dictionary"""
|
||||
|
||||
_resource_name = 'tsigkey'
|
||||
_collection_name = 'tsigkeys'
|
||||
|
||||
def show_basic(self, context, request, tsigkey):
|
||||
"""Detailed view of a TsigKey"""
|
||||
return {
|
||||
"id": tsigkey['id'],
|
||||
|
||||
"name": tsigkey['name'],
|
||||
"algorithm": tsigkey['algorithm'],
|
||||
"secret": tsigkey['secret'],
|
||||
"scope": tsigkey['scope'],
|
||||
"resource_id": tsigkey['resource_id'],
|
||||
|
||||
"created_at": tsigkey['created_at'],
|
||||
"updated_at": tsigkey['updated_at'],
|
||||
"links": self._get_resource_links(request, tsigkey)
|
||||
}
|
||||
|
||||
def load(self, context, request, body):
|
||||
"""Extract a "central" compatible dict from an API call"""
|
||||
valid_keys = ('name', 'algorithm', 'secret', 'scope', 'resource_id')
|
||||
return self._load(context, request, body, valid_keys)
|
@ -1,57 +0,0 @@
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@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.
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.api.v2.views import base as base_view
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ZonesView(base_view.BaseView):
|
||||
"""Model a Zone API response as a python dictionary"""
|
||||
|
||||
_resource_name = 'zone'
|
||||
_collection_name = 'zones'
|
||||
|
||||
def show_basic(self, context, request, zone):
|
||||
"""Basic view of a zone"""
|
||||
values = {
|
||||
"id": zone['id'],
|
||||
"pool_id": zone['pool_id'],
|
||||
"project_id": zone['tenant_id'],
|
||||
"name": zone['name'],
|
||||
"type": zone['type'],
|
||||
"email": zone['email'],
|
||||
"description": zone['description'],
|
||||
"ttl": zone['ttl'],
|
||||
"serial": zone['serial'],
|
||||
"status": zone['status'],
|
||||
"action": zone['action'],
|
||||
"version": zone['version'],
|
||||
"created_at": zone['created_at'],
|
||||
"updated_at": zone['updated_at'],
|
||||
"transferred_at": zone['transferred_at'],
|
||||
"masters": zone.masters,
|
||||
"links": self._get_resource_links(request, zone)
|
||||
}
|
||||
|
||||
return values
|
||||
|
||||
def load(self, context, request, body):
|
||||
"""Extract a "central" compatible dict from an API call"""
|
||||
zone_keys = ('name', 'description', 'type', 'email', 'masters', 'ttl')
|
||||
return self._load(context, request, body, zone_keys)
|
@ -1,53 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Graham Hayes <graham.hayes@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.
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.api.v2.views import base as base_view
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ZoneTransferAcceptsView(base_view.BaseView):
|
||||
"""Model a ZoneTransferRequest API response as a python dictionary"""
|
||||
|
||||
_resource_name = 'transfer_accept'
|
||||
_collection_name = 'transfer_accepts'
|
||||
|
||||
def _get_base_href(self, parents=None):
|
||||
href = "%s/v2/zones/tasks/%s" % (self.base_uri, self._collection_name)
|
||||
return href.rstrip('?')
|
||||
|
||||
def _get_resource_links(self, request, item):
|
||||
return {
|
||||
"self": self._get_resource_href(request, item),
|
||||
"zone": "%s/v2/zones/%s" % (self.base_uri, item.domain_id)
|
||||
}
|
||||
|
||||
def show_basic(self, context, request, zt_accept):
|
||||
"""Basic view of a ZoneTransferRequest"""
|
||||
|
||||
return {
|
||||
"id": zt_accept.id,
|
||||
"status": zt_accept.status,
|
||||
"links": self._get_resource_links(request, zt_accept)
|
||||
}
|
||||
|
||||
def load(self, context, request, body):
|
||||
"""Extract a "central" compatible dict from an API call"""
|
||||
valid_keys = ('zone_transfer_request_id', 'key')
|
||||
|
||||
return self._load(context, request, body, valid_keys)
|
@ -1,85 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Graham Hayes <graham.hayes@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.
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.api.v2.views import base as base_view
|
||||
from designate import exceptions
|
||||
from designate import policy
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ZoneTransferRequestsView(base_view.BaseView):
|
||||
"""Model a ZoneTransferRequest API response as a python dictionary"""
|
||||
|
||||
_resource_name = 'transfer_request'
|
||||
_collection_name = 'transfer_requests'
|
||||
|
||||
def _get_base_href(self, parents=None):
|
||||
href = "%s/v2/zones/tasks/%s" % (self.base_uri, self._collection_name)
|
||||
return href.rstrip('?')
|
||||
|
||||
def show_basic(self, context, request, zt_request):
|
||||
"""Basic view of a ZoneTransferRequest"""
|
||||
|
||||
try:
|
||||
target = {
|
||||
'tenant_id': zt_request.tenant_id,
|
||||
}
|
||||
|
||||
policy.check('get_zone_transfer_request_detailed', context, target)
|
||||
|
||||
except exceptions.Forbidden:
|
||||
return {
|
||||
"id": zt_request.id,
|
||||
"description": zt_request.description,
|
||||
"zone_id": zt_request.domain_id,
|
||||
"zone_name": zt_request.domain_name,
|
||||
"status": zt_request.status,
|
||||
"links": self._get_resource_links(request, zt_request)
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"id": zt_request.id,
|
||||
"description": zt_request.description,
|
||||
"zone_id": zt_request.domain_id,
|
||||
"zone_name": zt_request.domain_name,
|
||||
"target_project_id": zt_request.target_tenant_id,
|
||||
"project_id": zt_request.tenant_id,
|
||||
"created_at": zt_request.created_at,
|
||||
"updated_at": zt_request.updated_at,
|
||||
"status": zt_request.status,
|
||||
"key": zt_request.key,
|
||||
"links": self._get_resource_links(request, zt_request)
|
||||
}
|
||||
|
||||
def load(self, context, request, body):
|
||||
"""Extract a "central" compatible dict from an API call"""
|
||||
valid_keys = ('description', 'domain_id', 'target_tenant_id')
|
||||
|
||||
zt_request = body["transfer_request"]
|
||||
old_keys = {
|
||||
'zone_id': 'domain_id',
|
||||
'project_id': 'tenant_id',
|
||||
'target_project_id': 'target_tenant_id',
|
||||
}
|
||||
for key in zt_request:
|
||||
if key in old_keys:
|
||||
zt_request[old_keys[key]] = ''
|
||||
zt_request[old_keys[key]] = zt_request.pop(key)
|
||||
|
||||
return self._load(context, request, body, valid_keys)
|
@ -184,7 +184,7 @@ class Domain(base.DictObjectMixin, base.SoftDeleteObjectMixin,
|
||||
if self.type == 'SECONDARY' and self.masters is None:
|
||||
errors = ValidationErrorList()
|
||||
e = ValidationError()
|
||||
e.absolute_path = ['']
|
||||
e.path = ['type']
|
||||
e.validator = 'required'
|
||||
e.validator_value = ['masters']
|
||||
e.message = "'masters' is a required property"
|
||||
|
@ -194,13 +194,13 @@ class TestCase(base.BaseTestCase):
|
||||
{'name': 'Pool-One',
|
||||
'description': 'Pool-One description',
|
||||
'attributes': [{'key': 'scope', 'value': 'public'}],
|
||||
'ns_records': [{'priority': 0, 'hostname': 'ns1.example.org.'},
|
||||
{'priority': 1, 'hostname': 'ns2.example.org.'}]},
|
||||
'ns_records': [{'priority': 1, 'hostname': 'ns1.example.org.'},
|
||||
{'priority': 2, 'hostname': 'ns2.example.org.'}]},
|
||||
|
||||
{'name': 'Pool-Two',
|
||||
'description': 'Pool-Two description',
|
||||
'attributes': [{'key': 'scope', 'value': 'public'}],
|
||||
'ns_records': [{'priority': 0, 'hostname': 'ns1.example.org.'}]},
|
||||
'ns_records': [{'priority': 1, 'hostname': 'ns1.example.org.'}]},
|
||||
]
|
||||
|
||||
pool_attribute_fixtures = [
|
||||
|
@ -46,12 +46,12 @@ class ApiV2TestCase(ApiTestCase):
|
||||
# Inject the NormalizeURIMiddleware middleware
|
||||
self.app = middleware.NormalizeURIMiddleware(self.app)
|
||||
|
||||
# Inject the FaultWrapper middleware
|
||||
self.app = middleware.FaultWrapperMiddleware(self.app)
|
||||
|
||||
# Inject the ValidationError middleware
|
||||
self.app = middleware.APIv2ValidationErrorMiddleware(self.app)
|
||||
|
||||
# Inject the FaultWrapper middleware
|
||||
self.app = middleware.FaultWrapperMiddleware(self.app)
|
||||
|
||||
# Inject the TestContext middleware
|
||||
self.app = middleware.TestContextMiddleware(
|
||||
self.app, self.admin_context.tenant,
|
||||
|
@ -58,16 +58,15 @@ class ApiV2BlacklistsTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Verify the body structure
|
||||
self.assertIn('blacklist', response.json)
|
||||
self.assertIn('links', response.json['blacklist'])
|
||||
self.assertIn('self', response.json['blacklist']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Verify the returned values
|
||||
self.assertIn('id', response.json['blacklist'])
|
||||
self.assertIn('created_at', response.json['blacklist'])
|
||||
self.assertIsNone(response.json['blacklist']['updated_at'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
self.assertEqual(self.get_blacklist_fixture(0)['pattern'],
|
||||
response.json['blacklist']['pattern'])
|
||||
response.json['pattern'])
|
||||
|
||||
def test_get_bkaclist_invalid_id(self):
|
||||
self._assert_invalid_uuid(self.client.get, '/blacklists/%s')
|
||||
@ -75,24 +74,22 @@ class ApiV2BlacklistsTest(ApiV2TestCase):
|
||||
def test_create_blacklist(self):
|
||||
self.policy({'create_blacklist': '@'})
|
||||
fixture = self.get_blacklist_fixture(0)
|
||||
response = self.client.post_json('/blacklists/',
|
||||
{'blacklist': fixture})
|
||||
response = self.client.post_json('/blacklists/', fixture)
|
||||
|
||||
# Verify the headers
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Verify the body structure
|
||||
self.assertIn('blacklist', response.json)
|
||||
self.assertIn('links', response.json['blacklist'])
|
||||
self.assertIn('self', response.json['blacklist']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Verify the returned values
|
||||
self.assertIn('id', response.json['blacklist'])
|
||||
self.assertIn('created_at', response.json['blacklist'])
|
||||
self.assertIsNone(response.json['blacklist']['updated_at'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
self.assertEqual(fixture['pattern'],
|
||||
response.json['blacklist']['pattern'])
|
||||
response.json['pattern'])
|
||||
|
||||
def test_delete_blacklist(self):
|
||||
blacklist = self.create_blacklist(fixture=0)
|
||||
@ -108,8 +105,7 @@ class ApiV2BlacklistsTest(ApiV2TestCase):
|
||||
self.policy({'update_blacklist': '@'})
|
||||
|
||||
# Prepare the update body
|
||||
body = {'blacklist': {'description': 'prefix-%s' %
|
||||
blacklist['description']}}
|
||||
body = {'description': 'prefix-%s' % blacklist['description']}
|
||||
|
||||
response = self.client.patch_json('/blacklists/%s' %
|
||||
blacklist['id'], body,
|
||||
@ -120,15 +116,14 @@ class ApiV2BlacklistsTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Verify the body structure
|
||||
self.assertIn('blacklist', response.json)
|
||||
self.assertIn('links', response.json['blacklist'])
|
||||
self.assertIn('self', response.json['blacklist']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Verify the returned values
|
||||
self.assertIn('id', response.json['blacklist'])
|
||||
self.assertIsNotNone(response.json['blacklist']['updated_at'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIsNotNone(response.json['updated_at'])
|
||||
self.assertEqual('prefix-%s' % blacklist['description'],
|
||||
response.json['blacklist']['description'])
|
||||
response.json['description'])
|
||||
|
||||
def test_update_bkaclist_invalid_id(self):
|
||||
self._assert_invalid_uuid(self.client.patch_json, '/blacklists/%s')
|
||||
|
@ -33,10 +33,9 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
|
||||
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('floatingip', response.json)
|
||||
|
||||
# TODO(ekarlso): Remove the floatingip key - bug in v2 api
|
||||
fip_record = response.json['floatingip']
|
||||
fip_record = response.json
|
||||
self.assertEqual(":".join([fip['region'],
|
||||
fip['id']]), fip_record['id'])
|
||||
self.assertEqual(fip['address'], fip_record['address'])
|
||||
@ -60,10 +59,9 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
|
||||
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('floatingip', response.json)
|
||||
|
||||
# TODO(ekarlso): Remove the floatingip key - bug in v2 api
|
||||
fip_record = response.json['floatingip']
|
||||
fip_record = response.json
|
||||
self.assertEqual(":".join([fip['region'], fip['id']]),
|
||||
fip_record['id'])
|
||||
self.assertEqual(fip['address'], fip_record['address'])
|
||||
@ -140,14 +138,13 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
|
||||
|
||||
response = self.client.patch_json(
|
||||
'/reverse/floatingips/%s' % ":".join([fip['region'], fip['id']]),
|
||||
{"floatingip": fixture.to_dict()},
|
||||
fixture.to_dict(),
|
||||
headers={'X-Test-Tenant-Id': 'tenant'})
|
||||
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('floatingip', response.json)
|
||||
|
||||
fip_record = response.json['floatingip']
|
||||
fip_record = response.json
|
||||
self.assertEqual(":".join([fip['region'], fip['id']]),
|
||||
fip_record['id'])
|
||||
self.assertEqual(fip['address'], fip_record['address'])
|
||||
@ -163,7 +160,7 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
|
||||
url = '/reverse/floatingips/%s' % ":".join([fip['region'], fip['id']])
|
||||
|
||||
self._assert_exception('not_found', 404, self.client.patch_json, url,
|
||||
{'floatingip': fixture.to_dict()})
|
||||
fixture.to_dict())
|
||||
|
||||
def test_set_floatingip_invalid_ptrdname(self):
|
||||
fip = self.network_api.fake.allocate_floatingip('tenant')
|
||||
@ -171,7 +168,7 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
|
||||
url = '/reverse/floatingips/%s' % ":".join([fip['region'], fip['id']])
|
||||
|
||||
self._assert_exception('invalid_object', 400, self.client.patch_json,
|
||||
url, {'floatingip': {'ptrdname': 'test|'}})
|
||||
url, {'ptrdname': 'test|'})
|
||||
|
||||
def test_set_floatingip_invalid_key(self):
|
||||
url = '/reverse/floatingips/%s' % 'foo:random'
|
||||
@ -206,7 +203,7 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
|
||||
# Unset PTR ('ptrdname' is None aka null in JSON)
|
||||
response = self.client.patch_json(
|
||||
'/reverse/floatingips/%s' % ":".join([fip['region'], fip['id']]),
|
||||
{'floatingip': {'ptrdname': None}},
|
||||
{'ptrdname': None},
|
||||
headers={'X-Test-Tenant-Id': context.tenant})
|
||||
self.assertEqual(None, response.json)
|
||||
self.assertEqual(200, response.status_int)
|
||||
@ -235,4 +232,4 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase):
|
||||
url = '/reverse/floatingips/%s' % ":".join([fip['region'], fip['id']])
|
||||
|
||||
self._assert_exception('not_found', 404, self.client.patch_json, url,
|
||||
{"floatingip": {'ptrdname': None}})
|
||||
{'ptrdname': None})
|
||||
|
@ -25,16 +25,14 @@ class ApiV2LimitsTest(ApiV2TestCase):
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
self.assertIn('limits', response.json)
|
||||
self.assertIn('absolute', response.json['limits'])
|
||||
self.assertIn('max_zones', response.json['limits']['absolute'])
|
||||
self.assertIn('max_zone_records', response.json['limits']['absolute'])
|
||||
self.assertIn('max_zones', response.json)
|
||||
self.assertIn('max_zone_records', response.json)
|
||||
self.assertIn('max_zone_recordsets',
|
||||
response.json['limits']['absolute'])
|
||||
response.json)
|
||||
self.assertIn('max_recordset_records',
|
||||
response.json['limits']['absolute'])
|
||||
response.json)
|
||||
|
||||
absolutelimits = response.json['limits']['absolute']
|
||||
absolutelimits = response.json
|
||||
|
||||
self.assertEqual(cfg.CONF.quota_domains, absolutelimits['max_zones'])
|
||||
self.assertEqual(cfg.CONF.quota_domain_records,
|
||||
|
@ -42,28 +42,27 @@ class ApiV2PoolsTest(ApiV2TestCase):
|
||||
fixture['attributes'] = _attributes_to_api(fixture['attributes'])
|
||||
|
||||
response = self.client.post_json(
|
||||
'/pools', {'pool': fixture})
|
||||
'/pools', fixture)
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('pool', response.json)
|
||||
self.assertIn('links', response.json['pool'])
|
||||
self.assertIn('self', response.json['pool']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['pool'])
|
||||
self.assertIn('created_at', response.json['pool'])
|
||||
self.assertIsNone(response.json['pool']['updated_at'])
|
||||
self.assertEqual(response.json['pool']['name'], fixture['name'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
self.assertEqual(response.json['name'], fixture['name'])
|
||||
self.assertEqual(
|
||||
response.json['pool']['description'], fixture['description'])
|
||||
response.json['description'], fixture['description'])
|
||||
self.assertEqual(
|
||||
response.json['pool']['attributes'], fixture['attributes'])
|
||||
response.json['attributes'], fixture['attributes'])
|
||||
self.assertEqual(
|
||||
response.json['pool']['ns_records'], fixture['ns_records'])
|
||||
response.json['ns_records'], fixture['ns_records'])
|
||||
|
||||
def test_create_pool_validation(self):
|
||||
# NOTE: The schemas should be tested separatly to the API. So we
|
||||
@ -83,14 +82,10 @@ class ApiV2PoolsTest(ApiV2TestCase):
|
||||
|
||||
# Reset the correct attributes
|
||||
fixture['attributes'] = self.get_pool_attribute_fixture(fixture=0)
|
||||
body = {'pool': fixture, 'junk': 'Junk Field'}
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception(
|
||||
'invalid_object', 400, self.client.post_json, '/pools', body)
|
||||
|
||||
# Add a junk field to the body
|
||||
fixture['junk'] = 'Junk Field'
|
||||
body = {'pool': fixture}
|
||||
body = fixture
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception(
|
||||
'invalid_object', 400, self.client.post_json, '/pools', body)
|
||||
@ -100,7 +95,7 @@ class ApiV2PoolsTest(ApiV2TestCase):
|
||||
fixture = self.get_pool_fixture(fixture=0)
|
||||
fixture['attributes'] = _attributes_to_api(fixture['attributes'])
|
||||
|
||||
body = {'pool': fixture}
|
||||
body = fixture
|
||||
response = self.client.post_json('/pools', body)
|
||||
|
||||
# Check that the create went through
|
||||
@ -149,37 +144,36 @@ class ApiV2PoolsTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('pool', response.json)
|
||||
self.assertIn('links', response.json['pool'])
|
||||
self.assertIn('self', response.json['pool']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['pool'])
|
||||
self.assertIn('created_at', response.json['pool'])
|
||||
self.assertIsNone(response.json['pool']['updated_at'])
|
||||
self.assertEqual(pool['name'], response.json['pool']['name'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
self.assertEqual(pool['name'], response.json['name'])
|
||||
self.assertEqual(pool['description'],
|
||||
response.json['pool']['description'])
|
||||
response.json['description'])
|
||||
|
||||
self.assertEqual(len(pool['attributes']),
|
||||
len(response.json['pool']['attributes']))
|
||||
len(response.json['attributes']))
|
||||
for attribute in pool['attributes']:
|
||||
self.assertEqual(
|
||||
attribute['value'],
|
||||
response.json['pool']['attributes'][attribute['key']])
|
||||
response.json['attributes'][attribute['key']])
|
||||
|
||||
self.assertEqual(len(pool['ns_records']),
|
||||
len(response.json['pool']['ns_records']))
|
||||
len(response.json['ns_records']))
|
||||
self.assertEqual(
|
||||
[n.hostname for n in pool['ns_records']],
|
||||
[n['hostname'] for n in response.json['pool']['ns_records']])
|
||||
[n['hostname'] for n in response.json['ns_records']])
|
||||
|
||||
def test_update_pool(self):
|
||||
# Create a pool
|
||||
pool = self.create_pool()
|
||||
|
||||
# Prepare an update body
|
||||
body = {'pool': {'description': 'Tester'}}
|
||||
body = {'description': 'Tester'}
|
||||
|
||||
url = '/pools/%s' % pool['id']
|
||||
response = self.client.patch_json(url, body, status=200)
|
||||
@ -189,39 +183,38 @@ class ApiV2PoolsTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('pool', response.json)
|
||||
self.assertIn('links', response.json['pool'])
|
||||
self.assertIn('self', response.json['pool']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['pool'])
|
||||
self.assertIsNotNone(response.json['pool']['updated_at'])
|
||||
self.assertEqual('Tester', response.json['pool']['description'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIsNotNone(response.json['updated_at'])
|
||||
self.assertEqual('Tester', response.json['description'])
|
||||
|
||||
# Check the rest of the values are unchanged
|
||||
self.assertEqual(pool['name'], response.json['pool']['name'])
|
||||
self.assertEqual(pool['name'], response.json['name'])
|
||||
self.assertEqual(len(pool['attributes']),
|
||||
len(response.json['pool']['attributes']))
|
||||
len(response.json['attributes']))
|
||||
for attribute in pool['attributes']:
|
||||
self.assertEqual(
|
||||
attribute['value'],
|
||||
response.json['pool']['attributes'][attribute['key']])
|
||||
response.json['attributes'][attribute['key']])
|
||||
|
||||
self.assertEqual(len(pool['ns_records']),
|
||||
len(response.json['pool']['ns_records']))
|
||||
len(response.json['ns_records']))
|
||||
self.assertEqual(
|
||||
[n.hostname for n in pool['ns_records']],
|
||||
[n['hostname'] for n in response.json['pool']['ns_records']])
|
||||
[n['hostname'] for n in response.json['ns_records']])
|
||||
|
||||
def test_update_pool_ns_records(self):
|
||||
# Create a pool
|
||||
pool = self.create_pool()
|
||||
|
||||
# Prepare an update body
|
||||
body = {'pool': {'ns_records': [
|
||||
body = {'ns_records': [
|
||||
{'priority': 1, 'hostname': 'new-ns1.example.org.'},
|
||||
{'priority': 2, 'hostname': 'new-ns2.example.org.'},
|
||||
]}}
|
||||
]}
|
||||
|
||||
url = '/pools/%s' % pool['id']
|
||||
response = self.client.patch_json(url, body, status=200)
|
||||
@ -231,22 +224,21 @@ class ApiV2PoolsTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('pool', response.json)
|
||||
self.assertIn('id', response.json['pool'])
|
||||
self.assertIn('links', response.json['pool'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('links', response.json)
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertEqual(2, len(response.json['pool']['ns_records']))
|
||||
self.assertEqual(2, len(response.json['ns_records']))
|
||||
self.assertEqual(['new-ns1.example.org.', 'new-ns2.example.org.'],
|
||||
[n['hostname'] for n in
|
||||
response.json['pool']['ns_records']])
|
||||
response.json['ns_records']])
|
||||
|
||||
def test_update_pool_attributes(self):
|
||||
# Create a pool
|
||||
pool = self.create_pool()
|
||||
|
||||
# Prepare an update body
|
||||
body = {'pool': {'attributes': {'scope': 'private'}}}
|
||||
body = {"attributes": {"scope": "private"}}
|
||||
|
||||
url = '/pools/%s' % pool['id']
|
||||
response = self.client.patch_json(url, body, status=200)
|
||||
@ -256,9 +248,9 @@ class ApiV2PoolsTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertEqual(1, len(response.json['pool']['attributes']))
|
||||
self.assertEqual(1, len(response.json['attributes']))
|
||||
self.assertEqual('private',
|
||||
response.json['pool']['attributes']['scope'])
|
||||
response.json['attributes']['scope'])
|
||||
|
||||
def test_delete_pool(self):
|
||||
pool = self.create_pool()
|
||||
|
@ -35,25 +35,24 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
# Prepare a RecordSet fixture
|
||||
fixture = self.get_recordset_fixture(self.domain['name'], fixture=0)
|
||||
response = self.client.post_json(
|
||||
'/zones/%s/recordsets' % self.domain['id'], {'recordset': fixture})
|
||||
'/zones/%s/recordsets' % self.domain['id'], fixture)
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('recordset', response.json)
|
||||
self.assertIn('links', response.json['recordset'])
|
||||
self.assertIn('self', response.json['recordset']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['recordset'])
|
||||
self.assertIn('created_at', response.json['recordset'])
|
||||
self.assertIsNone(response.json['recordset']['updated_at'])
|
||||
self.assertIn('records', response.json['recordset'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
self.assertIn('records', response.json)
|
||||
# The action and status are NONE and ACTIVE as there are no records
|
||||
self.assertEqual('NONE', response.json['recordset']['action'])
|
||||
self.assertEqual('ACTIVE', response.json['recordset']['status'])
|
||||
self.assertEqual('NONE', response.json['action'])
|
||||
self.assertEqual('ACTIVE', response.json['status'])
|
||||
|
||||
def test_create_recordset_with_records(self):
|
||||
# Prepare a RecordSet fixture
|
||||
@ -65,20 +64,17 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
)
|
||||
|
||||
response = self.client.post_json(
|
||||
'/zones/%s/recordsets' % self.domain['id'], {'recordset': fixture})
|
||||
'/zones/%s/recordsets' % self.domain['id'], fixture)
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('recordset', response.json)
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('records', response.json['recordset'])
|
||||
self.assertEqual(2, len(response.json['recordset']['records']))
|
||||
self.assertEqual('CREATE', response.json['recordset']['action'])
|
||||
self.assertEqual('PENDING', response.json['recordset']['status'])
|
||||
self.assertIn('records', response.json)
|
||||
self.assertEqual(2, len(response.json['records']))
|
||||
self.assertEqual('CREATE', response.json['action'])
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
|
||||
# Check the zone's status is as expected
|
||||
response = self.client.get('/zones/%s' % self.domain['id'],
|
||||
@ -86,9 +82,9 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertEqual('UPDATE', response.json['zone']['action'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
|
||||
self.assertEqual('UPDATE', response.json['action'])
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
|
||||
def test_create_recordset_invalid_id(self):
|
||||
self._assert_invalid_uuid(self.client.post, '/zones/%s/recordsets')
|
||||
@ -99,18 +95,11 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
# Fetch a fixture
|
||||
fixture = self.get_recordset_fixture(self.domain['name'], fixture=0)
|
||||
|
||||
# Add a junk field to the wrapper
|
||||
body = {'recordset': fixture, 'junk': 'Junk Field'}
|
||||
|
||||
url = '/zones/%s/recordsets' % self.domain['id']
|
||||
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception(
|
||||
'invalid_object', 400, self.client.post_json, url, body)
|
||||
|
||||
# Add a junk field to the body
|
||||
fixture['junk'] = 'Junk Field'
|
||||
body = {'recordset': fixture}
|
||||
body = fixture
|
||||
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception(
|
||||
@ -121,7 +110,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
def test_create_recordset_timeout(self, _):
|
||||
fixture = self.get_recordset_fixture(self.domain['name'], fixture=0)
|
||||
|
||||
body = {'recordset': fixture}
|
||||
body = fixture
|
||||
|
||||
url = '/zones/%s/recordsets' % self.domain['id']
|
||||
|
||||
@ -133,7 +122,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
def test_create_recordset_duplicate(self, _):
|
||||
fixture = self.get_recordset_fixture(self.domain['name'], fixture=0)
|
||||
|
||||
body = {'recordset': fixture}
|
||||
body = fixture
|
||||
|
||||
url = '/zones/%s/recordsets' % self.domain['id']
|
||||
|
||||
@ -143,7 +132,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
def test_create_recordset_invalid_domain(self):
|
||||
fixture = self.get_recordset_fixture(self.domain['name'], fixture=0)
|
||||
|
||||
body = {'recordset': fixture}
|
||||
body = fixture
|
||||
|
||||
url = '/zones/ba751950-6193-11e3-949a-0800200c9a66/recordsets'
|
||||
|
||||
@ -219,7 +208,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
for fixture in fixtures:
|
||||
response = self.client.post_json(
|
||||
'/zones/%s/recordsets' % self.domain['id'],
|
||||
{'recordset': fixture})
|
||||
fixture)
|
||||
|
||||
get_urls = [
|
||||
'/zones/%s/recordsets?data=192.0.2.1' % self.domain['id'],
|
||||
@ -284,20 +273,18 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('recordset', response.json)
|
||||
self.assertIn('links', response.json['recordset'])
|
||||
self.assertIn('self', response.json['recordset']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['recordset'])
|
||||
self.assertIn('created_at', response.json['recordset'])
|
||||
self.assertIsNone(response.json['recordset']['updated_at'])
|
||||
self.assertEqual(recordset['name'], response.json['recordset']['name'])
|
||||
self.assertEqual(recordset['type'], response.json['recordset']['type'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
self.assertEqual(recordset['name'], response.json['name'])
|
||||
self.assertEqual(recordset['type'], response.json['type'])
|
||||
# The action and status are NONE and ACTIVE as there are no records
|
||||
self.assertEqual('NONE', response.json['recordset']['action'])
|
||||
self.assertEqual('ACTIVE', response.json['recordset']['status'])
|
||||
self.assertEqual('NONE', response.json['action'])
|
||||
self.assertEqual('ACTIVE', response.json['status'])
|
||||
|
||||
def test_get_recordset_invalid_id(self):
|
||||
self._assert_invalid_uuid(self.client.get, '/zones/%s/recordsets/%s')
|
||||
@ -326,7 +313,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
recordset = self.create_recordset(self.domain)
|
||||
|
||||
# Prepare an update body
|
||||
body = {'recordset': {'description': 'Tester'}}
|
||||
body = {'description': 'Tester'}
|
||||
|
||||
url = '/zones/%s/recordsets/%s' % (recordset['domain_id'],
|
||||
recordset['id'])
|
||||
@ -337,17 +324,16 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('recordset', response.json)
|
||||
self.assertIn('links', response.json['recordset'])
|
||||
self.assertIn('self', response.json['recordset']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['recordset'])
|
||||
self.assertIsNotNone(response.json['recordset']['updated_at'])
|
||||
self.assertEqual('Tester', response.json['recordset']['description'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIsNotNone(response.json['updated_at'])
|
||||
self.assertEqual('Tester', response.json['description'])
|
||||
# The action and status are NONE and ACTIVE as there are no records
|
||||
self.assertEqual('NONE', response.json['recordset']['action'])
|
||||
self.assertEqual('ACTIVE', response.json['recordset']['status'])
|
||||
self.assertEqual('NONE', response.json['action'])
|
||||
self.assertEqual('ACTIVE', response.json['status'])
|
||||
|
||||
# Check the zone's status is as expected
|
||||
response = self.client.get('/zones/%s' % recordset['domain_id'],
|
||||
@ -355,9 +341,9 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertEqual('UPDATE', response.json['zone']['action'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
|
||||
self.assertEqual('UPDATE', response.json['action'])
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
|
||||
def test_update_recordset_with_record_create(self):
|
||||
# Create a recordset
|
||||
@ -368,8 +354,9 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
self.assertEqual('ACTIVE', recordset['status'])
|
||||
|
||||
# Prepare an update body
|
||||
body = {'recordset': {'description': 'Tester',
|
||||
'records': ['192.0.2.1', '192.0.2.2']}}
|
||||
body = {'description': 'Tester',
|
||||
'type': 'A',
|
||||
'records': ['192.0.2.1', '192.0.2.2']}
|
||||
|
||||
url = '/zones/%s/recordsets/%s' % (recordset['domain_id'],
|
||||
recordset['id'])
|
||||
@ -379,16 +366,13 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('recordset', response.json)
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('records', response.json['recordset'])
|
||||
self.assertEqual(2, len(response.json['recordset']['records']))
|
||||
self.assertIn('records', response.json)
|
||||
self.assertEqual(2, len(response.json['records']))
|
||||
self.assertEqual(set(['192.0.2.1', '192.0.2.2']),
|
||||
set(response.json['recordset']['records']))
|
||||
self.assertEqual('UPDATE', response.json['recordset']['action'])
|
||||
self.assertEqual('PENDING', response.json['recordset']['status'])
|
||||
set(response.json['records']))
|
||||
self.assertEqual('UPDATE', response.json['action'])
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
|
||||
# Check the zone's status is as expected
|
||||
response = self.client.get('/zones/%s' % recordset['domain_id'],
|
||||
@ -396,9 +380,9 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertEqual('UPDATE', response.json['zone']['action'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
|
||||
self.assertEqual('UPDATE', response.json['action'])
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
|
||||
def test_update_recordset_with_record_replace(self):
|
||||
# Create a recordset with one record
|
||||
@ -406,8 +390,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
self.create_record(self.domain, recordset)
|
||||
|
||||
# Prepare an update body
|
||||
body = {'recordset': {'description': 'Tester',
|
||||
'records': ['192.0.2.201', '192.0.2.202']}}
|
||||
body = {'description': 'Tester',
|
||||
'records': ['192.0.2.201', '192.0.2.202']}
|
||||
|
||||
url = '/zones/%s/recordsets/%s' % (recordset['domain_id'],
|
||||
recordset['id'])
|
||||
@ -417,14 +401,11 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('recordset', response.json)
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('records', response.json['recordset'])
|
||||
self.assertEqual(2, len(response.json['recordset']['records']))
|
||||
self.assertIn('records', response.json)
|
||||
self.assertEqual(2, len(response.json['records']))
|
||||
self.assertEqual(set(['192.0.2.201', '192.0.2.202']),
|
||||
set(response.json['recordset']['records']))
|
||||
set(response.json['records']))
|
||||
|
||||
# Check the zone's status is as expected
|
||||
response = self.client.get('/zones/%s' % recordset['domain_id'],
|
||||
@ -432,9 +413,9 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertEqual('UPDATE', response.json['zone']['action'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
|
||||
self.assertEqual('UPDATE', response.json['action'])
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
|
||||
def test_update_recordset_with_record_clear(self):
|
||||
# Create a recordset with one record
|
||||
@ -442,7 +423,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
self.create_record(self.domain, recordset)
|
||||
|
||||
# Prepare an update body
|
||||
body = {'recordset': {'description': 'Tester', 'records': []}}
|
||||
body = {'description': 'Tester', 'records': []}
|
||||
|
||||
url = '/zones/%s/recordsets/%s' % (recordset['domain_id'],
|
||||
recordset['id'])
|
||||
@ -452,12 +433,9 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('recordset', response.json)
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('records', response.json['recordset'])
|
||||
self.assertEqual(0, len(response.json['recordset']['records']))
|
||||
self.assertIn('records', response.json)
|
||||
self.assertEqual(0, len(response.json['records']))
|
||||
|
||||
# Check the zone's status is as expected
|
||||
response = self.client.get('/zones/%s' % recordset['domain_id'],
|
||||
@ -465,9 +443,9 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertEqual('UPDATE', response.json['zone']['action'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
|
||||
self.assertEqual('UPDATE', response.json['action'])
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
|
||||
def test_update_recordset_invalid_id(self):
|
||||
self._assert_invalid_uuid(
|
||||
@ -480,9 +458,9 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
recordset = self.create_recordset(self.domain)
|
||||
|
||||
# Prepare an update body with junk in the wrapper
|
||||
body = {'recordset': {'description': 'Tester',
|
||||
'records': ['192.3.3.17'],
|
||||
'junk': 'Junk Field'}}
|
||||
body = {'description': 'Tester',
|
||||
'records': ['192.3.3.17'],
|
||||
'junk': 'Junk Field'}
|
||||
|
||||
# Ensure it fails with a 400
|
||||
url = '/zones/%s/recordsets/%s' % (recordset['domain_id'],
|
||||
@ -492,7 +470,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
url, body)
|
||||
|
||||
# Prepare an update body with junk in the body
|
||||
body = {'recordset': {'description': 'Tester', 'junk': 'Junk Field'}}
|
||||
body = {'description': 'Tester', 'junk': 'Junk Field'}
|
||||
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception('invalid_object', 400, self.client.put_json,
|
||||
@ -502,7 +480,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
side_effect=exceptions.DuplicateRecordSet())
|
||||
def test_update_recordset_duplicate(self, _):
|
||||
# Prepare an update body
|
||||
body = {'recordset': {'description': 'Tester'}}
|
||||
body = {'description': 'Tester'}
|
||||
|
||||
# Ensure it fails with a 409
|
||||
url = ('/zones/%s/recordsets/ba751950-6193-11e3-949a-0800200c9a66'
|
||||
@ -515,7 +493,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
side_effect=messaging.MessagingTimeout())
|
||||
def test_update_recordset_timeout(self, _):
|
||||
# Prepare an update body
|
||||
body = {'recordset': {'description': 'Tester'}}
|
||||
body = {'description': 'Tester'}
|
||||
|
||||
# Ensure it fails with a 504
|
||||
url = ('/zones/%s/recordsets/ba751950-6193-11e3-949a-0800200c9a66'
|
||||
@ -528,7 +506,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
side_effect=exceptions.RecordSetNotFound())
|
||||
def test_update_recordset_missing(self, _):
|
||||
# Prepare an update body
|
||||
body = {'recordset': {'description': 'Tester'}}
|
||||
body = {'description': 'Tester'}
|
||||
|
||||
# Ensure it fails with a 404
|
||||
url = ('/zones/%s/recordsets/ba751950-6193-11e3-949a-0800200c9a66'
|
||||
@ -545,11 +523,10 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
response = self.client.delete(url, status=202)
|
||||
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('recordset', response.json)
|
||||
# Currently recordset does not have a status field. As there are no
|
||||
# records, the recordset action/status show up as 'NONE', 'ACTIVE'
|
||||
self.assertEqual('NONE', response.json['recordset']['action'])
|
||||
self.assertEqual('ACTIVE', response.json['recordset']['status'])
|
||||
self.assertEqual('NONE', response.json['action'])
|
||||
self.assertEqual('ACTIVE', response.json['status'])
|
||||
|
||||
# Check the zone's status is as expected
|
||||
response = self.client.get('/zones/%s' % recordset['domain_id'],
|
||||
@ -557,9 +534,9 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertEqual('UPDATE', response.json['zone']['action'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
|
||||
self.assertEqual('UPDATE', response.json['action'])
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
|
||||
def test_delete_recordset_with_records(self):
|
||||
# Create a recordset with one record
|
||||
@ -571,9 +548,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
response = self.client.delete(url, status=202)
|
||||
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('recordset', response.json)
|
||||
self.assertEqual('DELETE', response.json['recordset']['action'])
|
||||
self.assertEqual('PENDING', response.json['recordset']['status'])
|
||||
self.assertEqual('DELETE', response.json['action'])
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
|
||||
# Check the zone's status is as expected
|
||||
response = self.client.get('/zones/%s' % recordset['domain_id'],
|
||||
@ -581,9 +557,9 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertEqual('UPDATE', response.json['zone']['action'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
|
||||
self.assertEqual('UPDATE', response.json['action'])
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
|
||||
@patch.object(central_service.Service, 'delete_recordset',
|
||||
side_effect=exceptions.RecordSetNotFound())
|
||||
@ -618,7 +594,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
# Create a recordset
|
||||
fixture = self.get_recordset_fixture(self.domain['name'], fixture=0)
|
||||
response = self.client.post_json(
|
||||
'/zones/%s/recordsets' % self.domain['id'], {'recordset': fixture})
|
||||
'/zones/%s/recordsets' % self.domain['id'], fixture)
|
||||
|
||||
response = self.client.get(url)
|
||||
|
||||
@ -629,11 +605,11 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
# Create two recordsets
|
||||
fixture = self.get_recordset_fixture(self.domain['name'], fixture=0)
|
||||
response = self.client.post_json(
|
||||
'/zones/%s/recordsets' % self.domain['id'], {'recordset': fixture})
|
||||
'/zones/%s/recordsets' % self.domain['id'], fixture)
|
||||
|
||||
fixture = self.get_recordset_fixture(self.domain['name'], fixture=1)
|
||||
response = self.client.post_json(
|
||||
'/zones/%s/recordsets' % self.domain['id'], {'recordset': fixture})
|
||||
'/zones/%s/recordsets' % self.domain['id'], fixture)
|
||||
|
||||
# Paginate the recordsets to two, there should be four now
|
||||
url = '/zones/%s/recordsets?limit=2' % self.domain['id']
|
||||
@ -662,17 +638,15 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('recordset', response.json)
|
||||
self.assertIn('links', response.json['recordset'])
|
||||
self.assertIn('self', response.json['recordset']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['recordset'])
|
||||
self.assertIn('created_at', response.json['recordset'])
|
||||
self.assertIsNone(response.json['recordset']['updated_at'])
|
||||
self.assertEqual(recordset['name'], response.json['recordset']['name'])
|
||||
self.assertEqual(recordset['type'], response.json['recordset']['type'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
self.assertEqual(recordset['name'], response.json['name'])
|
||||
self.assertEqual(recordset['type'], response.json['type'])
|
||||
|
||||
def test_get_secondary_zone_recordsets(self):
|
||||
fixture = self.get_domain_fixture('SECONDARY', 1)
|
||||
@ -716,7 +690,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
|
||||
url = '/zones/%s/recordsets' % secondary['id']
|
||||
self._assert_exception('forbidden', 403, self.client.post_json, url,
|
||||
{'recordset': fixture})
|
||||
fixture)
|
||||
|
||||
def test_update_secondary_zone_recordset(self):
|
||||
fixture = self.get_domain_fixture('SECONDARY', 1)
|
||||
@ -730,7 +704,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
recordset['id'])
|
||||
|
||||
self._assert_exception('forbidden', 403, self.client.put_json, url,
|
||||
{'recordset': {'ttl': 100}})
|
||||
{'ttl': 100})
|
||||
|
||||
def test_delete_secondary_zone_recordset(self):
|
||||
fixture = self.get_domain_fixture('SECONDARY', 1)
|
||||
@ -748,7 +722,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
def test_no_create_rs_deleting_zone(self):
|
||||
# Prepare a create
|
||||
fixture = self.get_recordset_fixture(self.domain['name'], fixture=0)
|
||||
body = {'recordset': fixture}
|
||||
body = fixture
|
||||
|
||||
self.client.delete('/zones/%s' % self.domain['id'], status=202)
|
||||
self._assert_exception('bad_request', 400, self.client.post_json,
|
||||
@ -760,7 +734,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase):
|
||||
recordset = self.create_recordset(self.domain)
|
||||
|
||||
# Prepare an update body
|
||||
body = {'recordset': {'description': 'Tester'}}
|
||||
body = {'description': 'Tester'}
|
||||
url = '/zones/%s/recordsets/%s' % (recordset['domain_id'],
|
||||
recordset['id'])
|
||||
self.client.delete('/zones/%s' % self.domain['id'], status=202)
|
||||
|
@ -22,22 +22,21 @@ class ApiV2TldsTest(ApiV2TestCase):
|
||||
def test_create_tld(self):
|
||||
self.policy({'create_tld': '@'})
|
||||
fixture = self.get_tld_fixture(0)
|
||||
response = self.client.post_json('/tlds/', {'tld': fixture})
|
||||
response = self.client.post_json('/tlds/', fixture)
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('tld', response.json)
|
||||
self.assertIn('links', response.json['tld'])
|
||||
self.assertIn('self', response.json['tld']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['tld'])
|
||||
self.assertIn('created_at', response.json['tld'])
|
||||
self.assertIsNone(response.json['tld']['updated_at'])
|
||||
self.assertEqual(fixture['name'], response.json['tld']['name'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
self.assertEqual(fixture['name'], response.json['name'])
|
||||
|
||||
def test_create_tld_validation(self):
|
||||
self.policy({'create_tld': '@'})
|
||||
@ -45,7 +44,7 @@ class ApiV2TldsTest(ApiV2TestCase):
|
||||
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception('invalid_object', 400, self.client.post_json,
|
||||
'/tlds', {'tld': invalid_fixture})
|
||||
'/tlds', invalid_fixture)
|
||||
|
||||
def test_get_tlds(self):
|
||||
self.policy({'find_tlds': '@'})
|
||||
@ -78,16 +77,15 @@ class ApiV2TldsTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('tld', response.json)
|
||||
self.assertIn('links', response.json['tld'])
|
||||
self.assertIn('self', response.json['tld']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['tld'])
|
||||
self.assertIn('created_at', response.json['tld'])
|
||||
self.assertIsNone(response.json['tld']['updated_at'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
self.assertEqual(self.get_tld_fixture(0)['name'],
|
||||
response.json['tld']['name'])
|
||||
response.json['name'])
|
||||
|
||||
def test_get_tld_invalid_id(self):
|
||||
self._assert_invalid_uuid(self.client.get, '/tlds/%s')
|
||||
@ -106,7 +104,7 @@ class ApiV2TldsTest(ApiV2TestCase):
|
||||
self.policy({'update_tld': '@'})
|
||||
|
||||
# Prepare an update body
|
||||
body = {'tld': {'description': 'prefix-%s' % tld['description']}}
|
||||
body = {'description': 'prefix-%s' % tld['description']}
|
||||
|
||||
response = self.client.patch_json('/tlds/%s' % tld['id'], body,
|
||||
status=200)
|
||||
@ -116,15 +114,14 @@ class ApiV2TldsTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('tld', response.json)
|
||||
self.assertIn('links', response.json['tld'])
|
||||
self.assertIn('self', response.json['tld']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['tld'])
|
||||
self.assertIsNotNone(response.json['tld']['updated_at'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIsNotNone(response.json['updated_at'])
|
||||
self.assertEqual('prefix-%s' % tld['description'],
|
||||
response.json['tld']['description'])
|
||||
response.json['description'])
|
||||
|
||||
def test_update_tld_invalid_id(self):
|
||||
self._assert_invalid_uuid(self.client.patch_json, '/tlds/%s')
|
||||
|
@ -36,24 +36,23 @@ class ApiV2TsigKeysTest(ApiV2TestCase):
|
||||
def test_create_tsigkey(self):
|
||||
# Create a TSIG Key
|
||||
fixture = self.get_tsigkey_fixture(0)
|
||||
response = self.client.post_json('/tsigkeys/', {'tsigkey': fixture})
|
||||
response = self.client.post_json('/tsigkeys/', fixture)
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('tsigkey', response.json)
|
||||
self.assertIn('links', response.json['tsigkey'])
|
||||
self.assertIn('self', response.json['tsigkey']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the generated values returned are what we expect
|
||||
self.assertIn('id', response.json['tsigkey'])
|
||||
self.assertIn('created_at', response.json['tsigkey'])
|
||||
self.assertIsNone(response.json['tsigkey']['updated_at'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
|
||||
# Check the supplied values returned are what we expect
|
||||
self.assertDictContainsSubset(fixture, response.json['tsigkey'])
|
||||
self.assertDictContainsSubset(fixture, response.json)
|
||||
|
||||
def test_create_tsigkey_validation(self):
|
||||
# NOTE: The schemas should be tested separately to the API. So we
|
||||
@ -61,18 +60,11 @@ class ApiV2TsigKeysTest(ApiV2TestCase):
|
||||
# Fetch a fixture
|
||||
fixture = self.get_tsigkey_fixture(0)
|
||||
|
||||
# Add a junk field to the wrapper
|
||||
body = {'tsigkey': fixture, 'junk': 'Junk Field'}
|
||||
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception('invalid_object', 400, self.client.post_json,
|
||||
'/tsigkeys', body)
|
||||
|
||||
# Add a junk field to the body
|
||||
fixture['junk'] = 'Junk Field'
|
||||
|
||||
# Ensure it fails with a 400
|
||||
body = {'tsigkey': fixture}
|
||||
body = fixture
|
||||
|
||||
self._assert_exception('invalid_object', 400, self.client.post_json,
|
||||
'/tsigkeys', body)
|
||||
@ -80,7 +72,7 @@ class ApiV2TsigKeysTest(ApiV2TestCase):
|
||||
def test_create_tsigkey_duplicate(self):
|
||||
# Prepare a TSIG Key fixture
|
||||
fixture = self.get_tsigkey_fixture(0)
|
||||
body = {'tsigkey': fixture}
|
||||
body = fixture
|
||||
|
||||
# Create the first TSIG Key
|
||||
response = self.client.post_json('/tsigkeys', body)
|
||||
@ -126,23 +118,22 @@ class ApiV2TsigKeysTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('tsigkey', response.json)
|
||||
self.assertIn('links', response.json['tsigkey'])
|
||||
self.assertIn('self', response.json['tsigkey']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the generated values returned are what we expect
|
||||
self.assertIn('id', response.json['tsigkey'])
|
||||
self.assertIn('created_at', response.json['tsigkey'])
|
||||
self.assertIsNone(response.json['tsigkey']['updated_at'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
|
||||
# Check the supplied values returned are what we expect
|
||||
self.assertEqual(tsigkey.name, response.json['tsigkey']['name'])
|
||||
self.assertEqual(tsigkey.name, response.json['name'])
|
||||
self.assertEqual(
|
||||
tsigkey.algorithm, response.json['tsigkey']['algorithm'])
|
||||
self.assertEqual(tsigkey.secret, response.json['tsigkey']['secret'])
|
||||
self.assertEqual(tsigkey.scope, response.json['tsigkey']['scope'])
|
||||
tsigkey.algorithm, response.json['algorithm'])
|
||||
self.assertEqual(tsigkey.secret, response.json['secret'])
|
||||
self.assertEqual(tsigkey.scope, response.json['scope'])
|
||||
self.assertEqual(
|
||||
tsigkey.resource_id, response.json['tsigkey']['resource_id'])
|
||||
tsigkey.resource_id, response.json['resource_id'])
|
||||
|
||||
def test_get_tsigkey_invalid_id(self):
|
||||
self._assert_invalid_uuid(self.client.get, '/tsigkeys/%s')
|
||||
@ -166,7 +157,7 @@ class ApiV2TsigKeysTest(ApiV2TestCase):
|
||||
tsigkey = self.create_tsigkey()
|
||||
|
||||
# Prepare an update body
|
||||
body = {'tsigkey': {'secret': 'prefix-%s' % tsigkey.secret}}
|
||||
body = {'secret': 'prefix-%s' % tsigkey.secret}
|
||||
|
||||
response = self.client.patch_json('/tsigkeys/%s' % tsigkey.id, body)
|
||||
|
||||
@ -175,15 +166,14 @@ class ApiV2TsigKeysTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('tsigkey', response.json)
|
||||
self.assertIn('links', response.json['tsigkey'])
|
||||
self.assertIn('self', response.json['tsigkey']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['tsigkey'])
|
||||
self.assertIsNotNone(response.json['tsigkey']['updated_at'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIsNotNone(response.json['updated_at'])
|
||||
self.assertEqual('prefix-%s' % tsigkey['secret'],
|
||||
response.json['tsigkey']['secret'])
|
||||
response.json['secret'])
|
||||
|
||||
def test_update_tsigkey_invalid_id(self):
|
||||
self._assert_invalid_uuid(self.client.patch_json, '/tsigkeys/%s')
|
||||
@ -192,7 +182,7 @@ class ApiV2TsigKeysTest(ApiV2TestCase):
|
||||
side_effect=exceptions.DuplicateTsigKey())
|
||||
def test_update_tsigkey_duplicate(self, _):
|
||||
# Prepare an update body
|
||||
body = {'tsigkey': {'name': 'AnyOldName'}}
|
||||
body = {'name': 'AnyOldName'}
|
||||
|
||||
url = '/tsigkeys/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980'
|
||||
|
||||
@ -204,7 +194,7 @@ class ApiV2TsigKeysTest(ApiV2TestCase):
|
||||
side_effect=messaging.MessagingTimeout())
|
||||
def test_update_tsigkey_timeout(self, _):
|
||||
# Prepare an update body
|
||||
body = {'tsigkey': {'name': 'AnyOldName'}}
|
||||
body = {'name': 'AnyOldName'}
|
||||
|
||||
url = '/tsigkeys/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980'
|
||||
|
||||
@ -216,7 +206,7 @@ class ApiV2TsigKeysTest(ApiV2TestCase):
|
||||
side_effect=exceptions.TsigKeyNotFound())
|
||||
def test_update_tsigkey_missing(self, _):
|
||||
# Prepare an update body
|
||||
body = {'tsigkey': {'name': 'AnyOldName'}}
|
||||
body = {'name': 'AnyOldName'}
|
||||
|
||||
url = '/tsigkeys/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980'
|
||||
|
||||
|
@ -27,118 +27,113 @@ class ApiV2ZoneTransfersTest(ApiV2TestCase):
|
||||
def test_create_zone_transfer_request(self):
|
||||
response = self.client.post_json(
|
||||
'/zones/%s/tasks/transfer_requests' % (self.domain.id),
|
||||
{'transfer_request': {}})
|
||||
{})
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('transfer_request', response.json)
|
||||
self.assertIn('links', response.json['transfer_request'])
|
||||
self.assertIn('self', response.json['transfer_request']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['transfer_request'])
|
||||
self.assertIn('created_at', response.json['transfer_request'])
|
||||
self.assertEqual('ACTIVE', response.json['transfer_request']['status'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertEqual('ACTIVE', response.json['status'])
|
||||
self.assertEqual(
|
||||
self.domain.id,
|
||||
response.json['transfer_request']['zone_id'])
|
||||
self.assertIsNone(response.json['transfer_request']['updated_at'])
|
||||
response.json['zone_id'])
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
|
||||
def test_create_zone_transfer_request_scoped(self):
|
||||
response = self.client.post_json(
|
||||
'/zones/%s/tasks/transfer_requests' % (self.domain.id),
|
||||
{'transfer_request':
|
||||
{'target_project_id': str(self.tenant_1_context.tenant)}})
|
||||
{'target_project_id': str(self.tenant_1_context.tenant)})
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('transfer_request', response.json)
|
||||
self.assertIn('links', response.json['transfer_request'])
|
||||
self.assertIn('self', response.json['transfer_request']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['transfer_request'])
|
||||
self.assertIn('created_at', response.json['transfer_request'])
|
||||
self.assertEqual('ACTIVE', response.json['transfer_request']['status'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertEqual('ACTIVE', response.json['status'])
|
||||
self.assertEqual(
|
||||
str(self.tenant_1_context.tenant),
|
||||
response.json['transfer_request']['target_project_id'])
|
||||
response.json['target_project_id'])
|
||||
self.assertEqual(
|
||||
self.domain.id,
|
||||
response.json['transfer_request']['zone_id'])
|
||||
self.assertIsNone(response.json['transfer_request']['updated_at'])
|
||||
response.json['zone_id'])
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
|
||||
def test_get_zone_transfer_request(self):
|
||||
initial = self.client.post_json(
|
||||
'/zones/%s/tasks/transfer_requests' % (self.domain.id),
|
||||
{'transfer_request': {}})
|
||||
{})
|
||||
|
||||
response = self.client.get(
|
||||
'/zones/tasks/transfer_requests/%s' %
|
||||
(initial.json['transfer_request']['id']))
|
||||
(initial.json['id']))
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('transfer_request', response.json)
|
||||
self.assertIn('links', response.json['transfer_request'])
|
||||
self.assertIn('self', response.json['transfer_request']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['transfer_request'])
|
||||
self.assertIn('created_at', response.json['transfer_request'])
|
||||
self.assertEqual('ACTIVE', response.json['transfer_request']['status'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertEqual('ACTIVE', response.json['status'])
|
||||
self.assertEqual(
|
||||
self.domain.id,
|
||||
response.json['transfer_request']['zone_id'])
|
||||
self.assertIn('updated_at', response.json['transfer_request'])
|
||||
response.json['zone_id'])
|
||||
self.assertIn('updated_at', response.json)
|
||||
|
||||
def test_update_zone_transfer_request(self):
|
||||
initial = self.client.post_json(
|
||||
'/zones/%s/tasks/transfer_requests' % (self.domain.id),
|
||||
{'transfer_request': {}})
|
||||
{})
|
||||
|
||||
response = self.client.patch_json(
|
||||
'/zones/tasks/transfer_requests/%s' %
|
||||
(initial.json['transfer_request']['id']),
|
||||
{'transfer_request': {"description": "TEST"}})
|
||||
(initial.json['id']),
|
||||
{"description": "TEST"})
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('transfer_request', response.json)
|
||||
self.assertIn('links', response.json['transfer_request'])
|
||||
self.assertIn('self', response.json['transfer_request']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['transfer_request'])
|
||||
self.assertIn('created_at', response.json['transfer_request'])
|
||||
self.assertEqual('ACTIVE', response.json['transfer_request']['status'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertEqual('ACTIVE', response.json['status'])
|
||||
self.assertEqual(
|
||||
self.domain.id,
|
||||
response.json['transfer_request']['zone_id'])
|
||||
response.json['zone_id'])
|
||||
self.assertEqual(
|
||||
'TEST', response.json['transfer_request']['description'])
|
||||
self.assertIn('updated_at', response.json['transfer_request'])
|
||||
'TEST', response.json['description'])
|
||||
self.assertIn('updated_at', response.json)
|
||||
|
||||
def test_delete_zone_transfer_request(self):
|
||||
initial = self.client.post_json(
|
||||
'/zones/%s/tasks/transfer_requests' % (self.domain.id),
|
||||
{'transfer_request': {}})
|
||||
{})
|
||||
|
||||
response = self.client.delete(
|
||||
'/zones/tasks/transfer_requests/%s' %
|
||||
(initial.json['transfer_request']['id']))
|
||||
(initial.json['id']))
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(204, response.status_int)
|
||||
@ -146,50 +141,49 @@ class ApiV2ZoneTransfersTest(ApiV2TestCase):
|
||||
def test_create_zone_transfer_accept(self):
|
||||
initial = self.client.post_json(
|
||||
'/zones/%s/tasks/transfer_requests' % (self.domain.id),
|
||||
{'transfer_request': {}})
|
||||
{})
|
||||
|
||||
response = self.client.post_json(
|
||||
'/zones/tasks/transfer_accepts',
|
||||
{'transfer_accept': {
|
||||
{
|
||||
'zone_transfer_request_id':
|
||||
initial.json['transfer_request']['id'],
|
||||
'key': initial.json['transfer_request']['key']
|
||||
}})
|
||||
initial.json['id'],
|
||||
'key': initial.json['key']
|
||||
})
|
||||
|
||||
new_ztr = self.client.get(
|
||||
'/zones/tasks/transfer_requests/%s' %
|
||||
(initial.json['transfer_request']['id']))
|
||||
(initial.json['id']))
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('transfer_accept', response.json)
|
||||
self.assertIn('links', response.json['transfer_accept'])
|
||||
self.assertIn('self', response.json['transfer_accept']['links'])
|
||||
self.assertIn('zone', response.json['transfer_accept']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
self.assertIn('zone', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['transfer_accept'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertEqual(
|
||||
'COMPLETE',
|
||||
response.json['transfer_accept']['status'])
|
||||
response.json['status'])
|
||||
|
||||
self.assertEqual(
|
||||
'COMPLETE',
|
||||
new_ztr.json['transfer_request']['status'])
|
||||
new_ztr.json['status'])
|
||||
|
||||
def test_create_zone_transfer_request_deleting_zone(self):
|
||||
url = '/zones/%s/tasks/transfer_requests' % (self.domain.id)
|
||||
body = {'transfer_request': {}}
|
||||
body = {}
|
||||
self.client.delete('/zones/%s' % self.domain['id'], status=202)
|
||||
self._assert_exception('bad_request', 400, self.client.post_json, url,
|
||||
body)
|
||||
|
||||
def test_create_zone_transfer_accept_deleting_zone(self):
|
||||
url = '/zones/%s/tasks/transfer_requests' % (self.domain.id)
|
||||
body = {'transfer_request': {}}
|
||||
body = {}
|
||||
self.client.delete('/zones/%s' % self.domain['id'], status=202)
|
||||
self._assert_exception('bad_request', 400, self.client.post_json, url,
|
||||
body)
|
||||
|
@ -38,54 +38,52 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
# Create a zone
|
||||
fixture = self.get_domain_fixture(fixture=0)
|
||||
|
||||
response = self.client.post_json('/zones/', {'zone': fixture})
|
||||
response = self.client.post_json('/zones/', fixture)
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertIn('links', response.json['zone'])
|
||||
self.assertIn('self', response.json['zone']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['zone'])
|
||||
self.assertIn('created_at', response.json['zone'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
self.assertEqual('PRIMARY', response.json['zone']['type'])
|
||||
self.assertEqual([], response.json['zone']['masters'])
|
||||
self.assertIsNone(response.json['zone']['updated_at'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
self.assertEqual('PRIMARY', response.json['type'])
|
||||
self.assertEqual([], response.json['masters'])
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
|
||||
for k in fixture:
|
||||
self.assertEqual(fixture[k], response.json['zone'][k])
|
||||
self.assertEqual(fixture[k], response.json[k])
|
||||
|
||||
def test_create_zone_no_type(self):
|
||||
# Create a zone
|
||||
fixture = self.get_domain_fixture(fixture=0)
|
||||
del fixture['type']
|
||||
|
||||
response = self.client.post_json('/zones/', {'zone': fixture})
|
||||
response = self.client.post_json('/zones/', fixture)
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertIn('links', response.json['zone'])
|
||||
self.assertIn('self', response.json['zone']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['zone'])
|
||||
self.assertIn('created_at', response.json['zone'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
self.assertEqual('PRIMARY', response.json['zone']['type'])
|
||||
self.assertEqual([], response.json['zone']['masters'])
|
||||
self.assertIsNone(response.json['zone']['updated_at'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
self.assertEqual('PRIMARY', response.json['type'])
|
||||
self.assertEqual([], response.json['masters'])
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
|
||||
for k in fixture:
|
||||
self.assertEqual(fixture[k], response.json['zone'][k])
|
||||
self.assertEqual(fixture[k], response.json[k])
|
||||
|
||||
def test_create_zone_validation(self):
|
||||
# NOTE: The schemas should be tested separately to the API. So we
|
||||
@ -93,18 +91,11 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
# Fetch a fixture
|
||||
fixture = self.get_domain_fixture(fixture=0)
|
||||
|
||||
# Add a junk field to the wrapper
|
||||
body = {'zone': fixture, 'junk': 'Junk Field'}
|
||||
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception('invalid_object', 400, self.client.post_json,
|
||||
'/zones', body)
|
||||
|
||||
# Add a junk field to the body
|
||||
fixture['junk'] = 'Junk Field'
|
||||
|
||||
# Ensure it fails with a 400
|
||||
body = {'zone': fixture}
|
||||
body = fixture
|
||||
|
||||
self._assert_exception('invalid_object', 400, self.client.post_json,
|
||||
'/zones', body)
|
||||
@ -114,7 +105,7 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
# Add id to the body
|
||||
fixture['id'] = '2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980'
|
||||
# Ensure it fails with a 400
|
||||
body = {'zone': fixture}
|
||||
body = fixture
|
||||
self._assert_exception('invalid_object', 400, self.client.post_json,
|
||||
'/zones', body)
|
||||
|
||||
@ -122,7 +113,7 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
# Add created_at to the body
|
||||
fixture['created_at'] = '2014-03-12T19:07:53.000000'
|
||||
# Ensure it fails with a 400
|
||||
body = {'zone': fixture}
|
||||
body = fixture
|
||||
self._assert_exception('invalid_object', 400, self.client.post_json,
|
||||
'/zones', body)
|
||||
|
||||
@ -132,14 +123,14 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception('invalid_object', 400, self.client.post_json,
|
||||
'/zones', {'zone': fixture})
|
||||
'/zones', fixture)
|
||||
|
||||
@patch.object(central_service.Service, 'create_domain',
|
||||
side_effect=messaging.MessagingTimeout())
|
||||
def test_create_zone_timeout(self, _):
|
||||
fixture = self.get_domain_fixture(fixture=0)
|
||||
|
||||
body = {'zone': fixture}
|
||||
body = fixture
|
||||
|
||||
self._assert_exception('timeout', 504, self.client.post_json,
|
||||
'/zones/', body)
|
||||
@ -149,7 +140,7 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
def test_create_zone_duplicate(self, _):
|
||||
fixture = self.get_domain_fixture(fixture=0)
|
||||
|
||||
body = {'zone': fixture}
|
||||
body = fixture
|
||||
|
||||
self._assert_exception('duplicate_domain', 409, self.client.post_json,
|
||||
'/zones/', body)
|
||||
@ -215,17 +206,16 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertIn('links', response.json['zone'])
|
||||
self.assertIn('self', response.json['zone']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['zone'])
|
||||
self.assertIn('created_at', response.json['zone'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
self.assertIsNone(response.json['zone']['updated_at'])
|
||||
self.assertEqual(zone['name'], response.json['zone']['name'])
|
||||
self.assertEqual(zone['email'], response.json['zone']['email'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
self.assertEqual(zone['name'], response.json['name'])
|
||||
self.assertEqual(zone['email'], response.json['email'])
|
||||
|
||||
def test_get_zone_invalid_id(self):
|
||||
self._assert_invalid_uuid(self.client.get, '/zones/%s')
|
||||
@ -259,7 +249,7 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
zone = self.create_domain()
|
||||
|
||||
# Prepare an update body
|
||||
body = {'zone': {'email': 'prefix-%s' % zone['email']}}
|
||||
body = {'email': 'prefix-%s' % zone['email']}
|
||||
|
||||
response = self.client.patch_json('/zones/%s' % zone['id'], body,
|
||||
status=202)
|
||||
@ -269,16 +259,15 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertIn('links', response.json['zone'])
|
||||
self.assertIn('self', response.json['zone']['links'])
|
||||
self.assertIn('status', response.json['zone'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
self.assertIn('status', response.json)
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['zone'])
|
||||
self.assertIsNotNone(response.json['zone']['updated_at'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIsNotNone(response.json['updated_at'])
|
||||
self.assertEqual('prefix-%s' % zone['email'],
|
||||
response.json['zone']['email'])
|
||||
response.json['email'])
|
||||
|
||||
def test_update_zone_invalid_id(self):
|
||||
self._assert_invalid_uuid(self.client.patch_json, '/zones/%s')
|
||||
@ -289,35 +278,27 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
# Create a zone
|
||||
zone = self.create_domain()
|
||||
|
||||
# Prepare an update body with junk in the wrapper
|
||||
body = {'zone': {'email': 'prefix-%s' % zone['email']},
|
||||
# Prepare an update body with junk in the body
|
||||
body = {'email': 'prefix-%s' % zone['email'],
|
||||
'junk': 'Junk Field'}
|
||||
|
||||
url = '/zones/%s' % zone['id']
|
||||
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception('invalid_object', 400, self.client.patch_json,
|
||||
url, body)
|
||||
|
||||
# Prepare an update body with junk in the body
|
||||
body = {'zone': {'email': 'prefix-%s' % zone['email'],
|
||||
'junk': 'Junk Field'}}
|
||||
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception('invalid_object', 400, self.client.patch_json,
|
||||
url, body)
|
||||
|
||||
# Prepare an update body with negative ttl in the body
|
||||
body = {'zone': {'email': 'prefix-%s' % zone['email'],
|
||||
'ttl': -20}}
|
||||
body = {'email': 'prefix-%s' % zone['email'],
|
||||
'ttl': -20}
|
||||
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception('invalid_object', 400, self.client.patch_json,
|
||||
url, body)
|
||||
|
||||
# Prepare an update body with ttl > maximum (2147483647) in the body
|
||||
body = {'zone': {'email': 'prefix-%s' % zone['email'],
|
||||
'ttl': 2147483648}}
|
||||
body = {'email': 'prefix-%s' % zone['email'],
|
||||
'ttl': 2147483648}
|
||||
|
||||
# Ensure it fails with a 400
|
||||
self._assert_exception('invalid_object', 400, self.client.patch_json,
|
||||
@ -327,7 +308,7 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
side_effect=exceptions.DuplicateDomain())
|
||||
def test_update_zone_duplicate(self, _):
|
||||
# Prepare an update body
|
||||
body = {'zone': {'email': 'example@example.org'}}
|
||||
body = {'email': 'example@example.org'}
|
||||
|
||||
url = '/zones/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980'
|
||||
|
||||
@ -339,7 +320,7 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
side_effect=messaging.MessagingTimeout())
|
||||
def test_update_zone_timeout(self, _):
|
||||
# Prepare an update body
|
||||
body = {'zone': {'email': 'example@example.org'}}
|
||||
body = {'email': 'example@example.org'}
|
||||
|
||||
url = '/zones/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980'
|
||||
|
||||
@ -351,7 +332,7 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
side_effect=exceptions.DomainNotFound())
|
||||
def test_update_zone_missing(self, _):
|
||||
# Prepare an update body
|
||||
body = {'zone': {'email': 'example@example.org'}}
|
||||
body = {'email': 'example@example.org'}
|
||||
|
||||
url = '/zones/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980'
|
||||
|
||||
@ -367,9 +348,8 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertEqual('DELETE', response.json['zone']['action'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
self.assertEqual('DELETE', response.json['action'])
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
|
||||
def test_delete_zone_invalid_id(self):
|
||||
self._assert_invalid_uuid(self.client.delete, '/zones/%s')
|
||||
@ -422,39 +402,38 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
fixture = self.get_domain_fixture('SECONDARY', 0)
|
||||
fixture['masters'] = ["10.0.0.1"]
|
||||
|
||||
response = self.client.post_json('/zones/', {'zone': fixture})
|
||||
response = self.client.post_json('/zones/', fixture)
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertIn('links', response.json['zone'])
|
||||
self.assertIn('self', response.json['zone']['links'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['zone'])
|
||||
self.assertIn('created_at', response.json['zone'])
|
||||
self.assertEqual('PENDING', response.json['zone']['status'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIn('created_at', response.json)
|
||||
self.assertEqual('PENDING', response.json['status'])
|
||||
self.assertEqual(cfg.CONF['service:central'].managed_resource_email,
|
||||
response.json['zone']['email'])
|
||||
response.json['email'])
|
||||
|
||||
self.assertIsNone(response.json['zone']['updated_at'])
|
||||
self.assertIsNone(response.json['updated_at'])
|
||||
# Zone is not transferred yet
|
||||
self.assertIsNone(response.json['zone']['transferred_at'])
|
||||
self.assertIsNone(response.json['transferred_at'])
|
||||
# Serial defaults to 1
|
||||
self.assertEqual(response.json['zone']['serial'], 1)
|
||||
self.assertEqual(response.json['serial'], 1)
|
||||
|
||||
for k in fixture:
|
||||
self.assertEqual(fixture[k], response.json['zone'][k])
|
||||
self.assertEqual(fixture[k], response.json[k])
|
||||
|
||||
def test_create_secondary_no_masters(self):
|
||||
# Create a zone
|
||||
fixture = self.get_domain_fixture('SECONDARY', 0)
|
||||
|
||||
self._assert_exception('invalid_object', 400, self.client.post_json,
|
||||
'/zones/', {'zone': fixture})
|
||||
'/zones/', fixture)
|
||||
|
||||
def test_update_secondary(self):
|
||||
# Create a zone
|
||||
@ -468,7 +447,7 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
masters = ['10.0.0.1', '10.0.0.2']
|
||||
|
||||
# Prepare an update body
|
||||
body = {'zone': {'masters': masters}}
|
||||
body = {'masters': masters}
|
||||
|
||||
response = self.client.patch_json('/zones/%s' % zone['id'], body,
|
||||
status=202)
|
||||
@ -478,16 +457,15 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the body structure is what we expect
|
||||
self.assertIn('zone', response.json)
|
||||
self.assertIn('links', response.json['zone'])
|
||||
self.assertIn('self', response.json['zone']['links'])
|
||||
self.assertIn('status', response.json['zone'])
|
||||
self.assertIn('links', response.json)
|
||||
self.assertIn('self', response.json['links'])
|
||||
self.assertIn('status', response.json)
|
||||
|
||||
# Check the values returned are what we expect
|
||||
self.assertIn('id', response.json['zone'])
|
||||
self.assertIsNotNone(response.json['zone']['updated_at'])
|
||||
self.assertEqual(masters, response.json['zone']['masters'])
|
||||
self.assertEqual(1, response.json['zone']['serial'])
|
||||
self.assertIn('id', response.json)
|
||||
self.assertIsNotNone(response.json['updated_at'])
|
||||
self.assertEqual(masters, response.json['masters'])
|
||||
self.assertEqual(1, response.json['serial'])
|
||||
|
||||
def test_update_secondary_email_invalid_object(self):
|
||||
# Create a zone
|
||||
@ -497,7 +475,7 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
# Create a zone
|
||||
zone = self.create_domain(**fixture)
|
||||
|
||||
body = {'zone': {'email': 'foo@bar.io'}}
|
||||
body = {'email': 'foo@bar.io'}
|
||||
|
||||
self._assert_exception('invalid_object', 400, self.client.patch_json,
|
||||
'/zones/%s' % zone['id'], body)
|
||||
@ -528,7 +506,7 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
self.get_zonefile_fixture(),
|
||||
headers={'Content-type': 'text/dns'})
|
||||
get_response = self.client.get('/zones/%s' %
|
||||
post_response.json['zone']['id'],
|
||||
post_response.json['id'],
|
||||
headers={'Accept': 'text/dns'})
|
||||
|
||||
exported_zonefile = get_response.body
|
||||
@ -566,7 +544,7 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
|
||||
# Create a zone
|
||||
fixture = self.get_domain_fixture(fixture=0)
|
||||
response = self.client.post_json('/zones/', {'zone': fixture})
|
||||
response = self.client.post_json('/zones/', fixture)
|
||||
|
||||
response = self.client.get('/zones/')
|
||||
|
||||
@ -576,10 +554,10 @@ class ApiV2ZonesTest(ApiV2TestCase):
|
||||
def test_total_count_pagination(self):
|
||||
# Create two zones
|
||||
fixture = self.get_domain_fixture(fixture=0)
|
||||
response = self.client.post_json('/zones/', {'zone': fixture})
|
||||
response = self.client.post_json('/zones/', fixture)
|
||||
|
||||
fixture = self.get_domain_fixture(fixture=1)
|
||||
response = self.client.post_json('/zones/', {'zone': fixture})
|
||||
response = self.client.post_json('/zones/', fixture)
|
||||
|
||||
# Paginate so that there is only one zone returned
|
||||
response = self.client.get('/zones?limit=1')
|
||||
|
@ -17,12 +17,13 @@ example:
|
||||
Content-Type: application/json
|
||||
|
||||
{ # The rest is the body of request
|
||||
"pool": {
|
||||
"name": "Example Pool",
|
||||
"nameservers": [
|
||||
"ns1.example.org."
|
||||
]
|
||||
}
|
||||
"name": "Example Pool",
|
||||
"ns_records": [
|
||||
{
|
||||
"hostname": "ns1.example.org.",
|
||||
"priority": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
With this info we can make this request using the cURL_ tool. We'll
|
||||
@ -77,3 +78,12 @@ V2 API
|
||||
rest/v2/blacklists
|
||||
rest/v2/quotas
|
||||
rest/v2/pools
|
||||
|
||||
Admin API
|
||||
---------
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
rest/admin/quotas
|
||||
|
||||
|
@ -27,7 +27,7 @@ The quotas extension can be used to retrieve a tenant's absolute limits.
|
||||
If Designate returns a 404 error, ensure that the following line has been
|
||||
added to the designate.conf file::
|
||||
|
||||
enabled_extensions_v2 = quotas
|
||||
enabled_extensions_admin = quotas
|
||||
|
||||
Once this line has been added, restart the designate-central and designate-api
|
||||
services.
|
||||
@ -44,7 +44,7 @@ Get Quotas
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /v2/quotas/12345 HTTP/1.1
|
||||
GET /admin/quotas/12345 HTTP/1.1
|
||||
Host: 127.0.0.1:9001
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
@ -85,7 +85,7 @@ Update Quotas
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
PATCH /v2/quotas/12345 HTTP/1.1
|
||||
PATCH /admin/quotas/12345 HTTP/1.1
|
||||
Host: 127.0.0.1:9001
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
@ -128,7 +128,7 @@ Reset Quotas to Default
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
DELETE /v2/quotas/12345 HTTP/1.1
|
||||
DELETE /admin/quotas/12345 HTTP/1.1
|
||||
Host: 127.0.0.1:9001
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
@ -65,10 +65,8 @@ Create a Blacklist
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"blacklist" : {
|
||||
"pattern" : "^([A-Za-z0-9_\\-]+\\.)*example\\.com\\.$",
|
||||
"description" : "This is a blacklisted domain."
|
||||
}
|
||||
"pattern" : "^([A-Za-z0-9_\\-]+\\.)*example\\.com\\.$",
|
||||
"description" : "This is a blacklisted domain."
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
@ -79,18 +77,16 @@ Create a Blacklist
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
Location: 127.0.0.1:9001/v2/blacklists/c47229fb-0831-4b55-a5b5-380d361be4bd
|
||||
|
||||
{
|
||||
"blacklist":{
|
||||
"description":"This is a blacklisted domain.",
|
||||
"links":{
|
||||
"self":"http://127.0.0.1:9001/v2/blacklists/c47229fb-0831-4b55-a5b5-380d361be4bd"
|
||||
},
|
||||
"pattern":"^([A-Za-z0-9_\\-]+\\.)*example\\.com\\.$",
|
||||
"created_at":"2014-03-11T21:54:57.000000",
|
||||
"updated_at":null,
|
||||
"id":"c47229fb-0831-4b55-a5b5-380d361be4bd"
|
||||
{
|
||||
"description":"This is a blacklisted domain.",
|
||||
"links":{
|
||||
"self":"http://127.0.0.1:9001/v2/blacklists/c47229fb-0831-4b55-a5b5-380d361be4bd"
|
||||
},
|
||||
"pattern":"^([A-Za-z0-9_\\-]+\\.)*example\\.com\\.$",
|
||||
"created_at":"2014-03-11T21:54:57.000000",
|
||||
"updated_at":null,
|
||||
"id":"c47229fb-0831-4b55-a5b5-380d361be4bd"
|
||||
}
|
||||
}
|
||||
|
||||
:form created_at: timestamp
|
||||
:form updated_at: timestamp
|
||||
@ -126,16 +122,14 @@ Get a Blacklist
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
{
|
||||
"blacklist":{
|
||||
"description":"This is a blacklisted domain.",
|
||||
"links":{
|
||||
"self":"http://127.0.0.1:9001/v2/blacklists/c47229fb-0831-4b55-a5b5-380d361be4bd"
|
||||
},
|
||||
"pattern":"^([A-Za-z0-9_\\-]+\\.)*example\\.com\\.$",
|
||||
"created_at":"2014-03-11T21:54:57.000000",
|
||||
"updated_at":null,
|
||||
"id":"c47229fb-0831-4b55-a5b5-380d361be4bd"
|
||||
}
|
||||
"description":"This is a blacklisted domain.",
|
||||
"links":{
|
||||
"self":"http://127.0.0.1:9001/v2/blacklists/c47229fb-0831-4b55-a5b5-380d361be4bd"
|
||||
},
|
||||
"pattern":"^([A-Za-z0-9_\\-]+\\.)*example\\.com\\.$",
|
||||
"created_at":"2014-03-11T21:54:57.000000",
|
||||
"updated_at":null,
|
||||
"id":"c47229fb-0831-4b55-a5b5-380d361be4bd"
|
||||
}
|
||||
|
||||
:form created_at: timestamp
|
||||
@ -224,10 +218,8 @@ Update a Blacklist
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"blacklist" : {
|
||||
"pattern" : "^([A-Za-z0-9_\\-]+\\.)*example\\.com\\.$",
|
||||
"description" : "Updated the description"
|
||||
}
|
||||
"pattern" : "^([A-Za-z0-9_\\-]+\\.)*example\\.com\\.$",
|
||||
"description" : "Updated the description"
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
@ -238,16 +230,14 @@ Update a Blacklist
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
{
|
||||
"blacklist":{
|
||||
"description":"Updated the pattern to catch subdomains",
|
||||
"links":{
|
||||
"self":"http://127.0.0.1:9001/v2/blacklists/c47229fb-0831-4b55-a5b5-380d361be4bd"
|
||||
},
|
||||
"created_at":"2014-03-11T21:54:57.000000",
|
||||
"updated_at":"2014-03-13T16:49:32.117187",
|
||||
"id":"c47229fb-0831-4b55-a5b5-380d361be4bd",
|
||||
"pattern":"^([A-Za-z0-9_\\-]+\\.)*example\\.com\\.$"
|
||||
}
|
||||
"description":"Updated the pattern to catch subdomains",
|
||||
"links":{
|
||||
"self":"http://127.0.0.1:9001/v2/blacklists/c47229fb-0831-4b55-a5b5-380d361be4bd"
|
||||
},
|
||||
"created_at":"2014-03-11T21:54:57.000000",
|
||||
"updated_at":"2014-03-13T16:49:32.117187",
|
||||
"id":"c47229fb-0831-4b55-a5b5-380d361be4bd",
|
||||
"pattern":"^([A-Za-z0-9_\\-]+\\.)*example\\.com\\.$"
|
||||
}
|
||||
|
||||
:form created_at: timestamp
|
||||
|
@ -46,13 +46,13 @@ Create Pool
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"pool": {
|
||||
"attributes": {},
|
||||
"nameservers": [
|
||||
"ns1.example.org."
|
||||
],
|
||||
"name": "example_pool"
|
||||
}
|
||||
"name": "Example Pool",
|
||||
"ns_records": [
|
||||
{
|
||||
"hostname": "ns1.example.org.",
|
||||
"priority": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -65,21 +65,22 @@ Create Pool
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
{
|
||||
"pool": {
|
||||
"description": null,
|
||||
"id": "d1716333-8c16-490f-85ee-29af36907605",
|
||||
"project_id": "noauth-project",
|
||||
"created_at": "2015-02-23T21:56:33.000000",
|
||||
"attributes": null,
|
||||
"nameservers": [
|
||||
"ns1.example.org."
|
||||
],
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/pools/d1716333-8c16-490f-85ee-29af36907605"
|
||||
},
|
||||
"name": "example_pool",
|
||||
"updated_at": null
|
||||
}
|
||||
"description": null,
|
||||
"id": "d1716333-8c16-490f-85ee-29af36907605",
|
||||
"project_id": "noauth-project",
|
||||
"created_at": "2015-02-23T21:56:33.000000",
|
||||
"attributes": null,
|
||||
"ns_records": [
|
||||
{
|
||||
"hostname": "ns1.example.org.",
|
||||
"priority": 1
|
||||
}
|
||||
],
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/pools/d1716333-8c16-490f-85ee-29af36907605"
|
||||
},
|
||||
"name": "example_pool",
|
||||
"updated_at": null
|
||||
}
|
||||
|
||||
:form name: UTF-8 text field
|
||||
@ -87,7 +88,7 @@ Create Pool
|
||||
:form tenant_id: the UUID of the tenant
|
||||
:form provisioner: the type backend that should be used
|
||||
:form attributes: meta data for the pool
|
||||
:form nameservers: a list of nameservers as fully qualified domains
|
||||
:form ns_records: a list of ns_records as fully qualified domains
|
||||
|
||||
:statuscode 201: Created
|
||||
:statuscode 400: Bad Request
|
||||
@ -131,8 +132,11 @@ Get Pools
|
||||
"project_id": null,
|
||||
"created_at": "2015-02-18T22:18:58.000000",
|
||||
"attributes": null,
|
||||
"nameservers": [
|
||||
"ns1.example.org."
|
||||
"ns_records": [
|
||||
{
|
||||
"hostname": "ns1.example.org.",
|
||||
"priority": 1
|
||||
}
|
||||
],
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/pools/794ccc2c-d751-44fe-b57f-8894c9f5c842"
|
||||
@ -146,8 +150,11 @@ Get Pools
|
||||
"project_id": "noauth-project",
|
||||
"created_at": "2015-02-23T21:56:33.000000",
|
||||
"attributes": null,
|
||||
"nameservers": [
|
||||
"ns1.example.org."
|
||||
"ns_records": [
|
||||
{
|
||||
"hostname": "ns2.example.org.",
|
||||
"priority": 1
|
||||
}
|
||||
],
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/pools/d1716333-8c16-490f-85ee-29af36907605"
|
||||
@ -186,21 +193,22 @@ Get Pool
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
{
|
||||
"pool": {
|
||||
"description": null,
|
||||
"id": "794ccc2c-d751-44fe-b57f-8894c9f5c842",
|
||||
"project_id": null,
|
||||
"created_at": "2015-02-18T22:18:58.000000",
|
||||
"attributes": null,
|
||||
"nameservers": [
|
||||
"ns1.example.org."
|
||||
],
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/pools/794ccc2c-d751-44fe-b57f-8894c9f5c842"
|
||||
},
|
||||
"name": "default",
|
||||
"updated_at": "2015-02-19T15:59:44.000000"
|
||||
}
|
||||
"description": null,
|
||||
"id": "794ccc2c-d751-44fe-b57f-8894c9f5c842",
|
||||
"project_id": null,
|
||||
"created_at": "2015-02-18T22:18:58.000000",
|
||||
"attributes": null,
|
||||
"ns_records": [
|
||||
{
|
||||
"hostname": "ns1.example.org.",
|
||||
"priority": 1
|
||||
}
|
||||
],
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/pools/794ccc2c-d751-44fe-b57f-8894c9f5c842"
|
||||
},
|
||||
"name": "default",
|
||||
"updated_at": "2015-02-19T15:59:44.000000"
|
||||
}
|
||||
|
||||
:statuscode 200: OK
|
||||
@ -225,11 +233,16 @@ Update Pool
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"pool": {
|
||||
"nameservers": [
|
||||
"ns3.example.org."
|
||||
]
|
||||
}
|
||||
"ns_records": [
|
||||
{
|
||||
"hostname": "ns1.example.org.",
|
||||
"priority": 1
|
||||
},
|
||||
{
|
||||
"hostname": "ns3.example.org.",
|
||||
"priority": 2
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
@ -241,22 +254,26 @@ Update Pool
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
{
|
||||
"pool": {
|
||||
"description": null,
|
||||
"id": "794ccc2c-d751-44fe-b57f-8894c9f5c842",
|
||||
"project_id": null,
|
||||
"created_at": "2015-02-18T22:18:58.000000",
|
||||
"attributes": null,
|
||||
"nameservers": [
|
||||
"ns1.example.org.",
|
||||
"ns3.example.org."
|
||||
],
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/pools/794ccc2c-d751-44fe-b57f-8894c9f5c842"
|
||||
},
|
||||
"name": "default",
|
||||
"updated_at": "2015-02-24T17:39:07.000000"
|
||||
}
|
||||
"description": null,
|
||||
"id": "794ccc2c-d751-44fe-b57f-8894c9f5c842",
|
||||
"project_id": null,
|
||||
"created_at": "2015-02-18T22:18:58.000000",
|
||||
"attributes": null,
|
||||
"ns_records": [
|
||||
{
|
||||
"hostname": "ns1.example.org.",
|
||||
"priority": 1
|
||||
}
|
||||
{
|
||||
"hostname": "ns3.example.org.",
|
||||
"priority": 2
|
||||
}
|
||||
],
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/pools/794ccc2c-d751-44fe-b57f-8894c9f5c842"
|
||||
},
|
||||
"name": "default",
|
||||
"updated_at": "2015-02-24T17:39:07.000000"
|
||||
}
|
||||
|
||||
.. note::
|
||||
@ -268,12 +285,15 @@ Update Pool
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"pool": {
|
||||
"nameservers": ["ns3.example.org"]
|
||||
}
|
||||
"ns_records": [
|
||||
{
|
||||
"hostname": "ns3.example.org.",
|
||||
"priority": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
This would **replace** the value of the `nameservers` key.
|
||||
This would **replace** the value of the `ns_records` key.
|
||||
|
||||
It is a good practice to peform a GET and mutate the result
|
||||
accordingly.
|
||||
|
@ -46,15 +46,13 @@ The following format can be used for common record set types including A, AAAA,
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset" : {
|
||||
"name" : "example.org.",
|
||||
"description" : "This is an example record set.",
|
||||
"type" : "A",
|
||||
"ttl" : 3600,
|
||||
"records" : [
|
||||
"10.1.0.2"
|
||||
]
|
||||
}
|
||||
"name" : "example.org.",
|
||||
"description" : "This is an example record set.",
|
||||
"type" : "A",
|
||||
"ttl" : 3600,
|
||||
"records" : [
|
||||
"10.1.0.2"
|
||||
]
|
||||
}
|
||||
|
||||
**Example response:**
|
||||
@ -65,23 +63,21 @@ The following format can be used for common record set types including A, AAAA,
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset": {
|
||||
"description": "This is an example record set.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records": [
|
||||
"10.1.0.2"
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096648",
|
||||
"name": "example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-10-24T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "A"
|
||||
}
|
||||
"description": "This is an example record set.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records": [
|
||||
"10.1.0.2"
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096648",
|
||||
"name": "example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-10-24T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "A"
|
||||
}
|
||||
|
||||
|
||||
@ -120,23 +116,21 @@ Get Record Set
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset": {
|
||||
"description": "This is an example recordset.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records": [
|
||||
"10.1.0.2"
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096648",
|
||||
"name": "example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-10-24T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "A"
|
||||
}
|
||||
"description": "This is an example recordset.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records": [
|
||||
"10.1.0.2"
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096648",
|
||||
"name": "example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-10-24T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "A"
|
||||
}
|
||||
|
||||
:statuscode 200: Success
|
||||
@ -248,13 +242,11 @@ Update Record Set
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset" : {
|
||||
"description" : "I updated this example.",
|
||||
"ttl" : 60,
|
||||
"records" : [
|
||||
"10.1.0.2"
|
||||
]
|
||||
}
|
||||
"description" : "I updated this example.",
|
||||
"ttl" : 60,
|
||||
"records" : [
|
||||
"10.1.0.2"
|
||||
]
|
||||
}
|
||||
|
||||
**Response:**
|
||||
@ -265,23 +257,21 @@ Update Record Set
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset": {
|
||||
"description": "I updated this example.",
|
||||
"ttl": 60,
|
||||
"records": [
|
||||
"10.1.0.2"
|
||||
],
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648"
|
||||
},
|
||||
"updated_at": "2014-10-24T20:15:27.000000",
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096648",
|
||||
"name": "example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-10-24T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "A"
|
||||
}
|
||||
"description": "I updated this example.",
|
||||
"ttl": 60,
|
||||
"records": [
|
||||
"10.1.0.2"
|
||||
],
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096648"
|
||||
},
|
||||
"updated_at": "2014-10-24T20:15:27.000000",
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096648",
|
||||
"name": "example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-10-24T19:59:44.000000",
|
||||
"version": 2,
|
||||
"type": "A"
|
||||
}
|
||||
|
||||
:form description: UTF-8 text field
|
||||
@ -334,18 +324,16 @@ Create MX Record Set
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset" : {
|
||||
"name" : "mail.example.org.",
|
||||
"description" : "An MX recordset.",
|
||||
"type" : "MX",
|
||||
"ttl" : 3600,
|
||||
"records" : [
|
||||
"name" : "mail.example.org.",
|
||||
"description" : "An MX recordset.",
|
||||
"type" : "MX",
|
||||
"ttl" : 3600,
|
||||
"records" : [
|
||||
"10 mail1.example.org.",
|
||||
"20 mail2.example.org.",
|
||||
"30 mail3.example.org.",
|
||||
"40 mail4.example.org."
|
||||
]
|
||||
}
|
||||
"20 mail2.example.org.",
|
||||
"30 mail3.example.org.",
|
||||
"40 mail4.example.org."
|
||||
]
|
||||
}
|
||||
|
||||
**Example response:**
|
||||
@ -356,26 +344,24 @@ Create MX Record Set
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset": {
|
||||
"description": "An MX recordset.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096649"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records" : [
|
||||
"10 mail1.example.org.",
|
||||
"20 mail2.example.org.",
|
||||
"30 mail3.example.org.",
|
||||
"40 mail4.example.org."
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096649",
|
||||
"name": "mail.example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-10-25T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "MX"
|
||||
}
|
||||
"description": "An MX recordset.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096649"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records" : [
|
||||
"10 mail1.example.org.",
|
||||
"20 mail2.example.org.",
|
||||
"30 mail3.example.org.",
|
||||
"40 mail4.example.org."
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096649",
|
||||
"name": "mail.example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-10-25T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "MX"
|
||||
}
|
||||
|
||||
|
||||
@ -405,7 +391,6 @@ Create SSHFP Record Set
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset" : {
|
||||
"name" : "foo.example.org.",
|
||||
"description" : "An SSHFP recordset.",
|
||||
"type" : "SSHFP",
|
||||
@ -413,7 +398,6 @@ Create SSHFP Record Set
|
||||
"records" : [
|
||||
"1 2 aa2df857dc65c5359f02ca75ec5c4308c0100594d931e8d243a42f586257b5e8"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
**Example response:**
|
||||
@ -424,23 +408,21 @@ Create SSHFP Record Set
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset": {
|
||||
"description": "An SSHFP recordset.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096650"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records" : [
|
||||
"1 2 aa2df857dc65c5359f02ca75ec5c4308c0100594d931e8d243a42f586257b5e8"
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096650",
|
||||
"name": "foo.example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-11-10T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "SSHFP"
|
||||
}
|
||||
"description": "An SSHFP recordset.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096650"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records" : [
|
||||
"1 2 aa2df857dc65c5359f02ca75ec5c4308c0100594d931e8d243a42f586257b5e8"
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096650",
|
||||
"name": "foo.example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-11-10T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "SSHFP"
|
||||
}
|
||||
|
||||
|
||||
@ -470,7 +452,6 @@ Create SPF Record Set
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset" : {
|
||||
"name" : "foospf.example.org.",
|
||||
"description" : "An SPF recordset.",
|
||||
"type" : "SPF",
|
||||
@ -478,7 +459,6 @@ Create SPF Record Set
|
||||
"records" : [
|
||||
"v=spf1 +all"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
**Example response:**
|
||||
@ -489,23 +469,21 @@ Create SPF Record Set
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset": {
|
||||
"description": "An SPF recordset.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096651"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records" : [
|
||||
"v=spf1 +all"
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096651",
|
||||
"name": "foospf.example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-11-10T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "SPF"
|
||||
}
|
||||
"description": "An SPF recordset.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096651"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records" : [
|
||||
"v=spf1 +all"
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096651",
|
||||
"name": "foospf.example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-11-10T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "SPF"
|
||||
}
|
||||
|
||||
|
||||
@ -535,7 +513,6 @@ Create SRV Record Set
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset" : {
|
||||
"name" : "_sip.tcp.example.org.",
|
||||
"description" : "An SRV recordset.",
|
||||
"type" : "SRV",
|
||||
@ -543,7 +520,6 @@ Create SRV Record Set
|
||||
"records" : [
|
||||
"10 0 5060 server1.example.org."
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
**Example response:**
|
||||
@ -554,23 +530,21 @@ Create SRV Record Set
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"recordset": {
|
||||
"description": "An SRV recordset.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096652"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records" : [
|
||||
"10 0 5060 server1.example.org."
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096652",
|
||||
"name": "_sip.tcp.example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-11-10T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "SRV"
|
||||
}
|
||||
"description": "An SRV recordset.",
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets/f7b10e9b-0cae-4a91-b162-562bc6096652"
|
||||
},
|
||||
"updated_at": null,
|
||||
"records" : [
|
||||
"10 0 5060 server1.example.org."
|
||||
],
|
||||
"ttl": 3600,
|
||||
"id": "f7b10e9b-0cae-4a91-b162-562bc6096652",
|
||||
"name": "_sip.tcp.example.org.",
|
||||
"zone_id": "2150b1bf-dee2-4221-9d85-11f7886fb15f",
|
||||
"created_at": "2014-11-10T19:59:44.000000",
|
||||
"version": 1,
|
||||
"type": "SRV"
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,10 +55,8 @@ Create Tld
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"tld" : {
|
||||
"name" : "com",
|
||||
"description" : "Tld source http://data.iana.org/TLD/tlds-alpha-by-domain.txt"
|
||||
}
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
@ -70,7 +68,6 @@ Create Tld
|
||||
Location: http://127.0.0.1:9001/v2/tlds/5abe514c-9fb5-41e8-ab73-5ed25f8a73e9
|
||||
|
||||
{
|
||||
"tld":{
|
||||
"description":"Tld source http://data.iana.org/TLD/tlds-alpha-by-domain.txt",
|
||||
"links":{
|
||||
"self":"http://127.0.0.1:9001/v2/tlds/5abe514c-9fb5-41e8-ab73-5ed25f8a73e9"
|
||||
@ -79,7 +76,6 @@ Create Tld
|
||||
"updated_at":null,
|
||||
"id":"5abe514c-9fb5-41e8-ab73-5ed25f8a73e9",
|
||||
"name":"com"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -117,7 +113,6 @@ Get a Tld
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
{
|
||||
"tld":{
|
||||
"description":"Tld source http://data.iana.org/TLD/tlds-alpha-by-domain.txt",
|
||||
"links":{
|
||||
"self":"http://127.0.0.1:9001/v2/tlds/5abe514c-9fb5-41e8-ab73-5ed25f8a73e9"
|
||||
@ -126,7 +121,6 @@ Get a Tld
|
||||
"updated_at":null,
|
||||
"id":"5abe514c-9fb5-41e8-ab73-5ed25f8a73e9",
|
||||
"name":"com"
|
||||
}
|
||||
}
|
||||
|
||||
:form created_at: timestamp
|
||||
@ -215,10 +209,8 @@ Update a Tld
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"tld" : {
|
||||
"name" : "org",
|
||||
"description" : "Updated the name from com to org"
|
||||
}
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
@ -229,7 +221,6 @@ Update a Tld
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
{
|
||||
"tld":{
|
||||
"description":"Updated the name from com to org",
|
||||
"links":{
|
||||
"self":"http://127.0.0.1:9001/v2/tlds/5abe514c-9fb5-41e8-ab73-5ed25f8a73e9"
|
||||
@ -238,7 +229,6 @@ Update a Tld
|
||||
"updated_at":"2014-01-23T20:35:12.449599",
|
||||
"id":"5abe514c-9fb5-41e8-ab73-5ed25f8a73e9",
|
||||
"name":"org"
|
||||
}
|
||||
}
|
||||
|
||||
:form created_at: timestamp
|
||||
|
@ -37,12 +37,10 @@ Create Zone
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"zone": {
|
||||
"name": "example.org.",
|
||||
"email": "joe@example.org",
|
||||
"ttl": 7200,
|
||||
"description": "This is an example zone."
|
||||
}
|
||||
}
|
||||
|
||||
**Example response:**
|
||||
@ -53,7 +51,6 @@ Create Zone
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"zone": {
|
||||
"id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
|
||||
"pool_id": "572ba08c-d929-4c70-8e42-03824bb24ca2",
|
||||
"project_id": "4335d1f0-f793-11e2-b778-0800200c9a66",
|
||||
@ -72,7 +69,6 @@ Create Zone
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:form description: UTF-8 text field.
|
||||
@ -112,7 +108,6 @@ Get Zone
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"zone": {
|
||||
"id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
|
||||
"pool_id": "572ba08c-d929-4c70-8e42-03824bb24ca2",
|
||||
"project_id": "4335d1f0-f793-11e2-b778-0800200c9a66",
|
||||
@ -131,7 +126,6 @@ Get Zone
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:statuscode 200: Success
|
||||
@ -229,9 +223,7 @@ Update Zone
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"zone": {
|
||||
"ttl": 3600
|
||||
}
|
||||
}
|
||||
|
||||
**Response:**
|
||||
@ -242,7 +234,6 @@ Update Zone
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"zone": {
|
||||
"id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
|
||||
"pool_id": "572ba08c-d929-4c70-8e42-03824bb24ca2",
|
||||
"project_id": "4335d1f0-f793-11e2-b778-0800200c9a66",
|
||||
@ -261,7 +252,6 @@ Update Zone
|
||||
"links": {
|
||||
"self": "https://127.0.0.1:9001/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:form description: UTF-8 text field.
|
||||
@ -334,24 +324,22 @@ Import Zone
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"zone": {
|
||||
"email": "nsadmin@example.com",
|
||||
"id": "6b78734a-aef1-45cd-9708-8eb3c2d26ff1",
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/zones/6b78734a-aef1-45cd-9708-8eb3c2d26ff1"
|
||||
},
|
||||
"name": "example.com.",
|
||||
"pool_id": "572ba08c-d929-4c70-8e42-03824bb24ca2",
|
||||
"project_id": "d7accc2f8ce343318386886953f2fc6a",
|
||||
"serial": 1404757531,
|
||||
"ttl": "42",
|
||||
"created_at": "2014-07-07T18:25:31.275934",
|
||||
"updated_at": null,
|
||||
"version": 1,
|
||||
"masters": [],
|
||||
"type": "PRIMARY",
|
||||
"transferred_at": null
|
||||
}
|
||||
"email": "nsadmin@example.com",
|
||||
"id": "6b78734a-aef1-45cd-9708-8eb3c2d26ff1",
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/zones/6b78734a-aef1-45cd-9708-8eb3c2d26ff1"
|
||||
},
|
||||
"name": "example.com.",
|
||||
"pool_id": "572ba08c-d929-4c70-8e42-03824bb24ca2",
|
||||
"project_id": "d7accc2f8ce343318386886953f2fc6a",
|
||||
"serial": 1404757531,
|
||||
"ttl": "42",
|
||||
"created_at": "2014-07-07T18:25:31.275934",
|
||||
"updated_at": null,
|
||||
"version": 1,
|
||||
"masters": [],
|
||||
"type": "PRIMARY",
|
||||
"transferred_at": null
|
||||
}
|
||||
|
||||
:statuscode 201: Created
|
||||
@ -465,10 +453,8 @@ Create Zone Transfer Request
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"transfer_request":{
|
||||
"target_project_id": "123456",
|
||||
"description": "Transfer qa.dev.example.com. to QA Team"
|
||||
}
|
||||
"target_project_id": "123456",
|
||||
"description": "Transfer qa.dev.example.com. to QA Team"
|
||||
}
|
||||
|
||||
**Example Response**
|
||||
@ -479,20 +465,18 @@ Create Zone Transfer Request
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"transfer_request": {
|
||||
"created_at": "2014-07-17T20:34:40.882579",
|
||||
"description": null,
|
||||
"id": "f2ad17b5-807a-423f-a991-e06236c247be",
|
||||
"key": "9Z2R50Y0",
|
||||
"project_id": "1",
|
||||
"status": "ACTIVE",
|
||||
"target_project_id": "123456",
|
||||
"updated_at": null,
|
||||
"zone_id": "6b78734a-aef1-45cd-9708-8eb3c2d26ff8",
|
||||
"zone_name": "qa.dev.example.com.",
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/zones/tasks/transfer_requests/f2ad17b5-807a-423f-a991-e06236c247be"
|
||||
}
|
||||
"created_at": "2014-07-17T20:34:40.882579",
|
||||
"description": null,
|
||||
"id": "f2ad17b5-807a-423f-a991-e06236c247be",
|
||||
"key": "9Z2R50Y0",
|
||||
"project_id": "1",
|
||||
"status": "ACTIVE",
|
||||
"target_project_id": "123456",
|
||||
"updated_at": null,
|
||||
"zone_id": "6b78734a-aef1-45cd-9708-8eb3c2d26ff8",
|
||||
"zone_name": "qa.dev.example.com.",
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/zones/tasks/transfer_requests/f2ad17b5-807a-423f-a991-e06236c247be"
|
||||
}
|
||||
}
|
||||
|
||||
@ -583,15 +567,13 @@ View a Transfer Request
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"transfer_request":{
|
||||
"description": "This is scoped to the requesting project",
|
||||
"id": "efd2d720-b0c4-43d4-99f7-d9b53e08860d",
|
||||
"zone_id": "2c4d5e37-f823-4bee-9859-031cb44f80e7",
|
||||
"zone_name": "subdomain.example.com.",
|
||||
"status": "ACTIVE",
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/zones/tasks/transfer_requests/efd2d720-b0c4-43d4-99f7-d9b53e08860d"
|
||||
}
|
||||
"description": "This is scoped to the requesting project",
|
||||
"id": "efd2d720-b0c4-43d4-99f7-d9b53e08860d",
|
||||
"zone_id": "2c4d5e37-f823-4bee-9859-031cb44f80e7",
|
||||
"zone_name": "subdomain.example.com.",
|
||||
"status": "ACTIVE",
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/zones/tasks/transfer_requests/efd2d720-b0c4-43d4-99f7-d9b53e08860d"
|
||||
}
|
||||
}
|
||||
|
||||
@ -616,10 +598,8 @@ Accept a Transfer Request
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"transfer_accept":{
|
||||
"key":"9Z2R50Y0",
|
||||
"zone_transfer_request_id":"f2ad17b5-807a-423f-a991-e06236c247be"
|
||||
}
|
||||
"key":"9Z2R50Y0",
|
||||
"zone_transfer_request_id":"f2ad17b5-807a-423f-a991-e06236c247be"
|
||||
}
|
||||
|
||||
**Example Response**
|
||||
@ -630,13 +610,11 @@ Accept a Transfer Request
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"transfer_accept": {
|
||||
"id": "581891d5-99f5-49e1-86c3-eec0f44d66fd",
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/zones/tasks/transfer_accepts/581891d5-99f5-49e1-86c3-eec0f44d66fd",
|
||||
"zone": "http://127.0.0.1:9001/v2/zones/6b78734a-aef1-45cd-9708-8eb3c2d26ff8"
|
||||
},
|
||||
"status": "COMPLETE"
|
||||
}
|
||||
"id": "581891d5-99f5-49e1-86c3-eec0f44d66fd",
|
||||
"links": {
|
||||
"self": "http://127.0.0.1:9001/v2/zones/tasks/transfer_accepts/581891d5-99f5-49e1-86c3-eec0f44d66fd",
|
||||
"zone": "http://127.0.0.1:9001/v2/zones/6b78734a-aef1-45cd-9708-8eb3c2d26ff8"
|
||||
},
|
||||
"status": "COMPLETE"
|
||||
}
|
||||
|
||||
|
@ -16,18 +16,12 @@ limitations under the License.
|
||||
|
||||
from functionaltests.common.models import BaseModel
|
||||
from functionaltests.common.models import CollectionModel
|
||||
from functionaltests.common.models import EntityModel
|
||||
|
||||
|
||||
class ZoneData(BaseModel):
|
||||
class ZoneModel(BaseModel):
|
||||
pass
|
||||
|
||||
|
||||
class ZoneModel(EntityModel):
|
||||
ENTITY_NAME = 'zone'
|
||||
MODEL_TYPE = ZoneData
|
||||
|
||||
|
||||
class ZoneListModel(CollectionModel):
|
||||
COLLECTION_NAME = 'zones'
|
||||
MODEL_TYPE = ZoneData
|
||||
MODEL_TYPE = ZoneModel
|
||||
|
Loading…
Reference in New Issue
Block a user