from durable.engine import MessageObservedException from durable.lang import * import shutil import os import os.path import jinja2 from .utils import * from . import acme from . import dba from . import machine from . import terraform with ruleset("phase-1"): acme.Acme.declare_rules() acme.AcmeOperations.declare_rules() machine.Machine.declare_rules() terraform.Terraform.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 == 'machine')) def defaultMachine(c): pass @when_all(pri(1000), (m.type == 'dba-container')) def dba_container(c): pass # 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.key == 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.key == c.container.cluster)), # ) # def dbCluster(c): # print("dba-cluster: CATCH ALL") # print(f"c.container: {c.container}") # print(f"c.cluster: {c.cluster}") # pass m1 = machine.Machine.make("acme-1") m2 = machine.Machine.make("acme-2") m3 = machine.Machine.make("acme-3") acmeCi = acme.Acme.make("ci", "development") acmeProduction = acme.Acme.make("production", "master") acmeOps = acme.AcmeOperations.make() x = assert_fact("phase-1", acmeCi); print(f"x: {x}") x = assert_fact("phase-1", acmeProduction); print(f"x: {x}") x = assert_fact("phase-1", acmeOps); print(f"x: {x}") x = assert_fact("phase-1", m1); print(f"x: {x}") x = assert_fact("phase-1", m2); print(f"x: {x}") x = assert_fact("phase-1", m3); print(f"x: {x}") if False: print("Facts:") for f in get_facts("phase-1"): print(f"fact: {f}") print("dba-clusters:") for f in [f for f in get_facts("phase-1") if f["type"] == "dba-cluster"]: cluster_name = f["key"] del f["key"] print(f" cluster:") print(f" key: {cluster_name}") print(f" json: {f}") print(" dba-containers:") for f in [f for f in get_facts("phase-1") if f.get("cluster") == cluster_name and f["type"] == "dba-container"]: del f["cluster"] del f["type"] print(f" container: {f}") write_facts("phase-1") 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.key) & m.ports.anyItem(item > 0)) c.container << ((m.type == "dba-container") & +m.ports_classified & (m.public_ports > 0)) ) def container(c): pass # 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): pass # print(f"private container: {c.m}") print("PHASE 2") for f in [f for f in get_facts("phase-1") if f["type"] in ("dba-cluster", "dba-container")]: x = assert_fact("phase-2", f); print(f"x: {x}") write_facts("phase-2") # Prepare if os.path.isdir("gen"): shutil.rmtree("gen") os.mkdir("gen") os.mkdir("gen/platform") os.mkdir("gen/platform/terraform") os.mkdir("gen/platform/ansible") os.mkdir("gen/dns") print("PHASE 3: Generating stuff") file_loader = jinja2.FileSystemLoader("j2") j2 = jinja2.Environment(loader=file_loader) # TODO: merge the dns files into the platform tf files as they are # one-to-one now. with ruleset("phase-3"): @when_all(m.type == "meta") def ignoreMeta(c): print(f"ignoring {c.m}") pass @when_all( pri(-1), (m.type == "terraform-machine"), none(m.done == "platform/terraform/main.tf"), ) def mainTf(c): path = f"gen/platform/terraform/main.tf" print(f"WRITING {path}") with open(path, "w") as f: f.write(""" terraform { required_providers { scaleway = { source = "scaleway/scaleway" } } } """.strip()) f.write("\n") machines = [] for f in c.get_facts(): if f.get("type") != "terraform-machine": continue machines.append(f) # print(f"machine: {f}") template = j2.get_template("terraform-machine-outputs.j2") path = f"gen/platform/terraform/outputs.tf" print(f"WRITING {path}") with open(path, "w") as f: s = template.render(**{"machines": machines}) f.write(s.strip()) f.write("\n") try: c.assert_fact({"type": "meta", "done": path}) except MessageObservedException: pass @when_all((m.type == "terraform-machine")) def ansibleMachine(c): template = j2.get_template("platform-ansible.j2") path = f"gen/platform/ansible/{c.m.key}.yml" print(f"WRITING {path}") with open(path, "w") as f: s = template.render(**{"m": c.m}) f.write(s.strip()) f.write("\n") @when_all((m.type == "terraform-machine")) def terraformMachine(c): template = j2.get_template("terraform-machine.j2") path = f"gen/platform/terraform/{c.m.key}.tf" print(f"WRITING {path}") with open(path, "w") as f: s = template.render(**{"m": c.m}) f.write(s.strip()) f.write("\n") @when_all((m.type == "terraform-record-set")) def terraformRecordSet(c): template = j2.get_template("terraform-record-set.j2") path = f"gen/dns/{c.m.key}.tf" print(f"WRITING {path}") with open(path, "w") as f: s = template.render(**{"m": c.m}) f.write(s.strip()) f.write("\n") @when_all( pri(-1), c.x << (m.type == "terraform-record-set"), none(m.done == "gen/dns/inputs.tf"), # c.x << (m.done == "gen/dns/inputs.tf"), ) def mainTf(c): path = f"gen/dns/inputs.tf" print(f"WRITING {path}") with open(path, "w") as f: f.write(""" variable "addresses" { type = map(string) } """.strip()) f.write("\n") try: c.assert_fact({"type": "meta", "done": path}) except MessageObservedException: pass facts = [f for f in get_facts("phase-1") if f["type"] in ("terraform-record-set", "terraform-machine")] #for f in facts: # x = assert_fact("phase-3", f); print(f"x: {x}") x = assert_facts("phase-3", facts); print(f"x: {x}") write_facts("phase-3")