Source code for medikit.feature.kube

"""
Setup make targets to rollout and rollback this project as a deployment onto a Kubernetes cluster.

"""
import json

from medikit.events import subscribe
from medikit.feature import Feature
from medikit.feature.make import which


[docs]class KubeConfig(Feature.Config): def __init__(self): self._targets = dict() self._targets_patches = dict() self._use_helm = False
[docs] def add_target(self, name, variant=None, *, patch, patch_path=""): if not variant in self._targets: self._targets[variant] = list() self._targets_patches[variant] = dict() if name in self._targets[variant]: raise ValueError("Kubernetes target {} already defined.".format(name)) self._targets[variant].append(name) self._targets_patches[variant][name] = patch_path, patch
[docs] def get_variants(self): return list(self._targets.keys())
[docs] def get_targets(self, variant=None): for target in self._targets[variant]: yield target, self._targets_patches[variant][target]
@property def use_helm(self): return self._use_helm
[docs] def enable_helm(self): self._use_helm = True return self
[docs] def disable_helm(self): self._use_helm = False return self
[docs]class KubeFeature(Feature): Config = KubeConfig requires = {"docker"}
[docs] @subscribe("medikit.feature.make.on_generate", priority=-1) def on_make_generate(self, event): kube_config = event.config["kube"] event.makefile["KUBECTL"] = which("kubectl") event.makefile["KUBECTL_OPTIONS"] = "" event.makefile["KUBECONFIG"] = "" event.makefile["KUBE_NAMESPACE"] = "default" if kube_config.use_helm: event.makefile["HELM"] = which("helm") event.makefile["HELM_RELEASE"] = event.config.get_name() for variant in kube_config.get_variants(): targets = list(kube_config.get_targets(variant=variant)) if len(targets): rollout_target = "-".join(filter(None, ("kube-rollout", variant))) rollback_target = "-".join(filter(None, ("kube-rollback", variant))) rollout_commands, rollback_commands = [], [] for target, (patch_path, patch) in targets: while patch_path: try: patch_path, _bit = patch_path.rsplit(".", 1) except ValueError: patch_path, _bit = None, patch_path patch = {_bit: patch} rollout_commands.append( "$(KUBECTL) $(KUBECTL_OPTIONS) --namespace=$(KUBE_NAMESPACE) patch {target} -p{patch}".format( target=target, patch=repr(json.dumps(patch)) ) ) rollback_commands.append("$(KUBECTL) rollout undo {target}".format(target=target)) event.makefile.add_target( rollout_target, "\n".join(rollout_commands), phony=True, doc="Rollout docker image onto kubernetes cluster.", ) event.makefile.add_target( rollback_target, "\n".join(rollback_commands), phony=True, doc="Rollbacks last kubernetes patch operation.", )