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
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
{{- /*
|
||||
AlmaLinux 9 kickstart, ported from the Cobbler default.ks contract.
|
||||
|
||||
Rendered by bootapi from NetBox data + render-time secrets. The %post hands off
|
||||
to the existing Puppet firstrun bootstrap: it installs the agent, points it at
|
||||
the Consul-discovered puppet servers, and triggers the first run. Autosign
|
||||
(*.main.unkin.net + the PXE subnets) and the `profiles::firstrun` class do the
|
||||
rest, exactly as they did under Cobbler.
|
||||
Rendered by bootapi from NetBox data + render-time secrets + the distro catalog.
|
||||
Install source comes from the artifactapi almalinux remote (via the catalog
|
||||
mirror var). The %post installs the Puppet agent and points it at the k8s
|
||||
puppetserver (puppet.k8s.syd1.au.unkin.net / puppetca.k8s...), writes the
|
||||
puppet-initial PUPPETCA_URL env file, then posts back to bootapi so pxe_enabled
|
||||
flips off (Cobbler's netboot_enabled flow).
|
||||
|
||||
Data model: see docs/data-model.md. `.RootPasswordHash` comes from Vault at
|
||||
render time, never from NetBox.
|
||||
Data model: see docs/data-model.md. `.RootPasswordHash` and `.ProvisionToken`
|
||||
come from Vault/env at render time, never from NetBox.
|
||||
*/ -}}
|
||||
{{- $mirror := .DistroVars.mirror -}}
|
||||
#version=RHEL9
|
||||
# Rendered by bootapi for {{ .FQDN }} (platform {{ .Platform }}, role {{ default "none" .Role }})
|
||||
text
|
||||
@@ -17,9 +19,9 @@ eula --agreed
|
||||
firstboot --disable
|
||||
reboot
|
||||
|
||||
# --- install source (served by bootapi's configured mirror) ---
|
||||
url --url={{ .BootBaseURL }}/BaseOS/{{ .Arch }}/os/
|
||||
repo --name=AppStream --baseurl={{ .BootBaseURL }}/AppStream/{{ .Arch }}/os/
|
||||
# --- install source (artifactapi almalinux remote, from the distro catalog) ---
|
||||
url --url={{ $mirror }}/BaseOS/{{ .Arch }}/os/
|
||||
repo --name=AppStream --baseurl={{ $mirror }}/AppStream/{{ .Arch }}/os/
|
||||
|
||||
# --- localization ---
|
||||
keyboard --xlayouts='us'
|
||||
@@ -61,7 +63,7 @@ git
|
||||
-iwl*-firmware
|
||||
%end
|
||||
|
||||
# --- bootstrap: hand off to Puppet firstrun ---
|
||||
# --- bootstrap: puppet (k8s) + end-of-install callback ---
|
||||
%post --log=/root/bootapi-post.log
|
||||
set -x
|
||||
|
||||
@@ -82,15 +84,30 @@ rpm -q puppet-agent >/dev/null 2>&1 || \
|
||||
dnf install -y https://yum.puppet.com/puppet8-release-el-9.noarch.rpm
|
||||
dnf install -y puppet-agent
|
||||
|
||||
# Point the agent at the Consul-discovered servers (matches the pre-bootapi
|
||||
# Cobbler kickstart + hieradata/roles/infra/puppet).
|
||||
# Point the agent at the k8s puppetserver / CA.
|
||||
PUPPET_BIN=/opt/puppetlabs/bin/puppet
|
||||
"$PUPPET_BIN" config set --section main certname "{{ .FQDN }}"
|
||||
"$PUPPET_BIN" config set --section main server "{{ .PuppetServer }}"
|
||||
"$PUPPET_BIN" config set --section main ca_server "{{ .PuppetCAServer }}"
|
||||
"$PUPPET_BIN" config set --section main certname "{{ .FQDN }}"
|
||||
"$PUPPET_BIN" config set --section main server "{{ .PuppetServer }}"
|
||||
"$PUPPET_BIN" config set --section main ca_server "{{ .PuppetCAServer }}"
|
||||
"$PUPPET_BIN" config set --section main report_server "{{ .PuppetServer }}"
|
||||
"$PUPPET_BIN" config set --section main environment production
|
||||
"$PUPPET_BIN" config set --section main environment production
|
||||
|
||||
# Enable the agent; the first boot triggers firstrun (autosign handles the CSR).
|
||||
# puppet-initial bootstrap unit reads PUPPETCA_URL from this EnvironmentFile.
|
||||
install -d -m0755 /etc/sysconfig
|
||||
cat > /etc/sysconfig/puppet-initial <<'EOF'
|
||||
PUPPETCA_URL={{ .PuppetCAURL }}
|
||||
EOF
|
||||
|
||||
# Enable the agent; first boot triggers firstrun (autosign handles the CSR).
|
||||
systemctl enable puppet
|
||||
|
||||
{{ if and .ProvisionToken .CallbackURL -}}
|
||||
# Tell bootapi the install is done so it clears pxe_enabled in NetBox and the
|
||||
# next PXE boots local disk. Runs over plain HTTP (no internal CA trust yet);
|
||||
# the token authenticates the call. Non-fatal if it fails (the local-disk
|
||||
# fallback still protects a re-provisioned host on the following boot).
|
||||
curl -fsS -m 15 -X POST \
|
||||
-H "Authorization: Bearer {{ .ProvisionToken }}" \
|
||||
"{{ .CallbackURL }}" || echo "bootapi: provisioned callback failed (non-fatal)"
|
||||
{{- end }}
|
||||
%end
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
{{- /*
|
||||
Fedora kickstart (family-level template: matches any "fedoraNN" platform slug
|
||||
via the OS-family selection fallback). Kept close to the AlmaLinux template so
|
||||
the two stay comparable; the differences are the install tree layout and that
|
||||
Fedora ships a recent-enough dnf/agent story out of the box.
|
||||
via the catalog family match). Kept close to the AlmaLinux template so the two
|
||||
stay comparable; the differences are the install-tree layout (releases/.../
|
||||
Everything) and the puppet release RPM. Install source + boot images come from
|
||||
the artifactapi fedora remote via the distro catalog.
|
||||
*/ -}}
|
||||
{{- $mirror := .DistroVars.mirror -}}
|
||||
#version=F{{ default "" .OSVersion }}
|
||||
# Rendered by bootapi for {{ .FQDN }} (platform {{ .Platform }})
|
||||
text
|
||||
firstboot --disable
|
||||
reboot
|
||||
|
||||
# --- install source ---
|
||||
url --url={{ .BootBaseURL }}/releases/{{ default "rawhide" .OSVersion }}/Everything/{{ .Arch }}/os/
|
||||
# --- install source (artifactapi fedora remote, from the distro catalog) ---
|
||||
url --url={{ $mirror }}/{{ .Arch }}/os/
|
||||
|
||||
keyboard --xlayouts='us'
|
||||
lang en_AU.UTF-8
|
||||
@@ -56,11 +58,23 @@ cat > /root/.ssh/authorized_keys <<'EOF'
|
||||
{{ end }}EOF
|
||||
chmod 0600 /root/.ssh/authorized_keys
|
||||
{{- end }}
|
||||
dnf install -y https://yum.puppet.com/puppet8-release-fedora-{{ default "40" .OSVersion }}.noarch.rpm || true
|
||||
dnf install -y "https://yum.puppet.com/puppet8-release-fedora-{{ default "40" .OSVersion }}.noarch.rpm" || true
|
||||
dnf install -y puppet-agent
|
||||
PUPPET_BIN=/opt/puppetlabs/bin/puppet
|
||||
"$PUPPET_BIN" config set --section main certname "{{ .FQDN }}"
|
||||
"$PUPPET_BIN" config set --section main server "{{ .PuppetServer }}"
|
||||
"$PUPPET_BIN" config set --section main ca_server "{{ .PuppetCAServer }}"
|
||||
|
||||
install -d -m0755 /etc/sysconfig
|
||||
cat > /etc/sysconfig/puppet-initial <<'EOF'
|
||||
PUPPETCA_URL={{ .PuppetCAURL }}
|
||||
EOF
|
||||
|
||||
systemctl enable puppet
|
||||
|
||||
{{ if and .ProvisionToken .CallbackURL -}}
|
||||
curl -fsS -m 15 -X POST \
|
||||
-H "Authorization: Bearer {{ .ProvisionToken }}" \
|
||||
"{{ .CallbackURL }}" || echo "bootapi: provisioned callback failed (non-fatal)"
|
||||
{{- end }}
|
||||
%end
|
||||
|
||||
Reference in New Issue
Block a user