Add PowerDNS 4 driver

Fixes-Bug: #1590429

Change-Id: I1f6017ce83a49dc0c3827c540ac18186bb14f72b
This commit is contained in:
Graham Hayes 2016-09-15 14:24:42 +01:00
parent ed04418957
commit aa23d86835
9 changed files with 444 additions and 2 deletions

View File

@ -0,0 +1,82 @@
# 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.
import urlparse
import requests
from oslo_log import log as logging
from oslo_config import cfg
from designate import exceptions
from designate.backend import base
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
class PDNS4Backend(base.Backend):
__plugin_name__ = 'pdns4'
__backend_status__ = 'release-compatible'
def __init__(self, target):
super(PDNS4Backend, self).__init__(target)
self.api_endpoint = self.options.get('api_endpoint')
self.api_token = self.options.get('api_token')
def _build_url(self, zone=''):
r_url = urlparse.urlparse(self.api_endpoint)
return "%s://%s/api/v1/servers/localhost/zones%s%s" % (
r_url.scheme, r_url.netloc, '/' if zone else '', zone)
def create_zone(self, context, zone):
"""Create a DNS zone"""
masters = \
['%s:%d' % (master.host, master.port) for master in self.masters]
data = {
"name": zone.name,
"kind": "slave",
"masters": masters,
}
headers = {
"X-API-Key": self.api_token
}
try:
requests.post(
self._build_url(),
json=data,
headers=headers
).raise_for_status()
except requests.HTTPError as e:
raise exceptions.Backend(e)
def delete_zone(self, context, zone):
"""Delete a DNS zone"""
headers = {
"X-API-Key": self.api_token
}
try:
requests.delete(
self._build_url(zone.name),
headers=headers
).raise_for_status()
except requests.HTTPError as e:
raise exceptions.Backend(e)

View File

@ -40,7 +40,7 @@ def _map_col(keys, col):
class PowerDNSBackend(base.Backend):
__plugin_name__ = 'powerdns'
__backend_status__ = 'integrated'
__backend_status__ = 'deprecated'
@classmethod
def get_cfg_opts(cls):

View File

