Files
designate/designate/backend/agent_backend/impl_bind9.py
T
Erik Olof Gunnar Andersson 097ffec548 Finalized centralization of configuration
This patch removes get_cfg_opts from the plugin class,
and moves all configuration directly into designate.conf.

There are no changes in the generated configuration due
to this patch.

Finally, this complets the blueprint to centralize all
configuration, and is a follow up to this patch
I3be68bf294157631a9bac128df0841220020de96

blueprint centralize-config-designate

Change-Id: I007fc004fc533950c5eda3974f41f05c6db5b43f
2019-06-18 18:41:10 +00:00

130 lines
4.4 KiB
Python

# Copyright 2014 Rackspace Inc.
#
# Author: Tim Simmons <tim.simmons@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.
import os
import dns
import dns.resolver
import six
from oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_log import log as logging
from designate.backend.agent_backend import base
from designate import exceptions
from designate import utils
CFG_GROUP_NAME = 'backend:agent:bind9'
LOG = logging.getLogger(__name__)
class Bind9Backend(base.AgentBackend):
__plugin_name__ = 'bind9'
__backend_status__ = 'untested'
def start(self):
LOG.info("Started bind9 backend")
def find_zone_serial(self, zone_name):
LOG.debug("Finding %s", zone_name)
resolver = dns.resolver.Resolver()
resolver.nameservers = [cfg.CONF[CFG_GROUP_NAME].query_destination]
try:
rdata = resolver.query(zone_name, 'SOA')[0]
except Exception:
return None
return rdata.serial
def create_zone(self, zone):
LOG.debug("Creating %s", zone.origin.to_text())
self._sync_zone(zone, new_zone_flag=True)
def update_zone(self, zone):
LOG.debug("Updating %s", zone.origin.to_text())
self._sync_zone(zone)
def delete_zone(self, zone_name):
LOG.debug('Delete Zone: %s' % zone_name)
rndc_op = 'delzone'
# RNDC doesn't like the trailing dot on the zone name
rndc_call = self._rndc_base() + [rndc_op, zone_name.rstrip('.')]
utils.execute(*rndc_call)
def _rndc_base(self):
rndc_call = [
'rndc',
'-s', cfg.CONF[CFG_GROUP_NAME].rndc_host,
'-p', str(cfg.CONF[CFG_GROUP_NAME].rndc_port),
]
if cfg.CONF[CFG_GROUP_NAME].rndc_config_file:
rndc_call.extend(['-c',
cfg.CONF[CFG_GROUP_NAME].rndc_config_file])
if cfg.CONF[CFG_GROUP_NAME].rndc_key_file:
rndc_call.extend(['-k',
cfg.CONF[CFG_GROUP_NAME].rndc_key_file])
return rndc_call
def _sync_zone(self, zone, new_zone_flag=False):
"""Sync a single zone's zone file and reload bind config"""
# NOTE: Different versions of BIND9 behave differently with a trailing
# dot, so we're just going to take it off.
zone_name = zone.origin.to_text(omit_final_dot=True)
if six.PY3 and isinstance(zone_name, bytes):
zone_name = zone_name.decode('utf-8')
# NOTE: Only one thread should be working with the Zonefile at a given
# time. The sleep(1) below introduces a not insignificant risk
# of more than 1 thread working with a zonefile at a given time.
with lockutils.lock('bind9-%s' % zone_name):
LOG.debug('Synchronising Zone: %s' % zone_name)
zone_path = cfg.CONF[CFG_GROUP_NAME].zone_file_path
output_path = os.path.join(zone_path,
'%s.zone' % zone_name)
zone.to_file(output_path, relativize=False)
rndc_call = self._rndc_base()
if new_zone_flag:
rndc_op = [
'addzone',
'%s { type master; file "%s"; };' % (zone_name,
output_path),
]
rndc_call.extend(rndc_op)
else:
rndc_op = 'reload'
rndc_call.extend([rndc_op])
rndc_call.extend([zone_name])
LOG.debug('Calling RNDC with: %s' % " ".join(rndc_call))
self._execute_rndc(rndc_call)
def _execute_rndc(self, rndc_call):
try:
LOG.debug('Executing RNDC call: %s' % " ".join(rndc_call))
utils.execute(*rndc_call)
except utils.processutils.ProcessExecutionError as e:
LOG.debug('RNDC call failure: %s' % e)
raise exceptions.Backend(e)