Charmed-Kubernetes/flannel/hooks/relations/kubernetes-cni/provides.py

90 lines
3.3 KiB
Python

#!/usr/bin/python
from charmhelpers.core import hookenv
from charmhelpers.core.host import file_hash
from charms.layer.kubernetes_common import kubeclientconfig_path
from charms.reactive import Endpoint
from charms.reactive import toggle_flag, is_flag_set, clear_flag, set_flag
class CNIPluginProvider(Endpoint):
def manage_flags(self):
toggle_flag(self.expand_name("{endpoint_name}.connected"), self.is_joined)
toggle_flag(
self.expand_name("{endpoint_name}.available"), self.config_available()
)
if is_flag_set(self.expand_name("endpoint.{endpoint_name}.changed")):
clear_flag(self.expand_name("{endpoint_name}.configured"))
clear_flag(self.expand_name("endpoint.{endpoint_name}.changed"))
def set_config(self, is_master):
"""Relays a dict of kubernetes configuration information."""
for relation in self.relations:
relation.to_publish_raw.update({"is_master": is_master})
set_flag(self.expand_name("{endpoint_name}.configured"))
def config_available(self):
"""Ensures all config from the CNI plugin is available."""
goal_state = hookenv.goal_state()
related_apps = [
app
for app in goal_state.get("relations", {}).get(self.endpoint_name, "")
if "/" not in app
]
if not related_apps:
return False
configs = self.get_configs()
return all(
"cidr" in config and "cni-conf-file" in config
for config in [configs.get(related_app, {}) for related_app in related_apps]
)
def get_config(self, default=None):
"""Get CNI config for one related application.
If default is specified, and there is a related application with a
matching name, then that application is chosen. Otherwise, the
application is chosen alphabetically.
Whichever application is chosen, that application's CNI config is
returned.
"""
configs = self.get_configs()
if not configs:
return {}
elif default and default not in configs:
msg = "relation not found for default CNI %s, ignoring" % default
hookenv.log(msg, level="WARN")
return self.get_config()
elif default:
return configs.get(default, {})
else:
return configs.get(sorted(configs)[0], {})
def get_configs(self):
"""Get CNI configs for all related applications.
This returns a mapping of application names to CNI configs. Here's an
example return value:
{
'flannel': {
'cidr': '10.1.0.0/16',
'cni-conf-file': '10-flannel.conflist'
},
'calico': {
'cidr': '192.168.0.0/16',
'cni-conf-file': '10-calico.conflist'
}
}
"""
return {
relation.application_name: relation.joined_units.received_raw
for relation in self.relations
if relation.application_name
}
def notify_kubeconfig_changed(self):
kubeconfig_hash = file_hash(kubeclientconfig_path)
for relation in self.relations:
relation.to_publish_raw.update({"kubeconfig-hash": kubeconfig_hash})