From 023b447ea78380bdec965db04b3ba3621c4d3a5b Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Wed, 30 Dec 2020 17:33:04 +0100 Subject: Organizing code. --- py/acme/rai/__main__.py | 259 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 py/acme/rai/__main__.py (limited to 'py/acme/rai/__main__.py') diff --git a/py/acme/rai/__main__.py b/py/acme/rai/__main__.py new file mode 100644 index 0000000..9319ec5 --- /dev/null +++ b/py/acme/rai/__main__.py @@ -0,0 +1,259 @@ +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(m.type == "meta") + def ignoreMeta(c): + print(f"ignoring 2 {c.m}") + pass + + @when_all( + pri(1000), + (m.type == "terraform-machine"), + none(m.done == "platform/terraform/main.tf"), + ) + def mainTf(c): + print(f"WRITING gen/platform/terraform/main.tf") + with open(f"gen/platform/terraform/main.tf", "w") as f: + f.write(""" +terraform { + required_providers { + scaleway = { + source = "scaleway/scaleway" + } + } +} +""".strip()) + f.write("\n") + c.assert_fact({"type": "meta", "done": "platform/terraform/main.tf"}) + + 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") + with open(f"gen/platform/terraform/outputs.tf", "w") as f: + s = template.render(**{"machines": machines}) + f.write(s.strip()) + f.write("\n") + + @when_all((m.type == "terraform-machine")) + def ansibleMachine(c): + template = j2.get_template("platform-ansible.j2") + with open(f"gen/platform/ansible/{c.m.key}.yml", "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") + with open(f"gen/platform/terraform/{c.m.key}.tf", "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") + with open(f"gen/dns/{c.m.key}.tf", "w") as f: + s = template.render(**{"m": c.m}) + f.write(s.strip()) + f.write("\n") + + @when_all( + (m.type == "terraform-record-set"), + none(m.done == "dns/inputs.tf"), + ) + def mainTf(c): + print("WRITING dns/inputs.tf") + with open(f"gen/dns/inputs.tf", "w") as f: + f.write(""" +variable "addresses" { + type = map(string) +} +""".strip()) + f.write("\n") + c.assert_fact({"type": "meta", "done": "dns/inputs.tf"}) + +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") -- cgit v1.2.3