aboutsummaryrefslogtreecommitdiffstats
path: root/charms/trusty/neutron-contrail/hooks/neutron_contrail_hooks.py
diff options
context:
space:
mode:
Diffstat (limited to 'charms/trusty/neutron-contrail/hooks/neutron_contrail_hooks.py')
-rwxr-xr-xcharms/trusty/neutron-contrail/hooks/neutron_contrail_hooks.py353
1 files changed, 353 insertions, 0 deletions
diff --git a/charms/trusty/neutron-contrail/hooks/neutron_contrail_hooks.py b/charms/trusty/neutron-contrail/hooks/neutron_contrail_hooks.py
new file mode 100755
index 0000000..a0b013c
--- /dev/null
+++ b/charms/trusty/neutron-contrail/hooks/neutron_contrail_hooks.py
@@ -0,0 +1,353 @@
+#!/usr/bin/env python
+
+from subprocess import CalledProcessError
+import sys
+
+from apt_pkg import version_compare
+import json
+import uuid
+import yaml
+
+from charmhelpers.core.hookenv import (
+ Hooks,
+ UnregisteredHookError,
+ config,
+ is_leader,
+ leader_get,
+ leader_set,
+ log,
+ relation_get,
+ relation_ids,
+ relation_set
+)
+
+from charmhelpers.core.host import (
+ restart_on_change,
+ service_restart
+)
+
+from charmhelpers.fetch import (
+ apt_install,
+ apt_upgrade,
+ configure_sources
+)
+
+from neutron_contrail_utils import (
+ CONTRAIL_VERSION,
+ OPENSTACK_VERSION,
+ configure_vrouter,
+ disable_vrouter_vgw,
+ dpkg_version,
+ drop_caches,
+ enable_vrouter_vgw,
+ fix_nodemgr,
+ fix_permissions,
+ fix_vrouter_scripts,
+ ifdown,
+ ifup,
+ modprobe,
+ provision_local_metadata,
+ provision_vrouter,
+ remove_juju_bridge,
+ units,
+ unprovision_local_metadata,
+ unprovision_vrouter,
+ write_barbican_auth_config,
+ write_nodemgr_config,
+ write_vnc_api_config,
+ write_vrouter_config,
+ write_vrouter_vgw_interfaces
+)
+
+PACKAGES = [ "contrail-vrouter-dkms", "contrail-vrouter-agent",
+ "contrail-nova-driver", "contrail-utils", "python-jinja2",
+ "python-netifaces", "python-netaddr", "contrail-nodemgr" ]
+
+PACKAGES_LBAAS = [ "python-barbicanclient", "haproxy" ]
+
+hooks = Hooks()
+config = config()
+
+def check_local_metadata():
+ if not is_leader():
+ return
+
+ if not config.get("vrouter-provisioned"):
+ if leader_get("local-metadata-provisioned"):
+ # impossible to know if current hook is firing because
+ # relation or leader is being removed lp #1469731
+ if not relation_ids("cluster"):
+ unprovision_local_metadata()
+ leader_set({"local-metadata-provisioned": ""})
+ return
+
+ if config["local-metadata-server"]:
+ if not leader_get("local-metadata-provisioned"):
+ provision_local_metadata()
+ leader_set({"local-metadata-provisioned": True})
+ elif leader_get("local-metadata-provisioned"):
+ unprovision_local_metadata()
+ leader_set({"local-metadata-provisioned": ""})
+
+def check_vrouter():
+ # check relation dependencies
+ if config_get("contrail-api-ready") \
+ and config_get("control-node-ready") \
+ and config_get("identity-admin-ready"):
+ if not config_get("vrouter-provisioned"):
+ provision_vrouter()
+ config["vrouter-provisioned"] = True
+ elif config_get("vrouter-provisioned"):
+ unprovision_vrouter()
+ config["vrouter-provisioned"] = False
+
+@hooks.hook("config-changed")
+def config_changed():
+ configure_local_metadata()
+ configure_virtual_gateways()
+ write_config()
+ if not units("contrail-discovery") and not units("control-node"):
+ config["control-node-ready"] = True if config.get("discovery-server-ip") \
+ else False
+ if not units("contrail-api"):
+ config["contrail-api-ready"] = True if config.get("contrail-api-ip") \
+ else False
+ check_vrouter()
+ check_local_metadata()
+
+def config_get(key):
+ try:
+ return config[key]
+ except KeyError:
+ return None
+
+def configure_local_metadata():
+ if config["local-metadata-server"]:
+ if "local-metadata-secret" not in config:
+ # generate secret
+ secret = str(uuid.uuid4())
+ config["local-metadata-secret"] = secret
+ settings = { "metadata-shared-secret": secret }
+ # inform relations
+ for rid in relation_ids("neutron-plugin"):
+ relation_set(relation_id=rid, relation_settings=settings)
+ else:
+ if "local-metadata-secret" in config:
+ # remove secret
+ del config["local-metadata-secret"]
+ settings = { "metadata-shared-secret": None }
+ # inform relations
+ for rid in relation_ids("neutron-plugin"):
+ relation_set(relation_id=rid, relation_settings=settings)
+
+def configure_virtual_gateways():
+ gateways = config.get("virtual-gateways")
+ previous_gateways = config_get("virtual-gateways-prev")
+ if gateways != previous_gateways:
+ # create/destroy virtual gateway interfaces according to new value
+ interfaces = { gateway["interface"]: set(gateway["subnets"])
+ for gateway in yaml.safe_load(gateways) } \
+ if gateways else {}
+ previous_interfaces = { gateway["interface"]: set(gateway["subnets"])
+ for gateway in yaml.safe_load(previous_gateways) } \
+ if previous_gateways else {}
+ ifaces = [ interface for interface, subnets in previous_interfaces.iteritems()
+ if interface not in interfaces
+ or subnets != interfaces[interface] ]
+ if ifaces:
+ ifdown(ifaces)
+
+ write_vrouter_vgw_interfaces()
+
+ ifaces = [ interface for interface, subnets in interfaces.iteritems()
+ if interface not in previous_interfaces
+ or subnets != previous_interfaces[interface] ]
+ if ifaces:
+ ifup(ifaces)
+
+ if interfaces:
+ enable_vrouter_vgw()
+ else:
+ disable_vrouter_vgw()
+
+ config["virtual-gateways-prev"] = gateways
+
+@hooks.hook("contrail-api-relation-departed")
+@hooks.hook("contrail-api-relation-broken")
+def contrail_api_departed():
+ if not units("contrail-api") and not config.get("contrail-api-ip"):
+ config["contrail-api-ready"] = False
+ check_vrouter()
+ check_local_metadata()
+ write_vnc_api_config()
+
+@hooks.hook("contrail-api-relation-changed")
+def contrail_api_changed():
+ if not relation_get("port"):
+ log("Relation not ready")
+ return
+ write_vnc_api_config()
+ config["contrail-api-ready"] = True
+ check_vrouter()
+ check_local_metadata()
+
+@hooks.hook("contrail-discovery-relation-changed")
+def contrail_discovery_changed():
+ if not relation_get("port"):
+ log("Relation not ready")
+ return
+ contrail_discovery_relation()
+ config["control-node-ready"] = True
+ check_vrouter()
+ check_local_metadata()
+
+@hooks.hook("contrail-discovery-relation-departed")
+@hooks.hook("contrail-discovery-relation-broken")
+def contrail_discovery_departed():
+ if not units("contrail-discovery") \
+ and not units("control-node") \
+ and not config.get("discovery-server-ip"):
+ config["control-node-ready"] = False
+ check_vrouter()
+ check_local_metadata()
+ contrail_discovery_relation()
+
+@restart_on_change({"/etc/contrail/contrail-vrouter-agent.conf": ["contrail-vrouter-agent"],
+ "/etc/contrail/contrail-vrouter-nodemgr.conf": ["contrail-vrouter-nodemgr"]})
+def contrail_discovery_relation():
+ write_vrouter_config()
+ write_nodemgr_config()
+
+@hooks.hook("control-node-relation-departed")
+@hooks.hook("control-node-relation-broken")
+def control_node_departed():
+ if not units("control-node") \
+ and not units("contrail-discovery") \
+ and not config.get("discovery-server-ip"):
+ config["control-node-ready"] = False
+ check_vrouter()
+ check_local_metadata()
+ control_node_relation()
+
+@hooks.hook("control-node-relation-joined")
+def control_node_joined():
+ control_node_relation()
+ config["control-node-ready"] = True
+ check_vrouter()
+ check_local_metadata()
+
+@restart_on_change({"/etc/contrail/contrail-vrouter-agent.conf": ["contrail-vrouter-agent"]})
+def control_node_relation():
+ write_vrouter_config()
+
+@hooks.hook("identity-admin-relation-changed")
+def identity_admin_changed():
+ if not relation_get("service_hostname"):
+ log("Relation not ready")
+ return
+ write_vnc_api_config()
+ if version_compare(CONTRAIL_VERSION, "3.0.2.0-34") >= 0:
+ write_barbican_auth_config()
+ config["identity-admin-ready"] = True
+ check_vrouter()
+ check_local_metadata()
+
+@hooks.hook("identity-admin-relation-departed")
+@hooks.hook("identity-admin-relation-broken")
+def identity_admin_departed():
+ if not units("identity-admin"):
+ config["identity-admin-ready"] = False
+ check_vrouter()
+ check_local_metadata()
+ write_vnc_api_config()
+ if version_compare(CONTRAIL_VERSION, "3.0.2.0-34") >= 0:
+ write_barbican_auth_config()
+
+@hooks.hook()
+def install():
+ configure_sources(True, "install-sources", "install-keys")
+ apt_upgrade(fatal=True, dist=True)
+ fix_vrouter_scripts() # bug in 2.0+20141015.1 packages
+ apt_install(PACKAGES, fatal=True)
+
+ contrail_version = dpkg_version("contrail-vrouter-agent")
+ openstack_version = dpkg_version("nova-compute")
+ if version_compare(contrail_version, "3.0.2.0-34") >= 0 \
+ and version_compare(openstack_version, "2:12.0.0") >= 0:
+ # install lbaas packages
+ apt_install(PACKAGES_LBAAS, fatal=True)
+
+ fix_permissions()
+ fix_nodemgr()
+ if config.get("remove-juju-bridge"):
+ remove_juju_bridge()
+ try:
+ modprobe("vrouter")
+ except CalledProcessError:
+ log("vrouter kernel module failed to load, clearing pagecache and retrying")
+ drop_caches()
+ modprobe("vrouter")
+ modprobe("vrouter", True, True)
+ configure_vrouter()
+ service_restart("nova-compute")
+
+@hooks.hook("neutron-metadata-relation-changed")
+def neutron_metadata_changed():
+ if not relation_get("shared-secret"):
+ log("Relation not ready")
+ return
+ neutron_metadata_relation()
+
+@hooks.hook("neutron-metadata-relation-departed")
+@hooks.hook("neutron-metadata-relation-broken")
+@restart_on_change({"/etc/contrail/contrail-vrouter-agent.conf": ["contrail-vrouter-agent"]})
+def neutron_metadata_relation():
+ write_vrouter_config()
+
+@hooks.hook("neutron-plugin-relation-joined")
+def neutron_plugin_joined():
+ # create plugin config
+ section = []
+ if version_compare(OPENSTACK_VERSION, "1:2015.1~") < 0:
+ if version_compare(OPENSTACK_VERSION, "1:2014.2") >= 0:
+ section.append(("network_api_class", "nova_contrail_vif.contrailvif.ContrailNetworkAPI"))
+ else:
+ section.append(("libvirt_vif_driver", "nova_contrail_vif.contrailvif.VRouterVIFDriver"))
+ section.append(("firewall_driver", "nova.virt.firewall.NoopFirewallDriver"))
+ conf = {
+ "nova-compute": {
+ "/etc/nova/nova.conf": {
+ "sections": {
+ "DEFAULT": section
+ }
+ }
+ }
+ }
+ relation_set(subordinate_configuration=json.dumps(conf))
+
+ if config["local-metadata-server"]:
+ settings = { "metadata-shared-secret": config["local-metadata-secret"] }
+ relation_set(relation_settings=settings)
+
+def main():
+ try:
+ hooks.execute(sys.argv)
+ except UnregisteredHookError as e:
+ log("Unknown hook {} - skipping.".format(e))
+
+@hooks.hook("upgrade-charm")
+def upgrade_charm():
+ write_vrouter_config()
+ write_vnc_api_config()
+ write_nodemgr_config()
+ service_restart("supervisor-vrouter")
+
+@restart_on_change({"/etc/contrail/contrail-vrouter-agent.conf": ["contrail-vrouter-agent"],
+ "/etc/contrail/contrail-vrouter-nodemgr.conf": ["contrail-vrouter-nodemgr"]})
+def write_config():
+ write_vrouter_config()
+ write_vnc_api_config()
+ write_nodemgr_config()
+
+if __name__ == "__main__":
+ main()