def config_changed():
    if config.changed("nested_mode"):
        raise Exception('Nested mode cannot be changed after deployment.')
    # TODO: analyze other params and raise exception if readonly params were changed

    utils.update_nrpe_config()
    if config.changed("control-network"):
        settings = {'private-address': common_utils.get_ip()}
        rnames = ("contrail-controller", "contrail-kubernetes-config")
        for rname in rnames:
            for rid in relation_ids(rname):
                relation_set(relation_id=rid, relation_settings=settings)

    _notify_contrail_kubernetes_node()
    if config.changed("kubernetes_api_hostname") or config.changed(
            "kubernetes_api_secure_port"):
        _notify_controller()

    config[
        "config_analytics_ssl_available"] = common_utils.is_config_analytics_ssl_available(
        )
    config.save()

    docker_utils.config_changed()
    utils.update_charm_status()
def upgrade_charm():
    _notify_contrail_kubernetes_node()
    if is_leader():
        leader_set(
            settings={"kubernetes_workers": json.dumps(_collect_worker_ips())})
        _notify_controller()

    utils.update_charm_status()
def update_status():
    if is_leader():
        # try to obtain token again if it's not set yet
        changed = utils.update_kubernetes_token()
        if changed:
            # notify clients
            _notify_controller()
    # and update self
    utils.update_charm_status()
def contrail_cotroller_departed():
    units = [
        unit for rid in relation_ids("contrail-controller")
        for unit in related_units(rid)
    ]
    if units:
        return

    utils.update_charm_status()
    status_set("blocked", "Missing relation to contrail-controller")
def contrail_controller_changed():
    data = relation_get()
    log("RelData: " + str(data))

    _update_config(data, "analytics_servers", "analytics-server")
    _update_config(data, "maintenance", "maintenance")
    _update_config(data, "controller_ips", "controller_ips")
    _update_config(data, "controller_data_ips", "controller_data_ips")
    config.save()

    utils.update_charm_status()
def upgrade_charm():
    _notify_contrail_kubernetes_node()
    if is_leader():
        leader_set(
            settings={"kubernetes_workers": json.dumps(_collect_worker_ips())})
        _notify_controller()

    # to update config flags and certs params if any was changed
    _update_tls()

    utils.update_charm_status()
def cluster_changed():
    data = relation_get()
    log("Peer relation changed with {}: {}".format(remote_unit(), data))

    ip = data.get("unit-address")
    if not ip:
        log("There is no unit-address in the relation")
    elif is_leader():
        unit = remote_unit()
        _address_changed(unit, ip)
        utils.update_charm_status()
def cluster_departed():
    if not is_leader():
        return
    unit = remote_unit()
    cluster_info = common_utils.json_loads(leader_get("cluster_info"), dict())
    cluster_info.pop(unit, None)
    log("Unit {} departed. Cluster info: {}".format(unit, str(cluster_info)))
    settings = {"cluster_info": json.dumps(cluster_info)}
    leader_set(settings=settings)

    _notify_controller()
    utils.update_charm_status()
def contrail_controller_changed():
    data = relation_get()

    _update_config(data, "analytics_servers", "analytics-server")
    _update_config(data, "analyticsdb_enabled", "analyticsdb_enabled")
    _update_config(data, "maintenance", "maintenance")
    _update_config(data, "controller_ips", "controller_ips")
    _update_config(data, "controller_data_ips", "controller_data_ips")
    _update_config(data, "auth_info", "auth-info")
    _update_config(data, "orchestrator_info", "orchestrator-info")
    config.save()

    utils.update_charm_status()
def leader_elected():
    current_info = utils.get_cluster_info("unit-address",
                                          common_utils.get_ip())
    saved_info = common_utils.json_loads(leader_get("cluster_info"), dict())
    log("Cluster current info: {}".format(str(current_info)))
    log("Cluster saved info: {}".format(str(saved_info)))
    if not saved_info:
        log("Cluster info: {}".format(str(current_info)))
        settings = {"cluster_info": json.dumps(current_info)}
        leader_set(settings=settings)

    _notify_controller()
    utils.update_charm_status()
def kube_api_endpoint_changed():
    data = relation_get()

    changed = _update_config(data, "kubernetes_api_server", "hostname")
    changed |= _update_config(data, "kubernetes_api_port", "port")
    config.save()

    if is_leader():
        changed |= utils.update_kubernetes_token()
    if not changed:
        return

    # notify clients
    _notify_controller()
    # and update self
    utils.update_charm_status()
def contrail_cotroller_departed():
    units = [
        unit for rid in relation_ids("contrail-controller")
        for unit in related_units(rid)
    ]
    if units:
        return

    keys = [
        "auth_info", "orchestrator_info", "controller_ips",
        "controller_data_ips", "analytics-server", "analyticsdb_enabled"
    ]
    for key in keys:
        config.pop(key, None)
    utils.update_charm_status()
    status_set("blocked", "Missing relation to contrail-controller")
def config_changed():
    if config.changed("nested_mode"):
        raise Exception('Nested mode cannot be changed after deployment.')
    # TODO: analyze other params and raise exception if readonly params were changed

    utils.update_nrpe_config()
    if config.changed("control-network"):
        _notify_cluster()
        if is_leader():
            _address_changed(local_unit(), common_utils.get_ip())

    _notify_contrail_kubernetes_node()
    if (config.changed("kubernetes_api_hostname")
            or config.changed("kubernetes_api_secure_port")
            or config.changed("cluster_name")
            or config.changed("pod_subnets")):
        _notify_controller()

    docker_utils.config_changed()
    utils.update_charm_status()
def upgrade_charm():
    _notify_contrail_kubernetes_node()
    utils.update_charm_status()
def tls_certificates_relation_departed():
    config['tls_present'] = False
    common_utils.tls_changed(utils.MODULE, None)
    utils.update_charm_status()
def tls_certificates_relation_departed():
    if common_utils.tls_changed(utils.MODULE, None):
        utils.update_charm_status()
def tls_certificates_relation_changed():
    if common_utils.tls_changed(utils.MODULE, relation_get()):
        utils.update_charm_status()
def leader_settings_changed():
    utils.update_charm_status()
def leader_settings_changed():
    _notify_controller()
    utils.update_charm_status()
def upgrade_charm():
    utils.update_charm_status()
def tls_certificates_relation_changed():
    # it can be fired several times without server's cert
    if common_utils.tls_changed(utils.MODULE, relation_get()):
        utils.update_charm_status()