from durable.engine import MessageObservedException from durable.lang import * class VimScore: @staticmethod def make(env: str, tag: str): return {"type": "vimscore-application", "env": env, "tag": tag} @staticmethod def declare_rules(): @when_all((m.type == "vimscore-application")) def vsApp(c): print(f"vimscoreApplication: {c.m}") cluster = f"vimscore-{c.m.env}" tag = f"{c.m.tag}" # c.assert_fact(dba.cluster(cluster)) for f in [ dba.container(cluster, "app", "statera", "statera", tag), dba.container(cluster, "app", "statera-console", "statera-console", tag), dba.container(cluster, "app", "4tune-web", "4tune-web", tag), dba.container(cluster, "app", "4tune-api", "4tune-api", tag), dba.container(cluster, "db", "pdb", "postgresql", "13"), dba.container(cluster, "db", "mdb", "mongodb", "3.2"), ]: c.assert_fact(f) class VsOperations: @staticmethod def make(): return {"type": "vimscore-ops"} @staticmethod def declare_rules(): @when_all((m.type == "vimscore-ops")) def vsOps(c): cluster = "vimscore-ops" c.assert_fact(dba.cluster(cluster)) c.assert_fact(dba.container(cluster, "app", "pdb", "postgresql", "11")) c.assert_fact(dba.container(cluster, "app", "n8n", "n8n", "0.84.1")) # pgadmin, loki class DockerBasedApplications: @staticmethod def cluster(name: str): return {"type": "dba-cluster", "name": name} @staticmethod def container(cluster: str, machineRole: str, name: str, image: str, tag: str): return {"type": "dba-container", "cluster": cluster, "machineRole": machineRole, "name": name, "image": image, "tag": tag} dba = DockerBasedApplications with ruleset("my-rules"): VimScore.declare_rules() VsOperations.declare_rules() @when_all(+s.exception) def second(c): print("Processing failed!") print(c.s["exception"]) c.s.exception = None @when_all(pri(1000), (m.type == 'dba-container')) def dba_container(c): print(f"dba-container: {c.m}") @when_all(pri(900), (m.type == 'dba-container') & (m.image == "statera") & -m.ports) def addPortsToStatera(c): c.retract_fact(c.m) c.m.ports = [8090] c.assert_fact(c.m) @when_all(pri(900), (m.type == 'dba-container') & (m.image == "statera-console") & -m.ports) def addPortsToStateraConsole(c): c.retract_fact(c.m) c.m.ports = [80] c.assert_fact(c.m) # The none() part doesn't work as is, but it is worked around with the try/except block. @when_all( (c.container << m.type == "dba-container"), none((m.type == "dba-cluster") & (m.name == c.container.cluster)), ) def dbCluster(c): cluster = c.container.cluster try: c.assert_fact(dba.cluster(cluster)) print(f"NEW CLUSTER: c.container={c.container}") except MessageObservedException: pass # @when_all(pri(40), # (c.container << m.type == "dba-container"), # (c.cluster << (m.type == "dba-cluster") & (m.name == c.container.cluster)), # ) # def dbCluster(c): # print("dba-cluster: CATCH ALL") # print(f"c.container: {c.container}") # print(f"c.cluster: {c.cluster}") # pass vimscoreCi = VimScore.make("ci", "development") vimscoreProduction = VimScore.make("production", "master") vsOps = VsOperations.make() #x = assert_fact("my-rules", vimscoreCi); print(f"x: {x}") x = assert_fact("my-rules", vimscoreProduction); print(f"x: {x}") #x = assert_fact("my-rules", vsOps); print(f"x: {x}") if True: print("Facts:") for f in get_facts("my-rules"): print(f"fact: {f}") print("dba-clusters:") for f in [f for f in get_facts("my-rules") if f["type"] == "dba-cluster"]: cluster_name = f["name"] del f["name"] print(f" cluster:") print(f" name: {cluster_name}") print(f" json: {f}") print(" dba-containers:") for f in [f for f in get_facts("my-rules") if f.get("cluster") == cluster_name and f["type"] == "dba-container"]: del f["cluster"] del f["type"] print(f" container: {f}") with ruleset("phase-2"): @when_all(+s.exception) def second(c): print("Processing failed!") print(c.s["exception"]) c.s.exception = None # @when_all(pri(100), m.type == "dba-cluster") # def container(c): # print(f"default: cluster: {c.m}") @when_all((m.type == "dba-container") & -m.ports_classified) def mark_public_containers(c): # print(f"marking container.. {c.m}") item = c.m c.retract_fact(item) # print(f"marking container.. {c.m.name}, ports={c.m.ports}") item["public_ports"] = len(item.ports or []) > 0 item["ports_classified"] = True # print(f"marking container.. {item}") c.assert_fact(item) @when_all(pri(50), c.cluster << (m.type == "dba-cluster"), # c.container << ((m.type == "dba-container") & (m.cluster == c.cluster.name) & m.ports.anyItem(item > 0)) c.container << ((m.type == "dba-container") & +m.ports_classified & (m.public_ports > 0)) ) def container(c): print(f"public container") print(f" cluster: {c.cluster}") print(f" container: {c.container}") @when_all(((m.type == "dba-container") & (+m.ports_classified) & (m.public_ports == 0))) def container(c): print(f"private container: {c.m}") print("PHASE 2") for f in [f for f in get_facts("my-rules") if f["type"] in ("dba-cluster", "dba-container")]: assert_fact("phase-2", f)