aboutsummaryrefslogtreecommitdiffstats
path: root/charms/trusty/contrail-webui/hooks/services.py
diff options
context:
space:
mode:
Diffstat (limited to 'charms/trusty/contrail-webui/hooks/services.py')
-rw-r--r--charms/trusty/contrail-webui/hooks/services.py210
1 files changed, 210 insertions, 0 deletions
diff --git a/charms/trusty/contrail-webui/hooks/services.py b/charms/trusty/contrail-webui/hooks/services.py
new file mode 100644
index 0000000..61c58cb
--- /dev/null
+++ b/charms/trusty/contrail-webui/hooks/services.py
@@ -0,0 +1,210 @@
+import os
+import socket
+import urllib
+
+import yaml
+
+import actions
+from charmhelpers.core import hookenv
+from charmhelpers.core import services
+from charmhelpers.core import templating
+
+from setup import (
+ create_ssl_certificate,
+ is_opencontrail,
+ write_ssl_certificate
+)
+
+
+CONFIG_FILE = os.path.join(os.sep, 'etc', 'contrail', 'config.global.js')
+
+
+class CassandraRelation(services.RelationContext):
+ name = 'cassandra'
+ interface = 'cassandra'
+ required_keys = ['private-address']
+
+
+class ContrailAPIRelation(services.RelationContext):
+ name = 'contrail_api'
+ interface = 'contrail-api'
+ required_keys = ['private-address', 'port']
+
+
+class ContrailDiscoveryRelation(services.RelationContext):
+ name = 'contrail_discovery'
+ interface = 'contrail-discovery'
+ required_keys = ['private-address', 'port']
+
+
+class KeystoneRelation(services.RelationContext):
+ name = 'identity_admin'
+ interface = 'keystone-admin'
+ required_keys = ['service_hostname', 'service_port', 'service_username',
+ 'service_tenant_name', 'service_password']
+
+
+class RedisRelation(services.RelationContext):
+ name = 'redis'
+ interface = 'redis-master'
+ required_keys = ['hostname', 'port']
+
+
+class ContrailWebUIConfig(services.ManagerCallback):
+
+ context_contrail = {
+ 'webcontroller_path': '/usr/src/contrail/contrail-web-controller',
+ 'logo_file': '/usr/src/contrail/contrail-web-core/webroot/img/juniper-networks-logo.png',
+ 'favicon_file': '/usr/src/contrail/contrail-web-core/webroot/img/juniper-networks-favicon.ico'
+ }
+
+ context_opencontrail = {
+ 'webcontroller_path': '/var/lib/contrail-webui/contrail-web-controller',
+ 'logo_file': '/var/lib/contrail/contrail-web-core/webroot/img/opencontrail-logo.png',
+ 'favicon_file': '/var/lib/contrail/contrail-web-core/webroot/img/opencontrail-favicon.ico'
+ }
+
+ def __call__(self, manager, service_name, event_name):
+ config = hookenv.config()
+ context = {
+ 'config': config
+ }
+
+ context.update(self.context_opencontrail if is_opencontrail()
+ else self.context_contrail)
+
+ context.update(ContrailAPIRelation())
+ context.update(ContrailDiscoveryRelation())
+ context.update(CassandraRelation())
+ context.update(KeystoneRelation())
+
+ # Redis relation is optional
+ redis = RedisRelation()
+ if redis.is_ready():
+ context.update(redis)
+ else:
+ context.update({
+ 'redis': [{
+ 'hostname': '127.0.0.1',
+ 'port': '6379'
+ }]
+ })
+
+ # Download logo and favicon or use the cached one
+ # if failed, falling back to the defaults
+ for target in ('logo', 'favicon'):
+ url = context['config']['{0}-url'.format(target)]
+ filename = os.path.join(os.sep, 'etc', 'contrail',
+ os.path.basename(url))
+ context['config']['{0}-filename'.format(target)] = ''
+ if url:
+ try:
+ urllib.urlretrieve(url, filename)
+ except IOError:
+ pass
+
+ try:
+ if os.stat(filename).st_size > 0:
+ context['config']['{0}-filename'.format(target)] = (
+ filename
+ )
+ except OSError:
+ pass
+
+ templating.render(
+ context=context,
+ source='config.global.js.j2',
+ target=CONFIG_FILE,
+ perms=0o644
+ )
+
+ templating.render(
+ context=context,
+ source='contrail-webui-userauth.js',
+ target='/etc/contrail/contrail-webui-userauth.js',
+ perms=0o640,
+ owner='root',
+ group='contrail'
+ )
+
+
+class SSLConfig(services.ManagerCallback):
+ def __call__(self, manager, service_name, event_name):
+ if hookenv.is_leader():
+ config = hookenv.config()
+ cert = config.get('ssl-cert')
+ key = config.get('ssl-key')
+ if cert and key:
+ write_ssl_certificate(cert, key)
+ hookenv.leader_set({'ssl-cert': cert, 'ssl-key': key,
+ 'ssl-cert-created': ''})
+ elif not hookenv.leader_get('ssl-cert-created'):
+ cert, key = create_ssl_certificate()
+ hookenv.leader_set({'ssl-cert': cert, 'ssl-key': key,
+ 'ssl-cert-created': True})
+
+
+class LeaderCallback(services.ManagerCallback):
+ def __call__(self, manager, service_name, event_name):
+ if not hookenv.is_leader():
+ cert = hookenv.leader_get('ssl-cert')
+ key = hookenv.leader_get('ssl-key')
+ if cert and key:
+ write_ssl_certificate(cert, key)
+
+
+class ContrailWebRelation(services.ManagerCallback):
+ def __call__(self, manager, service_name, event_name):
+ config = hookenv.config()
+ name = hookenv.local_unit().replace('/', '-')
+ addr = socket.gethostbyname(hookenv.unit_get('private-address'))
+ http_port = config['http-port']
+ https_port = config['https-port']
+ services = [ { 'service_name': 'contrail-webui-http',
+ 'service_host': '0.0.0.0',
+ 'service_port': http_port,
+ 'service_options': [ 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.1\\r\\nHost:\\ www', 'stick on src table contrail-webui-https' ],
+ 'servers': [ [ name, addr, http_port, 'check' ] ] },
+ { 'service_name': 'contrail-webui-https',
+ 'service_host': '0.0.0.0',
+ 'service_port': https_port,
+ 'service_options': [ 'mode tcp', 'balance leastconn', 'stick-table type ip size 10k expire 25h', 'stick on src' ],
+ 'servers': [ [ name, addr, https_port, 'check' ] ] } ]
+
+ for relation in hookenv.relation_ids('website'):
+ hookenv.relation_set(relation, services=yaml.dump(services))
+
+
+def manage():
+ config = hookenv.config()
+ cassandra = CassandraRelation()
+ contrail_api = ContrailAPIRelation()
+ contrail_discovery = ContrailDiscoveryRelation()
+ keystone = KeystoneRelation()
+
+ config_callback = ContrailWebUIConfig()
+ ssl_callback = SSLConfig()
+ leader_callback = LeaderCallback()
+ website_callback = ContrailWebRelation()
+
+ manager = services.ServiceManager([
+ {
+ 'service': 'supervisor-webui',
+ 'ports': (config['http-port'], config['https-port']),
+ 'required_data': [
+ config,
+ cassandra,
+ contrail_api,
+ contrail_discovery,
+ keystone,
+ ],
+ 'data_ready': [
+ actions.log_start,
+ config_callback,
+ ssl_callback,
+ leader_callback,
+ website_callback,
+ ],
+ },
+ ])
+ manager.manage()