90 lines
3.3 KiB
Python
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})
|