Enable use of Pools YAML
This change adds the tooling to use the DB Tables created for pool config data and the tooling to migrate the config info itself. Change-Id: If99dbf527ef1ac0f05f15fe77f68f64e357fe0a5
This commit is contained in:
parent
1375a45a71
commit
e612a3974f
@ -16,6 +16,7 @@ import pecan
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate import utils
|
||||
from designate.i18n import _LW
|
||||
from designate.api.v2.controllers import rest
|
||||
from designate.objects import Pool
|
||||
from designate.objects.adapters import DesignateAdapter
|
||||
@ -63,6 +64,11 @@ class PoolsController(rest.RestController):
|
||||
@pecan.expose(template='json:', content_type='application/json')
|
||||
def post_all(self):
|
||||
"""Create a Pool"""
|
||||
|
||||
LOG.warning(_LW("Use of this API Method is DEPRICATED. This will have "
|
||||
"unforseen side affects when used with the "
|
||||
"designate-manage pool commands"))
|
||||
|
||||
request = pecan.request
|
||||
response = pecan.response
|
||||
context = request.environ['context']
|
||||
@ -86,6 +92,11 @@ class PoolsController(rest.RestController):
|
||||
@utils.validate_uuid('pool_id')
|
||||
def patch_one(self, pool_id):
|
||||
"""Update the specific pool"""
|
||||
|
||||
LOG.warning(_LW("Use of this API Method is DEPRICATED. This will have "
|
||||
"unforseen side affects when used with the "
|
||||
"designate-manage pool commands"))
|
||||
|
||||
request = pecan.request
|
||||
context = request.environ['context']
|
||||
body = request.body_dict
|
||||
@ -111,6 +122,11 @@ class PoolsController(rest.RestController):
|
||||
@utils.validate_uuid('pool_id')
|
||||
def delete_one(self, pool_id):
|
||||
"""Delete the specific pool"""
|
||||
|
||||
LOG.warning(_LW("Use of this API Method is DEPRICATED. This will have "
|
||||
"unforseen side affects when used with the "
|
||||
"designate-manage pool commands"))
|
||||
|
||||
request = pecan.request
|
||||
response = pecan.response
|
||||
context = request.environ['context']
|
||||
|
@ -13,24 +13,172 @@
|
||||
# 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 pprint
|
||||
|
||||
import yaml
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
import oslo_messaging as messaging
|
||||
|
||||
from designate.manage import base
|
||||
from designate import exceptions
|
||||
from designate import rpc
|
||||
from designate.i18n import _LI
|
||||
from designate.i18n import _LC
|
||||
from designate import objects
|
||||
from designate.central import rpcapi as central_rpcapi
|
||||
from designate.manage import base
|
||||
from designate.objects.adapters import DesignateAdapter
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class PoolCommands(base.Commands):
|
||||
def __init__(self):
|
||||
super(PoolCommands, self).__init__()
|
||||
rpc.init(cfg.CONF)
|
||||
self.central_api = central_rpcapi.CentralAPI()
|
||||
|
||||
@base.args('--file', help='The path to the file the yaml output should be '
|
||||
'writen to',
|
||||
default='/etc/designate/pools.yaml')
|
||||
def generate_file(self, file):
|
||||
try:
|
||||
pools = self.central_api.find_pools(self.context)
|
||||
except messaging.exceptions.MessagingTimeout:
|
||||
LOG.critical(_LC("No response recieved from designate-central. "
|
||||
"Check it is running, and retry"))
|
||||
with open(file, 'w') as stream:
|
||||
yaml.dump(
|
||||
DesignateAdapter.render('YAML', pools),
|
||||
stream,
|
||||
default_flow_style=False
|
||||
)
|
||||
|
||||
@base.args('--file', help='The path to the file the yaml output should be '
|
||||
'writen to',
|
||||
default='/etc/designate/pools.yaml')
|
||||
def export_from_config(self, file):
|
||||
try:
|
||||
pools = self.central_api.find_pools(self.context)
|
||||
except messaging.exceptions.MessagingTimeout:
|
||||
LOG.critical(_LC("No response recieved from designate-central. "
|
||||
"Check it is running, and retry"))
|
||||
r_pools = objects.PoolList()
|
||||
for pool in pools:
|
||||
r_pool = objects.Pool.from_config(CONF, pool.id)
|
||||
r_pool.id = pool.id
|
||||
r_pool.ns_records = pool.ns_records
|
||||
r_pool.attributes = pool.attributes
|
||||
r_pools.append(r_pool)
|
||||
with open(file, 'w') as stream:
|
||||
yaml.dump(
|
||||
DesignateAdapter.render('YAML', r_pools),
|
||||
stream,
|
||||
default_flow_style=False
|
||||
)
|
||||
|
||||
@base.args('--pool_id', help='ID of the pool to be examined',
|
||||
default=CONF['service:central'].default_pool_id)
|
||||
default=CONF['service:central'].default_pool_id)
|
||||
def show_config(self, pool_id):
|
||||
print('*' * 100)
|
||||
print('Pool Configuration:')
|
||||
print('*' * 100)
|
||||
pprint.pprint(objects.Pool.from_config(CONF, pool_id).to_dict())
|
||||
try:
|
||||
pool = self.central_api.find_pool(self.context, {"id": pool_id})
|
||||
|
||||
print('Pool Configuration:')
|
||||
print('-------------------')
|
||||
|
||||
print(yaml.dump(DesignateAdapter.render('YAML', pool),
|
||||
default_flow_style=False))
|
||||
|
||||
except messaging.exceptions.MessagingTimeout:
|
||||
LOG.critical(_LC("No response recieved from designate-central. "
|
||||
"Check it is running, and retry"))
|
||||
|
||||
@base.args('--file', help='The path to the yaml file describing the pools',
|
||||
default='/etc/designate/pools.yaml')
|
||||
@base.args(
|
||||
'--delete',
|
||||
help='Any Pools not listed in the config file will be deleted. '
|
||||
' WARNING: This will delete any zones left in this pool',
|
||||
default=False)
|
||||
@base.args(
|
||||
'--dry_run',
|
||||
help='This will simulate what will happen when you run this command',
|
||||
default=False)
|
||||
def update(self, file, delete, dry_run):
|
||||
print('Updating Pools Configuration')
|
||||
print('****************************')
|
||||
|
||||
output_msg = ['']
|
||||
|
||||
with open(file, 'r') as stream:
|
||||
xpools = yaml.safe_load(stream)
|
||||
|
||||
if dry_run:
|
||||
output_msg.append("The following changes will occur:")
|
||||
output_msg.append("*********************************")
|
||||
|
||||
for xpool in xpools:
|
||||
try:
|
||||
if 'id' in xpool:
|
||||
try:
|
||||
pool = self.central_api.get_pool(
|
||||
self.context, xpool['id'])
|
||||
except Exception:
|
||||
LOG.critical(
|
||||
_LC("Bad ID Supplied for pool %s"), xpool['name'])
|
||||
continue
|
||||
else:
|
||||
pool = self.central_api.find_pool(
|
||||
self.context, {"name": xpool['name']})
|
||||
|
||||
LOG.info(_LI('Updating existing pool: %s'), pool)
|
||||
|
||||
# TODO(kiall): Move the below into the pool object
|
||||
|
||||
pool = DesignateAdapter.parse('YAML', xpool, pool)
|
||||
|
||||
if dry_run:
|
||||
output_msg.append("Update Pool: %s" % pool)
|
||||
else:
|
||||
pool = self.central_api.update_pool(self.context, pool)
|
||||
|
||||
except exceptions.PoolNotFound:
|
||||
pool = DesignateAdapter.parse('YAML', xpool, objects.Pool())
|
||||
# pool = objects.Pool.from_dict(xpool)
|
||||
if dry_run:
|
||||
output_msg.append("Create Pool: %s" % pool)
|
||||
else:
|
||||
LOG.info(_LI('Creating new pool: %s'), pool)
|
||||
self.central_api.create_pool(self.context, pool)
|
||||
except messaging.exceptions.MessagingTimeout:
|
||||
LOG.critical(_LC("No response recieved from designate-central."
|
||||
" Check it is running, and retry"))
|
||||
|
||||
if delete:
|
||||
pools = self.central_api.find_pools(self.context)
|
||||
pools_in_db = {pool.name for pool in pools}
|
||||
pools_in_yaml = {xpool['name'] for xpool in xpools}
|
||||
|
||||
pools_to_delete = pools_in_db - pools_in_yaml
|
||||
|
||||
for pool in pools_to_delete:
|
||||
try:
|
||||
p = self.central_api.find_pool(
|
||||
self.context,
|
||||
criterion={'name': pool})
|
||||
|
||||
if dry_run:
|
||||
output_msg.append("Delete Pool: %s" % p)
|
||||
|
||||
else:
|
||||
LOG.info(_LI('Deleting %s'), p)
|
||||
self.central_api.delete_pool(self.context, p.id)
|
||||
|
||||
except messaging.exceptions.MessagingTimeout:
|
||||
LOG.critical(_LC("No response recieved from "
|
||||
"designate-central. "
|
||||
"Check it is running, and retry"))
|
||||
|
||||
for line in output_msg:
|
||||
print(line)
|
||||
|
@ -21,7 +21,9 @@ from oslo_db.sqlalchemy.migration_cli import manager as migration_manager
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.manage import base
|
||||
from designate import rpc
|
||||
from designate import utils
|
||||
from designate.central import rpcapi as central_rpcapi
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -32,33 +34,50 @@ CONF = cfg.CONF
|
||||
utils.register_plugin_opts()
|
||||
|
||||
|
||||
def get_manager(pool_target_id):
|
||||
pool_target_options = CONF['pool_target:%s' % pool_target_id].options
|
||||
connection = pool_target_options['connection']
|
||||
def get_manager(pool_target):
|
||||
connection = pool_target.options.get('connection', None)
|
||||
|
||||
migration_config = {
|
||||
'migration_repo_path': REPOSITORY,
|
||||
'db_url': connection}
|
||||
|
||||
return migration_manager.MigrationManager(migration_config)
|
||||
|
||||
|
||||
class DatabaseCommands(base.Commands):
|
||||
@base.args('pool-target-id', help="Pool Target to Migrate", type=str)
|
||||
def version(self, pool_target_id):
|
||||
current = get_manager(pool_target_id).version()
|
||||
latest = versioning_api.version(repository=REPOSITORY).value
|
||||
print("Current: %s Latest: %s" % (current, latest))
|
||||
def __init__(self):
|
||||
super(DatabaseCommands, self).__init__()
|
||||
rpc.init(cfg.CONF)
|
||||
self.central_api = central_rpcapi.CentralAPI()
|
||||
|
||||
@base.args('pool-target-id', help="Pool Target to Migrate", type=str)
|
||||
def sync(self, pool_target_id):
|
||||
get_manager(pool_target_id).upgrade(None)
|
||||
@base.args('pool-id', help="Pool to Migrate", type=str)
|
||||
def version(self, pool_id):
|
||||
pool = self.central_api.find_pool(self.context, {"id": pool_id})
|
||||
|
||||
@base.args('pool-target-id', help="Pool Target to Migrate", type=str)
|
||||
for pool_target in pool.targets:
|
||||
current = get_manager(pool_target).version()
|
||||
latest = versioning_api.version(repository=REPOSITORY).value
|
||||
print("Current: %s Latest: %s" % (current, latest))
|
||||
|
||||
@base.args('pool-id', help="Pool to Migrate", type=str)
|
||||
def sync(self, pool_id):
|
||||
pool = self.central_api.find_pool(self.context, {"id": pool_id})
|
||||
|
||||
for pool_target in pool.targets:
|
||||
get_manager(pool_target).upgrade(None)
|
||||
|
||||
@base.args('pool-id', help="Pool to Migrate", type=str)
|
||||
@base.args('revision', nargs='?')
|
||||
def upgrade(self, pool_target_id, revision):
|
||||
get_manager(pool_target_id).upgrade(revision)
|
||||
def upgrade(self, pool_id, revision):
|
||||
pool = self.central_api.find_pool(self.context, {"id": pool_id})
|
||||
|
||||
@base.args('pool-target-id', help="Pool Target to Migrate", type=str)
|
||||
for pool_target in pool.targets:
|
||||
get_manager(pool_target).upgrade(revision)
|
||||
|
||||
@base.args('pool-id', help="Pool to Migrate", type=str)
|
||||
@base.args('revision', nargs='?')
|
||||
def downgrade(self, pool_target_id, revision):
|
||||
get_manager(pool_target_id).downgrade(revision)
|
||||
def downgrade(self, pool_id, revision):
|
||||
pool = self.central_api.find_pool(self.context, {"id": pool_id})
|
||||
|
||||
for pool_target in pool.targets:
|
||||
get_manager(pool_target).downgrade(revision)
|
||||
|
@ -32,3 +32,14 @@ from designate.objects.adapters.api_v2.zone_transfer_request import ZoneTransfer
|
||||
from designate.objects.adapters.api_v2.validation_error import ValidationErrorAPIv2Adapter, ValidationErrorListAPIv2Adapter # noqa
|
||||
from designate.objects.adapters.api_v2.zone_import import ZoneImportAPIv2Adapter, ZoneImportListAPIv2Adapter # noqa
|
||||
from designate.objects.adapters.api_v2.zone_export import ZoneExportAPIv2Adapter, ZoneExportListAPIv2Adapter # noqa
|
||||
|
||||
# YAML
|
||||
|
||||
from designate.objects.adapters.yaml.pool import PoolYAMLAdapter, PoolListYAMLAdapter # noqa
|
||||
from designate.objects.adapters.yaml.pool_attribute import PoolAttributeYAMLAdapter, PoolAttributeListYAMLAdapter # noqa
|
||||
from designate.objects.adapters.yaml.pool_also_notify import PoolAlsoNotifyYAMLAdapter, PoolAlsoNotifyListYAMLAdapter # noqa
|
||||
from designate.objects.adapters.yaml.pool_nameserver import PoolNameserverYAMLAdapter, PoolNameserverListYAMLAdapter # noqa
|
||||
from designate.objects.adapters.yaml.pool_ns_record import PoolNsRecordYAMLAdapter, PoolNsRecordListYAMLAdapter # noqa
|
||||
from designate.objects.adapters.yaml.pool_target import PoolTargetYAMLAdapter, PoolTargetListYAMLAdapter # noqa
|
||||
from designate.objects.adapters.yaml.pool_target_master import PoolTargetMasterYAMLAdapter, PoolTargetMasterListYAMLAdapter # noqa
|
||||
from designate.objects.adapters.yaml.pool_target_option import PoolTargetOptionYAMLAdapter, PoolTargetOptionListYAMLAdapter # noqa
|
||||
|
0
designate/objects/adapters/yaml/__init__.py
Normal file
0
designate/objects/adapters/yaml/__init__.py
Normal file
81
designate/objects/adapters/yaml/base.py
Normal file
81
designate/objects/adapters/yaml/base.py
Normal file
@ -0,0 +1,81 @@
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
#
|
||||
# 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.objects.adapters import base
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class YAMLAdapter(base.DesignateAdapter):
|
||||
|
||||
ADAPTER_FORMAT = 'YAML'
|
||||
|
||||
#####################
|
||||
# Parsing methods #
|
||||
#####################
|
||||
|
||||
@classmethod
|
||||
def parse(cls, values, output_object, *args, **kwargs):
|
||||
obj = super(YAMLAdapter, cls).parse(
|
||||
cls.ADAPTER_FORMAT, values, output_object, *args, **kwargs)
|
||||
return obj
|
||||
|
||||
@classmethod
|
||||
def _render_object(cls, object, *args, **kwargs):
|
||||
# The dict we will return to be rendered to JSON / output format
|
||||
r_obj = {}
|
||||
# Loop over all fields that are supposed to be output
|
||||
for key, value in cls.MODIFICATIONS['fields'].items():
|
||||
# Get properties for this field
|
||||
field_props = cls.MODIFICATIONS['fields'][key]
|
||||
# Check if it has to be renamed
|
||||
if field_props.get('rename', False):
|
||||
obj = getattr(object, field_props.get('rename'))
|
||||
# if rename is specified we need to change the key
|
||||
obj_key = field_props.get('rename')
|
||||
else:
|
||||
# if not, move on
|
||||
obj = getattr(object, key, None)
|
||||
obj_key = key
|
||||
# Check if this item is a relation (another DesignateObject that
|
||||
# will need to be converted itself
|
||||
if object.FIELDS.get(obj_key, {}).get('relation'):
|
||||
# Get a adapter for the nested object
|
||||
# Get the class the object is and get its adapter, then set
|
||||
# the item in the dict to the output
|
||||
r_obj[key] = cls.get_object_adapter(
|
||||
cls.ADAPTER_FORMAT,
|
||||
object.FIELDS[obj_key].get('relation_cls')).render(
|
||||
cls.ADAPTER_FORMAT, obj, *args, **kwargs)
|
||||
elif object.FIELDS.get(
|
||||
obj_key, {}).get('schema', {}).get('type') == 'integer':
|
||||
r_obj[key] = int(obj)
|
||||
elif obj is not None:
|
||||
# Just attach the damn item if there is no weird edge cases
|
||||
r_obj[key] = str(obj)
|
||||
# Send it back
|
||||
return r_obj
|
||||
|
||||
@classmethod
|
||||
def _render_list(cls, list_object, *args, **kwargs):
|
||||
# The list we will return to be rendered to JSON / output format
|
||||
r_list = []
|
||||
# iterate and convert each DesignateObject in the list, and append to
|
||||
# the object we are returning
|
||||
for object in list_object:
|
||||
r_list.append(cls.get_object_adapter(
|
||||
cls.ADAPTER_FORMAT,
|
||||
object).render(cls.ADAPTER_FORMAT, object, *args, **kwargs))
|
||||
return r_list
|
59
designate/objects/adapters/yaml/pool.py
Normal file
59
designate/objects/adapters/yaml/pool.py
Normal file
@ -0,0 +1,59 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.objects.adapters.yaml import base
|
||||
from designate import objects
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PoolYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.Pool
|
||||
|
||||
MODIFICATIONS = {
|
||||
'fields': {
|
||||
'id': {
|
||||
'read_only': False
|
||||
},
|
||||
'name': {
|
||||
'read_only': False
|
||||
},
|
||||
'description': {
|
||||
'read_only': False
|
||||
},
|
||||
'attributes': {
|
||||
'read_only': False
|
||||
},
|
||||
'ns_records': {
|
||||
'read_only': False
|
||||
},
|
||||
'nameservers': {
|
||||
'read_only': False
|
||||
},
|
||||
'targets': {
|
||||
'read_only': False
|
||||
},
|
||||
'also_notifies': {
|
||||
'read_only': False
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PoolListYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolList
|
||||
|
||||
MODIFICATIONS = {}
|
41
designate/objects/adapters/yaml/pool_also_notify.py
Normal file
41
designate/objects/adapters/yaml/pool_also_notify.py
Normal file
@ -0,0 +1,41 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.objects.adapters.yaml import base
|
||||
from designate import objects
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PoolAlsoNotifyYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolAlsoNotify
|
||||
|
||||
MODIFICATIONS = {
|
||||
'fields': {
|
||||
'host': {
|
||||
'read_only': False
|
||||
},
|
||||
'port': {
|
||||
'read_only': False
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PoolAlsoNotifyListYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolAlsoNotifyList
|
||||
|
||||
MODIFICATIONS = {}
|
86
designate/objects/adapters/yaml/pool_attribute.py
Normal file
86
designate/objects/adapters/yaml/pool_attribute.py
Normal file
@ -0,0 +1,86 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 six
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.objects.adapters.yaml import base
|
||||
from designate import objects
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PoolAttributeYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolAttribute
|
||||
|
||||
MODIFICATIONS = {
|
||||
'fields': {
|
||||
'key': {
|
||||
'read_only': False
|
||||
},
|
||||
'value': {
|
||||
'read_only': False
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def _render_object(cls, object, *arg, **kwargs):
|
||||
return {str(object.key): str(object.value)}
|
||||
|
||||
@classmethod
|
||||
def _parse_object(cls, values, object, *args, **kwargs):
|
||||
for key in six.iterkeys(values):
|
||||
object.key = key
|
||||
object.value = values[key]
|
||||
|
||||
return object
|
||||
|
||||
|
||||
class PoolAttributeListYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolAttributeList
|
||||
|
||||
MODIFICATIONS = {}
|
||||
|
||||
@classmethod
|
||||
def _render_list(cls, list_object, *args, **kwargs):
|
||||
|
||||
r_list = {}
|
||||
|
||||
for object in list_object:
|
||||
value = cls.get_object_adapter(
|
||||
cls.ADAPTER_FORMAT,
|
||||
object).render(cls.ADAPTER_FORMAT, object, *args, **kwargs)
|
||||
for key in six.iterkeys(value):
|
||||
r_list[key] = value[key]
|
||||
|
||||
return r_list
|
||||
|
||||
@classmethod
|
||||
def _parse_list(cls, values, output_object, *args, **kwargs):
|
||||
|
||||
for key, value in values.items():
|
||||
# Add the object to the list
|
||||
output_object.append(
|
||||
# Get the right Adapter
|
||||
cls.get_object_adapter(
|
||||
cls.ADAPTER_FORMAT,
|
||||
# This gets the internal type of the list, and parses it
|
||||
# We need to do `get_object_adapter` as we need a new
|
||||
# instance of the Adapter
|
||||
output_object.LIST_ITEM_TYPE()).parse(
|
||||
{key: value}, output_object.LIST_ITEM_TYPE()))
|
||||
|
||||
# Return the filled list
|
||||
return output_object
|
41
designate/objects/adapters/yaml/pool_nameserver.py
Normal file
41
designate/objects/adapters/yaml/pool_nameserver.py
Normal file
@ -0,0 +1,41 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.objects.adapters.yaml import base
|
||||
from designate import objects
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PoolNameserverYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolNameserver
|
||||
|
||||
MODIFICATIONS = {
|
||||
'fields': {
|
||||
'host': {
|
||||
'read_only': False
|
||||
},
|
||||
'port': {
|
||||
'read_only': False
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PoolNameserverListYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolNameserverList
|
||||
|
||||
MODIFICATIONS = {}
|
41
designate/objects/adapters/yaml/pool_ns_record.py
Normal file
41
designate/objects/adapters/yaml/pool_ns_record.py
Normal file
@ -0,0 +1,41 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.objects.adapters.yaml import base
|
||||
from designate import objects
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PoolNsRecordYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolNsRecord
|
||||
|
||||
MODIFICATIONS = {
|
||||
'fields': {
|
||||
'priority': {
|
||||
'read_only': False
|
||||
},
|
||||
'hostname': {
|
||||
'read_only': False
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PoolNsRecordListYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolNsRecordList
|
||||
|
||||
MODIFICATIONS = {}
|
50
designate/objects/adapters/yaml/pool_target.py
Normal file
50
designate/objects/adapters/yaml/pool_target.py
Normal file
@ -0,0 +1,50 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.objects.adapters.yaml import base
|
||||
from designate import objects
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PoolTargetYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolTarget
|
||||
|
||||
MODIFICATIONS = {
|
||||
'fields': {
|
||||
'type': {
|
||||
'read_only': False
|
||||
},
|
||||
'tsigkey_id': {
|
||||
'read_only': False
|
||||
},
|
||||
'description': {
|
||||
'read_only': False
|
||||
},
|
||||
'masters': {
|
||||
'read_only': False
|
||||
},
|
||||
'options': {
|
||||
'read_only': False
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PoolTargetListYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolTargetList
|
||||
|
||||
MODIFICATIONS = {}
|
41
designate/objects/adapters/yaml/pool_target_master.py
Normal file
41
designate/objects/adapters/yaml/pool_target_master.py
Normal file
@ -0,0 +1,41 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.objects.adapters.yaml import base
|
||||
from designate import objects
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PoolTargetMasterYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolTargetMaster
|
||||
|
||||
MODIFICATIONS = {
|
||||
'fields': {
|
||||
'host': {
|
||||
'read_only': False
|
||||
},
|
||||
'port': {
|
||||
'read_only': False
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PoolTargetMasterListYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolTargetMasterList
|
||||
|
||||
MODIFICATIONS = {}
|
86
designate/objects/adapters/yaml/pool_target_option.py
Normal file
86
designate/objects/adapters/yaml/pool_target_option.py
Normal file
@ -0,0 +1,86 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 six
|
||||
from oslo_log import log as logging
|
||||
|
||||
from designate.objects.adapters.yaml import base
|
||||
from designate import objects
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PoolTargetOptionYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolTargetOption
|
||||
|
||||
MODIFICATIONS = {
|
||||
'fields': {
|
||||
'key': {
|
||||
'read_only': False
|
||||
},
|
||||
'value': {
|
||||
'read_only': False
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def _render_object(cls, object, *arg, **kwargs):
|
||||
return {str(object.key): str(object.value)}
|
||||
|
||||
@classmethod
|
||||
def _parse_object(cls, values, object, *args, **kwargs):
|
||||
for key in six.iterkeys(values):
|
||||
object.key = key
|
||||
object.value = values[key]
|
||||
|
||||
return object
|
||||
|
||||
|
||||
class PoolTargetOptionListYAMLAdapter(base.YAMLAdapter):
|
||||
|
||||
ADAPTER_OBJECT = objects.PoolTargetOptionList
|
||||
|
||||
MODIFICATIONS = {}
|
||||
|
||||
@classmethod
|
||||
def _render_list(cls, list_object, *args, **kwargs):
|
||||
|
||||
r_list = {}
|
||||
|
||||
for object in list_object:
|
||||
value = cls.get_object_adapter(
|
||||
cls.ADAPTER_FORMAT,
|
||||
object).render(cls.ADAPTER_FORMAT, object, *args, **kwargs)
|
||||
for key in six.iterkeys(value):
|
||||
r_list[key] = value[key]
|
||||
|
||||
return r_list
|
||||
|
||||
@classmethod
|
||||
def _parse_list(cls, values, output_object, *args, **kwargs):
|
||||
|
||||
for key, value in values.items():
|
||||
# Add the object to the list
|
||||
output_object.append(
|
||||
# Get the right Adapter
|
||||
cls.get_object_adapter(
|
||||
cls.ADAPTER_FORMAT,
|
||||
# This gets the internal type of the list, and parses it
|
||||
# We need to do `get_object_adapter` as we need a new
|
||||
# instance of the Adapter
|
||||
output_object.LIST_ITEM_TYPE()).parse(
|
||||
{key: value}, output_object.LIST_ITEM_TYPE()))
|
||||
|
||||
# Return the filled list
|
||||
return output_object
|
@ -18,11 +18,34 @@ from designate.objects import base
|
||||
class PoolAlsoNotify(base.DictObjectMixin, base.PersistentObjectMixin,
|
||||
base.DesignateObject):
|
||||
FIELDS = {
|
||||
'pool_id': {},
|
||||
'host': {},
|
||||
'port': {},
|
||||
'pool_id': {
|
||||
'schema': {
|
||||
'type': 'string',
|
||||
'description': 'Pool identifier',
|
||||
'format': 'uuid',
|
||||
},
|
||||
},
|
||||
'host': {
|
||||
'schema': {
|
||||
'type': 'string',
|
||||
'format': 'ip-or-host',
|
||||
'required': True,
|
||||
},
|
||||
},
|
||||
'port': {
|
||||
'schema': {
|
||||
'type': 'integer',
|
||||
'minimum': 1,
|
||||
'maximum': 65535,
|
||||
'required': True,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
STRING_KEYS = [
|
||||
'id', 'host', 'port', 'pool_id'
|
||||
]
|
||||
|
||||
|
||||
class PoolAlsoNotifyList(base.ListObjectMixin, base.DesignateObject):
|
||||
LIST_ITEM_TYPE = PoolAlsoNotify
|
||||
|
@ -18,11 +18,34 @@ from designate.objects import base
|
||||
class PoolNameserver(base.DictObjectMixin, base.PersistentObjectMixin,
|
||||
base.DesignateObject):
|
||||
FIELDS = {
|
||||
'pool_id': {},
|
||||
'host': {},
|
||||
'port': {},
|
||||
'pool_id': {
|
||||
'schema': {
|
||||
'type': 'string',
|
||||
'description': 'Pool identifier',
|
||||
'format': 'uuid',
|
||||
},
|
||||
},
|
||||
'host': {
|
||||
'schema': {
|
||||
'type': 'string',
|
||||
'format': 'ip-or-host',
|
||||
'required': True,
|
||||
},
|
||||
},
|
||||
'port': {
|
||||
'schema': {
|
||||
'type': 'integer',
|
||||
'minimum': 1,
|
||||
'maximum': 65535,
|
||||
'required': True,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
STRING_KEYS = [
|
||||
'id', 'host', 'port', 'pool_id'
|
||||
]
|
||||
|
||||
|
||||
class PoolNameserverList(base.ListObjectMixin, base.DesignateObject):
|
||||
LIST_ITEM_TYPE = PoolNameserver
|
||||
|
@ -18,11 +18,28 @@ from designate.objects import base
|
||||
class PoolTarget(base.DictObjectMixin, base.PersistentObjectMixin,
|
||||
base.DesignateObject):
|
||||
FIELDS = {
|
||||
'pool_id': {},
|
||||
'pool_id': {
|
||||
'schema': {
|
||||
'type': 'string',
|
||||
'description': 'Pool identifier',
|
||||
'format': 'uuid',
|
||||
},
|
||||
},
|
||||
'type': {},
|
||||
'tsigkey_id': {},
|
||||
'description': {},
|
||||
|
||||
'tsigkey_id': {
|
||||
'schema': {
|
||||
'type': ['string', 'null'],
|
||||
'description': 'TSIG identifier',
|
||||
'format': 'uuid',
|
||||
},
|
||||
},
|
||||
'description': {
|
||||
'schema': {
|
||||
'type': ['string', 'null'],
|
||||
'description': 'Description for the pool',
|
||||
'maxLength': 160
|
||||
}
|
||||
},
|
||||
'masters': {
|
||||
'relation': True,
|
||||
'relation_cls': 'PoolTargetMasterList'
|
||||
@ -33,6 +50,10 @@ class PoolTarget(base.DictObjectMixin, base.PersistentObjectMixin,
|
||||
},
|
||||
}
|
||||
|
||||
STRING_KEYS = [
|
||||
'id', 'type', 'pool_id'
|
||||
]
|
||||
|
||||
|
||||
class PoolTargetList(base.ListObjectMixin, base.DesignateObject):
|
||||
LIST_ITEM_TYPE = PoolTarget
|
||||
|
@ -18,11 +18,34 @@ from designate.objects import base
|
||||
class PoolTargetMaster(base.DictObjectMixin, base.PersistentObjectMixin,
|
||||
base.DesignateObject):
|
||||
FIELDS = {
|
||||
'pool_target_id': {},
|
||||
'host': {},
|
||||
'port': {}
|
||||
'pool_target_id': {
|
||||
'schema': {
|
||||
'type': 'string',
|
||||
'description': 'Pool Target identifier',
|
||||
'format': 'uuid',
|
||||
},
|
||||
},
|
||||
'host': {
|
||||
'schema': {
|
||||
'type': 'string',
|
||||
'format': 'ip-or-host',
|
||||
'required': True,
|
||||
},
|
||||
},
|
||||
'port': {
|
||||
'schema': {
|
||||
'type': 'integer',
|
||||
'minimum': 1,
|
||||
'maximum': 65535,
|
||||
'required': True,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
STRING_KEYS = [
|
||||
'id', 'host', 'port', 'pool_target_id'
|
||||
]
|
||||
|
||||
|
||||
class PoolTargetMasterList(base.ListObjectMixin, base.DesignateObject):
|
||||
LIST_ITEM_TYPE = PoolTargetMaster
|
||||
|
@ -18,11 +18,33 @@ from designate.objects import base
|
||||
class PoolTargetOption(base.DictObjectMixin, base.PersistentObjectMixin,
|
||||
base.DesignateObject):
|
||||
FIELDS = {
|
||||
'pool_target_id': {},
|
||||
'key': {},
|
||||
'value': {},
|
||||
'pool_target_id': {
|
||||
'schema': {
|
||||
'type': 'string',
|
||||
'description': 'Pool Target identifier',
|
||||
'format': 'uuid',
|
||||
},
|
||||
},
|
||||
'key': {
|
||||
'schema': {
|
||||
'type': 'string',
|
||||
'maxLength': 255,
|
||||
},
|
||||
'required': True,
|
||||
},
|
||||
'value': {
|
||||
'schema': {
|
||||
'type': 'string',
|
||||
'maxLength': 255,
|
||||
},
|
||||
'required': True
|
||||
}
|
||||
}
|
||||
|
||||
STRING_KEYS = [
|
||||
'id', 'key', 'value', 'pool_target_id'
|
||||
]
|
||||
|
||||
|
||||
class PoolTargetOptionList(base.AttributeListObjectMixin,
|
||||
base.DesignateObject):
|
||||
|
@ -97,10 +97,6 @@ class Service(service.RPCService, coordination.CoordinationMixin,
|
||||
def __init__(self, threads=None):
|
||||
super(Service, self).__init__(threads=threads)
|
||||
|
||||
# Build the Pool (and related) Object from Config
|
||||
self.pool = objects.Pool.from_config(
|
||||
CONF, CONF['service:pool_manager'].pool_id)
|
||||
|
||||
# Get a pool manager cache connection.
|
||||
self.cache = cache.get_pool_manager_cache(
|
||||
CONF['service:pool_manager'].cache_driver)
|
||||
@ -118,11 +114,8 @@ class Service(service.RPCService, coordination.CoordinationMixin,
|
||||
|
||||
# Compute a time (seconds) by which things should have propagated
|
||||
self.max_prop_time = (self.timeout * self.max_retries +
|
||||
self.max_retries * self.retry_interval +
|
||||
self.delay)
|
||||
|
||||
# Create the necessary Backend instances for each target
|
||||
self._setup_target_backends()
|
||||
self.max_retries * self.retry_interval +
|
||||
self.delay)
|
||||
|
||||
def _setup_target_backends(self):
|
||||
self.target_backends = {}
|
||||
@ -154,6 +147,34 @@ class Service(service.RPCService, coordination.CoordinationMixin,
|
||||
return topic
|
||||
|
||||
def start(self):
|
||||
|
||||
# Build the Pool (and related) Object from Config
|
||||
context = DesignateContext.get_admin_context()
|
||||
pool_id = CONF['service:pool_manager'].pool_id
|
||||
|
||||
has_targets = False
|
||||
|
||||
while not has_targets:
|
||||
try:
|
||||
self.pool = self.central_api.get_pool(context, pool_id)
|
||||
|
||||
if len(self.pool.targets) > 0:
|
||||
has_targets = True
|
||||
else:
|
||||
LOG.error(_LE("No targets for %s found."), self.pool)
|
||||
time.sleep(5)
|
||||
|
||||
# Pool data may not have migrated to the DB yet
|
||||
except exceptions.PoolNotFound:
|
||||
LOG.error(_LE("Pool ID %s not found."), pool_id)
|
||||
time.sleep(5)
|
||||
# designate-central service may not have started yet
|
||||
except messaging.exceptions.MessagingTimeout:
|
||||
time.sleep(0.2)
|
||||
|
||||
# Create the necessary Backend instances for each target
|
||||
self._setup_target_backends()
|
||||
|
||||
for target in self.pool.targets:
|
||||
self.target_backends[target.id].start()
|
||||
|
||||
|
@ -382,9 +382,14 @@ class TestCase(base.BaseTestCase):
|
||||
# Fetch the default pool
|
||||
pool = self.storage.get_pool(self.admin_context, default_pool_id)
|
||||
|
||||
# Add a NS record to it
|
||||
pool.ns_records.append(
|
||||
objects.PoolNsRecord(priority=0, hostname='ns1.example.org.'))
|
||||
# Fill out the necessary pool details
|
||||
pool.ns_records = objects.PoolNsRecordList.from_list([
|
||||
{'hostname': 'ns1.example.org.', 'priority': 0}
|
||||
])
|
||||
|
||||
pool.targets = objects.PoolTargetList.from_list([
|
||||
{'type': 'fake', u'description': "Fake PoolTarget for Tests"}
|
||||
])
|
||||
|
||||
# Save the default pool
|
||||
self.storage.update_pool(self.admin_context, pool)
|
||||
|
63
designate/tests/resources/pools_yaml/multiple-pools.yaml
Normal file
63
designate/tests/resources/pools_yaml/multiple-pools.yaml
Normal file
@ -0,0 +1,63 @@
|
||||
---
|
||||
- name: pool-1
|
||||
description: Default PowerDNS Pool
|
||||
attributes:
|
||||
internal: true
|
||||
ns_records:
|
||||
- hostname: ns1-1.example.org.
|
||||
priority: 1
|
||||
- hostname: ns1-2.example.org.
|
||||
priority: 2
|
||||
nameservers:
|
||||
- host: 192.0.2.2
|
||||
port: 53
|
||||
- host: 192.0.2.3
|
||||
port: 53
|
||||
targets:
|
||||
- type: powerdns
|
||||
description: PowerDNS Database Cluster
|
||||
masters:
|
||||
- host: 192.0.2.1
|
||||
port: 5354
|
||||
options:
|
||||
connection: 'mysql+pymysql://designate:password@127.0.0.1/designate_pdns?charset=utf8'
|
||||
also_notifies:
|
||||
- host: 192.0.2.4
|
||||
port: 53
|
||||
|
||||
- name: pool-2
|
||||
id: cf2e8eab-76cd-4162-bf76-8aeee3556de0
|
||||
description: Default PowerDNS Pool
|
||||
|
||||
attributes:
|
||||
external: true
|
||||
ns_records:
|
||||
- hostname: ns1-1.example.org.
|
||||
priority: 1
|
||||
- hostname: ns1-2.example.org.
|
||||
priority: 2
|
||||
nameservers:
|
||||
- host: 192.0.2.2
|
||||
port: 53
|
||||
- host: 192.0.2.3
|
||||
port: 53
|
||||
|
||||
targets:
|
||||
- type: bind
|
||||
description: BIND9 Server 1
|
||||
masters:
|
||||
- host: 192.0.2.1
|
||||
port: 5354
|
||||
options:
|
||||
rndc_host: 192.0.2.2
|
||||
rndc_port: 953
|
||||
rndc_key_file: /etc/designate/rndc.key
|
||||
- type: bind
|
||||
description: BIND9 Server 2
|
||||
masters:
|
||||
- host: 192.0.2.1
|
||||
port: 5354
|
||||
options:
|
||||
rndc_host: 192.0.2.3
|
||||
rndc_port: 953
|
||||
rndc_key_file: /etc/designate/rndc.key
|
32
designate/tests/resources/pools_yaml/pools.yaml
Normal file
32
designate/tests/resources/pools_yaml/pools.yaml
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
|
||||
- name: default
|
||||
description: Default PowerDNS Pool
|
||||
|
||||
attributes:
|
||||
type: internal
|
||||
|
||||
ns_records:
|
||||
- hostname: ns1-1.example.org.
|
||||
priority: 1
|
||||
- hostname: ns1-2.example.org.
|
||||
priority: 2
|
||||
|
||||
nameservers:
|
||||
- host: 192.0.2.2
|
||||
port: 53
|
||||
- host: 192.0.2.3
|
||||
port: 53
|
||||
|
||||
targets:
|
||||
- type: powerdns
|
||||
description: PowerDNS Database Cluster
|
||||
masters:
|
||||
- host: 192.0.2.1
|
||||
port: 5354
|
||||
options:
|
||||
connection: 'mysql+pymysql://designate:password@127.0.0.1/designate_pdns?charset=utf8'
|
||||
also_notifies:
|
||||
- host: 192.0.2.4
|
||||
port: 53
|
||||
|
25
designate/tests/resources/pools_yaml/sample_output.yaml
Normal file
25
designate/tests/resources/pools_yaml/sample_output.yaml
Normal file
@ -0,0 +1,25 @@
|
||||
- also_notifies:
|
||||
- host: 192.0.2.4
|
||||
port: 53
|
||||
attributes: {}
|
||||
description: Default PowerDNS Pool
|
||||
id: cf2e8eab-76cd-4162-bf76-8aeee3556de0
|
||||
name: default
|
||||
nameservers:
|
||||
- host: 192.0.2.2
|
||||
port: 53
|
||||
- host: 192.0.2.3
|
||||
port: 53
|
||||
ns_records:
|
||||
- hostname: ns1-1.example.org.
|
||||
priority: 1
|
||||
- hostname: ns1-2.example.org.
|
||||
priority: 2
|
||||
targets:
|
||||
- description: PowerDNS Database Cluster
|
||||
masters:
|
||||
- host: 192.0.2.1
|
||||
port: 5354
|
||||
options:
|
||||
connection: mysql+pymysql://designate:password@127.0.0.1/designate_pdns?charset=utf8
|
||||
type: powerdns
|
@ -15,6 +15,49 @@
|
||||
# under the License.
|
||||
from designate.tests import TestCase
|
||||
|
||||
POOL_DICT = {
|
||||
'id': u'794ccc2c-d751-44fe-b57f-8894c9f5c842',
|
||||
'name': u'default',
|
||||
'targets': [
|
||||
{
|
||||
'id': 'f278782a-07dc-4502-9177-b5d85c5f7c7e',
|
||||
'type': 'fake',
|
||||
'masters': [
|
||||
{
|
||||
'host': '127.0.0.1',
|
||||
'port': 5354
|
||||
}
|
||||
],
|
||||
'options': {}
|
||||
},
|
||||
{
|
||||
'id': 'a38703f2-b71e-4e5b-ab22-30caaed61dfd',
|
||||
'type': 'fake',
|
||||
'masters': [
|
||||
{
|
||||
'host': '127.0.0.1',
|
||||
'port': 5354
|
||||
}
|
||||
],
|
||||
'options': {}
|
||||
},
|
||||
],
|
||||
'nameservers': [
|
||||
{
|
||||
'id': 'c5d64303-4cba-425a-9f3c-5d708584dde4',
|
||||
'host': '127.0.0.1',
|
||||
'port': 5355
|
||||
|
||||
},
|
||||
{
|
||||
'id': 'c67cdc95-9a9e-4d2a-98ed-dc78cbd85234',
|
||||
'host': '127.0.0.1',
|
||||
'port': 5356
|
||||
},
|
||||
],
|
||||
'also_notifies': [],
|
||||
}
|
||||
|
||||
|
||||
class PoolManagerTestCase(TestCase):
|
||||
pass
|
||||
|
@ -18,7 +18,6 @@ import logging
|
||||
import uuid
|
||||
|
||||
import oslo_messaging as messaging
|
||||
from oslo_config import cfg
|
||||
from mock import call
|
||||
from mock import Mock
|
||||
from mock import patch
|
||||
@ -30,6 +29,7 @@ from designate.central import rpcapi as central_rpcapi
|
||||
from designate.mdns import rpcapi as mdns_rpcapi
|
||||
from designate.storage.impl_sqlalchemy import tables
|
||||
from designate.tests.test_pool_manager import PoolManagerTestCase
|
||||
from designate.tests.test_pool_manager import POOL_DICT
|
||||
import designate.pool_manager.service as pm_module
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -55,61 +55,13 @@ class PoolManagerServiceNoopTest(PoolManagerTestCase):
|
||||
pool_id='794ccc2c-d751-44fe-b57f-8894c9f5c842',
|
||||
group='service:pool_manager')
|
||||
|
||||
# Configure the Pool
|
||||
section_name = 'pool:794ccc2c-d751-44fe-b57f-8894c9f5c842'
|
||||
section_opts = [
|
||||
cfg.ListOpt('targets', default=[
|
||||
'f278782a-07dc-4502-9177-b5d85c5f7c7e',
|
||||
'a38703f2-b71e-4e5b-ab22-30caaed61dfd',
|
||||
]),
|
||||
cfg.ListOpt('nameservers', default=[
|
||||
'c5d64303-4cba-425a-9f3c-5d708584dde4',
|
||||
'c67cdc95-9a9e-4d2a-98ed-dc78cbd85234',
|
||||
]),
|
||||
cfg.ListOpt('also_notifies', default=[]),
|
||||
]
|
||||
cfg.CONF.register_group(cfg.OptGroup(name=section_name))
|
||||
cfg.CONF.register_opts(section_opts, group=section_name)
|
||||
|
||||
# Configure the Pool Targets
|
||||
section_name = 'pool_target:f278782a-07dc-4502-9177-b5d85c5f7c7e'
|
||||
section_opts = [
|
||||
cfg.StrOpt('type', default='fake'),
|
||||
cfg.ListOpt('masters', default=['127.0.0.1:5354']),
|
||||
cfg.DictOpt('options', default={})
|
||||
]
|
||||
cfg.CONF.register_group(cfg.OptGroup(name=section_name))
|
||||
cfg.CONF.register_opts(section_opts, group=section_name)
|
||||
|
||||
section_name = 'pool_target:a38703f2-b71e-4e5b-ab22-30caaed61dfd'
|
||||