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:
+35
-18
@@ -23,11 +23,15 @@ against. It is assembled in `internal/render.dataFor` from a NetBox device
|
||||
| `.Nameservers` | `[]string` | NetBox CF `nameservers`, else `BOOTAPI_NAMESERVERS` | |
|
||||
| `.RootPasswordHash` | string | **render-time** (`BOOTAPI_ROOT_PASSWORD_HASH[_FILE]`) | crypt(3) hash; empty ⇒ lock root. **Never** from NetBox — see [security.md](security.md) |
|
||||
| `.SSHAuthorizedKeys` | `[]string` | **render-time** (`BOOTAPI_SSH_AUTHORIZED_KEYS`) | |
|
||||
| `.PuppetServer` | string | `BOOTAPI_PUPPET_SERVER` | default `puppet.query.consul` |
|
||||
| `.PuppetCAServer` | string | `BOOTAPI_PUPPET_CA_SERVER` | default `puppetca.query.consul` |
|
||||
| `.BaseURL` | string | `BOOTAPI_BASE_URL` | bootapi's own URL |
|
||||
| `.BootBaseURL` | string | `BOOTAPI_BOOT_BASE_URL` | OS install-tree base |
|
||||
| `.PuppetServer` | string | `BOOTAPI_PUPPET_SERVER` | default `puppet.k8s.syd1.au.unkin.net` |
|
||||
| `.PuppetCAServer` | string | `BOOTAPI_PUPPET_CA_SERVER` | default `puppetca.k8s.syd1.au.unkin.net` |
|
||||
| `.PuppetCAURL` | string | `BOOTAPI_PUPPET_CA_URL` | written to `/etc/sysconfig/puppet-initial` as `PUPPETCA_URL` |
|
||||
| `.BaseURL` | string | `BOOTAPI_BASE_URL` | bootapi's own **http** URL |
|
||||
| `.KickstartURL` | string | derived | `BaseURL/ks/Hostname` |
|
||||
| `.CallbackURL` | string | derived | `CallbackBaseURL/provisioned/Hostname` |
|
||||
| `.ProvisionToken` | string | **render-time** (`BOOTAPI_PROVISION_TOKEN[_FILE]`) | bearer token the `%post` callback sends; empty ⇒ callback snippet omitted |
|
||||
| `.DistroVars` | `map[string]string` | selected catalog entry's evaluated `vars` | e.g. `.DistroVars.mirror` (install-tree base); empty when no catalog entry matched |
|
||||
| `.BootBaseURL` | string | `BOOTAPI_BOOT_BASE_URL` | legacy OS-tree base; empty when catalog-driven |
|
||||
| `.Custom` | `map[string]any` | **all** NetBox custom fields, verbatim | escape hatch for site-specific knobs without a code change |
|
||||
|
||||
### `Interface`
|
||||
@@ -49,8 +53,10 @@ Rendered with everything above **plus**:
|
||||
|
||||
| Field | Type | Notes |
|
||||
|-------|------|-------|
|
||||
| `.KernelURL` | string | `BootBaseURL/images/pxeboot/vmlinuz` (empty if `BootBaseURL` unset) |
|
||||
| `.InitrdURL` | string | `BootBaseURL/images/pxeboot/initrd.img` |
|
||||
| `.KernelURL` | string | from the selected catalog entry's `kernel_url` (else legacy `BootBaseURL/images/pxeboot/vmlinuz`) |
|
||||
| `.InitrdURL` | string | catalog `initrd_url` (else legacy path) |
|
||||
| `.RepoURL` | string | OS install-tree root (`KernelURL` minus `images/pxeboot/vmlinuz`); passed as `inst.repo=` |
|
||||
| `.KernelArgs` | `[]string` | catalog entry's extra kernel args |
|
||||
|
||||
The fallback templates (`fallback-local`, `fallback-shell`) are rendered with an
|
||||
empty value — they take no host data by design.
|
||||
@@ -60,18 +66,29 @@ empty value — they take no host data by design.
|
||||
Define these on the *device* (or, where noted, the *IP address*) in NetBox.
|
||||
All are optional; sensible fallbacks apply.
|
||||
|
||||
| Custom field | On | Effect |
|
||||
|--------------|----|--------|
|
||||
| `domain` | device | DNS domain; overrides `BOOTAPI_DOMAIN` |
|
||||
| `gateway` | device / IP address | default gateway (IP-level wins) |
|
||||
| `nameservers` | device | comma-separated resolvers; overrides `BOOTAPI_NAMESERVERS` |
|
||||
| `provision_template` | device | force a specific template name (see below) |
|
||||
| Custom field | On | Type | Effect |
|
||||
|--------------|----|------|--------|
|
||||
| `domain` | device | text | DNS domain; overrides `BOOTAPI_DOMAIN` |
|
||||
| `gateway` | device / IP address | text | default gateway (IP-level wins) |
|
||||
| `nameservers` | device | text | comma-separated resolvers; overrides `BOOTAPI_NAMESERVERS` |
|
||||
| `provision_template` | device | text | force a specific catalog entry / template name |
|
||||
| `pxe_enabled` | device | boolean | gate network install (Cobbler's `netboot_enabled`). Unset ⇒ treated as enabled. Set `false` (or let the callback clear it) to boot local disk instead of re-installing. |
|
||||
|
||||
## Template selection precedence
|
||||
## Distro selection and the catalog
|
||||
|
||||
`SelectKickstart` picks the first template name that exists, in order:
|
||||
Host → distro is resolved through the **distro catalog** (`catalog/*.yaml` in the
|
||||
templates repo / embedded defaults). Each entry names a kickstart template, the
|
||||
kernel/initrd URL templates (artifactapi remotes) and extra kernel args. See
|
||||
[template-authoring.md](template-authoring.md#the-distro-catalog).
|
||||
|
||||
1. `provision_template` custom field (exact template name)
|
||||
2. `.Platform` slug (e.g. `almalinux9`)
|
||||
3. `.OSFamily` (e.g. `almalinux`, or `fedora`)
|
||||
4. `BOOTAPI_DEFAULT_TEMPLATE` (default `almalinux9`)
|
||||
Selection precedence (both catalog `Select` and the kickstart-name fallback):
|
||||
|
||||
1. `provision_template` custom field — exact catalog entry / template name.
|
||||
2. `.Platform` slug (e.g. `almalinux9`) matched against a catalog entry's
|
||||
`match.platforms`, else a template of that name.
|
||||
3. `.OSFamily` (e.g. `fedora`) matched against `match.family`, else a template
|
||||
of that name.
|
||||
4. `BOOTAPI_DEFAULT_TEMPLATE` (default `almalinux9`).
|
||||
|
||||
The version substituted into the catalog URLs is `.OSVersion` (the numeric
|
||||
suffix of the platform slug), falling back to the entry's `version_default`.
|
||||
|
||||
Reference in New Issue
Block a user