diff options
Diffstat (limited to 'contrail-analytics/hooks/contrail_analytics_utils.py')
-rw-r--r-- | contrail-analytics/hooks/contrail_analytics_utils.py | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/contrail-analytics/hooks/contrail_analytics_utils.py b/contrail-analytics/hooks/contrail_analytics_utils.py new file mode 100644 index 0000000..43aefec --- /dev/null +++ b/contrail-analytics/hooks/contrail_analytics_utils.py @@ -0,0 +1,163 @@ +from socket import inet_aton +import struct + +import apt_pkg + +from charmhelpers.core.hookenv import ( + config, + related_units, + relation_get, + relation_ids, + status_set, + open_port, +) +from charmhelpers.core.templating import render + +from common_utils import ( + get_ip, + decode_cert, + save_file, + check_run_prerequisites, + run_container, + json_loads, +) + +apt_pkg.init() +config = config() + + +CONTAINER_NAME = "contrail-analytics" +CONFIG_NAME = "analytics" +SERVICES_TO_CHECK = ["contrail-collector", "contrail-analytics-api"] + + +def controller_ctx(): + """Get the ipaddress of all contrail control nodes""" + auth_mode = config.get("auth_mode") + if auth_mode is None: + # NOTE: auth_mode must be transmitted by controller + return {} + + controller_ip_list = [] + for rid in relation_ids("contrail-analytics"): + for unit in related_units(rid): + if unit.startswith("contrail-controller"): + ip = relation_get("private-address", unit, rid) + controller_ip_list.append(ip) + sort_key = lambda ip: struct.unpack("!L", inet_aton(ip))[0] + controller_ip_list = sorted(controller_ip_list, key=sort_key) + return { + "auth_mode": auth_mode, + "controller_servers": controller_ip_list, + } + + +def analytics_ctx(): + """Get the ipaddress of all analytics control nodes""" + analytics_ip_list = [] + for rid in relation_ids("analytics-cluster"): + for unit in related_units(rid): + ip = relation_get("private-address", unit, rid) + analytics_ip_list.append(ip) + # add it's own ip address + analytics_ip_list.append(get_ip()) + sort_key = lambda ip: struct.unpack("!L", inet_aton(ip))[0] + analytics_ip_list = sorted(analytics_ip_list, key=sort_key) + return {"analytics_servers": analytics_ip_list} + + +def analyticsdb_ctx(): + """Get the ipaddress of all contrail analyticsdb nodes""" + analyticsdb_ip_list = [] + for rid in relation_ids("contrail-analyticsdb"): + for unit in related_units(rid): + ip = relation_get("private-address", unit, rid) + analyticsdb_ip_list.append(ip) + + sort_key = lambda ip: struct.unpack("!L", inet_aton(ip))[0] + analyticsdb_ip_list = sorted(analyticsdb_ip_list, key=sort_key) + return {"analyticsdb_servers": analyticsdb_ip_list} + + +def get_context(): + ctx = {} + ctx.update(json_loads(config.get("orchestrator_info"), dict())) + + ssl_ca = decode_cert("ssl_ca") + ctx["ssl_ca"] = ssl_ca + ctx["ssl_cert"] = decode_cert("ssl_cert") + ctx["ssl_key"] = decode_cert("ssl_key") + ctx["ssl_enabled"] = (ssl_ca is not None and len(ssl_ca) > 0) + + ctx["db_user"] = config.get("db_user") + ctx["db_password"] = config.get("db_password") + + ctx["rabbitmq_user"] = config.get("rabbitmq_user") + ctx["rabbitmq_password"] = config.get("rabbitmq_password") + ctx["rabbitmq_vhost"] = config.get("rabbitmq_vhost") + + ctx.update(controller_ctx()) + ctx.update(analytics_ctx()) + ctx.update(analyticsdb_ctx()) + ctx.update(json_loads(config.get("auth_info"), dict())) + return ctx + + +def render_config(ctx=None): + if not ctx: + ctx = get_context() + + # NOTE: store files in default paths cause no way to pass this path to + # some of components (sandesh) + ssl_ca = ctx["ssl_ca"] + save_file("/etc/contrailctl/ssl/ca-cert.pem", ssl_ca) + ssl_cert = ctx["ssl_cert"] + save_file("/etc/contrailctl/ssl/server.pem", ssl_cert) + ssl_key = ctx["ssl_key"] + save_file("/etc/contrailctl/ssl/server-privkey.pem", ssl_key) + + render("analytics.conf", "/etc/contrailctl/analytics.conf", ctx) + + +def update_charm_status(update_config=True): + update_config_func = render_config if update_config else None + result = check_run_prerequisites(CONTAINER_NAME, CONFIG_NAME, + update_config_func, SERVICES_TO_CHECK) + if not result: + return + + ctx = get_context() + missing_relations = [] + if not ctx.get("controller_servers"): + missing_relations.append("contrail-controller") + if not ctx.get("analyticsdb_servers"): + missing_relations.append("contrail-analyticsdb") + if missing_relations: + status_set('blocked', + 'Missing relations: ' + ', '.join(missing_relations)) + return + if not ctx.get("cloud_orchestrator"): + status_set('blocked', + 'Missing cloud_orchestrator info in relation ' + 'with contrail-controller.') + return + if not ctx.get("keystone_ip"): + status_set('blocked', + 'Missing auth info in relation with contrail-controller.') + return + if not ctx.get("db_user"): + # NOTE: Charms don't allow to deploy cassandra in AllowAll mode + status_set('blocked', + 'Missing DB user/password info in ' + 'relation with contrail-controller.') + if not ctx.get("rabbitmq_user"): + # NOTE: Charms don't allow to deploy rabbitmq with guest access + status_set('blocked', + 'Missing rabbitmq user/password info in ' + 'relation with contrail-controller.') + # TODO: what should happens if relation departed? + + render_config(ctx) + open_port(8081, "TCP") + + run_container(CONTAINER_NAME, "contrail-analytics") |