@ -0,0 +1,181 @@
# Configure the powerdns backend
# Enable with:
# DESIGNATE_BACKEND_DRIVER=powerdns
# Dependencies:
# ``functions`` file
# ``designate`` configuration
# install_designate_backend - install any external requirements
# configure_designate_backend - make configuration changes, including those to other services
# init_designate_backend - initialize databases, etc.
# start_designate_backend - start any external services
# stop_designate_backend - stop any external services
# cleanup_designate_backend - remove transient data and cache
# Save trace setting
DP_PDNS_XTRACE=$(set +o | grep xtrace)
set +o xtrace
# Defaults
# --------
if is_fedora; then
POWERDNS_CFG_DIR=/etc/pdns
else
POWERDNS_CFG_DIR=/etc/powerdns
fi
# Entry Points
# ------------
# install_designate_backend - install any external requirements
function install_designate_backend {
if is_ubuntu; then
GetOSVersion
if [ "$os_CODENAME" = "trusty" ]; then
sudo tee /etc/apt/sources.list.d/pdns.list > /dev/null <<EOF
deb [arch=amd64] http://repo.powerdns.com/ubuntu trusty-auth-40 main
EOF
sudo tee /etc/apt/preferences.d/pdns > /dev/null <<EOF
Package: pdns-*
Pin: origin repo.powerdns.com
Pin-Priority: 600
EOF
curl https://repo.powerdns.com/FD380FBB-pub.asc | sudo apt-key add - &&
sudo apt-get update
elif [ "$os_CODENAME" = "xenial" ]; then
echo "Use PDNS4 from apt repo"
else
die $LINENO "PDNS4 backend only supports trusty or xenial"
fi
PDNS=pdns-server
else
die $LINENO "PDNS4 Backend plugin backend only supports Ubuntu"
fi
if is_service_enabled mysql; then
PDNS+=" pdns-backend-mysql"
else
die $LINENO "PDNS4 backend only supports MySQL"
fi
install_package $PDNS
sudo rm -rf $POWERDNS_CFG_DIR/pdns.d
}
# configure_designate_backend - make configuration changes, including those to other services
function configure_designate_backend {
# Generate Designate pool.yaml file
sudo tee $DESIGNATE_CONF_DIR/pools.yaml > /dev/null <<EOF
---
- name: default
description: DevStack PowerDNS Pool
attributes: {}
ns_records:
- hostname: $DESIGNATE_DEFAULT_NS_RECORD
priority: 1
nameservers:
- host: $DESIGNATE_SERVICE_HOST
port: $DESIGNATE_SERVICE_PORT_DNS
targets:
- type: pdns4
description: PowerDNS Database Cluster
masters:
- host: $DESIGNATE_SERVICE_HOST
port: $DESIGNATE_SERVICE_PORT_MDNS
options:
host: $DESIGNATE_SERVICE_HOST
port: $DESIGNATE_SERVICE_PORT_DNS
api_endpoint: http://$DESIGNATE_SERVICE_HOST:8081
api_token: changeme
EOF
# Generate PowerDNS pdns.conf file
sudo tee $POWERDNS_CFG_DIR/pdns.conf > /dev/null <<EOF
# General Config
setgid=pdns
setuid=pdns
config-dir=$POWERDNS_CFG_DIR
socket-dir=/var/run
guardian=yes
daemon=yes
disable-axfr=no
local-address=$DESIGNATE_SERVICE_HOST
local-port=$DESIGNATE_SERVICE_PORT_DNS
master=no
slave=yes
cache-ttl=0
query-cache-ttl=0
negquery-cache-ttl=0
out-of-zone-additional-processing=no
webserver=yes
webserver-address=$DESIGNATE_SERVICE_HOST
api=yes
api-key=changeme
EOF
if is_service_enabled mysql; then
sudo tee -a $POWERDNS_CFG_DIR/pdns.conf > /dev/null <<EOF
# Launch gmysql backend
launch=gmysql
# gmysql parameters
gmysql-host=$DATABASE_HOST
gmysql-user=$DATABASE_USER
gmysql-password=$DATABASE_PASSWORD
gmysql-dbname=designate_pdns
gmysql-dnssec=yes
EOF
else
die $LINENO "PDNS4 backend only supports MySQL"
fi
restart_service pdns
}
# init_designate_backend - initialize databases, etc.
function init_designate_backend {
# Stop pdns so that the migration succeeds, if not you get a error
# that the schema is still in use.
if is_service_enabled postgresql; then
stop_designate_backend
fi
# (Re)create designate_pdns database
recreate_database designate_pdns utf8
if is_service_enabled mysql; then
sudo mysql -u root designate_pdns < $DESIGNATE_PLUGINS/backend-pdns4-mysql-db.sql
else
die $LINENO "PDNS4 backend only supports MySQL"
fi
}
# create_designate_pool_configuration_backend - Perform post-pool config tasks
function create_designate_pool_configuration_backend {
# Init and migrate designate_pdns database
:
}
# start_designate_backend - start any external services
function start_designate_backend {
start_service pdns
}
# stop_designate_backend - stop any external services
function stop_designate_backend {
stop_service pdns
}
# cleanup_designate_backend - remove transient data and cache
function cleanup_designate_backend {
:
}
# Restore xtrace
$DP_PDNS_XTRACE

View File

@ -0,0 +1,92 @@
CREATE TABLE domains (
id INT AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
master VARCHAR(128) DEFAULT NULL,
last_check INT DEFAULT NULL,
type VARCHAR(6) NOT NULL,
notified_serial INT DEFAULT NULL,
account VARCHAR(40) DEFAULT NULL,
PRIMARY KEY (id)
) Engine=InnoDB;
CREATE UNIQUE INDEX name_index ON domains(name);
CREATE TABLE records (
id INT AUTO_INCREMENT,
domain_id INT DEFAULT NULL,
name VARCHAR(255) DEFAULT NULL,
type VARCHAR(10) DEFAULT NULL,
-- Changed to "TEXT", as VARCHAR(65000) is too big for most MySQL installs
content TEXT DEFAULT NULL,
ttl INT DEFAULT NULL,
prio INT DEFAULT NULL,
change_date INT DEFAULT NULL,
disabled TINYINT(1) DEFAULT 0,
ordername VARCHAR(255) BINARY DEFAULT NULL,
auth TINYINT(1) DEFAULT 1,
PRIMARY KEY (id)
) Engine=InnoDB;
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);
CREATE INDEX recordorder ON records (domain_id, ordername);
CREATE TABLE supermasters (
ip VARCHAR(64) NOT NULL,
nameserver VARCHAR(255) NOT NULL,
account VARCHAR(40) NOT NULL,
PRIMARY KEY (ip, nameserver)
) Engine=InnoDB;
CREATE TABLE comments (
id INT AUTO_INCREMENT,
domain_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
type VARCHAR(10) NOT NULL,
modified_at INT NOT NULL,
account VARCHAR(40) NOT NULL,
-- Changed to "TEXT", as VARCHAR(65000) is too big for most MySQL installs
comment TEXT NOT NULL,
PRIMARY KEY (id)
) Engine=InnoDB;
CREATE INDEX comments_domain_id_idx ON comments (domain_id);
CREATE INDEX comments_name_type_idx ON comments (name, type);
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);
CREATE TABLE domainmetadata (
id INT AUTO_INCREMENT,
domain_id INT NOT NULL,
kind VARCHAR(32),
content TEXT,
PRIMARY KEY (id)
) Engine=InnoDB;
CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);
CREATE TABLE cryptokeys (
id INT AUTO_INCREMENT,
domain_id INT NOT NULL,
flags INT NOT NULL,
active BOOL,
content TEXT,
PRIMARY KEY(id)
) Engine=InnoDB;
CREATE INDEX domainidindex ON cryptokeys(domain_id);
CREATE TABLE tsigkeys (
id INT AUTO_INCREMENT,
name VARCHAR(255),
algorithm VARCHAR(50),
secret VARCHAR(255),
PRIMARY KEY (id)
) Engine=InnoDB;
CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);

