def put(self, name): if "values" not in flask.request.json: return {"error": "missing config"}, 400 obj = pykube.KlotIOApp.objects(kube()).filter().get(name=name).obj fields = self.fields(obj, flask.request.json["values"]) if not fields.validate(): return {"fields": fields.to_list(), "errors": fields.errors}, 400 obj["settings"] = fields.values for field in fields: if not field.content.get("node") or field.value == field.original: continue label = f"{obj['metadata']['name']}/{field.name}" current = field.value if field.multi else [field.value] original = field.original if field.multi else [field.original] for value in current: if value not in original: node = pykube.Node.objects(kube()).get(name=value).obj node["metadata"]["labels"][label] = field.content["node"] pykube.Node(kube(), node).replace() if obj["status"] == "Installed": obj["status"] = "Installing" for value in original: if value not in current: node = pykube.Node.objects(kube()).get(name=value).obj del node["metadata"]["labels"][label] pykube.Node(kube(), node).replace() if obj["status"] == "NeedSettings": obj["status"] = "Installing" pykube.KlotIOApp(kube(), obj).replace() try: config = pykube.ConfigMap.objects(kube()).filter( namespace=obj["spec"]["namespace"]).get(name="config").obj config["data"] = { "settings.yaml": yaml.safe_dump(flask.request.json["values"]) } pykube.ConfigMap(kube(), config).replace() except pykube.ObjectDoesNotExist: pass return {"values": flask.request.json["values"]}
def act(self, name, action): obj = pykube.KlotIOApp.objects(self.kube).get(name=name).obj if obj.get("action", "Preview") == "Install" and action == "Preview": return print(f"setting {name} for {action}") obj["action"] = action pykube.KlotIOApp(self.kube, obj).replace()
def delete(self, name): obj = pykube.KlotIOApp.objects(kube()).filter().get(name=name).obj if "status" in obj and obj["status"] == "Installed": return { "error": f"Can't delete Installed {name}. Uninstall first." } pykube.KlotIOApp(kube(), obj).delete() return {"message": f"{name} deleted"}, 201
def patch(self, name): if "action" not in flask.request.json: return {"error": "missing action"}, 400 obj = pykube.KlotIOApp.objects(kube()).filter().get(name=name).obj obj["action"] = flask.request.json["action"] if "error" in obj: del obj["error"] pykube.KlotIOApp(kube(), obj).replace() return {self.singular: self.to_dict(obj)}
def apps(self): for obj in [ app.obj for app in pykube.KlotIOApp.objects(self.kube).filter() ]: obj.setdefault("status", "Discovered") obj.setdefault("action", "Preview") if obj["action"] == "Retry" or obj["status"] == "NeedSettings": continue try: if "spec" not in obj: self.define(obj) elif "resources" not in obj: self.download(obj) elif obj['action'] == "Install" and "created" not in obj: self.create(obj) elif obj['action'] == "Install" and obj.get("status") in [ "Installing" ]: if not self.check(obj): continue elif obj['action'] == "Uninstall": self.destroy(obj) else: continue except Exception as exception: obj["action"] = "Retry" obj["status"] = "Error" obj["error"] = traceback.format_exc().splitlines() traceback.print_exc() pykube.KlotIOApp(self.kube, obj).replace()
def discover(self, name, source, action): try: pykube.KlotIOApp.objects(self.kube).get(name=name).obj return except pykube.ObjectDoesNotExist: pass print(f"discovering {name} with {source} for {action}") obj = { "apiVersion": "klot.io/v1", "kind": "KlotIOApp", "metadata": { "name": name, }, "source": source, "action": action, "status": "Discovered" } pykube.KlotIOApp(self.kube, obj).create()
def post(self): if "name" not in flask.request.json: return {"error": "missing name"}, 400 if "source" not in flask.request.json: return {"error": "missing source"}, 400 obj = { "apiVersion": "klot.io/v1", "kind": "KlotIOApp", "metadata": { "name": flask.request.json["name"], }, "source": flask.request.json["source"] } if "action" in flask.request.json: obj["action"] = flask.request.json["action"] pykube.KlotIOApp(kube(), obj).create() return {"message": f"{obj['metadata']['name']} queued"}, 202