From 1420d63c7f9edc91fba5d2a50ae89a52e3f9b5fc Mon Sep 17 00:00:00 2001
From: Michal Rostecki <michal.rostecki@allegrogroup.com>
Date: Mon, 8 Jun 2015 20:22:53 +0200
Subject: [PATCH] Add designate-sink service

Container for Designate Sink, automatic domain creation for
enabled notification handlers (nova and/or neutron).

Change-Id: I41118cb149e7f39a17bff49123d82905b51b7939
Blueprint: designate-container
---
 compose/designate.yml                         | 11 ++++
 .../designate-base/config-designate.sh        | 17 +++++
 .../designate/designate-sink/Dockerfile       | 11 ++++
 .../binary/designate/designate-sink/build     |  1 +
 .../binary/designate/designate-sink/start.sh  | 64 +++++++++++++++++++
 docs/integration-guide.md                     |  5 ++
 tools/genenv                                  |  8 +++
 7 files changed, 117 insertions(+)
 create mode 100644 docker/centos/binary/designate/designate-sink/Dockerfile
 create mode 120000 docker/centos/binary/designate/designate-sink/build
 create mode 100755 docker/centos/binary/designate/designate-sink/start.sh

diff --git a/compose/designate.yml b/compose/designate.yml
index 96d0219528..05ae7b53ba 100644
--- a/compose/designate.yml
+++ b/compose/designate.yml
@@ -52,3 +52,14 @@ designatemdns:
   restart: always
   env_file:
    - openstack.env
+
+# The Sink service gets notifications from the message queue about events like
+# instance creation/deletion or floating IP association/disassociation.
+# It then creates records for instances included in events.
+designatesink:
+  image: kollaglue/centos-rdo-designate-sink:latest
+  name: designate-sink
+  net: "host"
+  restart: always
+  env_file:
+   - openstack.env
diff --git a/docker/centos/binary/designate/designate-base/config-designate.sh b/docker/centos/binary/designate/designate-base/config-designate.sh
index 5a31401eec..6edfd1bd24 100755
--- a/docker/centos/binary/designate/designate-base/config-designate.sh
+++ b/docker/centos/binary/designate/designate-base/config-designate.sh
@@ -4,6 +4,23 @@ set -e
 
 . /opt/kolla/kolla-common.sh
 
+get_or_create_domain() {
+    local DOMAIN_NAME=$1
+
+    DOMAIN_ID=$(designate domain-create --name $DOMAIN_NAME | awk '/id/ { print $4; }')
+    # Searching domain if not created
+    if [ -z $DOMAIN_ID ]; then
+        DOMAIN_ID=$(designate domain-list | awk "/$DOMAIN_NAME/ { print \$2; }")
+    fi
+    # Fail if domain still don't exist
+    if [ -z $DOMAIN_ID ]; then
+        echo "Creating domain failed" 1>&2
+        exit 1
+    fi
+
+    echo $DOMAIN_ID
+}
+
 check_required_vars DESIGNATE_DB_PASSWORD DESIGNATE_KEYSTONE_PASSWORD \
                     KEYSTONE_PUBLIC_SERVICE_HOST RABBITMQ_SERVICE_HOST \
                     DESIGNATE_BIND9_RNDC_KEY DESIGNATE_BACKEND \