View File

@ -0,0 +1,57 @@
..
Copyright 2016 Hewlett Packard Enterprise Development, 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.
.. _backend-pdns4:
PDNS4 Backend
=============
PDNS4 Configuration
-------------------
The version PowerDNS in Ubuntu Xenial is pdns4.
This has a different DB schema, and is incompatible with the legacy PowerDNS
driver. In PDNS 4 the API was marked stable, and this is what we will use.
You will need to configure PowerDNS, and its database before perfoming these
steps.
You will need to use a database backend for PowerDNS's API to function.
See `PowerDNS Docs`_ for details.
1. Enable the API in the ``pdns.conf`` file.
.. code-block:: ini
webserver=yes
api=yes
api-key=changeme
2. Configure the PowerDNS Backend using this sample target snippet
.. literalinclude:: sample_yaml_snippets/pdns4.yaml
:language: yaml
3. Then update the pools in designate
.. code-block:: console
$ designate-manage pool update
See :ref:`designate_manage_pool` for further details on the ``designate-manage pool``
command, and :ref:`pools` for information about the yaml file syntax
.. _PowerDNS Docs: https://doc.powerdns.com/md/authoritative/installation/

View File

@ -18,6 +18,9 @@
PowerDNS Backend
================
.. warning:: This backend will not work with PowerDNS version 4 or greater. Use the ``pdns4`` backend.
PowerDNS Configuration
----------------------

View File

@ -0,0 +1,16 @@
targets:
- type: pdns4
description: PowerDNS4 DNS Server
# List out the designate-mdns servers from which PowerDNS servers should
# request zone transfers (AXFRs) from.
masters:
- host: 192.0.2.1
port: 5354
# PowerDNS Configuration options
options:
host: 192.0.2.1
port: 53
api_endpoint: http://127.0.0.1:8081
api_token: changeme

View File

@ -45,6 +45,7 @@ in-tree=True
[backends]
backend-impl-bind9=Bind9
backend-impl-powerdns-mysql=Power DNS (MySQL)
backend-impl-pdns4=Power DNS 4
backend-impl-designate=Designate to Designate
backend-impl-dynect=DynECT
backend-impl-akamai=Akamai eDNS
@ -61,7 +62,10 @@ backend-impl-msdns-agent=Microsoft DNS (Agent)
[backends.backend-impl-bind9]
[backends.backend-impl-pdns4]
[backends.backend-impl-powerdns-mysql]
notes=This has been replaced by the pdns4 backend for future releases
[backends.backend-impl-designate]
@ -101,7 +105,7 @@ type=agent
type=agent
[grades]
valid-grades=integrated,master-compatible,release-compatible,untested,failing,known-broken,experimental
valid-grades=integrated,master-compatible,release-compatible,untested,failing,known-broken,experimental,deprecated
[grades.integrated]
title=Integrated
@ -144,3 +148,9 @@ title=Experimental
notes=Backends that are under development, and may change at any time
in-tree=optional
css-class=warning
[grades.deprecated]
title=Deprecated
notes=Backends have been superseded, and will be removed in the future
in-tree=optional
css-class=warning

View File

@ -86,6 +86,7 @@ designate.backend =
bind9 = designate.backend.impl_bind9:Bind9Backend
designate = designate.backend.impl_designate:DesignateBackend
powerdns = designate.backend.impl_powerdns:PowerDNSBackend
pdns4 = designate.backend.impl_pdns4:PDNS4Backend
dynect = designate.backend.impl_dynect:DynECTBackend
akamai = designate.backend.impl_akamai:AkamaiBackend
nsd4 = designate.backend.impl_nsd4:NSD4Backend