109 lines
4.2 KiB
Text
109 lines
4.2 KiB
Text
#!/usr/bin/env nu
|
|
# Derived variables for cert_manager bundle rendering.
|
|
# cf_api_token is injected by components.nu via SOPS decryption before this script runs.
|
|
# CF_TOKEN_<ZONE> env var still works as an override (CI/CD pipelines).
|
|
# Renders per-issuer blocks into flat strings for {{var}} substitution.
|
|
|
|
def render_solver [s: record]: nothing -> string {
|
|
# selector must nest INSIDE this solver's own list item, as a sibling of
|
|
# dns01 (cert-manager's Solver type) — not a sibling of the "solvers"
|
|
# array, which YAML would otherwise happily accept with no warning while
|
|
# cert-manager silently misapplies it. Built as an explicit line list so
|
|
# indentation is exact regardless of which fields are present.
|
|
let dns_zones = ($s.dns_zones? | default [])
|
|
let lines = (
|
|
if ($dns_zones | is-not-empty) {
|
|
let zone_lines = ($dns_zones | each {|z| $" - \"($z)\"" })
|
|
[" - selector:", " dnsZones:"] ++ $zone_lines ++ [" dns01:"]
|
|
} else {
|
|
[" - dns01:"]
|
|
}
|
|
) ++ [
|
|
" cloudflare:",
|
|
" apiTokenSecretRef:",
|
|
$" name: ($s.secret_ref)",
|
|
" key: api-token",
|
|
]
|
|
$lines | str join "\n"
|
|
}
|
|
|
|
# One issuer can carry multiple DNS-01 solvers — a catch-all (no dns_zones)
|
|
# plus zone-scoped ones for certs whose SANs span more than one Cloudflare
|
|
# zone. issuer.solvers takes precedence; issuer.secret_ref (single, legacy
|
|
# shape) is used only when solvers is absent, for backward compatibility.
|
|
def render_acme_issuer [issuer: record]: nothing -> string {
|
|
let server = ($issuer.acme_server? | default "https://acme-v02.api.letsencrypt.org/directory")
|
|
let email = ($issuer.email? | default "")
|
|
let solvers = if ($issuer.solvers? | default [] | is-not-empty) {
|
|
$issuer.solvers
|
|
} else {
|
|
[{ secret_ref: ($issuer.secret_ref? | default "") }]
|
|
}
|
|
let solvers_block = ($solvers | each {|s| render_solver $s } | str join "\n")
|
|
$"apiVersion: cert-manager.io/v1
|
|
kind: ClusterIssuer
|
|
metadata:
|
|
name: ($issuer.name)
|
|
spec:
|
|
acme:
|
|
server: ($server)
|
|
email: ($email)
|
|
privateKeySecretRef:
|
|
name: ($issuer.name)-acme-key
|
|
solvers:
|
|
($solvers_block)"
|
|
}
|
|
|
|
def cf_token_from_env [secret_ref: string]: nothing -> string {
|
|
let env_var = ($"CF_TOKEN_($secret_ref | str upcase | str replace --all '-' '_')")
|
|
$env | get -o $env_var | default ""
|
|
}
|
|
|
|
def main [component_json: string]: nothing -> nothing {
|
|
let d = ($component_json | from json)
|
|
let ns = ($d.namespace? | default "cert-manager")
|
|
let version = ($d.version? | default "v1.19.5")
|
|
|
|
let issuers_block = (
|
|
$d.cluster_issuers?
|
|
| default []
|
|
| where { |i| ($i.kind? | default "") == "acme" }
|
|
| each { |i| render_acme_issuer $i }
|
|
| str join "\n---\n"
|
|
)
|
|
|
|
let acme_issuers = (
|
|
$d.cluster_issuers?
|
|
| default []
|
|
| where { |i| ($i.kind? | default "") == "acme" }
|
|
)
|
|
let cf_secret_ref = (
|
|
if ($acme_issuers | length) > 0 {
|
|
$acme_issuers | first | get -o secret_ref | default ""
|
|
} else {
|
|
""
|
|
}
|
|
)
|
|
let injected = ($d.cf_api_token? | default "")
|
|
let cf_token = if ($injected | is-not-empty) { $injected } else { cf_token_from_env $cf_secret_ref }
|
|
|
|
let tls_backup = ($d.tls_backup? | default {})
|
|
|
|
{
|
|
namespace: $ns,
|
|
version: $version,
|
|
issuers_block: $issuers_block,
|
|
cf_secret_ref: $cf_secret_ref,
|
|
cf_api_token: $cf_token,
|
|
restic_repository: ($env.RESTIC_REPOSITORY? | default ""),
|
|
restic_password: ($env.RESTIC_PASSWORD? | default ""),
|
|
aws_access_key_id: ($env.AWS_ACCESS_KEY_ID? | default ""),
|
|
aws_secret_access_key: ($env.AWS_SECRET_ACCESS_KEY? | default ""),
|
|
aws_default_region: ($env.AWS_DEFAULT_REGION? | default ""),
|
|
tls_backup_enabled: ($tls_backup.enabled? | default false),
|
|
tls_backup_kubectl_version: ($tls_backup.kubectl_version? | default "v1.32.3"),
|
|
tls_backup_nushell_image: ($tls_backup.nushell_image? | default "ghcr.io/nushell/nushell:latest"),
|
|
}
|
|
| to json --raw
|
|
| print
|
|
}
|