diff --git a/docker/centos/binary/designate/designate-sink/Dockerfile b/docker/centos/binary/designate/designate-sink/Dockerfile
new file mode 100644
index 0000000000..5c7f58fb99
--- /dev/null
+++ b/docker/centos/binary/designate/designate-sink/Dockerfile
@@ -0,0 +1,11 @@
+FROM %%KOLLA_NAMESPACE%%/%%KOLLA_PREFIX%%designate-base:%%KOLLA_TAG%%
+MAINTAINER Kolla Project (https://launchpad.net/kolla)
+
+RUN yum install -y \
+    openstack-designate-sink \
+    python-designateclient \
+    && yum clean all
+
+COPY start.sh /start.sh
+
+CMD ["/start.sh"]
diff --git a/docker/centos/binary/designate/designate-sink/build b/docker/centos/binary/designate/designate-sink/build
new file mode 120000
index 0000000000..ec19138031
--- /dev/null
+++ b/docker/centos/binary/designate/designate-sink/build
@@ -0,0 +1 @@
+../../../../../tools/build-docker-image
\ No newline at end of file
diff --git a/docker/centos/binary/designate/designate-sink/start.sh b/docker/centos/binary/designate/designate-sink/start.sh
new file mode 100755
index 0000000000..a6a3a4bacb
--- /dev/null
+++ b/docker/centos/binary/designate/designate-sink/start.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+set -e
+
+. /opt/kolla/kolla-common.sh
+. /opt/kolla/config-designate.sh
+
+CONF=/etc/designate/designate.conf
+
+configure_nova_handler() {
+    local DOMAIN_ID=$1
+
+    crudini --set $CONF handler:nova_fixed domain_id "$DOMAIN_ID"
+    crudini --set $CONF handler:nova_fixed notification_topics "notifications"
+    crudini --set $CONF handler:nova_fixed control_exchange "nova"
+    # Configuring multiple record formats
+    for FORMAT in $DESIGNATE_SINK_NOVA_FORMATS; do
+        crudini --set $CONF handler:nova_fixed format "$FORMAT"
+    done
+}
+
+configure_neutron_handler() {
+    local DOMAIN_ID=$1
+
+    crudini --set $CONF handler:neutron_floatingip domain_id "$DOMAIN_ID"
+    crudini --set $CONF handler:neutron_floatingip notification_topics "notifications"
+    crudini --set $CONF handler:neutron_floatingip control_exchange "neutron"
+    # Configuring multiple record formats
+    for FORMAT in $DESIGNATE_SINK_NEUTRON_FORMATS; do
+        crudini --set $CONF handler:neutron_floatingip format "$FORMAT"
+    done
+}
+
+check_required_vars DESIGNATE_API_SERVICE_HOST DESIGNATE_API_SERVICE_PORT \
+                    DESIGNATE_DEFAULT_POOL_NS_RECORD
+
+check_for_os_service_endpoint designate DESIGNATE_API_SERVICE_HOST DESIGNATE_API_SERVICE_PORT || exit $?
+
+if [ -z "$DESIGNATE_SINK_NOVA_DOMAIN_NAME" && -z "$DESIGNATE_SINK_NEUTRON_DOMAIN_NAME" ]; then
+    echo "Please specify either Nova or Neutron domain name for Designate Sink"
+    exit 1
+fi
+
+designate server-create --name ${DESIGNATE_DEFAULT_POOL_NS_RECORD}
+if [ $? != 0 ]; then
+    echo "Creating server failed" 1>&2
+    exit 1
+fi
+
+if [ -n "$DESIGNATE_SINK_NOVA_DOMAIN_NAME" ]; then
+    NOVA_DOMAIN_ID=$(get_or_create_domain $DESIGNATE_SINK_NOVA_DOMAIN_NAME)
+    configure_nova_handler $NOVA_DOMAIN_ID
+    HANDLERS="nova_fixed"
+fi
+
+if [ -n "$DESIGNATE_SINK_NEUTRON_DOMAIN_NAME" ]; then
+    NEUTRON_DOMAIN_ID=$(get_or_create_domain $DESIGNATE_SINK_NEUTRON_DOMAIN_NAME)
+    configure_neutron_handler $NEUTRON_DOMAIN_ID
+    [ -n "$HANDLERS" ] && HANDLERS+=","
+    HANDLERS+="neutron_floatingip"
+fi
+
+crudini --set $CONF service:sink enabled_notification_handlers "$HANDLERS"
+
+exec /usr/bin/designate-sink
diff --git a/docs/integration-guide.md b/docs/integration-guide.md
index eb7c475b19..a1989eaf5f 100644
--- a/docs/integration-guide.md
+++ b/docs/integration-guide.md
@@ -137,6 +137,11 @@ all containers.  This allows a simple method of ensuring every type of node
     DESIGNATE_DNS_PORT=<53> - The port of the Designate-backed DNS slaves that are used by the world
     DESIGNATE_INITDB=<true|false> - Configures if the database should be created and initialised
     DESIGNATE_ALLOW_RECURSION=<true|false> - Configure a recursive nameserver
+    DESIGNATE_DEFAULT_POOL_NS_RECORD=<ns1.example.org.> - Name of server used to generate NS records
+    DESIGNATE_SINK_NOVA_DOMAIN_NAME=<nova.example.org.> - Name of domain used to create records from Nova notifications
+    DESIGNATE_SINK_NEUTRON_DOMAIN_NAME=<neutron.example.org.> - Name of domain used to create records from Neutron notifications
+    DESIGNATE_SINK_NOVA_FORMATS=<("%(octet0)s-%(octet1)s-%(octet2)s-%(octet3)s.%(domain)s" "%(hostname)s.%(domain)s")> - List of formats for records that will be created by Nova handler
+    DESIGNATE_SINK_NEUTRON_FORMATS=<("%(octet0)s-%(octet1)s-%(octet2)s-%(octet3)s.%(domain)s" "%(hostname)s.%(domain)s")> - List of formats for records that will be created by Neutron handler
 
 
 [Minimum environment variable setup guide.](https://github.com/stackforge/kolla/blob/master/docs/minimal-environment-vars.md)
diff --git a/tools/genenv b/tools/genenv
index e7a30a9c49..e182f66ed5 100755
--- a/tools/genenv
+++ b/tools/genenv
@@ -151,6 +151,11 @@ DESIGNATE_POOLMAN_TARGETS=$(uuidgen)
 DESIGNATE_POOLMAN_NSS=$(uuidgen)
 DESIGNATE_INITDB=true
 DESIGNATE_ALLOW_RECURSION=true
+DESIGNATE_DEFAULT_POOL_NS_RECORD=ns1.example.org.
+DESIGNATE_SINK_NOVA_DOMAIN_NAME=nova.example.org.
+DESIGNATE_SINK_NEUTRON_DOMAIN_NAME=neutron.example.org.
+DESIGNATE_SINK_NOVA_FORMATS=("%(octet0)s-%(octet1)s-%(octet2)s-%(octet3)s.%(domain)s" "%(hostname)s.%(domain)s")
+DESIGNATE_SINK_NEUTRON_FORMATS=("%(octet0)s-%(octet1)s-%(octet2)s-%(octet3)s.%(domain)s" "%(hostname)s.%(domain)s")
 
 cat > ./openrc <<EOF
 export OS_AUTH_URL="http://${KEYSTONE_PUBLIC_SERVICE_HOST}:5000/v2.0"
@@ -260,6 +265,9 @@ DESIGNATE_POOLMAN_TARGETS=$DESIGNATE_POOLMAN_TARGETS
 DESIGNATE_POOLMAN_NSS=$DESIGNATE_POOLMAN_NSS
 DESIGNATE_INITDB=$DESIGNATE_INITDB
 DESIGNATE_ALLOW_RECURSION=$DESIGNATE_ALLOW_RECURSION
+DESIGNATE_DEFAULT_POOL_NS_RECORD=$DESIGNATE_DEFAULT_POOL_NS_RECORD
+DESIGNATE_SINK_NOVA_DOMAIN_NAME=$DESIGNATE_SINK_NOVA_DOMAIN_NAME
+DESIGNATE_SINK_NEUTRON_DOMAIN_NAME=$DESIGNATE_SINK_NEUTRON_DOMAIN_NAME
 DB_CLUSTER_BIND_ADDRESS=$DB_CLUSTER_BIND_ADDRESS
 DB_CLUSTER_INIT_DB=$DB_CLUSTER_INIT_DB
 DB_CLUSTER_NAME=$DB_CLUSTER_NAME