Initial baseline

This commit is contained in:
James Page 2016-02-11 10:03:13 +00:00
commit 86ab342e02
22 changed files with 1075 additions and 0 deletions

4
.bzrignore Normal file
View File

@ -0,0 +1,4 @@
build
layers
.tox
interfaces

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
build
layers
.tox
interfaces

8
Makefile Normal file
View File

@ -0,0 +1,8 @@
#!/usr/bin/make
LAYER_PATH := layers
clean:
rm -Rf build
generate: clean
LAYER_PATH=$(LAYER_PATH) tox -e generate

2
TODO Normal file
View File

@ -0,0 +1,2 @@
status
floating ip records

87
bind-install.sh Executable file
View 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
View 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
View 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
View 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
View File

@ -0,0 +1 @@
includes: ['layer:openstack-principle', 'interface:mysql-shared', 'interface:rabbitmq', 'interface:keystone', 'interface:bind-rndc']

27
charm/metadata.yaml Normal file
View 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

View 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
View 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())

View 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]

View 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'

View 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
View 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 }}

View File

@ -0,0 +1 @@
DAEMON_ARGS="{{ options.nova_conf_args }} {{ options.neutron_conf_args }}"

4
charm/templates/rndc.key Normal file
View File

@ -0,0 +1,4 @@
key "rndc-key" {
algorithm {{ dns_backend.algorithm }}
secret {{ dns_backend.rndckey }}
};

10
designate.yaml Normal file
View 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
View File

@ -0,0 +1,2 @@
charm-tools
flake8

25
setup.sh Executable file
View 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
View 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