Initial baseline
This commit is contained in:
commit
86ab342e02
4
.bzrignore
Normal file
4
.bzrignore
Normal file
@ -0,0 +1,4 @@
|
||||
build
|
||||
layers
|
||||
.tox
|
||||
interfaces
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
build
|
||||
layers
|
||||
.tox
|
||||
interfaces
|
8
Makefile
Normal file
8
Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/make
|
||||
LAYER_PATH := layers
|
||||
|
||||
clean:
|
||||
rm -Rf build
|
||||
|
||||
generate: clean
|
||||
LAYER_PATH=$(LAYER_PATH) tox -e generate
|
87
bind-install.sh
Executable file
87
bind-install.sh
Executable file
@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
|
||||
apt-get install --yes bind9
|
||||
mv /etc/bind/named.conf.options /etc/bind/named.conf.options.org.$$
|
||||
mv /etc/bind/named.conf.local /etc/bind/named.conf.local.$$
|
||||
BASTION_IP="10.5.17.29"
|
||||
IP=$(ip -4 addr show eth0 | awk '/inet/ {print $2}' | sed -e 's!/.*!!')
|
||||
REV=$(echo $IP | awk 'BEGIN{FS="."} {print $3 "." $2 "." $1}')
|
||||
LAST_OCTET=$(echo $IP | awk 'BEGIN{FS="."} {print $4}')
|
||||
UNAME=$(uname -n)
|
||||
cat << EOF > /etc/bind/named.conf.options
|
||||
options {
|
||||
directory "/var/cache/bind";
|
||||
|
||||
// If there is a firewall between you and nameservers you want
|
||||
// to talk to, you may need to fix the firewall to allow multiple
|
||||
// ports to talk. See http://www.kb.cert.org/vuls/id/800113
|
||||
|
||||
// If your ISP provided one or more IP addresses for stable
|
||||
// nameservers, you probably want to use them as forwarders.
|
||||
// Uncomment the following block, and insert the addresses replacing
|
||||
// the all-0's placeholder.
|
||||
|
||||
forwarders {
|
||||
$BASTION_IP;
|
||||
};
|
||||
|
||||
//========================================================================
|
||||
// If BIND logs error messages about the root key being expired,
|
||||
// you will need to update your keys. See https://www.isc.org/bind-keys
|
||||
//========================================================================
|
||||
dnssec-validation auto;
|
||||
|
||||
auth-nxdomain no; # conform to RFC1035
|
||||
listen-on-v6 { any; };
|
||||
};
|
||||
EOF
|
||||
|
||||
cat << EOF > /etc/bind/named.conf.local
|
||||
// forward zone
|
||||
zone "openstacklocal." {
|
||||
type master;
|
||||
file "/etc/bind/db.openstacklocal.com";
|
||||
};
|
||||
// reverse zone
|
||||
zone "${REV}.in-addr.arpa" {
|
||||
type master;
|
||||
notify no;
|
||||
file "/etc/bind/db.10";
|
||||
};
|
||||
EOF
|
||||
TTL='$TTL'
|
||||
|
||||
cat << EOF > /etc/bind/db.openstacklocal.com
|
||||
;
|
||||
; BIND data forward DNS sample for deployment on top of serverstack
|
||||
;
|
||||
$TTL 604800
|
||||
@ IN SOA ${UNAME}.openstacklocal. root.${UNAME}.openstacklocal. (
|
||||
201511161 ; Serial
|
||||
604800 ; Refresh
|
||||
86400 ; Retry
|
||||
2419200 ; Expire
|
||||
604800 ) ; Negative Cache TTL
|
||||
;
|
||||
@ IN NS ${UNAME}.openstacklocal.
|
||||
${UNAME} IN A ${IP}
|
||||
EOF
|
||||
cat << EOF > /etc/bind/db.10
|
||||
;
|
||||
; BIND reverse data file DNS sample for deployment on top of serverstack
|
||||
;
|
||||
$TTL 604800
|
||||
@ IN SOA ${UNAME}.openstacklocal. root.${UNAME}.openstacklocal. (
|
||||
201511161 ; Serial
|
||||
604800 ; Refresh
|
||||
86400 ; Retry
|
||||
2419200 ; Expire
|
||||
604800 ) ; Negative Cache TTL
|
||||
;
|
||||
@ IN NS ${UNAME}.
|
||||
${LAST_OCTET} IN PTR ${UNAME}.openstacklocal.
|
||||
EOF
|
||||
|
||||
echo "nameserver 127.0.0.1" > /etc/resolvconf/resolv.conf.d/head
|
||||
|
||||
/etc/init.d/bind9 restart
|
45
charm/config.yaml
Normal file
45
charm/config.yaml
Normal file
@ -0,0 +1,45 @@
|
||||
options:
|
||||
rabbit-user:
|
||||
default: designate
|
||||
type: string
|
||||
description: Username used to access rabbitmq queue
|
||||
rabbit-vhost:
|
||||
default: openstack
|
||||
type: string
|
||||
description: Rabbitmq vhost
|
||||
database-user:
|
||||
default: designate
|
||||
type: string
|
||||
description: Username for Neutron database access (if enabled)
|
||||
database:
|
||||
default: designate
|
||||
type: string
|
||||
description: Database name for Neutron (if enabled)
|
||||
region:
|
||||
default: RegionOne
|
||||
type: string
|
||||
description: OpenStack Region
|
||||
dns-backend:
|
||||
default:
|
||||
type: string
|
||||
description: IP Address of dns backend
|
||||
nova-domain:
|
||||
default: 'www.example.com.'
|
||||
type: string
|
||||
description: Domain to add records for new instances to
|
||||
nova-domain-email:
|
||||
default: 'email@example.com'
|
||||
type: string
|
||||
description: Email address of the person responsible for the domain.
|
||||
dns-server-record:
|
||||
default: 'ns1.www.example.com.'
|
||||
type: string
|
||||
description: DNS server record
|
||||
neutron-domain:
|
||||
default: 'www.bob.com.'
|
||||
type: string
|
||||
description: Domain to add floating ip recirds to
|
||||
neutron-domain-email:
|
||||
default: 'email@example.com'
|
||||
type: string
|
||||
description: Email address of the person responsible for the domain.
|
159
charm/hooks/designate.py
Normal file
159
charm/hooks/designate.py
Normal file
@ -0,0 +1,159 @@
|
||||
from charm.openstack.adapters import (
|
||||
OpenStackRelationAdapters,
|
||||
ConfigurationAdapter,
|
||||
DatabaseRelationAdapter,
|
||||
)
|
||||
import subprocess
|
||||
import os
|
||||
from charm.openstack.ip import PUBLIC, INTERNAL, ADMIN
|
||||
from charmhelpers.core.hookenv import config
|
||||
from charmhelpers.core.hookenv import unit_private_ip
|
||||
from charm.openstack.charm import OpenStackCharmFactory, OpenStackCharm
|
||||
|
||||
DESIGNATE_DIR = '/etc/designate'
|
||||
DESIGNATE_DEFAULT = '/etc/default/openstack'
|
||||
DESIGNATE_CONF = DESIGNATE_DIR + '/designate.conf'
|
||||
RNDC_KEY_CONF = DESIGNATE_DIR + '/rndc.key'
|
||||
NOVA_SINK_FILE = DESIGNATE_DIR + '/conf.d/nova_sink.cfg'
|
||||
NEUTRON_SINK_FILE = DESIGNATE_DIR + '/conf.d/neutron_sink.cfg'
|
||||
RC_FILE = '/root/novarc'
|
||||
|
||||
|
||||
class DesignateDBAdapter(DatabaseRelationAdapter):
|
||||
|
||||
def __init__(self, relation):
|
||||
super(DesignateDBAdapter, self).__init__(relation)
|
||||
|
||||
@property
|
||||
def designate_uri(self):
|
||||
return self.get_uri(prefix='designate')
|
||||
|
||||
@property
|
||||
def designate_pool_uri(self):
|
||||
return self.get_uri(prefix='dpm')
|
||||
|
||||
|
||||
class DesignateAdapters(OpenStackRelationAdapters):
|
||||
"""
|
||||
Adapters class for the Designate charm.
|
||||
"""
|
||||
relation_adapters = {
|
||||
'shared_db': DesignateDBAdapter,
|
||||
}
|
||||
|
||||
def __init__(self, relations):
|
||||
super(DesignateAdapters, self).__init__(
|
||||
relations,
|
||||
options=DesignateConfigurationAdapter)
|
||||
|
||||
|
||||
class DesignateCharm(OpenStackCharm):
|
||||
|
||||
packages = ['designate-agent', 'designate-api', 'designate-central',
|
||||
'designate-common', 'designate-mdns', 'designate-pool-manager',
|
||||
'designate-sink', 'designate-zone-manager', 'bind9utils']
|
||||
|
||||
services = ['designate-mdns', 'designate-zone-manager',
|
||||
'designate-agent', 'designate-pool-manager',
|
||||
'designate-central', 'designate-sink',
|
||||
'designate-api']
|
||||
|
||||
api_ports = {
|
||||
'designate-api': {
|
||||
PUBLIC: 9001,
|
||||
ADMIN: 9001,
|
||||
INTERNAL: 9001,
|
||||
}
|
||||
}
|
||||
|
||||
restart_map = {
|
||||
'/etc/default/openstack': services,
|
||||
'/etc/designate/designate.conf': services,
|
||||
'/etc/designate/rndc.key': services,
|
||||
'/etc/designate/conf.d/nova_sink.cfg': services,
|
||||
'/etc/designate/conf.d/neutron_sink.cfg': services,
|
||||
}
|
||||
service_type = 'designate'
|
||||
default_service = 'designate-api'
|
||||
sync_cmd = ['designate-manage', 'database', 'sync']
|
||||
adapters_class = DesignateAdapters
|
||||
|
||||
def render_base_config(self):
|
||||
self.render_configs([RC_FILE, DESIGNATE_CONF, RNDC_KEY_CONF,
|
||||
DESIGNATE_DEFAULT])
|
||||
|
||||
def render_full_config(self):
|
||||
self.render_configs([NOVA_SINK_FILE, NEUTRON_SINK_FILE,
|
||||
DESIGNATE_DEFAULT])
|
||||
|
||||
@classmethod
|
||||
def get_domain_id(cls, domain):
|
||||
get_cmd = ['reactive/designate_utils.py', 'domain-get', domain]
|
||||
output = subprocess.check_output(get_cmd)
|
||||
if output:
|
||||
return output.decode('utf8').strip()
|
||||
|
||||
@classmethod
|
||||
def create_domain(cls, domain, email):
|
||||
create_cmd = ['reactive/designate_utils.py', 'domain-create', domain,
|
||||
email]
|
||||
subprocess.check_call(create_cmd)
|
||||
|
||||
@classmethod
|
||||
def create_server(cls, domain):
|
||||
create_cmd = ['reactive/designate_utils.py', 'server-create', domain]
|
||||
subprocess.check_call(create_cmd)
|
||||
|
||||
@classmethod
|
||||
def create_domains(cls):
|
||||
cls.create_server(config('dns-server-record'))
|
||||
cls.create_domain(config('nova-domain'), config('nova-domain-email'))
|
||||
cls.create_domain(config('neutron-domain'),
|
||||
config('neutron-domain-email'))
|
||||
|
||||
|
||||
class DesignateConfigurationAdapter(ConfigurationAdapter):
|
||||
|
||||
def __init__(self):
|
||||
super(DesignateConfigurationAdapter, self).__init__()
|
||||
|
||||
@property
|
||||
def listen_url(self):
|
||||
return 'http://{}:9001'.format(unit_private_ip())
|
||||
|
||||
@property
|
||||
def listen_ip(self):
|
||||
return unit_private_ip()
|
||||
|
||||
@property
|
||||
def nova_domain_id(self):
|
||||
domain = config('nova-domain')
|
||||
return DesignateCharm.get_domain_id(domain)
|
||||
|
||||
@property
|
||||
def nova_conf_args(self):
|
||||
daemon_arg = ''
|
||||
if os.path.exists(NOVA_SINK_FILE):
|
||||
daemon_arg = '--config-file={}'.format(NOVA_SINK_FILE)
|
||||
return daemon_arg
|
||||
|
||||
@property
|
||||
def neutron_domain_id(self):
|
||||
domain = config('neutron-domain')
|
||||
return DesignateCharm.get_domain_id(domain)
|
||||
|
||||
@property
|
||||
def neutron_conf_args(self):
|
||||
daemon_arg = ''
|
||||
if os.path.exists(NEUTRON_SINK_FILE):
|
||||
daemon_arg = '--config-file={}'.format(NEUTRON_SINK_FILE)
|
||||
return daemon_arg
|
||||
|
||||
|
||||
class DesignateCharmFactory(OpenStackCharmFactory):
|
||||
|
||||
releases = {
|
||||
'liberty': DesignateCharm
|
||||
}
|
||||
|
||||
first_release = 'liberty'
|
29
charm/hooks/install
Executable file
29
charm/hooks/install
Executable file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from glob import glob
|
||||
import os
|
||||
import sys
|
||||
from subprocess import check_call
|
||||
|
||||
|
||||
# Load modules from $CHARM_DIR/lib
|
||||
sys.path.append('lib')
|
||||
|
||||
# bootstrap wheelhouse
|
||||
if os.path.exists('wheelhouse'):
|
||||
check_call(['apt-get', 'install', '-yq', 'python3-pip'])
|
||||
# need newer pip, to fix spurious Double Requirement error https://github.com/pypa/pip/issues/56
|
||||
check_call(['pip3', 'install', '-U', '--no-index', '-f', 'wheelhouse', 'pip'])
|
||||
# install the rest of the wheelhouse deps
|
||||
check_call(['pip3', 'install', '-U', '--no-index', '-f', 'wheelhouse'] + glob('wheelhouse/*'))
|
||||
|
||||
check_call(['apt-get', 'install', '-yq', 'python3-netifaces'])
|
||||
|
||||
# This will load and run the appropriate @hook and other decorated
|
||||
# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
|
||||
# and $CHARM_DIR/hooks/relations.
|
||||
#
|
||||
# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive
|
||||
# for more information on this pattern.
|
||||
from charms.reactive import main
|
||||
main()
|
1
charm/layer.yaml
Normal file
1
charm/layer.yaml
Normal file
@ -0,0 +1 @@
|
||||
includes: ['layer:openstack-principle', 'interface:mysql-shared', 'interface:rabbitmq', 'interface:keystone', 'interface:bind-rndc']
|
27
charm/metadata.yaml
Normal file
27
charm/metadata.yaml
Normal file
@ -0,0 +1,27 @@
|
||||
name: designate
|
||||
summary: Designate provides DNSaaS services for OpenStack
|
||||
maintainer: OpenStack Charmers <openstack-charmers@lists.ubuntu.com>
|
||||
description: |
|
||||
Designate provides DNSaaS services for OpenStack:
|
||||
* REST API for domain/record management
|
||||
* Multi-tenant
|
||||
* Integrated with Keystone for authentication
|
||||
* Framework in place to integrate with Nova and Neutron notifications
|
||||
* Support for PowerDNS and Bind9 out of the box
|
||||
categories:
|
||||
- openstack
|
||||
subordinate: false
|
||||
provides:
|
||||
dnsaas:
|
||||
interface: designate
|
||||
nova-designate:
|
||||
interface: nova-designate
|
||||
requires:
|
||||
shared-db:
|
||||
interface: mysql-shared
|
||||
amqp:
|
||||
interface: rabbitmq
|
||||
identity-service:
|
||||
interface: keystone
|
||||
dns-backend:
|
||||
interface: bind-rndc
|
53
charm/reactive/designate_handlers.py
Normal file
53
charm/reactive/designate_handlers.py
Normal file
@ -0,0 +1,53 @@
|
||||
from charmhelpers.core.hookenv import config, unit_private_ip
|
||||
from charms.reactive import (
|
||||
hook,
|
||||
when,
|
||||
)
|
||||
from designate import DesignateCharmFactory
|
||||
|
||||
|
||||
@hook('install')
|
||||
def install_packages():
|
||||
charm = DesignateCharmFactory.charm()
|
||||
charm.configure_source()
|
||||
charm.install()
|
||||
|
||||
|
||||
@when('amqp.connected')
|
||||
def setup_amqp_req(amqp):
|
||||
amqp.request_access(username=config('rabbit-user'),
|
||||
vhost=config('rabbit-vhost'))
|
||||
|
||||
|
||||
@when('shared-db.connected')
|
||||
def setup_database(database):
|
||||
database.configure(config('database'), config('database-user'),
|
||||
unit_private_ip(), prefix='designate')
|
||||
database.configure('dpm', 'dpm',
|
||||
unit_private_ip(), prefix='dpm')
|
||||
|
||||
|
||||
@when('identity-service.connected')
|
||||
def setup_endpoint(keystone):
|
||||
charm = DesignateCharmFactory.charm()
|
||||
keystone.register_endpoints(charm.service_type,
|
||||
charm.region,
|
||||
charm.public_url,
|
||||
charm.internal_url,
|
||||
charm.admin_url)
|
||||
|
||||
|
||||
@when('dns-backend.available')
|
||||
@when('shared-db.available')
|
||||
@when('identity-service.available')
|
||||
@when('amqp.available')
|
||||
def render_stuff(amqp_interface, identity_interface, db_interface,
|
||||
dns_interface):
|
||||
charm = DesignateCharmFactory.charm(
|
||||
interfaces=[amqp_interface, identity_interface, db_interface,
|
||||
dns_interface]
|
||||
)
|
||||
charm.render_base_config()
|
||||
charm.db_sync()
|
||||
charm.create_domains()
|
||||
charm.render_full_config()
|
119
charm/reactive/designate_utils.py
Executable file
119
charm/reactive/designate_utils.py
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import subprocess
|
||||
import argparse
|
||||
import os
|
||||
|
||||
|
||||
def run_command(cmd):
|
||||
os_env = get_environment()
|
||||
p = subprocess.Popen(cmd, env=os_env, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
out, err = p.communicate()
|
||||
return out, err
|
||||
|
||||
|
||||
def get_environment():
|
||||
env = os.environ
|
||||
with open("/root/novarc", "r") as ins:
|
||||
for line in ins:
|
||||
k, v = line.replace('export', '').replace(" ", "").split('=')
|
||||
env[k] = v.strip()
|
||||
return env
|
||||
|
||||
|
||||
def get_server_id(args, server_name):
|
||||
servers = get_servers()
|
||||
if servers.get(server_name):
|
||||
return servers[server_name]['id']
|
||||
|
||||
|
||||
def get_domain_id(args, domain_name):
|
||||
domains = get_domains()
|
||||
if domains.get(domain_name):
|
||||
return domains[domain_name]['id']
|
||||
|
||||
|
||||
def create_server(args):
|
||||
server_name = args.command[1]
|
||||
server_id = get_server_id(args, server_name)
|
||||
if server_id:
|
||||
return server_id
|
||||
cmd = [
|
||||
'designate', 'server-create',
|
||||
'--name', server_name,
|
||||
'-f', 'value',
|
||||
]
|
||||
out, err = run_command(cmd)
|
||||
return get_server_id(args, server_name)
|
||||
|
||||
|
||||
def create_domain(args):
|
||||
domain_name = args.command[1]
|
||||
domain_email = args.command[2]
|
||||
domain_id = get_domain_id(args, domain_name)
|
||||
if domain_id:
|
||||
return domain_id
|
||||
cmd = [
|
||||
'designate', 'domain-create',
|
||||
'--name', domain_name,
|
||||
'--email', domain_email,
|
||||
'-f', 'value',
|
||||
]
|
||||
out, err = run_command(cmd)
|
||||
return get_domain_id(args, domain_name)
|
||||
|
||||
|
||||
def delete_domain(args, domain_id):
|
||||
cmd = ['domain-delete', domain_id]
|
||||
out, err = run_command(cmd)
|
||||
|
||||
|
||||
def get_domains():
|
||||
domains = {}
|
||||
cmd = ['designate', 'domain-list', '-f', 'value']
|
||||
out, err = run_command(cmd)
|
||||
for line in out.decode('utf8').split('\n'):
|
||||
values = line.split()
|
||||
if values:
|
||||
domains[values[1]] = {
|
||||
'id': values[0],
|
||||
'serial': values[2],
|
||||
}
|
||||
return domains
|
||||
|
||||
|
||||
def get_servers():
|
||||
servers = {}
|
||||
cmd = ['designate', 'server-list', '-f', 'value']
|
||||
out, err = run_command(cmd)
|
||||
for line in out.decode('utf8').split('\n'):
|
||||
values = line.split()
|
||||
if values:
|
||||
servers[values[1]] = {
|
||||
'id': values[0],
|
||||
}
|
||||
return servers
|
||||
|
||||
if __name__ == '__main__':
|
||||
get_environment()
|
||||
parser = argparse.ArgumentParser(description='Manage designate.')
|
||||
parser.add_argument('command', nargs='*', help='designate command')
|
||||
args = parser.parse_args()
|
||||
if args.command[0] == 'domain-create':
|
||||
print(create_domain(args))
|
||||
elif args.command[0] == 'server-create':
|
||||
print(create_server(args))
|
||||
elif args.command[0] == 'domain-get':
|
||||
domain_id = get_domain_id(args, args.command[1])
|
||||
if domain_id:
|
||||
print(domain_id)
|
||||
elif args.command[0] == 'server-get':
|
||||
server_id = get_server_id(args, args.command[1])
|
||||
if server_id:
|
||||
print(server_id)
|
||||
elif args.command[0] == 'domain-delete':
|
||||
domain_id = get_domain_id(args, args.command[1])
|
||||
delete_domain(args, domain_id)
|
||||
elif args.command[0] == 'domain-list':
|
||||
print(get_domains())
|
451
charm/templates/liberty/designate.conf
Normal file
451
charm/templates/liberty/designate.conf
Normal file
@ -0,0 +1,451 @@
|
||||
[DEFAULT]
|
||||
# Where an option is commented out, but filled in this shows the default
|
||||
# value of that optiona aaa
|
||||
|
||||
########################
|
||||
## General Configuration
|
||||
########################
|
||||
# Show more verbose log output (sets INFO log level output)
|
||||
verbose = {{ options.verbose }}
|
||||
|
||||
# Show debugging output in logs (sets DEBUG log level output)
|
||||
debug = {{ options.debug }}
|
||||
|
||||
# Top-level directory for maintaining designate's state
|
||||
#state_path = /var/lib/designate
|
||||
|
||||
# Log Configuration
|
||||
#log_config = None
|
||||
|
||||
# Log directory
|
||||
#logdir = /var/log/designate
|
||||
|
||||
# Driver used for issuing notifications
|
||||
notification_driver = messaging
|
||||
|
||||
# Notification Topics
|
||||
notification_topics = notifications_designate
|
||||
|
||||
# Use "sudo designate-rootwrap /etc/designate/rootwrap.conf" to use the real
|
||||
# root filter facility.
|
||||
# Change to "sudo" to skip the filtering and just run the comand directly
|
||||
#root_helper = sudo designate-rootwrap /etc/designate/rootwrap.conf
|
||||
|
||||
# Which networking API to use, Defaults to neutron
|
||||
#network_api = neutron
|
||||
|
||||
#-----------------------
|
||||
# RabbitMQ Config
|
||||
#-----------------------
|
||||
{% include "parts/section-rabbitmq-oslo" %}
|
||||
#rabbit_userid = guest
|
||||
#rabbit_password = guest
|
||||
#rabbit_virtual_host = /
|
||||
#rabbit_use_ssl = False
|
||||
#rabbit_hosts = 127.0.0.1:5672
|
||||
|
||||
########################
|
||||
## Service Configuration
|
||||
########################
|
||||
#-----------------------
|
||||
# Central Service
|
||||
#-----------------------
|
||||
[service:central]
|
||||
# Number of central worker processes to spawn
|
||||
#workers = None
|
||||
|
||||
# Number of central greenthreads to spawn
|
||||
#threads = 1000
|
||||
|
||||
# Maximum domain name length
|
||||
#max_domain_name_len = 255
|
||||
|
||||
# Maximum recordset name length
|
||||
#max_recordset_name_len = 255
|
||||
|
||||
# Minimum TTL
|
||||
#min_ttl = None
|
||||
|
||||
# The name of the default pool
|
||||
#default_pool_id = '794ccc2c-d751-44fe-b57f-8894c9f5c842'
|
||||
|
||||
## Managed resources settings
|
||||
|
||||
# Email to use for managed resources like domains created by the FloatingIP API
|
||||
#managed_resource_email = hostmaster@example.com.
|
||||
|
||||
# Tenant ID to own all managed resources - like auto-created records etc.
|
||||
#managed_resource_tenant_id = 123456
|
||||
|
||||
#-----------------------
|
||||
# API Service
|
||||
#-----------------------
|
||||
[service:api]
|
||||
# Number of api worker processes to spawn
|
||||
#workers = None
|
||||
|
||||
# Number of api greenthreads to spawn
|
||||
#threads = 1000
|
||||
|
||||
# Enable host request headers
|
||||
#enable_host_header = False
|
||||
|
||||
# The base uri used in responses
|
||||
#api_base_uri = 'http://127.0.0.1:9001/'
|
||||
api_base_uri = '{{ options.listen_url }}'
|
||||
|
||||
# Address to bind the API server
|
||||
#api_host = 0.0.0.0
|
||||
|
||||
# Port the bind the API server to
|
||||
#api_port = 9001
|
||||
|
||||
# Maximum line size of message headers to be accepted. max_header_line may
|
||||
# need to be increased when using large tokens (typically those generated by
|
||||
# the Keystone v3 API with big service catalogs).
|
||||
#max_header_line = 16384
|
||||
|
||||
# Authentication strategy to use - can be either "noauth" or "keystone"
|
||||
#auth_strategy = keystone
|
||||
|
||||
# Enable Version 1 API (deprecated)
|
||||
#enable_api_v1 = True
|
||||
|
||||
# Enabled API Version 1 extensions
|
||||
# Can be one or more of : diagnostics, quotas, reports, sync, touch
|
||||
#enabled_extensions_v1 =
|
||||
|
||||
# Enable Version 2 API
|
||||
#enable_api_v2 = True
|
||||
|
||||
# Enabled API Version 2 extensions
|
||||
#enabled_extensions_v2 =
|
||||
|
||||
# Default per-page limit for the V2 API, a value of None means show all results
|
||||
# by default
|
||||
#default_limit_v2 = 20
|
||||
|
||||
# Max page size in the V2 API
|
||||
#max_limit_v2 = 1000
|
||||
|
||||
# Enable Admin API (experimental)
|
||||
#enable_api_admin = False
|
||||
|
||||
# Enabled Admin API extensions
|
||||
# Can be one or more of : reports, quotas, counts, tenants, zones
|
||||
# zone export is in zones extension
|
||||
#enabled_extensions_admin =
|
||||
|
||||
# Default per-page limit for the Admin API, a value of None means show all results
|
||||
# by default
|
||||
#default_limit_admin = 20
|
||||
|
||||
# Max page size in the Admin API
|
||||
#max_limit_admin = 1000
|
||||
|
||||
# Show the pecan HTML based debug interface (v2 only)
|
||||
# This is only useful for development, and WILL break python-designateclient
|
||||
# if an error occurs
|
||||
#pecan_debug = False
|
||||
|
||||
#-----------------------
|
||||
# Keystone Middleware
|
||||
#-----------------------
|
||||
[keystone_authtoken]
|
||||
#auth_host = 127.0.0.1
|
||||
#auth_port = 35357
|
||||
#auth_protocol = http
|
||||
#admin_tenant_name = service
|
||||
#admin_user = designate
|
||||
#admin_password = designate
|
||||
auth_host = {{ identity_service.auth_host }}
|
||||
auth_port = {{ identity_service.auth_port }}
|
||||
auth_protocol = {{ identity_service.auth_protocol }}
|
||||
admin_tenant_name = {{ identity_service.service_tenant }}
|
||||
admin_user = {{ identity_service.service_username }}
|
||||
admin_password = {{ identity_service.service_password }}
|
||||
|
||||
#-----------------------
|
||||
# Sink Service
|
||||
#-----------------------
|
||||
[service:sink]
|
||||
# List of notification handlers to enable, configuration of these needs to
|
||||
# correspond to a [handler:my_driver] section below or else in the config
|
||||
# Can be one or more of : nova_fixed, neutron_floatingip
|
||||
enabled_notification_handlers = nova_fixed, neutron_floatingip
|
||||
|
||||
#-----------------------
|
||||
# mDNS Service
|
||||
#-----------------------
|
||||
[service:mdns]
|
||||
# Number of mdns worker processes to spawn
|
||||
#workers = None
|
||||
|
||||
# Number of mdns greenthreads to spawn
|
||||
#threads = 1000
|
||||
|
||||
# mDNS Bind Host
|
||||
#host = 0.0.0.0
|
||||
|
||||
# mDNS Port Number
|
||||
#port = 5354
|
||||
|
||||
# mDNS TCP Backlog
|
||||
#tcp_backlog = 100
|
||||
|
||||
# mDNS TCP Receive Timeout
|
||||
#tcp_recv_timeout = 0.5
|
||||
|
||||
# Enforce all incoming queries (including AXFR) are TSIG signed
|
||||
#query_enforce_tsig = False
|
||||
|
||||
# Send all traffic over TCP
|
||||
#all_tcp = False
|
||||
|
||||
# Maximum message size to emit
|
||||
#max_message_size = 65535
|
||||
|
||||
#-----------------------
|
||||
# Agent Service
|
||||
#-----------------------
|
||||
[service:agent]
|
||||
#workers = None
|
||||
#host = 0.0.0.0
|
||||
#port = 5358
|
||||
#tcp_backlog = 100
|
||||
#allow_notify = 127.0.0.1
|
||||
#masters = 127.0.0.1:5354
|
||||
#backend_driver = fake
|
||||
#transfer_source = None
|
||||
#notify_delay = 0
|
||||
|
||||
#-----------------------
|
||||
# Zone Manager Service
|
||||
#-----------------------
|
||||
[service:zone_manager]
|
||||
# Number of Zone Manager worker processes to spawn
|
||||
#workers = None
|
||||
|
||||
# Number of Zone Manager greenthreads to spawn
|
||||
#threads = 1000
|
||||
|
||||
# List of Zone Manager tasks to enable, a value of None will enable all tasks.
|
||||
# Can be one or more of: periodic_exists
|
||||
#enabled_tasks = None
|
||||
|
||||
# Whether to allow synchronous zone exports
|
||||
#export_synchronous = True
|
||||
|
||||
#------------------------
|
||||
# Deleted domains purging
|
||||
#------------------------
|
||||
[zone_manager_task:domain_purge]
|
||||
# How frequently to purge deleted domains, in seconds
|
||||
#interval = 3600 # 1h
|
||||
|
||||
# How many records to be deleted on each run
|
||||
#batch_size = 100
|
||||
|
||||
# How old deleted records should be (deleted_at) to be purged, in seconds
|
||||
#time_threshold = 604800 # 7 days
|
||||
|
||||
#-----------------------
|
||||
# Pool Manager Service
|
||||
#-----------------------
|
||||
[service:pool_manager]
|
||||
# Number of Pool Manager worker processes to spawn
|
||||
#workers = None
|
||||
|
||||
# Number of Pool Manager greenthreads to spawn
|
||||
#threads = 1000
|
||||
|
||||
# The ID of the pool managed by this instance of the Pool Manager
|
||||
pool_id = 794ccc2c-d751-44fe-b57f-8894c9f5c842
|
||||
|
||||
# The percentage of servers requiring a successful update for a domain change
|
||||
# to be considered active
|
||||
#threshold_percentage = 100
|
||||
|
||||
# The time to wait for a response from a server
|
||||
#poll_timeout = 30
|
||||
|
||||
# The time between retrying to send a request and waiting for a response from a
|
||||
# server
|
||||
#poll_retry_interval = 15
|
||||
|
||||
# The maximum number of times to retry sending a request and wait for a
|
||||
# response from a server
|
||||
#poll_max_retries = 10
|
||||
|
||||
# The time to wait before sending the first request to a server
|
||||
#poll_delay = 5
|
||||
|
||||
# Enable the recovery thread
|
||||
#enable_recovery_timer = True
|
||||
|
||||
# The time between recovering from failures
|
||||
#periodic_recovery_interval = 120
|
||||
|
||||
# Enable the sync thread
|
||||
#enable_sync_timer = True
|
||||
|
||||
# The time between synchronizing the servers with storage
|
||||
#periodic_sync_interval = 1800
|
||||
|
||||
# Zones Updated within last N seconds will be syncd. Use None to sync all zones
|
||||
#periodic_sync_seconds = None
|
||||
|
||||
# The cache driver to use
|
||||
#cache_driver = memcache
|
||||
|
||||
###################################
|
||||
## Pool Manager Cache Configuration
|
||||
###################################
|
||||
#-----------------------
|
||||
# SQLAlchemy Pool Manager Cache
|
||||
#-----------------------
|
||||
[pool_manager_cache:sqlalchemy]
|
||||
connection = {{ shared_db.designate_pool_uri }}
|
||||
#connection = sqlite:///$state_path/designate_pool_manager.sqlite
|
||||
#connection_debug = 100
|
||||
#connection_trace = False
|
||||
#sqlite_synchronous = True
|
||||
#idle_timeout = 3600
|
||||
#max_retries = 10
|
||||
#retry_interval = 10
|
||||
|
||||
#-----------------------
|
||||
# Memcache Pool Manager Cache
|
||||
#-----------------------
|
||||
[pool_manager_cache:memcache]
|
||||
#memcached_servers = None
|
||||
#expiration = 3600
|
||||
|
||||
#####################
|
||||
## Pool Configuration
|
||||
#####################
|
||||
|
||||
# This section does not have the defaults filled in but demonstrates an
|
||||
# example pool / server set up. Different backends will have different options.
|
||||
|
||||
[pool:794ccc2c-d751-44fe-b57f-8894c9f5c842]
|
||||
nameservers = 0f66b842-96c2-4189-93fc-1dc95a08b012
|
||||
targets = f26e0b32-736f-4f0a-831b-039a415c481e
|
||||
also_notifies = {{ dns_backend.private_address }}:53
|
||||
|
||||
[pool_nameserver:0f66b842-96c2-4189-93fc-1dc95a08b012]
|
||||
port = 53
|
||||
host = {{ dns_backend.private_address }}
|
||||
|
||||
[pool_target:f26e0b32-736f-4f0a-831b-039a415c481e]
|
||||
#options = rndc_host: 192.168.27.100, rndc_port: 953, rndc_config_file: /etc/bind/rndc.conf, rndc_key_file: /etc/bind/rndc.key, port: 53, host: 192.168.27.100, clean_zonefile: false
|
||||
options = rndc_host: {{ dns_backend.private_address }}, rndc_key_file: /etc/designate/rndc.key
|
||||
masters = {{ options.listen_ip }}:5354
|
||||
type = bind9
|
||||
#port = 53
|
||||
#host = {{ options.dns_backend }}
|
||||
|
||||
|
||||
##############
|
||||
## Network API
|
||||
##############
|
||||
[network_api:neutron]
|
||||
# Comma separated list of values, formatted "<name>|<neutron_uri>"
|
||||
#endpoints = RegionOne|http://localhost:9696
|
||||
#endpoint_type = publicURL
|
||||
#timeout = 30
|
||||
#admin_username = designate
|
||||
#admin_password = designate
|
||||
#admin_tenant_name = designate
|
||||
#auth_url = http://localhost:35357/v2.0
|
||||
#insecure = False
|
||||
#auth_strategy = keystone
|
||||
#ca_certificates_file =
|
||||
|
||||
########################
|
||||
## Storage Configuration
|
||||
########################
|
||||
#-----------------------
|
||||
# SQLAlchemy Storage
|
||||
#-----------------------
|
||||
[storage:sqlalchemy]
|
||||
# Database connection string - to configure options for a given implementation
|
||||
# like sqlalchemy or other see below
|
||||
#connection = sqlite:///$state_path/designate.sqlite
|
||||
connection = {{ shared_db.designate_uri }}
|
||||
#connection_debug = 0
|
||||
#connection_trace = False
|
||||
#sqlite_synchronous = True
|
||||
#idle_timeout = 3600
|
||||
#max_retries = 10
|
||||
#retry_interval = 10
|
||||
|
||||
########################
|
||||
## Handler Configuration
|
||||
########################
|
||||
#-----------------------
|
||||
# Nova Fixed Handler
|
||||
#-----------------------
|
||||
#format = '%(hostname)s.%(domain)s'
|
||||
|
||||
#------------------------
|
||||
# Neutron Floating Handler
|
||||
#------------------------
|
||||
[handler:neutron_floatingip]
|
||||
# Domain ID of domain to create records in. Should be pre-created
|
||||
domain_id = a2cd66c5-a1ec-47ae-b0dc-718ebb024a45
|
||||
notification_topics = notifications_designate
|
||||
control_exchange = 'neutron'
|
||||
format = '%(octet0)s-%(octet1)s-%(octet2)s-%(octet3)s.%(domain)s'
|
||||
#format = '%(hostname)s.%(domain)s'
|
||||
|
||||
#############################
|
||||
## Agent Backend Configuration
|
||||
#############################
|
||||
[backend:agent:bind9]
|
||||
rndc_host = {{ dns_backend.private_address }}
|
||||
rndc_port = 953
|
||||
#rndc_config_file = /etc/rndc.conf
|
||||
#rndc_key_file = /etc/rndc.key
|
||||
#zone_file_path = $state_path/zones
|
||||
#query_destination = 127.0.0.1
|
||||
#
|
||||
[backend:agent:denominator]
|
||||
#name = dynect
|
||||
#config_file = /etc/denominator.conf
|
||||
|
||||
########################
|
||||
## Library Configuration
|
||||
########################
|
||||
[oslo_concurrency]
|
||||
# Path for Oslo Concurrency to store lock files, defaults to the value
|
||||
# of the state_path setting.
|
||||
#lock_path = $state_path
|
||||
|
||||
########################
|
||||
## Coordination
|
||||
########################
|
||||
[coordination]
|
||||
# URL for the coordination backend to use.
|
||||
#backend_url = kazoo://127.0.0.1/
|
||||
|
||||
########################
|
||||
## Hook Points
|
||||
########################
|
||||
# Hook Points are enabled when added to the config and there has been
|
||||
# a package that provides the corresponding named designate.hook_point
|
||||
# entry point.
|
||||
|
||||
# [hook_point:name_of_hook_point]
|
||||
# some_param_for_hook = 42
|
||||
# Hooks can be disabled in the config
|
||||
# enabled = False
|
||||
|
||||
# Hook can also be applied to the import path when the hook has not
|
||||
# been given an explicit name. The name is created from the hook
|
||||
# target function / method:
|
||||
#
|
||||
# name = '%s.%s' % (func.__module__, func.__name__)
|
||||
|
||||
# [hook_point:designate.api.v2.controllers.zones.get_one]
|
||||
|
5
charm/templates/liberty/neutron_sink.cfg
Normal file
5
charm/templates/liberty/neutron_sink.cfg
Normal file
@ -0,0 +1,5 @@
|
||||
[handler:neutron_floatingip]
|
||||
domain_id = {{ options.neutron_domain_id }}
|
||||
notification_topics = notifications_designate
|
||||
control_exchange = 'neutron'
|
||||
format = '%(octet0)s-%(octet1)s-%(octet2)s-%(octet3)s.%(domain)s'
|
5
charm/templates/liberty/nova_sink.cfg
Normal file
5
charm/templates/liberty/nova_sink.cfg
Normal file
@ -0,0 +1,5 @@
|
||||
[handler:nova_fixed]
|
||||
domain_id = {{ options.nova_domain_id }}
|
||||
notification_topics = notifications_designate
|
||||
control_exchange = 'nova'
|
||||
format = '%(hostname)s.%(domain)s'
|
6
charm/templates/novarc
Normal file
6
charm/templates/novarc
Normal file
@ -0,0 +1,6 @@
|
||||
export OS_AUTH_URL=http://{{ identity_service.auth_host }}:{{ identity_service.auth_port }}/v2.0
|
||||
export OS_TENANT_NAME={{ identity_service.service_tenant }}
|
||||
export OS_USERNAME={{ identity_service.service_username }}
|
||||
export OS_PASSWORD={{ identity_service.service_password }}
|
||||
export OS_REGION_NAME={{ options.region }}
|
||||
|
1
charm/templates/openstack
Normal file
1
charm/templates/openstack
Normal file
@ -0,0 +1 @@
|
||||
DAEMON_ARGS="{{ options.nova_conf_args }} {{ options.neutron_conf_args }}"
|
4
charm/templates/rndc.key
Normal file
4
charm/templates/rndc.key
Normal file
@ -0,0 +1,4 @@
|
||||
key "rndc-key" {
|
||||
algorithm {{ dns_backend.algorithm }}
|
||||
secret {{ dns_backend.rndckey }}
|
||||
};
|
10
designate.yaml
Normal file
10
designate.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
# vim: set ts=2 et:
|
||||
# deployer bundle for development ('next') charms
|
||||
# UOSCI relies on this for OS-on-OS deployment testing
|
||||
openstack-services:
|
||||
series: trusty
|
||||
services:
|
||||
designate:
|
||||
charm: designate
|
||||
options:
|
||||
openstack-origin: cloud:trusty-liberty
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
charm-tools
|
||||
flake8
|
25
setup.sh
Executable file
25
setup.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
export http_proxy=http://squid.internal:3128
|
||||
export https_proxy=http://squid.internal:3128
|
||||
export JUJU_REPOSITORY="$(pwd)/build"
|
||||
export INTERFACE_PATH=interfaces
|
||||
export LAYER_PATH=layers
|
||||
rm -rf $JUJU_REPOSITORY
|
||||
mkdir -p $JUJU_REPOSITORY
|
||||
if [[ ! -d $INTERFACE_PATH ]]; then
|
||||
mkdir $INTERFACE_PATH
|
||||
( cd $INTERFACE_PATH;
|
||||
git clone git+ssh://git.launchpad.net/~gnuoy/charms/+source/interface-bind-rndc bind-rndc; )
|
||||
fi
|
||||
if [[ ! -d $LAYER_PATH ]]; then
|
||||
mkdir $LAYER_PATH
|
||||
( cd $LAYER_PATH;
|
||||
git clone git+ssh://git.launchpad.net/~openstack-charmers-layers/charms/+source/reactive-openstack-api-layer openstack-api;
|
||||
git clone git+ssh://git.launchpad.net/~openstack-charmers-layers/charms/+source/reactive-openstack-principle-layer openstack-principle;
|
||||
git clone git+ssh://git.launchpad.net/~gnuoy/charms/+source/reactive-openstack-layer openstack; )
|
||||
fi
|
||||
make clean
|
||||
make generate
|
||||
# ./kill_charms.sh designate
|
||||
#juju-deployer -c barbican.yaml
|
||||
echo $JUJU_REPOSITORY
|
28
tox.ini
Normal file
28
tox.ini
Normal file
@ -0,0 +1,28 @@
|
||||
[tox]
|
||||
skipsdist = True
|
||||
envlist = generate
|
||||
|
||||
[testenv]
|
||||
setenv = VIRTUAL_ENV={envdir}
|
||||
PYTHONHASHSEED=0
|
||||
TERM=linux
|
||||
INTERFACE_PATH={toxinidir}/interfaces
|
||||
LAYER_PATH={toxinidir}/layers
|
||||
JUJU_REPOSITORY={toxinidir}/build
|
||||
passenv = http_proxy https_proxy
|
||||
install_command =
|
||||
pip install {opts} {packages}
|
||||
deps =
|
||||
-r{toxinidir}/requirements.txt
|
||||
|
||||
[testenv:generate]
|
||||
basepython = python2.7
|
||||
commands =
|
||||
charm generate --log-level DEBUG -o {toxinidir}/build charm
|
||||
|
||||
[testenv:venv]
|
||||
commands = {posargs}
|
||||
|
||||
[testenv:lint]
|
||||
basepython = python2.7
|
||||
commands = flake8 {posargs} charm/reactive charm/tests
|
Loading…
Reference in New Issue
Block a user