Files
bootapi/config.example.env
unkinben 8f356346eb
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
Address PR review: PXE gate + callback, git-sync templates, distro catalog, k8s targets, http+https
Implements the six review comments on PR #1:

- Per-host PXE-enable gate: read NetBox pxe_enabled custom field; a known host
  with it false gets the safe local-boot script (Cobbler netboot_enabled). Add a
  token-guarded POST /provisioned/{ident} callback that clears pxe_enabled in
  NetBox, plus a %post snippet in the default kickstarts that calls it.
- Templates from a git repo: bootapi clones a templates repo and re-pulls every
  BOOTAPI_TEMPLATE_GIT_INTERVAL (default 3m), atomically swapping the template
  set (last-good kept on parse failure; embedded defaults are the startup
  fallback). Metrics for syncs/failures/generation.
- Distro catalog (catalog/*.yaml): NetBox host -> boot images/kickstart, so
  adding an OS is a YAML + template change. Ships almalinux + fedora entries
  (artifactapi remotes); debian/talos path documented.
- Boot images from the artifactapi almalinux/fedora remotes via the catalog.
- Bind resolvers, puppet server/CA and PUPPETCA_URL env file now target the k8s
  services (198.18.200.7; puppet(ca).k8s.syd1.au.unkin.net).
- Boot path served over plain HTTP (installers lack CA trust) with an optional
  parallel HTTPS listener; docs say do not 301 the boot endpoints.

New packages: internal/catalog, internal/gitsync. NetBox client gains a
pxe_enabled write (token needs that scope - noted in docs). `bootapi validate`
subcommand validates a template/catalog set for the templates-repo CI.

go build/vet clean, go test -race green, golangci-lint v2 clean, pre-commit clean.

Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
2026-07-28 22:34:44 +10:00

79 lines
3.8 KiB
Bash

# bootapi configuration (environment variables).
#
# bootapi is configured entirely from the environment (12-factor, like encapi).
# In Kubernetes these come from the Deployment env + a Vault-sourced Secret and
# a templates ConfigMap/git repo (see docs/deployment.md). Locally:
# env $(grep -v '^#' config.example.env | xargs) ./bin/bootapi
# --- HTTP (boot path is ALWAYS plain HTTP: PXE installers have no CA trust) ---
BOOTAPI_LISTEN_ADDR=:8000
# Optional parallel HTTPS listener for clients that DO trust the internal CA.
# The boot path still works over plain HTTP; do not 301 HTTP->HTTPS (see docs).
# BOOTAPI_TLS_LISTEN_ADDR=:8443
# BOOTAPI_TLS_CERT_FILE=/etc/bootapi/tls/tls.crt
# BOOTAPI_TLS_KEY_FILE=/etc/bootapi/tls/tls.key
# --- NetBox (source of truth for host -> boot data) ---
BOOTAPI_NETBOX_URL=https://netbox.k8s.syd1.au.unkin.net
# Provide the token inline OR (preferred in k8s) via a Vault-mounted file.
# NOTE: the token needs WRITE scope on the device pxe_enabled custom field for
# the /provisioned callback (see docs/security.md).
BOOTAPI_NETBOX_TOKEN=
# BOOTAPI_NETBOX_TOKEN_FILE=/var/run/secrets/netbox/api_token
BOOTAPI_NETBOX_TIMEOUT=5s
BOOTAPI_NETBOX_INSECURE=false
# --- caching (short: a re-provisioned host must pick up changes next boot) ---
BOOTAPI_CACHE_TTL=30s
# --- templates: git-sync (preferred) OR a local override dir OR embedded ---
# Pull a templates repo every interval (default 3m, like argocd); a parse
# failure keeps the last-good set. Embedded defaults are the startup fallback.
BOOTAPI_TEMPLATE_GIT_URL=https://git.unkin.net/unkin/bootapi-templates.git
BOOTAPI_TEMPLATE_GIT_BRANCH=main
BOOTAPI_TEMPLATE_GIT_INTERVAL=3m
# BOOTAPI_TEMPLATE_GIT_TOKEN= # only for a private templates repo
# BOOTAPI_TEMPLATE_DIR=/etc/bootapi/templates # used only when GIT_URL is unset
BOOTAPI_DEFAULT_TEMPLATE=almalinux9
# --- URLs baked into rendered output ---
# bootapi's own PLAIN-HTTP base (goes into iPXE inst.ks= and /ks URLs). Must be
# reachable without CA trust.
BOOTAPI_BASE_URL=http://bootapi.k8s.syd1.au.unkin.net
# Base the end-of-kickstart callback posts to; defaults to BOOTAPI_BASE_URL
# (plain HTTP, works before the internal CA is installed).
# BOOTAPI_CALLBACK_BASE_URL=http://bootapi.k8s.syd1.au.unkin.net
# artifactapi remote base the distro catalog builds kernel/initrd URLs from.
BOOTAPI_ARTIFACT_BASE_URL=https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote
# Legacy fallback OS-tree base, used only if no catalog entry matches. Normally
# empty (the distro catalog drives boot images).
# BOOTAPI_BOOT_BASE_URL=
# --- end-of-kickstart callback token (guards POST /provisioned) ---
# Empty disables the callback (pxe_enabled will not auto-clear). Embedded in the
# rendered kickstart, so treat as a provisioning secret (docs/security.md).
BOOTAPI_PROVISION_TOKEN=
# BOOTAPI_PROVISION_TOKEN_FILE=/var/run/secrets/bootapi/provision_token
# --- puppet bootstrap targets (k8s puppetserver; baked into kickstart %post) ---
BOOTAPI_PUPPET_SERVER=puppet.k8s.syd1.au.unkin.net
BOOTAPI_PUPPET_CA_SERVER=puppetca.k8s.syd1.au.unkin.net
# Written to /etc/sysconfig/puppet-initial as PUPPETCA_URL (read by the
# puppet-initial RPM's systemd bootstrap unit).
BOOTAPI_PUPPET_CA_URL=puppetca.k8s.syd1.au.unkin.net
# --- network defaults (used when NetBox records none per-device) ---
BOOTAPI_DOMAIN=main.unkin.net
# k8s bind-resolvers LoadBalancer (replaces the legacy VM resolvers).
BOOTAPI_NAMESERVERS=198.18.200.7
# --- render-time secrets (NEVER stored in NetBox; from Vault in k8s) ---
# crypt(3) hash for the root account. Empty => root account locked.
BOOTAPI_ROOT_PASSWORD_HASH=
# BOOTAPI_ROOT_PASSWORD_HASH_FILE=/var/run/secrets/bootapi/root_password_hash
# Newline-separated SSH public keys installed for root.
BOOTAPI_SSH_AUTHORIZED_KEYS=
# --- unknown-MAC fallback: "local" (safe: boot local disk) or "shell" (debug) ---
BOOTAPI_UNKNOWN_MAC_FALLBACK=local