Merge "Add Akamai Management comamnds"
This commit is contained in:
commit
8662fe52cd
@ -127,8 +127,30 @@ class EnhancedDNSClient(object):
|
|||||||
|
|
||||||
return zone
|
return zone
|
||||||
|
|
||||||
|
def getZone(self, zoneName):
|
||||||
|
LOG.debug("Performing getZone with zoneName: %s" % zoneName)
|
||||||
|
zoneName = self._sanitizeZoneName(zoneName)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return self.client.service.getZone(zoneName=zoneName)
|
||||||
|
except Exception as e:
|
||||||
|
raise EnhancedDNSException('Akamai Communication Failure: %s' % e)
|
||||||
|
|
||||||
|
def setZones(self, zones):
|
||||||
|
LOG.debug("Performing setZones")
|
||||||
|
try:
|
||||||
|
return self.client.service.setZones(zones=zones)
|
||||||
|
except Exception as e:
|
||||||
|
if 'You do not have permission to view this zone' in str(e):
|
||||||
|
raise DuplicateDomain()
|
||||||
|
elif 'You do not have access to edit this zone' in str(e):
|
||||||
|
raise Forbidden()
|
||||||
|
else:
|
||||||
|
raise EnhancedDNSException('Akamai Communication Failure: %s'
|
||||||
|
% e)
|
||||||
|
|
||||||
def setZone(self, zone):
|
def setZone(self, zone):
|
||||||
LOG.debug("Performing setZone with zoneName: %s", zone.zoneName)
|
LOG.debug("Performing setZone with zoneName: %s" % zone.zoneName)
|
||||||
try:
|
try:
|
||||||
self.client.service.setZone(zone=zone)
|
self.client.service.setZone(zone=zone)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -166,6 +188,24 @@ class EnhancedDNSClient(object):
|
|||||||
return zoneName.rstrip('.').lower()
|
return zoneName.rstrip('.').lower()
|
||||||
|
|
||||||
|
|
||||||
|
def build_zone(client, target, domain):
|
||||||
|
masters = [m.host for m in target.masters]
|
||||||
|
|
||||||
|
if target.options.get("tsig_key_name", None):
|
||||||
|
return client.buildZone(
|
||||||
|
domain.name,
|
||||||
|
masters,
|
||||||
|
domain.id,
|
||||||
|
target.options["tsig_key_name"],
|
||||||
|
target.options.get("tsig_key_secret", None),
|
||||||
|
target.options.get("tsig_key_algorithm", None))
|
||||||
|
else:
|
||||||
|
return client.buildZone(
|
||||||
|
domain.name,
|
||||||
|
masters,
|
||||||
|
domain.id)
|
||||||
|
|
||||||
|
|
||||||
class AkamaiBackend(base.Backend):
|
class AkamaiBackend(base.Backend):
|
||||||
__plugin_name__ = 'akamai'
|
__plugin_name__ = 'akamai'
|
||||||
|
|
||||||
@ -189,10 +229,6 @@ class AkamaiBackend(base.Backend):
|
|||||||
self.username = self.options.get('username')
|
self.username = self.options.get('username')
|
||||||
self.password = self.options.get('password')
|
self.password = self.options.get('password')
|
||||||
|
|
||||||
self.tsig_key_name = self.options.get('tsig_key_name', None)
|
|
||||||
self.tsig_key_algorithm = self.options.get('tsig_key_algorithm', None)
|
|
||||||
self.tsig_key_secret = self.options.get('tsig_key_secret', None)
|
|
||||||
|
|
||||||
self.client = EnhancedDNSClient(self.username, self.password)
|
self.client = EnhancedDNSClient(self.username, self.password)
|
||||||
|
|
||||||
for m in self.masters:
|
for m in self.masters:
|
||||||
@ -200,27 +236,9 @@ class AkamaiBackend(base.Backend):
|
|||||||
raise exceptions.ConfigurationError(
|
raise exceptions.ConfigurationError(
|
||||||
"Akamai only supports mDNS instances on port 53")
|
"Akamai only supports mDNS instances on port 53")
|
||||||
|
|
||||||
def _build_zone(self, domain):
|
|
||||||
masters = [m.host for m in self.masters]
|
|
||||||
|
|
||||||
if self.tsig_key_name is not None:
|
|
||||||
return self.client.buildZone(
|
|
||||||
domain.name,
|
|
||||||
masters,
|
|
||||||
domain.id,
|
|
||||||
self.tsig_key_name,
|
|
||||||
self.tsig_key_secret,
|
|
||||||
self.tsig_key_algorithm)
|
|
||||||
|
|
||||||
else:
|
|
||||||
return self.client.buildZone(
|
|
||||||
domain.name,
|
|
||||||
masters,
|
|
||||||
domain.id)
|
|
||||||
|
|
||||||
def create_domain(self, context, domain):
|
def create_domain(self, context, domain):
|
||||||
"""Create a DNS domain"""
|
"""Create a DNS domain"""
|
||||||
zone = self._build_zone(domain)
|
zone = build_zone(self.client, self.target, domain)
|
||||||
|
|
||||||
self.client.setZone(zone=zone)
|
self.client.setZone(zone=zone)
|
||||||
|
|
||||||
|
101
designate/manage/akamai.py
Normal file
101
designate/manage/akamai.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
from pprint import pformat
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from designate import exceptions
|
||||||
|
from designate import rpc
|
||||||
|
from designate.i18n import _ # noqa
|
||||||
|
from designate.i18n import _LI
|
||||||
|
from designate.objects import pool as pool_object
|
||||||
|
from designate.backend import impl_akamai
|
||||||
|
from designate.central import rpcapi as central_rpcapi
|
||||||
|
from designate.manage import base
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class AkamaiCommands(base.Commands):
|
||||||
|
def __init__(self):
|
||||||
|
super(AkamaiCommands, self).__init__()
|
||||||
|
rpc.init(cfg.CONF)
|
||||||
|
self.central_api = central_rpcapi.CentralAPI()
|
||||||
|
|
||||||
|
self.context.all_tenants = True
|
||||||
|
|
||||||
|
def _get_config(self, pool_id, target_id):
|
||||||
|
pool = pool_object.Pool.from_config(cfg.CONF, pool_id)
|
||||||
|
target = None
|
||||||
|
for t in pool.targets:
|
||||||
|
if t.id == target_id:
|
||||||
|
target = t
|
||||||
|
else:
|
||||||
|
msg = _("Failed to find target with ID %s")
|
||||||
|
raise exceptions.ConfigurationError(msg % target_id)
|
||||||
|
if target is None:
|
||||||
|
msg = _("Found multiple targets with ID %s")
|
||||||
|
raise exceptions.ConfigurationError(msg % target_id)
|
||||||
|
return pool, target
|
||||||
|
|
||||||
|
@base.args('pool-id', help="Pool to Sync", type=str)
|
||||||
|
@base.args('pool-target-id', help="Pool Target to Sync", type=str)
|
||||||
|
@base.args('zone-name', help="Zone name")
|
||||||
|
def debug_zone(self, pool_id, target_id, zone_name):
|
||||||
|
pool, target = self._get_config(pool_id, target_id)
|
||||||
|
|
||||||
|
client = impl_akamai.EnhancedDNSClient(
|
||||||
|
target.options.get("username"), target.options.get("password"))
|
||||||
|
|
||||||
|
zone = self.central_api.find_domain(self.context, {"name": zone_name})
|
||||||
|
akamai_zone = client.getZone(zone_name)
|
||||||
|
|
||||||
|
print("Designate zone\n%s" % pformat(zone.to_dict()))
|
||||||
|
print("Akamai Zone:\n%s" % repr(akamai_zone))
|
||||||
|
|
||||||
|
@base.args('pool-id', help="Pool to Sync", type=str)
|
||||||
|
@base.args('pool-target-id', help="Pool Target to Sync", type=str)
|
||||||
|
@base.args('--batch-size', default=20, type=int)
|
||||||
|
def sync_domains(self, pool_id, pool_target_id, batch_size):
|
||||||
|
pool, target = self._get_config(pool_id, pool_target_id)
|
||||||
|
|
||||||
|
client = impl_akamai.EnhancedDNSClient(
|
||||||
|
target.options.get("username"), target.options.get("password"))
|
||||||
|
|
||||||
|
LOG.info(_LI("Doing batches of %i") % batch_size)
|
||||||
|
|
||||||
|
criterion = {"pool_id": pool_id}
|
||||||
|
marker = None
|
||||||
|
|
||||||
|
while (marker is not False):
|
||||||
|
zones = self.central_api.find_domains(
|
||||||
|
self.context, criterion, limit=batch_size, marker=marker)
|
||||||
|
update = []
|
||||||
|
|
||||||
|
if len(zones) == 0:
|
||||||
|
LOG.info(_LI("Stopping as there are no more zones."))
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
marker = zones[-1]['id']
|
||||||
|
|
||||||
|
for zone in zones:
|
||||||
|
z = impl_akamai.build_zone(client, target, zone)
|
||||||
|
update.append(z)
|
||||||
|
|
||||||
|
LOG.info(_LI('Uploading %d Zones') % len(update))
|
||||||
|
|
||||||
|
client.setZones(update)
|
@ -13,6 +13,7 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
from designate import policy
|
||||||
from designate.context import DesignateContext
|
from designate.context import DesignateContext
|
||||||
|
|
||||||
|
|
||||||
@ -38,3 +39,4 @@ class Commands(object):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.context = DesignateContext.get_admin_context(
|
self.context = DesignateContext.get_admin_context(
|
||||||
request_id='designate-manage')
|
request_id='designate-manage')
|
||||||
|
policy.init()
|
||||||
|
@ -75,9 +75,7 @@ class Pool(base.DictObjectMixin, base.PersistentObjectMixin,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_config(cls, CONF):
|
def from_config(cls, CONF, pool_id):
|
||||||
pool_id = CONF['service:pool_manager'].pool_id
|
|
||||||
|
|
||||||
pool_target_ids = CONF['pool:%s' % pool_id].targets
|
pool_target_ids = CONF['pool:%s' % pool_id].targets
|
||||||
pool_nameserver_ids = CONF['pool:%s' % pool_id].nameservers
|
pool_nameserver_ids = CONF['pool:%s' % pool_id].nameservers
|
||||||
pool_also_notifies = CONF['pool:%s' % pool_id].also_notifies
|
pool_also_notifies = CONF['pool:%s' % pool_id].also_notifies
|
||||||
|
@ -76,7 +76,8 @@ class Service(service.RPCService, service.Service):
|
|||||||
super(Service, self).__init__(threads=threads)
|
super(Service, self).__init__(threads=threads)
|
||||||
|
|
||||||
# Build the Pool (and related) Object from Config
|
# Build the Pool (and related) Object from Config
|
||||||
self.pool = objects.Pool.from_config(CONF)
|
self.pool = objects.Pool.from_config(
|
||||||
|
CONF, CONF['service:pool_manager'].pool_id)
|
||||||
|
|
||||||
# Get a pool manager cache connection.
|
# Get a pool manager cache connection.
|
||||||
self.cache = cache.get_pool_manager_cache(
|
self.cache = cache.get_pool_manager_cache(
|
||||||
|
@ -102,6 +102,7 @@ designate.quota =
|
|||||||
|
|
||||||
designate.manage =
|
designate.manage =
|
||||||
database = designate.manage.database:DatabaseCommands
|
database = designate.manage.database:DatabaseCommands
|
||||||
|
akamai = designate.manage.akamai:AkamaiCommands
|
||||||
pool = designate.manage.pool:PoolCommands
|
pool = designate.manage.pool:PoolCommands
|
||||||
pool-manager-cache = designate.manage.pool_manager_cache:DatabaseCommands
|
pool-manager-cache = designate.manage.pool_manager_cache:DatabaseCommands
|
||||||
powerdns = designate.manage.powerdns:DatabaseCommands
|
powerdns = designate.manage.powerdns:DatabaseCommands
|
||||||
|
Loading…
Reference in New Issue
Block a user