Skip to content

Instantly share code, notes, and snippets.

@gnuoy
Created February 16, 2018 15:01
Show Gist options
  • Save gnuoy/4d408eef3d9b71037b6f523476b8bcac to your computer and use it in GitHub Desktop.
Save gnuoy/4d408eef3d9b71037b6f523476b8bcac to your computer and use it in GitHub Desktop.
diff --git a/src/actions.yaml b/src/actions.yaml
new file mode 100644
index 0000000..46edcec
--- /dev/null
+++ b/src/actions.yaml
@@ -0,0 +1,10 @@
+add-sink-config:
+ description: |
+ Add one of the pre-defined sink configs
+ params:
+ sink-config:
+ type: string
+ description: Name of predefined sink config
+ domain-id:
+ type: string
+ description: uuid of domain for records to be added to
diff --git a/src/actions/actions.py b/src/actions/actions.py
new file mode 100755
index 0000000..ed7954a
--- /dev/null
+++ b/src/actions/actions.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python3
+#
+# Copyright 2018 Canonical Ltd
+#
+# 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 json
+import os
+import sys
+
+# Load modules from $CHARM_DIR/lib
+sys.path.append('lib')
+
+from charms.layer import basic
+basic.bootstrap_charm_deps()
+basic.init_config_states()
+
+import charms.reactive as reactive
+import charmhelpers.core.hookenv as hookenv
+import charms_openstack.charm
+
+import charm.openstack.designate # noqa
+
+
+ACTION_CONFIG_LIST_KEY = 'action-config-list'
+
+
+def add_action_config(config_file, config_ns, context):
+ leader_settings = hookenv.leader_get()
+ config_list = {}
+ if leader_settings.get(ACTION_CONFIG_LIST_KEY):
+ config_list = json.loads(leader_settings.get(ACTION_CONFIG_LIST_KEY))
+ config_list[config_ns] = {
+ 'config_file': config_file,
+ 'context': context}
+ hookenv.leader_set({ACTION_CONFIG_LIST_KEY: json.dumps(config_list)})
+ reactive.set_state('action.config-render')
+ reactive.main()
+
+
+def add_sink_config(*args):
+ if not hookenv.is_leader():
+ return
+ action_config = hookenv.action_get()
+ add_action_config(
+ config_file='/etc/designate/conf.d/{}.cfg'.format(
+ action_config['sink-config']),
+ config_ns=action_config['sink-config'],
+ context={'domain_id': action_config['domain-id']})
+
+# Actions to function mapping, to allow for illegal python action names that
+# can map to a python function.
+
+ACTIONS = {
+ "add-sink-config": add_sink_config,
+}
+
+
+
+def main(args):
+ action_name = os.path.basename(args[0])
+ try:
+ action = ACTIONS[action_name]
+ except KeyError:
+ return "Action %s undefined" % action_name
+ else:
+ try:
+ action(args)
+ except Exception as e:
+ hookenv.action_fail(str(e))
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv))
+
diff --git a/src/actions/add-sink-config b/src/actions/add-sink-config
new file mode 100755
index 0000000..7cbe43b
--- /dev/null
+++ b/src/actions/add-sink-config
@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+#
+# Copyright 2018 Canonical Ltd
+#
+# 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 json
+import os
+import sys
+
+# Load modules from $CHARM_DIR/lib
+sys.path.append('lib')
+
+from charms.layer import basic
+basic.bootstrap_charm_deps()
+basic.init_config_states()
+
+import charms.reactive as reactive
+import charmhelpers.core.hookenv as hookenv
+import charms_openstack.charm
+
+import charm.openstack.designate # noqa
+
+
+ACTION_CONFIG_LIST_KEY = 'action-config-list'
+
+
+def add_action_config(config_file, config_ns, context):
+ leader_settings = hookenv.leader_get()
+ config_list = {}
+ if leader_settings.get(ACTION_CONFIG_LIST_KEY):
+ config_list = json.loads(leader_settings.get(ACTION_CONFIG_LIST_KEY))
+ config_list[config_ns] = {
+ 'config_file': config_file,
+ 'context': context}
+ hookenv.leader_set({ACTION_CONFIG_LIST_KEY: json.dumps(config_list)})
+ reactive.set_state('action.config-render')
+ reactive.main()
+
+
+def add_sink_config(*args):
+ print(hookenv.is_leader())
+ action_config = hookenv.action_get()
+ add_action_config(
+ config_file='/etc/designate/conf.d/{}.cfg'.format(
+ action_config['sink-config']),
+ config_ns=action_config['sink-config'],
+ context={'domain_id': action_config['domain-id']})
+
+# Actions to function mapping, to allow for illegal python action names that
+# can map to a python function.
+
+ACTIONS = {
+ "add-sink-config": add_sink_config,
+}
+
+
+
+def main(args):
+ action_name = os.path.basename(args[0])
+ try:
+ action = ACTIONS[action_name]
+ except KeyError:
+ return "Action %s undefined" % action_name
+ else:
+ try:
+ action(args)
+ except Exception as e:
+ hookenv.action_fail(str(e))
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv))
+
diff --git a/src/lib/charm/openstack/designate.py b/src/lib/charm/openstack/designate.py
index 961bce6..224d6df 100644
--- a/src/lib/charm/openstack/designate.py
+++ b/src/lib/charm/openstack/designate.py
@@ -14,6 +14,8 @@
import collections
import contextlib
+import copy
+import json
import os
import subprocess
import uuid
@@ -206,6 +208,8 @@ class DesignateConfigurationAdapter(
return DesignateCharm.get_domain_id(domain)
return None
+
+
@property
def nova_conf_args(self):
"""Returns config file directive to point daemons at nova config file.
@@ -251,6 +255,14 @@ class DesignateConfigurationAdapter(
rndc_master_ips.append(rndc_master_ip)
return rndc_master_ips
+ @property
+ def action_args(self):
+ action_ctxt = {}
+ contexts = json.loads(hookenv.leader_get(attribute='action-config-list'))
+ for key, value in contexts.items():
+ action_ctxt[key] = value['context']
+ return action_ctxt
+
class DesignateAdapters(openstack_adapters.OpenStackAPIRelationAdapters):
"""
@@ -327,6 +339,24 @@ class DesignateCharm(openstack_charm.HAOpenStackCharm):
release = ch_utils.os_release('python-keystonemiddleware')
super(DesignateCharm, self).__init__(release=release, **kwargs)
+ @property
+ def full_restart_map(self):
+ """Map of services to be restarted if a file changes
+
+ @return {
+ 'file1': ['svc1', 'svc3'],
+ 'file2': ['svc2', 'svc3'],
+ ...
+ }
+ """
+ restart_map = copy.deepcopy(self.restart_map)
+ extra_configs = json.loads(hookenv.leader_get(attribute='action-config-list'))
+ for key in extra_configs.keys():
+ config_file = extra_configs[key]['config_file']
+ restart_map[config_file] = self.services
+ return restart_map
+
+
def install(self):
"""Customise the installation, configure the source and then call the
parent install() method to install the packages
diff --git a/src/reactive/designate_handlers.py b/src/reactive/designate_handlers.py
index fd6cca2..95ee897 100644
--- a/src/reactive/designate_handlers.py
+++ b/src/reactive/designate_handlers.py
@@ -155,7 +155,7 @@ def update_peers(cluster):
instance.update_peers(cluster)
-@reactive.when('db.synched')
+@reactive.when_any('db.synched', 'action.config-render')
@reactive.when(*COMPLETE_INTERFACE_STATES)
def configure_designate_full(*args):
"""Write out all designate config include bootstrap domain info"""
@@ -181,6 +181,7 @@ def configure_designate_full(*args):
hookenv.log("ensure_api_responding() errored out: {}"
.format(str(e)),
level=hookenv.ERROR)
+ reactive.remove_state('action.config-render')
def _render_sink_configs(instance, interfaces_list):
diff --git a/src/templates/nova_private_ips.cfg b/src/templates/nova_private_ips.cfg
new file mode 100644
index 0000000..8dd5378
--- /dev/null
+++ b/src/templates/nova_private_ips.cfg
@@ -0,0 +1,7 @@
+# {{ options.action_args.nova_private_ips.domain_id }}
+{% if options.action_args.nova_private_ips.domain_id %}
+[handler:nova_fixed]
+zone_id = {{ options.action_args.nova_private_ips.domain_id }}
+notification_topics = 'notifications_designate'
+control_exchange = 'nova'
+{% endif %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment