#!/usr/bin/env nu # Derived variables for private_ingress bundle rendering. # Reads the component JSON, outputs Tera context vars as JSON. def slug_from_host [host: string]: nothing -> string { $host | str replace --all "." "-" } def resolve_cluster_ip [upstream: string, cp_host: string]: nothing -> string { # upstream is a K8s FQDN: ..svc. — extract svc+ns and resolve ClusterIP via SSH let parts = ($upstream | split row ".") if ($parts | length) < 2 { return $upstream } let svc = ($parts | first) let ns = ($parts | get 1) let r = (do { ^ssh $cp_host $"kubectl get svc ($svc) -n ($ns) -o jsonpath='{.spec.clusterIP}'" } | complete) if $r.exit_code != 0 or ($r.stdout | is-empty) { error make { msg: $"Could not resolve ClusterIP for ($svc).($ns): ($r.stderr | str trim)" } } $r.stdout | str trim | str replace "'" "" | str replace "'" "" } def sozu_cluster_block [route: record, cp_host: string]: nothing -> string { let slug = (slug_from_host $route.host) let cert_path = $"/etc/sozu/tls/($route.host)/tls.crt" let key_path = $"/etc/sozu/tls/($route.host)/tls.key" let clusterip = (resolve_cluster_ip $route.upstream $cp_host) [ $"[clusters.($slug)]", "protocol = \"http\"", "", $"[[clusters.($slug).frontends]]", "address = \"0.0.0.0:8443\"", $"hostname = \"($route.host)\"", $"certificate = \"($cert_path)\"", $"certificate_chain = \"($cert_path)\"", $"key = \"($key_path)\"", "", $"[[clusters.($slug).backends]]", $"backend_id = \"($slug)-0\"", $"address = \"($clusterip):($route.port)\"", ] | str join "\n" } def secret_volume_entry [route: record]: nothing -> string { let slug = (slug_from_host $route.host) let secret_name = $"private-ingress-tls-($slug)" [ $"- name: tls-($slug)", " secret:", $" secretName: ($secret_name)", " items:", " - key: tls.crt", " path: tls.crt", " - key: tls.key", " path: tls.key", ] | str join "\n" } def secret_mount_entry [route: record]: nothing -> string { let slug = (slug_from_host $route.host) [ $"- name: tls-($slug)", $" mountPath: /etc/sozu/tls/($route.host)", " readOnly: true", ] | str join "\n" } def certificate_entry [route: record, cluster_issuer: string, namespace: string]: nothing -> string { let slug = (slug_from_host $route.host) let secret_name = $"private-ingress-tls-($slug)" $"--- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: ($secret_name) namespace: ($namespace) labels: app.kubernetes.io/name: private-ingress app.kubernetes.io/managed-by: provisioning spec: secretName: ($secret_name) duration: 2160h renewBefore: 720h dnsNames: - ($route.host) issuerRef: name: ($cluster_issuer) kind: ClusterIssuer group: cert-manager.io" } def main [component_json: string]: nothing -> nothing { let d = ($component_json | from json) let ns = ($d.namespace? | default "ingress-private") let name = ($d.name? | default "private-ingress") let image = ($d.image? | default "ghcr.io/sozu-proxy/sozu:1.0.3") let cluster_issuer = ($d.cluster_issuer? | default "letsencrypt-prod-librecloud") let routes = ($d.routes? | default []) let private_lb_ip = ($d.private_lb_ip? | default "") let cp_host = ($d.cp_host? | default "libre-wuji-cp-0") let cluster_blocks = ( $routes | each { |r| sozu_cluster_block $r $cp_host } | str join "\n\n" ) let sozu_config = [ "[config]", "log_level = \"info\"", "log_target = \"stdout\"", "worker_count = 2", "command_socket = \"/var/run/sozu/sozu.sock\"", "", "[[listeners]]", "protocol = \"https\"", "address = \"0.0.0.0:8443\"", "", # HTTP listener removed — sozu v2 answer_301 requires a file path, not URL template. # Port 80 on the LB Service remains open (connections get TCP reset) until # a proper redirect file/mechanism is configured. "", $cluster_blocks, ] | str join "\n" let tls_volumes = ( $routes | each { |r| secret_volume_entry $r } | str join "\n" ) let tls_mounts = ( $routes | each { |r| secret_mount_entry $r } | str join "\n" ) let certificates_yaml = ( $routes | each { |r| certificate_entry $r $cluster_issuer $ns } | str join "\n" ) { sozu_config: $sozu_config, tls_volumes: $tls_volumes, tls_mounts: $tls_mounts, certificates_yaml: $certificates_yaml, private_lb_ip: $private_lb_ip, namespace: $ns, name: $name, image: $image, cluster_issuer: $cluster_issuer, } | to json --raw | print }