import yaml
from time import sleep
import tempfile
import subprocess
rust_lib = """//! Kubernetes CRDs for system-upgrade-controller
//!
//! This library provides automatically generated types for the [system-upgrade-controller] CRDs. It is
//! intended to be used with the [Kube-rs] library.
//!
//! [system-upgrade-controller]: https://github.com/rancher/system-upgrade-controller
//! [Kube-rs]: https://kube.rs/
"""
subprocess.run(["kind", "create", "cluster", "--name", "crds-sys-upgrade-controller"])
while True:
try:
subprocess.run(
["kubectl", "get", "nodes", "--context", "kind-crds-sys-upgrade-controller"]
)
break
except:
sleep(1)
subprocess.run(
[
"kubectl",
"apply",
"-f",
"https://raw.githubusercontent.com/rancher/system-upgrade-controller/master/manifests/system-upgrade-controller.yaml",
"--context",
"kind-crds-sys-upgrade-controller",
]
)
while True:
try:
subprocess.run(
[
"kubectl",
"get",
"crd",
"--context",
"kind-crds-sys-upgrade-controller",
"plans.upgrade.cattle.io",
]
).check_returncode()
break
except:
sleep(1)
crds = yaml.safe_load(
subprocess.run(
[
"kubectl",
"get",
"crd",
"--context",
"kind-crds-sys-upgrade-controller",
"-o",
"yaml",
],
capture_output=True,
).stdout
)
subprocess.run(["kind", "delete", "cluster", "--name", "crds-sys-upgrade-controller"])
for crd in crds['items']:
if crd == None:
continue
file_name = crd["metadata"]["name"].removesuffix(".upgrade.cattle.io")
if file_name == crd["metadata"]["name"]:
continue
rust_code = ""
if crd["kind"] != "CustomResourceDefinition":
continue
if file_name == "settings":
rust_lib += f"pub mod {file_name};\npub use {file_name}::*;\n"
continue
with tempfile.NamedTemporaryFile(mode="w") as f:
yaml.dump(crd, f)
tmp_file = f.name
rust_code = subprocess.run(
["kopium", "-f", tmp_file, "--schema=derived", "--docs", "-b"],
capture_output=True,
)
if rust_code.returncode != 0:
print(rust_code.stderr.decode("utf-8"))
exit(1)
rust_code = rust_code.stdout.decode("utf-8")
rust_code = rust_code.replace(
f"// kopium command: kopium -f {tmp_file} --schema=derived --docs -b",
f"// kopium command: kopium -f {file_name}.yml --schema=derived --docs -b",
)
rust_code = "\n".join(
[
line.replace("#[builder(", '#[cfg_attr(feature = "builder", builder(')
.strip()
.removesuffix("]")
+ ")]"
if "#[builder(" in line
else line
for line in rust_code.split("\n")
]
)
rust_code = (
rust_code.replace(
", TypedBuilder, JsonSchema)]\npub struct",
", PartialEq, Default, TypedBuilder, JsonSchema)]\npub struct",
)
.replace(
", TypedBuilder, JsonSchema)]\n#[kube",
", PartialEq, Default, TypedBuilder, JsonSchema)]\n#[kube",
)
.replace(
", TypedBuilder, JsonSchema)]\npub enum",
", PartialEq, TypedBuilder, JsonSchema)]\npub enum",
)
)
rust_code = "\n".join(
[
line.replace(
", TypedBuilder, JsonSchema)]",
')]\n#[cfg_attr(feature = "builder", derive(TypedBuilder))]\n#[cfg_attr(feature = "schemars", derive(JsonSchema))]\n#[cfg_attr(not(feature = "schemars"), kube(schema="disabled"))]',
)
if line.startswith("#[derive(") and "CustomResource" in line
else line.replace(
", TypedBuilder, JsonSchema)]",
')]\n#[cfg_attr(feature = "builder", derive(TypedBuilder))]\n#[cfg_attr(feature = "schemars", derive(JsonSchema))]',
)
if line.startswith("#[derive(")
else line
for line in rust_code.split("\n")
]
)
rust_code = (
rust_code.replace(
"use typed_builder::TypedBuilder;",
'#[cfg(feature = "builder")]\nuse typed_builder::TypedBuilder;',
)
.replace(
"use schemars::JsonSchema;",
'#[cfg(feature = "schemars")]\nuse schemars::JsonSchema;',
)
.replace("use kube::CustomResource;", "use kube_derive::CustomResource;")
.replace(
'#[cfg_attr(feature = "builder", derive(TypedBuilder))]\n#[cfg_attr(feature = "schemars", derive(JsonSchema))]\npub enum',
'#[cfg_attr(feature = "schemars", derive(JsonSchema))]\npub enum',
)
)
rust_file = f"./src/{file_name}.rs"
with open(rust_file, "w") as f:
f.write(rust_code)
subprocess.run(["rustfmt", rust_file])
rust_lib += f"pub mod {file_name};\npub use {file_name}::*;\n"
with open("./src/lib.rs", "w") as f:
f.write(rust_lib)