Commit Graph

393 Commits

Author SHA1 Message Date
unkinben 206a4521e5 Fix cobbler.main.unkin.net CNAME to resolve on k8s DNS (#491)
The cobbler master exports `cobbler.main.unkin.net` as a CNAME whose value is the bare hostname (`ausyd1nxvm2098`). The legacy puppet DNS master loaded this into a zone file under `$ORIGIN main.unkin.net.`, so BIND completed the bare label to `ausyd1nxvm2098.main.unkin.net.` and it resolved. `dns-updater` renders RFC2136 updates with no `$ORIGIN`, so the same bare label becomes root-absolute (`ausyd1nxvm2098.`) and dead-ends in NXDOMAIN — the record exists on the k8s authoritative servers (and via the resolvers at 198.18.200.7) but has no reachable address. This is the same failure already documented and fixed for haproxy in `profiles::haproxy::dns`.

Changes:
- Set the cobbler CNAME `value` to the fully-qualified `${facts.networking.fqdn}.` (trailing dot) so the target is origin-independent and resolves identically on both the legacy zone-file export and the dns-updater nsupdate path.
- Add an explanatory comment mirroring the one in `profiles::haproxy::dns` to prevent reintroducing a bare label.

Reviewed-on: #491
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-20 23:17:12 +10:00
unkinben 918c4f20e1 haproxy::dns: fully-qualify halb CNAME targets (#489)
## Why

The halb publishes service CNAMEs (`git.unkin.net`, `dashboard.ceph.unkin.net`, and every other halb-fronted name) with a **bare target label**, e.g.:
```
git.unkin.net.  300  IN  CNAME  au-syd1-prod-halb-vrrp.
```
`dns-updater` builds the RR with `dns.NewRR` and **no $ORIGIN**, so a bare value becomes root-absolute (`au-syd1-prod-halb-vrrp.`) and dead-ends in NXDOMAIN. Once the k8s bind became authoritative for these zones, that broke resolution of every halb-fronted service (git, the Ceph dashboard, ...). `au-syd1-prod-halb-vrrp.unkin.net` / `.main.unkin.net` resolve fine (198.18.19.17) — only the CNAME target was truncated.

## Change (`site/profiles/manifests/haproxy/dns.pp`)

Emit **fully-qualified** CNAME targets (trailing dot), the FQDN form `dns-updater` expects (per its own test fixture `au-syd1-prod-halb.main.unkin.net.`):
- vrrp cnames: `${location_environment}-halb-vrrp.${domain}.`
- non-vrrp cnames: `${location_environment}-halb.${domain}.`

The matching A records are already published in `main.unkin.net`/`unkin.net` just above, so the targets resolve to the VIP.

---------

Co-authored-by: benvin <neotheo@gmail.com>
Reviewed-on: #489
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-19 01:37:06 +10:00
unkinben 9aa470d329 dns: exclude k8s/LB ranges from dns-updater; track latest (#485)
Configures the dns-updater record filter (dns-updater#3) so k8s/LB/internal addresses stay out of the authoritative zones.

## Why
Hosts publish records the authoritative server should not hold — `*-flannel.1 A 10.42.x`, `*-kube-lb0 A 198.18.200.x`, and the matching reverse PTRs (`200.18.198`, `2.42.10`) — which the daemon WARNs `NOTAUTH`/`bad authentication` on.

## Changes
- `DNS_UPDATER_DENY_RANGES=198.18.199.0/24,198.18.200.0/24,10.42.0.0/16,10.43.0.0/16` (pod CIDR, service CIDR, LB VIP pool, .199).
- New class params: `deny_ranges` / `allow_ranges` / `deny_domains` / `allow_domains`.
- `package_ensure` → `latest` so hosts pick up the filter release (rpm-internal `metadata_expire` is 1h, so no thrash).

## Sequencing
Needs dns-updater **#3** merged + a new tag (v0.2.0) so the filter env vars are honored. The env keys are ignored by v0.1.0, so this is safe to merge first — it takes effect when hosts upgrade to v0.2.0.

Reviewed-on: #485
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-18 13:58:43 +10:00
unkinben d71e221049 dns: deploy dns-updater daemon in place of the shell nsupdate script [HOLD: needs dns-updater RPM published] (#482)
ci/woodpecker/pr/ruby-validate Pipeline was successful
ci/woodpecker/pr/puppet-lint Pipeline was successful
ci/woodpecker/pr/yamllint Pipeline was successful
ci/woodpecker/pr/erb-validate Pipeline was successful
ci/woodpecker/pr/bolt-validate Pipeline was successful
ci/woodpecker/pr/epp-validate Pipeline was successful
ci/woodpecker/pr/puppet-validate Pipeline was canceled
ci/woodpecker/pr/ruby-check Pipeline was canceled
## Why
Replace the `profiles::dns::updater` shell mechanism (`dns-update.sh` + `dns-update.path`/`.service` + the in-run `exec`) with the packaged **dns-updater** daemon. The daemon watches the records file (inotify) and network interfaces and pushes TSIG-signed RFC2136 updates to BIND natively — with structured per-zone RCODEs and a status API/facter fact, so failures like the recent `invalid owner name: empty label` / NOTZONE surface directly instead of as opaque nsupdate stderr.

## Changes
- Install the `dns-updater` package; manage `/etc/dns-updater/env`.
- Run the packaged `dns-updater.service`, restarting **only** on env/key change — records-file edits are picked up by the daemon`s own inotify watch, so no service churn on record changes.
- Keep the `concat` records file and the TSIG key file unchanged (same paths/format).
- Ensure the old `/usr/local/bin/dns-update` + `dns-update.path`/`.service` units are absent.
- Drop the now-dead `dns-update.{sh,service,path}.epp` templates.

## Sequencing — HOLD
Do not merge until the `dns-updater` RPM is published to artifactapi `rpm-internal` (needs terraform-git#33 to create the repo, then the daemon code pushed + tagged so Woodpecker builds the RPM). Merging before the package exists makes `package { dns-updater }` fail on every host.

Supersedes the interim shell fix in #481 (which stays valid until this rolls out). Keeps the file as the desired-state interface (puppet owns desired records; the daemon reconciles + reports).

Reviewed-on: #482
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-17 23:35:00 +10:00
unkinben 88fcb97ad1 dns: nsupdate host records to the authoritative server (#475)
Replaces the exported-resources → puppet DNS master zone-file flow with per-host RFC2136 dynamic updates against the k8s **bind-authoritative** write endpoint (198.18.200.9). The master no longer manages zone files.

## Design
Each node assembles its DNS records into a local concat file; a systemd `.path` unit watches it and runs `dns-update` (nsupdate) on change — exactly the watch-a-file model requested.

## Changes
- **profiles::dns::updater** (new): concat records file + TSIG key file + `dns-update` script + `dns-update.service` (oneshot) + `dns-update.path` (watcher). The script sends only the delta since last run and deletes removed records, grouped per zone.
- **profiles::dns::record**: writes a local concat fragment (`zone|name|type|ttl|value`) instead of exporting `@@concat::fragment` to the master.
- **profiles::dns::base**: includes `profiles::dns::updater` (all nodes).
- **hiera**: `profiles::dns::updater` server/key_name/algorithm in common.yaml.

## Inert until keyed
The updater does nothing until `profiles::dns::updater::key_secret` (TSIG) is set in eyaml — records are assembled but not applied, so nodes are safe before the key exists.

## Prerequisites (k8s side, separate)
1. The `bind-authoritative` zones must set `dynamicUpdate: true` + an `updateKeyRef` (a client-update BindTSIGKey) so they accept these updates.
2. The TSIG key must be shared: the operator-generated key value goes into eyaml here (or the planned Vault-sync feature bridges it).

## Validated
puppet parser/epp validate, puppet-lint, and a functional test of the generated per-zone nsupdate message (replace + delete-removed).

Reviewed-on: #475
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-12 22:23:18 +10:00
benvin 57c844b7e8 feat: upgrade grafana from default to 13.0.2 (#470)
Pin grafana package version to 13.0.2 via a new version parameter on
profiles::metrics::grafana, wired through to the puppet-grafana class.

---------

Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #470
2026-06-06 23:46:16 +10:00
unkinben 0451894b48 feat: add ceph service management profiles and facts (#459)
## Summary

- Adds `Unkin::Ceph::Utils` facter module detecting ceph service instances via `systemctl list-units`, exposing `is_ceph_mon`, `is_ceph_mgr`, `is_ceph_mds`, `is_ceph_osd` booleans and a `ceph_services` hash of unit names
- Adds `profiles::ceph::mon`, `mgr`, `mds`, `osd` — each with `Boolean $ensure_running` that iterates discovered service instances and manages them as running and enabled
- Works across incus nodes (mon/mgr/mds/osd) and k8s compute/control nodes (osd only); verified on prodnxsr0001 which correctly reports `is_ceph_osd: true` and `ceph_services: {osd: [ceph-osd@5]}`

## Test plan

- [x] Noop deploy against prodnxsr0001.main.unkin.net passed cleanly
- [x] `ceph_services` fact returns correct service map
- [x] `is_ceph_osd` returns `True`, `is_ceph_mon` returns `False` as expected
- [x] Test on an incus/ceph node with mon/mgr/mds services

Reviewed-on: #459
2026-04-07 19:02:17 +10:00
unkinben 476c8115c5 fix: replace puppetdbquery with native PQL queries (#457)
Replace deprecated dalen-puppetdbquery module with native puppetdb_query
function using PQL syntax to resolve URI.escape compatibility issues.
This is required to migrated to Puppet 8 (and kubernetes).

Changes:
- Remove dalen-puppetdbquery dependency from Puppetfile
- Replace query_nodes() calls with puppetdb_query() using PQL syntax
- Update 27 function calls across 18 Puppet manifests
- Maintain equivalent functionality with improved compatibility

Reviewed-on: #457
2026-03-21 22:35:42 +11:00
unkinben 1e707b8b9a feat: puppetboard 7 python (#453)
auto-upgraded to puppetboard 7, which requires 3.10 python. upgrade
puppetboard venv from 3.9 (system python) -> 3.12

Reviewed-on: #453
2026-03-16 23:53:52 +11:00
unkinben 8c24c6582f feat: manage vault version (#446)
- add params for version and package name
- add param to cleanup openbao
- add version lock (if not latest)

Reviewed-on: #446
2026-02-08 22:26:22 +11:00
unkinben 6bfc63ca31 feat: enable plugins for vault/openbao (#447)
- install openbao-plugins
- add plugin_directory

Reviewed-on: #447
2026-02-08 19:19:33 +11:00
unkinben dbe1398218 chore: centralise all yum repo configuration (#436)
- add 30+ repository definitions to AlmaLinux/all_releases.yaml with `ensure: absent` defaults
- update all role-specific hieradata files to use `ensure: present` pattern
- remove duplicated repository URL/GPG key configurations from individual roles
- maintains existing functionality while improving maintainability"

Reviewed-on: #436
2026-01-15 21:35:13 +11:00
unkinben 9f5b1cec82 fix: thundering hurd (#435)
- started all puppet clients at the same time, resulting in thundering herd
- add a randomness timer of 10 minutes

Reviewed-on: #435
2026-01-12 20:21:39 +11:00
unkinben 57870658b5 feat: act runner updates (#432)
saving artifacts are breaking in some actions as the runner will switch
between different git hosts. using haproxy will ensure the same backend
is always hit via stick-tables and cookies

- ensure runners use haproxy to reach git

we now package act_runner now, lets use the rpm

- change installation method to rpm instead of curl + untar
- add capability to versionlock act_runner
- fix paths to act_runner
- remove manually installed act_runner

Reviewed-on: #432
2026-01-03 21:51:47 +11:00
unkinben 40d8e924ee feat: enable managing root password (#429)
- update root password in common.eyaml
- add missing param to the accounts::root manifest
- remove if block as undef sshkeys has same effect

Reviewed-on: #429
2025-12-28 20:12:12 +11:00
unkinben 9eff241003 feat: add SMTP submission listener and enhance stalwart configuration (#425)
- add SMTP submission listener on port 587 with TLS requirement
- configure HAProxy frontend/backend for submission with send-proxy-v2 support
- add send-proxy-v2 support to all listeners
- add dynamic HAProxy node discovery for proxy trusted networks
- use service hostname instead of node FQDN for autoconfig/autodiscover
- remove redundant IMAP/IMAPS/SMTP alt-names from TLS certificates
- update VRRP CNAME configuration to use mail.main.unkin.net

Reviewed-on: #425
2025-11-09 18:48:06 +11:00
unkinben 5b0365c096 feat: manage haproxy for stalwart (#420)
- add frontends for imap, imaps and smtp
- add backends for webadmin, imap, imaps and smtp

Reviewed-on: #420
2025-11-08 21:07:43 +11:00
unkinben 78adef0eee refactor: recreate profiles::postfix::gateway with parameterization and templates (#416)
- refactor profiles::postfix::gateway as parameterized class
- move base postfix parameters, transports, and virtuals to hiera for flexibility
- convert SMTP restrictions to arrays for better readability using join()
- add postscreen enable/disable boolean with conditional master.cf configuration
- add per-domain TLS policy maps (smtp_tls_policy_maps)
- convert alias_maps to array parameter for flexibility
- convert all postfix map files to ERB templates with parameter hashes
- add map parameters: sender_canonical_maps, sender_access_maps, relay_recipients_maps,
  relay_domains_maps, recipient_canonical_maps, recipient_access_maps, postscreen_access_maps, helo_access_maps
- move default map data to hiera while keeping parameters as empty hashes by default

This approach balances flexibility with data-driven configuration, allowing
easy customization through parameters while keeping transport/virtual maps
and default map data in hiera for role-specific overrides.

Reviewed-on: #416
2025-11-01 17:26:00 +11:00
unkinben a2a8edb731 feat: implement comprehensive postfix gateway with eFa5 configuration (#414)
- add voxpupuli-postfix module to Puppetfile
- create profiles::postfix::gateway class with config based on efa5
- add master.cf entries for postscreen, smtpd, dnsblog, and tlsproxy services
- create postfix hash files: aliases, access controls, canonical maps
- configure TLS with system PKI certificates and strong cipher suites
- add transport and virtual alias mappings for mail routing

Reviewed-on: #414
2025-11-01 00:43:58 +11:00
unkinben e95a59b88a feat: migrate puppetserver -> openvox-server (#412)
- enable openvox repo
- ensure puppetdb-termini and puppetserver are purged
- set openvox-server as the package to install
- set termini package to openvoxdb-termini

Reviewed-on: #412
2025-10-18 23:49:51 +11:00
unkinben 8bed80eac8 feat: migrate puppetdb -> openvoxdb (#411)
- ensure the puppetdb package is purged before openvoxdb
- ensure the openvoxdb package is installed

Reviewed-on: #411
2025-10-18 21:47:33 +11:00
unkinben 98b866fce7 feat: migrate puppet-agent to openvox (#408)
- change from puppet-agent to openvox-agent
- upgrade version from 7.34 to 7.36
- ensure workflow of: Yumrepo -> dnf-makecache -> Package

Reviewed-on: #408
2025-10-18 19:11:38 +11:00
unkinben 66d8815e16 fix: ensure nginx restarts on certificate changes (#402)
Add hasrestart => true to nginx service in simpleproxy profile to ensure
nginx performs a full restart (not reload) when certificate files change.
This is required because nginx reload does not pick up SSL certificate
changes from disk.

Reviewed-on: #402
2025-09-29 22:38:00 +10:00
unkinben 6e4bc9fbc7 feat: adding rke2 (#394)
- manage rke2 repos
- add rke2 module (init, params, install, config, service)
- split roles::infra::k8s::node -> control/compute roles
- moved common k8s config into k8s.yaml
- add bootstrap_node, manage server and token fields in rke2 config
- manage install of helm
- manage node attributes (from puppet facts)
- manage frr exclusions for service/cluster network

Reviewed-on: #394
2025-09-14 13:27:49 +10:00
unkinben 8f5d102945 feat: enabling changing ip for consul client (#383)
- enable ability to set consul client bind/advertise ip

Reviewed-on: #383
2025-08-14 22:55:35 +10:00
unkinben 62aade77ff feat: add ceph-dashboard to haproxy (#382)
- add profile to export haproxy backend
- add new cert for dashboard.ceph.unkin.net
- extend balancemember with ipaddress attribute

Reviewed-on: #382
2025-08-14 11:06:11 +10:00
unkinben 92728047e7 feat: add ceph rgw (#380)
- start managing ceph configuration file
- manage ceph-radosgw
- merge the ceph::conf and ceph::node profiles
- ensure the ceph repos exist
- mange nginx frontend and consul service

Reviewed-on: #380
2025-08-13 12:33:41 +10:00
unkinben 308d97d783 feat: enable plugins for grafana (#378)
- add method to install plugins for grafana
- ensure victoriametrics-logs-datasource is installed

Reviewed-on: #378
2025-08-09 17:57:49 +10:00
unkinben ac36d9627b feat: capture all journald logs (#377)
- create module class for journald clients
- ensure module class it used on all hosts
- use consul service address for insert/journald

Reviewed-on: #377
2025-08-09 15:11:47 +10:00
unkinben f73d6f07ce fix: generate types as root (#375)
- larger permission issue that needs fixing
- reduce the number of failed runs

Reviewed-on: #375
2025-08-09 13:30:12 +10:00
unkinben d649195ccc fix: generate types needs to run more often (#373)
- seeing frequent errors in puppetboard about types missing
- change the puppet-generate-types timer from daily to per-minute

Reviewed-on: #373
2025-08-07 20:53:06 +10:00
unkinben a30ff81139 fix: reduce metadata lifetime (#371)
- metadata lifetime should be lowered to improve development speed

Reviewed-on: #371
2025-08-03 21:04:47 +10:00
unkinben df457306cc feat: add external grafana access (#366)
- enable access to grafana through haproxy
- ensure grafana cert created from letsencrypt
- enable user access to grafana

Reviewed-on: #366
2025-07-28 21:07:43 +10:00
unkinben fd902c1437 feat: create exporters module (#364)
- upgrade node_exporter, bring managed under exporters module
- upgrade postgres_exporter, bring managed under exporters module
- add flag to cleanup previous iterations of exporters from prometheus module
- fix issues with vmclusster: replication + dedup

Reviewed-on: #364
2025-07-27 13:28:41 +10:00
unkinben 780a97dfe4 feat: add new cobbler master (#355)
- change cobbler.main.unkin.net to 2098

Reviewed-on: #355
2025-07-12 20:31:43 +10:00
unkinben 80ab4e6889 chore: update cobbler for el9 (#353)
- update cobbler/cobbler-web package
- update path for ipxebins

Reviewed-on: #353
2025-07-12 14:19:14 +10:00
unkinben acef1bde29 feat: move puppetca role (#351)
- move puppetca from vm to lxd

Reviewed-on: #351
2025-07-09 21:15:09 +10:00
unkinben 40c57ede59 feat: add ci build task (#342)
- a ci workflow for build tests
- run pre-commit against all files

Reviewed-on: #342
2025-07-08 20:19:36 +10:00
unkinben a550d48f21 fix: sort nameservers (#348)
- sort nameservers before creating glue records

Reviewed-on: #348
2025-07-06 20:09:19 +10:00
unkinben 2d9faf578f feat: add unkin.net domain (#347)
- manage the unkin.net domain
- ensure forwarding for unkin.net
- split domain from cname list and set zone correctly
- add fafflix to cnames list for haproxy2

Reviewed-on: #347
2025-07-06 20:02:20 +10:00
unkinben 0063f68bc6 feat: enable external access to gitea (#344)
- add git.unkin.net to certbot
- export haproxy resources for gitea
- add be_gitea to haproxy, import the certbot cert
- update the ROOT_URL for gitea instances

Reviewed-on: #344
2025-07-06 13:47:56 +10:00
unkinben cf0ff85b70 fix: manage git user (#339)
- prevent different gid/uid for git users when deploying cluster
- only add sudo conf when sudo_rules is a list

Reviewed-on: https://git.query.consul/unkinben/puppet-prod/pulls/339
2025-07-06 11:27:35 +10:00
unkinben 93049707e7 benvin/gitea_cluster (#335)
Reviewed-on: https://git.query.consul/unkinben/puppet-prod/pulls/335
2025-07-05 14:49:56 +10:00
unkinben a9faa098ee benvin/grafana_postgres (#334)
Reviewed-on: https://git.query.consul/unkinben/puppet-prod/pulls/334
2025-07-01 19:07:24 +10:00
unkinben 9bed18f78c fix: duplicate toml resources (#332)
- change resource name for puppetserver_gem
- ensure toml installed on all agents

Reviewed-on: https://git.query.consul/unkinben/puppet-prod/pulls/332
2025-06-30 19:57:29 +10:00
unkinben 33c8b226e0 feat: add puppetserver gem for toml (#330)
- require toml for puppetserver gem

Reviewed-on: https://git.query.consul/unkinben/puppet-prod/pulls/330
2025-06-30 19:05:12 +10:00
unkinben 99b312669b benvin/dhcp_failover (#327)
Reviewed-on: https://git.query.consul/unkinben/puppet-prod/pulls/327
2025-06-29 13:36:16 +10:00
unkinben 770fd643ac feat: add haproxy2 role (#322)
- add basic haproxy2 role
- add peers and resolvers
- add haproxy2+ metrics frontend

Reviewed-on: https://git.query.consul/unkinben/puppet-prod/pulls/322
2025-06-28 16:20:06 +10:00
unkinben cb1d562cb0 feat: migrate pupeptdb sql to patroni (#318)
- change puppetdb::sql to using the patroni profile
- change puppetdb::api to use new patroni cluster
- remove references to puppetlabs-puppetdb managed database
- update consul rules to enable sessions

Reviewed-on: https://git.query.consul/unkinben/puppet-prod/pulls/318
2025-06-19 05:52:32 +10:00
unkinben 26b908e5e7 feat: add node_pools (#317)
- change agentv2 to common node_pool
- set default node_pool to default

Reviewed-on: https://git.query.consul/unkinben/puppet-prod/pulls/317
2025-06-15 17:43:19 +10:00