78 Commits

Author SHA1 Message Date
unkinben c104360c1a dns: stop exporting legacy DNS fragments (manage_export false)
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/bolt-validate Pipeline was successful
ci/woodpecker/pr/erb-validate Pipeline was successful
ci/woodpecker/pr/epp-validate Pipeline was successful
ci/woodpecker/pr/ruby-check Pipeline was successful
ci/woodpecker/pr/puppet-validate Pipeline was successful
Clients now resolve via the k8s bind (198.18.200.7) which serves the
authoritative zones fed by the nsupdate path, so the legacy
exported-resource -> VM-master /var/named/sources files are no longer in
the serving path. Turn off the export half of the dual-write; the
nsupdate (manage_nsupdate) half stays on.
2026-07-25 00:27:04 +10:00
unkinben 36d8230ac0 Migrate canary ausyd1nxvm2120 to puppet-on-k8s (#494)
First live agent migration to the k8s puppetserver, using the single-boolean mechanism from #493 on the lowest-risk host (roles::base test host).

- Adds hieradata/nodes/ausyd1nxvm2120.main.unkin.net.yaml with profiles::puppet::migrate::enabled: true

On merge: the node's next run (from the old master) rewrites puppet.conf to the k8s server/ca_server with a fresh ssl-k8s ssldir; the run after enrols against the k8s CA (autosigned) and compiles from the k8s compilers (ENC=encapi). Verify: node appears in the k8s PuppetDB with a fresh report. Rollback: revert this file — legacy ssldir/cert remain intact.

Reviewed-on: #494
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-25 00:16:30 +10:00
unkinben aebe80e73f Add profiles::puppet::migrate: repoint VM agents onto puppet-on-k8s (#493)
## Why

Migrate the VM puppet agents off the legacy VM puppetmasters onto the new puppet-on-kubernetes servers, one wave at a time and reversible without re-enrolment.

Changing `server`/`ca_server` alone is insufficient: each agent's ssldir holds a client certificate signed by the **old** CA, which the new k8s CA neither trusts nor recognises. Migrated nodes switch to a **fresh ssldir**, so the agent generates a new key + CSR on its next run (autosigned immediately by the k8s CA, which runs `autosign = true`), pulls its catalog from the new compilers, and leaves the old CA-signed creds intact on disk for rollback.

The reconfiguration catalog is compiled by the **old** server (the node still points there when it applies the change). `profiles::puppet::client` rewrites `puppet.conf` with the new endpoints + ssldir and notifies `Service['puppet']`, so the very next agent run lands on k8s.

**Single-boolean design (reworked):** cutover is now driven by one hiera key. `profiles::puppet::migrate` ships wired into `profiles::base` with `enabled => false`, so every node evaluates it but nothing changes until the boolean is flipped. `profiles::puppet::client` includes migrate and folds the migrate endpoints into the effective values it renders. Flip `profiles::puppet::migrate::enabled: true` at any hiera layer (node/role/common) to migrate a target -- no other keys required.

## Changes

- `profiles::base` (`site/profiles/manifests/base.pp`): `include profiles::puppet::migrate` alongside the other puppet profiles (ships disabled).
- `profiles::puppet::migrate` (`site/profiles/manifests/puppet/migrate.pp`): unchanged params (`enabled=false`, `new_server`, `new_ca_server`, `new_ssldir`); when enabled and the node is not a puppetmaster it owns the fresh ssldir directory. Class-header runbook rewritten for the single-boolean flow. No longer opt-in via `hiera_include`.
- `profiles::puppet::client` (`site/profiles/manifests/puppet/client.pp`): `include profiles::puppet::migrate` and compute `$effective_server` / `$effective_ca_server` / `$effective_report_server` / `$effective_ssldir`, feeding those to the template. Keeps the existing optional `$ssldir` / `$report_server` params as manual overrides.
- `puppet.conf.erb`: render from the `@effective_*` vars.

## Precedence

- **ssldir / report_server** (`Optional`, default `undef`): explicit `profiles::puppet::client::ssldir` / `::report_server` in hiera wins; else the migrate-derived value when `enabled`; else the legacy default (ssldir omitted -> puppet default; report_server -> effective server).
- **server / ca_server** (`String`, no undef sentinel): the migrate endpoint wins while `enabled => true`; otherwise the client param (legacy default unless set explicitly). To pin a bespoke server, leave `enabled => false` for that target and set `profiles::puppet::client::server` directly.
- No include cycle: migrate.pp never references client.pp; its guard uses `$facts['enc_role']`.

## Runbook

- **Canary (one node)** -> `hieradata/nodes/<certname>.yaml`: `profiles::puppet::migrate::enabled: true`
- **Wave (a role)** -> `hieradata/roles/<t1>/<t2>[/<t3>].yaml`: `profiles::puppet::migrate::enabled: true`
- **Estate flip** -> `hieradata/common.yaml`: `profiles::puppet::migrate::enabled: true`
- **Rollback** -> remove the key (or set `false`) at that layer; next run rewrites puppet.conf back to the legacy server + legacy ssldir (original CA-signed cert intact).
- The k8s endpoints (`new_server` / `new_ca_server` / `new_ssldir`) are `profiles::puppet::migrate` param defaults; override them in hiera if the k8s names change.

## Verification

- Render comparison: unmigrated node renders a **byte-identical** `puppet.conf` to `develop` (diff empty). Migrated render (only `enabled: true`) emits `server`/`ca_server`/`report_server` = k8s endpoints and `ssldir = /etc/puppetlabs/puppet/ssl-k8s`.
- `puppet-lint` (repo args `--no-80chars-check --no-documentation-check --no-puppet_url_without_modules-check --fail-on-warnings`): clean on all 3 manifests.
- `puppet parser validate`: OK. ERB syntax: OK. Repo pre-commit hooks (erb-validate, puppet-lint, puppet-validate): all Passed.

Reviewed-on: #493
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-25 00:04:11 +10:00
unkinben a69318b62d Pin openbao secrets plugins to exact versions (#492)
## Why

`ensure: present`/`latest` lets the plugin binaries drift from the sha256 pinned in the terraform-vault catalog (`config/plugins/*.yaml`). On the next OpenBao restart, a drifted binary fails the sha check and the plugin won't launch — a latent footgun (hit exactly this with rancher on `ensure: latest`).

## Changes

Pin each secrets plugin to the version whose binary matches its registered catalog sha (all verified against the RPMs in rpm-internal):

- `openbao-plugin-secrets-litellm`: **0.1.1** (sha 2263ebcb…)
- `openbao-plugin-secrets-gpg`: **0.1.0** (sha 0e92d740…)
- `openbao-plugin-secrets-rancher`: **0.1.1** (sha 9e597cd9…; was `ensure: latest`)

All three are no-op on the binary (installed versions already match) — this just locks them so a future release can't silently upgrade the binary out of lockstep with the catalog.

`openbao-plugins` (base bundle) left unpinned — its version couldn't be verified from the tooling side and it tracks the openbao package, not a catalog sha.

## Note

To upgrade a plugin in future: bump the RPM version here **and** the catalog sha256 in terraform-vault in the same change, then `vault write sys/plugins/reload/backend plugin=<name>`.

---------

Co-authored-by: Ben Vincent <neotheo@gmail.com>
Reviewed-on: #492
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-20 23:46:36 +10:00
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
benvin e8443ccfa1 feat: migrate clients to use bind-dns in kubernetes (#490)
- change the default anycast nameserver to bind-internal resolvers in
  kubernetes

---------

Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #490
2026-07-20 22:41:29 +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 732c938c5a ceph/rgw: add s3.ceph.unkin.net to radosgw cert SAN + nginx aliases (#487)
## Why

`s3.ceph.unkin.net` is the RGW S3 endpoint name used by cephrgw-operator consumers. A companion argocd-apps PR adds it as a CNAME to `radosgw.service.consul`. The radosgw hosts front RGW with nginx (443 -> radosgw:7480) using the vault-issued cert, so **both** the certificate and nginx must recognise the name.

## Changes (hieradata/roles/infra/ceph/rgw.yaml)

- Add `s3.ceph.unkin.net` to `profiles::pki::vault::alt_names` — puts the name in the radosgw cert SAN (renewal re-triggers on the alt-names change).
- Add `s3.ceph.unkin.net` to `profiles::nginx::simpleproxy::nginx_aliases` — nginx answers for that server_name.

### nginx: yes, needed

radosgw sits behind `profiles::nginx::simpleproxy` (listens 443, proxies to :7480) sharing the same vault cert, so the alias is required for nginx to serve the hostname — not just the cert SAN.

---------

Co-authored-by: benvin <neotheo@gmail.com>
Reviewed-on: #487
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-18 17:01:41 +10:00
unkinben 4230370418 Upgrade openbao-plugin-secrets-rancher to latest (v0.1.1) (#488)
## Why

The vault nodes have rancher plugin v0.1.0, which mints non-functional tokens (returns `status.value` not `status.bearerToken`; every cred/rotation 401s). v0.1.1 fixes it. `ensure_packages` defaults to `present`, which won't upgrade an already-installed package, so pin to `latest` to pull v0.1.1.

## Changes

- `openbao-plugin-secrets-rancher: { ensure: latest }` on the vault storage role.

## Note

`latest` will also pull future releases automatically — keep the terraform-vault catalog sha256 (`config/plugins/vault-plugin-secrets-rancher.yaml`) bumped in lockstep, or a vault restart after a future upgrade will fail the sha check. Happy to pin to an exact version instead if you'd prefer lockstep-by-pin.

---------

Co-authored-by: Ben Vincent <neotheo@gmail.com>
Reviewed-on: #488
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-18 17:01:14 +10:00
unkinben 8f49c35c16 yum: point rpmfusion repos at artifactapi (#486)
Repoints the `rpmfusion-free` and `rpmfusion-nonfree` yum repos from the retired `packagerepo.service.consul` mirror to the artifactapi RPM Fusion remotes.

dnf on media nodes (jellyfin, nzbget) failed with `Cannot download repomd.xml: All mirrors were tried`, which blocked package installs such as `dns-updater`.

Changes:
- `rpmfusion-free` baseurl → `.../api/v1/remote/rpmfusion-free/el/updates/$major/$arch/`, gpgkey → `.../rpmfusion-free/el/RPM-GPG-KEY-rpmfusion-free-el-$major`
- `rpmfusion-nonfree` baseurl → `.../api/v1/remote/rpmfusion-nonfree/el/updates/$major/$arch/`, gpgkey → `.../rpmfusion-nonfree/el/RPM-GPG-KEY-rpmfusion-nonfree-el-$major`

Depends on terraform-artifactapi PR #7 (adds the rpmfusion remotes) being applied first.

https://claude.ai/code/session_01VZ81u2JtjvaPq8Z3EDTSMb
Reviewed-on: #486
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-18 14:30:25 +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 6f70594484 Add rpm-vendor yum repository (#484)
Why: rpmbuilder's vendored third-party RPMs are moving from Gitea's RPM registry to the artifactapi rpm-vendor local repos. Managed AlmaLinux hosts need the matching yum repo to install them; this mirrors the existing rpm-internal repo and selects the per-EL-release repo via os.release.major.

Changes:
- Add rpm-vendor to profiles::yum::global::repos in hieradata/os/AlmaLinux/all_releases.yaml, pointing at .../api/v1/local/rpm-vendor-el<major>/ (el8/el9), gpgcheck disabled and mirrorlist absent, matching the rpm-internal repo definition.

Depends on terraform-artifactapi PR #6 (creates the rpm-vendor-el8/el9 repos).

Reviewed-on: #484
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-18 11:28:01 +10:00
unkinben 9891311d52 Install openbao-plugin-secrets-rancher on vault nodes (#483)
## Why

The Rancher token secrets engine needs its plugin binary present in the OpenBao plugin directory before terraform-vault can register/mount it. Mirrors #480 (gpg).

## Changes

- Add `openbao-plugin-secrets-rancher` to `profiles::packages::include` on the vault storage role. Installs the RPM (from rpm-internal) to `/opt/openbao-plugins/vault-plugin-secrets-rancher`.

## Merge order

Part 3 of 4 — merge first (binary must exist on disk before the terraform-vault plugin-import #92 registers it with a matching sha256).

---------

Co-authored-by: Ben Vincent <neotheo@gmail.com>
Reviewed-on: #483
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-18 11:20:02 +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 0de3ac2a0b dns: fix dns-update fqdn() double-appending zone to FQDN records (#481)
## Why
6 hosts (ausyd1nxvm2069-2073, 2098) ended up with a reverse PTR in bind-authoritative but **no forward A record**, and the `unkin.net` service records (git/grafana/auth/fafflix, all published by the halb host 2069) never landed at all.

VictoriaLogs (`dns-update-apply` on 2069 & 2070) shows the cause:
```
dns-update: nsupdate to 198.18.200.9 failed
invalid owner name: empty label
syntax error
```
`profiles::dns::record` publishes some records whose name is already fully-qualified (trailing dot) — e.g. `au-syd1-pve.main.unkin.net.`, `cobbler.main.unkin.net.`, `dashboard.ceph.unkin.net.`, and the halb CNAMEs. The `dns-update` script `fqdn()` unconditionally appended the zone, producing `…net..main.unkin.net.` — the `..` is an empty label, which nsupdate rejects, failing the entire per-zone `send`. The reverse-PTR send is sorted first and its name is always relative, so it still applied — hence "PTR but no A".

## Change
`fqdn()` now handles three cases:
- `@`/empty → zone apex (unchanged)
- name ending in `.` → already FQDN, used verbatim (**the fix**)
- otherwise → relative, append `.zone.` (unchanged)

Verified against all record shapes (relative host, apex, FQDN CNAME, reverse label) — no more `..`.

## After merge
Once puppet re-runs on the affected hosts their `main.unkin.net`/`unkin.net` updates succeed, filling in the missing A records and the `unkin.net` service zone. Pairs with argocd-apps#260 (adds the `ceph.unkin.net` zone so `dashboard.ceph.unkin.net` does not then hit NOTZONE).

Reviewed-on: #481
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-17 22:50:28 +10:00
unkinben 0702676da6 Install openbao-plugin-secrets-gpg on vault nodes (#480)
Deploy the GPG/OpenPGP secrets engine to the OpenBao (vault-role) cluster by installing its plugin RPM into `/opt/openbao-plugins`, mirroring the existing `openbao-plugin-secrets-litellm` deployment (#479).

- Add `openbao-plugin-secrets-gpg` to `profiles::packages::include` in the vault role hiera. The RPM ships from artifactapi `rpm-internal` (built on the [vault-plugin-secrets-gpg](https://git.unkin.net/unkin/vault-plugin-secrets-gpg) v0.1.0 tag) and lands the plugin binary in the node's configured `plugin_directory`.

Registering + enabling the secrets backend (`plugin register` / `secrets enable`) is a follow-up terraform-vault change, matching how litellm is wired.

Reviewed-on: #480
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-16 22:48:08 +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 69781df412 chore: change to openbao-plugin-secrets-litellm (#479)
change to openbao litellm plugin as it installs to the correct directory

---------

Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #479
2026-07-06 23:26:21 +10:00
benvin 2ae215daf7 feat: install vault-plugin-secrets-litellm (#477)
ensure the litellm plugin for vault is installed

---------

Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #477
2026-07-06 23:02:12 +10:00
benvin cd1c3e6ae2 chore: add rpm-internal repo (#476)
enable installing locally packaged rpms with no specific linux release

- add the rpm-internal repo from artifactapi

---------

Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #476
2026-07-06 23:02:02 +10:00
benvin 00a8088aed chore: reduce requsts for all jobs (#478)
- found jobs stalling

---------

Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #478
2026-07-06 22:22:51 +10:00
unkinben aeae26711f Convert RKE2 registries to template, disable default endpoints (#474)
## Summary
- Replace static `registries.yaml` with EPP template driven by `rke2::registries` hash
- Add `disable-default-registry-endpoint: true` to all mirrors — RKE2 will only use artifactapi and never fall back to upstream registries
- Registry configuration now fully managed via hiera data (`roles/infra/k8s.yaml`)

Reviewed-on: #474
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-06-29 22:30:48 +10:00
benvin 7b53be7f8c chore: enable rke2 registries (#473)
- re-enable registries for rke2 machines

---------

Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #473
2026-06-27 22:27:33 +10:00
benvin 97d21c81c5 feat: make rke2 registries.yaml conditional on manage_registries (#472)
Add/Remove the registries.yaml file based on the manage_registries
boolean. We are leaving it on default=false now as the artifactapi
server was broken.

---------

Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #472
2026-06-27 07:50:31 +10:00
unkinben e140b300bb chore: bump almalinux9 image tags (#471)
Bump almalinux9 image tags to 20260606

Reviewed-on: #471
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-06-07 00:31:30 +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
benvin 757de20682 feat: upgrade gitea from 1.22.0 to 1.26.2 (#469)
- update release to install to 1.26.2
- change base_url to artifactapi
- update releases/checksums

---------

Co-authored-by: Ben Vincent <ben@unkin.net>
Reviewed-on: #469
2026-06-06 20:23:25 +10:00
unkinben 6ef1b20abd feat: add switch to change to almalinux-vault (#468)
- move old almalinux versions to query the almalinux-vault
- default to the almalinux remote

Reviewed-on: #468
2026-06-06 17:35:04 +10:00
unkinben b754d947d5 feat: add auth.unkin.net proxying to Kubernetes Traefik ingress (#467)
Add static haproxy2 backends for syd1 Kubernetes Traefik ingress
(external 198.18.199.0, internal 198.18.200.4) and route
auth.unkin.net to the internal backend with Let's Encrypt cert.

Reviewed-on: #467
2026-06-02 22:50:10 +10:00
unkinben ba35c8907c chore: increase inotify limits on rke2 nodes to fix fsnotify watcher errors (#466)
Reviewed-on: #466
2026-05-26 23:50:25 +10:00
unkinben ceacfc85ae feat: restart rke2 when registries.yaml is deployed (#465)
- ensure we restart rke2 to pickup registries.yaml changes
- add a comment to registries.yaml to force a restart

Reviewed-on: #465
2026-05-06 23:11:20 +10:00
unkinben 7e45e0d2e5 chore: expand puppet-validate to two cpus (#464)
puppet validate takes 5 mins on one core. doubling to two cores should
bring it down to 2.5mins

Reviewed-on: #464
2026-05-06 22:29:39 +10:00
unkinben 682f65e046 chore: setup proper resource requirements for puppet ci jobs (#463)
currently, all woodpecker jobs jam onto one host, and have no resource
limits resulting in one kubernetes host suddenly maxing its cpu

- ensure we allocate resources for each woodpecker job

Reviewed-on: #463
2026-05-06 22:24:30 +10:00
unkinben 0d412aebdb chore: deploy rke2 registries.yaml (#462)
ensure all new docker pulls are actioned through artifactapi

Reviewed-on: #462
2026-05-06 22:17:59 +10:00
unkinben 4b9b28ddb7 chore: disable rp_filter on k8s nodes (#461)
- k8s control/compute are multihomed, must disable rp_filter

Reviewed-on: #461
2026-04-11 21:51:42 +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 3714691240 chore: enable access to dns (#460)
rebuilding router, taking the chance to not mess up ip ranges. I did
have 198.18.21.0/24 and 198.18.21.160/27 and 198.18.21.192/27 all on
differnt interfaces.

- update IP's that can reach bind view for main.unkin.net
- keep both for intermediate period

Reviewed-on: #460
2026-04-06 22:46:40 +10:00
unkinben dbe04a91e3 chore: change to ceph-public loopback (#458)
- use ceph public loopback port 9443 for dashboard

Reviewed-on: #458
2026-04-05 22:35:39 +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 1d41d07b2d fix: allow transfer for external-dns (#456)
external-dns required axfr support to remove old records. add the
capability for the externaldns tsig key.

Reviewed-on: #456
2026-03-18 20:00:22 +11:00
unkinben 029c998797 feat: improve ci performance (#455)
split all pre-commit checks into individual workflows, so that
woodpecker spawns a container/job for each. this vastly improves the
time it takes for CI to complete checks for puppet

- create per-pre-commit-check pre-commit config files
- create per-pre-commit-check woodpecker workflows

Reviewed-on: #455
2026-03-17 17:38:22 +11:00
unkinben 0c0d4a3f61 chore: update r10k repo path (#454)
- change to use letsencrypt ssl path for simpler tls trust management

Reviewed-on: #454
2026-03-17 17:36:58 +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 416c5ce7d9 chore: update puppet-bind repo url (#452)
changing this to `git.unkin.net` as that certificate is publicly
trusted, requiring no certificate changes for r10k docker container

Reviewed-on: #452
2026-03-08 19:01:55 +11:00
unkinben 0377c40a07 chore: cleanup gitea actions workflows (#451)
- migrated workflows to woodpeckerci

Reviewed-on: #451
2026-02-28 17:50:41 +11:00
unkinben 8bb40dadce feat: add woodpecker ci jobs (#450)
- pre-commit job to run pre-commit against

Reviewed-on: #450
2026-02-28 17:30:23 +11:00
unkinben bc769aa1df feat: add ldap groups for kubernetes/vault (#449)
need to separate the permissions inside vault into different groups, one
per-permission.

- add group for each kubernetes role in vault

Reviewed-on: #449
2026-02-14 19:22:26 +11:00
unkinben 4e652ccbe6 chore: add alt-names to consul (#448)
- ensure consul datacenter is added to altnames

Reviewed-on: #448
2026-02-09 01:03:20 +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 69dc9e8f66 docs: add docs for cephfs (#445)
- specifically related to managing csi volumes for kubernetes

Reviewed-on: #445
2026-02-03 19:56:14 +11:00
unkinben c4d28d52bc chore: remove helm deploys from puppet (#444)
- migrate helm deployments to terraform

Reviewed-on: #444
2026-01-30 20:52:51 +11:00
unkinben 6219855fb1 chore: add additional user (#443)
- as per request

Reviewed-on: #443
2026-01-26 20:21:10 +11:00
unkinben 7215a6f534 chore: terraform state too large for body (#442)
- update consul/nginx max body size to 512MB

Reviewed-on: #442
2026-01-18 17:15:08 +11:00
unkinben 88efdbcdd3 chore: reduce synced repos (#441)
- remove repos now available via artifactapi

Reviewed-on: #441
2026-01-17 17:12:44 +11:00
unkinben 3c114371e0 chore: docs for ceph (#440)
- add maintenance mode, how to bootstrap an osd, remove an osd

Reviewed-on: #440
2026-01-17 13:26:44 +11:00
unkinben 1077bdcbc1 chore: update ceph gpgkey (#438)
- stop checking ceph gpgkey (fixme)
- use artifactapi for retrieving large rke image bundle

Reviewed-on: #438
2026-01-16 23:51:11 +11:00
unkinben 4e928585f5 fix: ceph repos remove dash (#437)
Reviewed-on: #437
2026-01-15 21:52:17 +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 383bbb0507 fix: ensure join-api is functioning (#434)
- consul was directing new rke2 control nodes to a dead join api
- add additional check to verify its responding (not just up)

Reviewed-on: #434
2026-01-11 13:51:36 +11:00
unkinben 6f51bffeaa core: bump radowgw client_max_body_size (#433)
Reviewed-on: #433
2026-01-07 23:27:09 +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 f8caa71f34 fix: increase artifact upload size for git (#431)
- rpmbuilder artifacts can be very large
- increase 1Gb limit to 5GB

Reviewed-on: #431
2025-12-30 22:52:43 +11:00
unkinben a2c56c9e46 chore: add almalinux 9.7 repositories (#430)
- ensure almalinux 9.7 is synced

Reviewed-on: #430
2025-12-30 22:48:54 +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 0aec795aec feat: manage externaldns bind (#428)
- add module to manage externaldns bind for k8s
- add infra::dns::externaldns role
- add 198.18.19.20 as anycast for k8s external-dns service

Reviewed-on: #428
2025-11-22 23:25:55 +11:00
unkinben 9854403b02 feat: add syslog listener for vlinsert (#427)
- enable syslog capture via vlinsert
- add syslog.service.consul service

Reviewed-on: #427
2025-11-20 23:47:10 +11:00
unkinben 6400c89853 feat: add vmcluster static targets (#426)
- add ability to list static targets for vmagent to scrape
- add vyos router to be scraped

Reviewed-on: #426
2025-11-20 20:19:53 +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 35614060bd chore: replace stalwart S3 keys (#424)
- update stalwart S3 AK/SK after migrating to new zonegroup

Reviewed-on: #424
2025-11-08 22:56:24 +11:00
unkinben 1b0fd10fd7 fix: remove . from end of vrrp_cnames (#423)
- autoconfig/autodiscovery should not end with a dot

Reviewed-on: #423
2025-11-08 21:38:10 +11:00
unkinben 2c9fb3d86a chore: add stalwart required tls alt names (#422)
- add alt-names for service addresses stalwart is expected to reply too

Reviewed-on: #422
2025-11-08 21:28:41 +11:00
unkinben 559c453906 chore: change transport for main.unkin.net (#421)
- ensure main.unkin.net mail is delivered to stalwart load-balancer addr

Reviewed-on: #421
2025-11-08 21:10:11 +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 1e7dfb9d9d feat: manage additional ceph sections (#419)
- ensure mons configuration are managed in code
- ensure radowgw configuration are managed in code

Reviewed-on: #419
2025-11-08 19:19:44 +11:00
unkinben 9dd74013ea feat: create stalwart module (#418)
- add stalwart module
- add psql database on the shared patroni instance
- add ceph-rgw credentials to eyaml
- ensure psql pass and s3 access key are converted to sensitive

Reviewed-on: #418
2025-11-08 19:09:30 +11:00
unkinben 92a48b4113 feat: ensure latest openbao package (#417)
- stop version locking openbao, use latest

Reviewed-on: #417
2025-11-06 20:01:37 +11:00
128 changed files with 3358 additions and 931 deletions
-24
View File
@@ -1,24 +0,0 @@
name: Build
on:
pull_request:
jobs:
precommit:
runs-on: almalinux-8
container:
image: git.unkin.net/unkin/almalinux9-actionsdind:latest
options: --privileged
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install requirements
run: |
dnf groupinstall -y "Development Tools" -y
dnf install rubygems ruby-devel gcc make redhat-rpm-config glibc-headers glibc-devel -y
- name: Pre-Commit All Files
run: |
uvx pre-commit run --all-files
+18
View File
@@ -0,0 +1,18 @@
when:
- event: pull_request
steps:
- name: bolt-validate
image: git.unkin.net/unkin/almalinux9-puppet-pr-validator:20260317
commands:
- uvx pre-commit run --all-files --config ci/bolt-validate.yaml
backend_options:
kubernetes:
serviceAccountName: default
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 2Gi
cpu: 1
+18
View File
@@ -0,0 +1,18 @@
when:
- event: pull_request
steps:
- name: epp-validate
image: git.unkin.net/unkin/almalinux9-puppet-pr-validator:20260317
commands:
- uvx pre-commit run --all-files --config ci/epp-validate.yaml
backend_options:
kubernetes:
serviceAccountName: default
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 2Gi
cpu: 1
+18
View File
@@ -0,0 +1,18 @@
when:
- event: pull_request
steps:
- name: erb-validate
image: git.unkin.net/unkin/almalinux9-puppet-pr-validator:20260317
commands:
- uvx pre-commit run --all-files --config ci/erb-validate.yaml
backend_options:
kubernetes:
serviceAccountName: default
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 2Gi
cpu: 1
+18
View File
@@ -0,0 +1,18 @@
when:
- event: pull_request
steps:
- name: puppet-lint
image: git.unkin.net/unkin/almalinux9-puppet-pr-validator:20260317
commands:
- uvx pre-commit run --all-files --config ci/puppet-lint.yaml
backend_options:
kubernetes:
serviceAccountName: default
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 2Gi
cpu: 1
+18
View File
@@ -0,0 +1,18 @@
when:
- event: pull_request
steps:
- name: puppet-validate
image: git.unkin.net/unkin/almalinux9-puppet-pr-validator:20260317
commands:
- uvx pre-commit run --all-files --config ci/puppet-validate.yaml
backend_options:
kubernetes:
serviceAccountName: default
resources:
requests:
memory: 512Mi
cpu: 1
limits:
memory: 2Gi
cpu: 2
+18
View File
@@ -0,0 +1,18 @@
when:
- event: pull_request
steps:
- name: ruby-check
image: git.unkin.net/unkin/almalinux9-puppet-pr-validator:20260317
commands:
- uvx pre-commit run --all-files --config ci/ruby-check.yaml
backend_options:
kubernetes:
serviceAccountName: default
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 2Gi
cpu: 1
+18
View File
@@ -0,0 +1,18 @@
when:
- event: pull_request
steps:
- name: ruby-validate
image: git.unkin.net/unkin/almalinux9-puppet-pr-validator:20260317
commands:
- uvx pre-commit run --all-files --config ci/ruby-validate.yaml
backend_options:
kubernetes:
serviceAccountName: default
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 2Gi
cpu: 1
+18
View File
@@ -0,0 +1,18 @@
when:
- event: pull_request
steps:
- name: yamllint
image: git.unkin.net/unkin/almalinux9-base:20260606
commands:
- uvx pre-commit run --all-files --config ci/yamllint.yaml
backend_options:
kubernetes:
serviceAccountName: default
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 2Gi
cpu: 1
+1 -2
View File
@@ -53,7 +53,6 @@ mod 'saz-ssh', '13.1.0'
mod 'saz-limits', '5.0.0'
mod 'ghoneycutt-timezone', '4.0.0'
mod 'ghoneycutt-puppet', '3.3.0'
mod 'dalen-puppetdbquery', '3.0.1'
mod 'markt-galera', '3.1.0'
mod 'kogitoapp-minio', '1.1.4'
mod 'broadinstitute-certs', '3.0.1'
@@ -66,5 +65,5 @@ mod 'thias-sysctl', '1.0.8'
mod 'cirrax-dovecot', '1.3.3'
mod 'bind',
:git => 'https://git.service.au-syd1.consul/unkinben/puppet-bind.git',
:git => 'https://git.unkin.net/unkinben/puppet-bind.git',
:tag => '1.0'
+5
View File
@@ -0,0 +1,5 @@
repos:
- repo: 'https://github.com/chriskuehl/puppet-pre-commit-hooks.git'
rev: v2.2.0
hooks:
- id: bolt-validate
+5
View File
@@ -0,0 +1,5 @@
repos:
- repo: 'https://github.com/chriskuehl/puppet-pre-commit-hooks.git'
rev: v2.2.0
hooks:
- id: epp-validate
+5
View File
@@ -0,0 +1,5 @@
repos:
- repo: 'https://github.com/chriskuehl/puppet-pre-commit-hooks.git'
rev: v2.2.0
hooks:
- id: erb-validate
+10
View File
@@ -0,0 +1,10 @@
repos:
- repo: 'https://github.com/chriskuehl/puppet-pre-commit-hooks.git'
rev: v2.2.0
hooks:
- id: puppet-lint
args:
- --no-80chars-check
- --no-documentation-check
- --no-puppet_url_without_modules-check
- --fail-on-warnings
+5
View File
@@ -0,0 +1,5 @@
repos:
- repo: 'https://github.com/chriskuehl/puppet-pre-commit-hooks.git'
rev: v2.2.0
hooks:
- id: puppet-validate
+10
View File
@@ -0,0 +1,10 @@
repos:
- repo: 'https://github.com/chriskuehl/puppet-pre-commit-hooks.git'
rev: v2.2.0
hooks:
- id: ruby-validate
- repo: 'https://github.com/jumanjihouse/pre-commit-hooks'
rev: 3.0.0
hooks:
- id: reek
- id: rubocop
+5
View File
@@ -0,0 +1,5 @@
repos:
- repo: 'https://github.com/chriskuehl/puppet-pre-commit-hooks.git'
rev: v2.2.0
hooks:
- id: ruby-validate
+10
View File
@@ -0,0 +1,10 @@
repos:
- repo: 'https://github.com/adrienverge/yamllint'
rev: v1.32.0
hooks:
- id: 'yamllint'
args:
[
"-d {extends: relaxed, rules: {line-length: disable}, ignore: chart}",
"-s",
]
+167
View File
@@ -28,6 +28,98 @@ Always refer back to the official documentation at https://docs.ceph.com/en/late
sudo ceph fs set mediafs max_mds 2
```
## managing cephfs with subvolumes
Create erasure code profiles. The K and M values are equivalent to the number of data disks (K) and parity disks (M) in RAID5, RAID6, etc.
sudo ceph osd erasure-code-profile set ec_6_2 k=6 m=2
sudo ceph osd erasure-code-profile set ec_4_1 k=4 m=1
Create data pools using the erasure-code-profile, set some required options
sudo ceph osd pool create cephfs_data_ssd_ec_6_2 erasure ec_6_2
sudo ceph osd pool set cephfs_data_ssd_ec_6_2 allow_ec_overwrites true
sudo ceph osd pool set cephfs_data_ssd_ec_6_2 bulk true
sudo ceph osd pool create cephfs_data_ssd_ec_4_1 erasure ec_4_1
sudo ceph osd pool set cephfs_data_ssd_ec_4_1 allow_ec_overwrites true
sudo ceph osd pool set cephfs_data_ssd_ec_4_1 bulk true
Add the pool to the fs `cephfs`
sudo ceph fs add_data_pool cephfs cephfs_data_ssd_ec_6_2
sudo ceph fs add_data_pool cephfs cephfs_data_ssd_ec_4_1
Create a subvolumegroup using the new data pool
sudo ceph fs subvolumegroup create cephfs csi_ssd_ec_6_2 --pool_layout cephfs_data_ssd_ec_6_2
sudo ceph fs subvolumegroup create cephfs csi_ssd_ec_4_1 --pool_layout cephfs_data_ssd_ec_4_1
All together:
sudo ceph osd erasure-code-profile set ec_6_2 k=6 m=2
sudo ceph osd pool create cephfs_data_ssd_ec_6_2 erasure ec_6_2
sudo ceph osd pool set cephfs_data_ssd_ec_6_2 allow_ec_overwrites true
sudo ceph osd pool set cephfs_data_ssd_ec_6_2 bulk true
sudo ceph fs add_data_pool cephfs cephfs_data_ssd_ec_6_2
sudo ceph fs subvolumegroup create cephfs csi_ssd_ec_6_2 --pool_layout cephfs_data_ssd_ec_6_2
sudo ceph osd erasure-code-profile set ec_4_1 k=4 m=1
sudo ceph osd pool create cephfs_data_ssd_ec_4_1 erasure ec_4_1
sudo ceph osd pool set cephfs_data_ssd_ec_4_1 allow_ec_overwrites true
sudo ceph osd pool set cephfs_data_ssd_ec_4_1 bulk true
sudo ceph fs add_data_pool cephfs cephfs_data_ssd_ec_4_1
sudo ceph fs subvolumegroup create cephfs csi_ssd_ec_4_1 --pool_layout cephfs_data_ssd_ec_4_1
Create a key with access to the new subvolume groups. Check if the user already exists first:
sudo ceph auth get client.kubernetes-cephfs
If it doesnt:
sudo ceph auth get-or-create client.kubernetes-cephfs \
mgr 'allow rw' \
osd 'allow rw tag cephfs metadata=cephfs, allow rw tag cephfs data=cephfs' \
mds 'allow r fsname=cephfs path=/volumes, allow rws fsname=cephfs path=/volumes/csi_ssd_ec_6_2, allow rws fsname=cephfs path=/volumes/csi_ssd_ec_4_1' \
mon 'allow r fsname=cephfs'
If it does, use `sudo ceph auth caps client.kubernetes-cephfs ...` instead to update existing capabilities.
## removing a cephfs subvolumegroup from cephfs
This will cleanup the subvolumegroup, and subvolumes if they exist, then remove the pool.
Check for subvolumegroups first, then for subvolumes in it
sudo ceph fs subvolumegroup ls cephfs
sudo ceph fs subvolume ls cephfs --group_name csi_raid6
If subvolumes exist, remove each one-by-one:
sudo ceph fs subvolume rm cephfs <subvol_name> --group_name csi_raid6
If you have snapshots, remove snapshots first:
sudo ceph fs subvolume snapshot ls cephfs <subvol_name> --group_name csi_raid6
sudo ceph fs subvolume snapshot rm cephfs <subvol_name> <snap_name> --group_name csi_raid6
Once the group is empty, remove it:
sudo ceph fs subvolumegroup rm cephfs csi_raid6
If it complains its not empty, go back as theres still a subvolume or snapshot.
If you added it with `ceph fs add_data_pool`. Undo with `rm_data_pool`:
sudo ceph fs rm_data_pool cephfs cephfs_data_csi_raid6
After its detached from CephFS, you can delete it.
sudo ceph osd pool rm cephfs_data_csi_raid6 cephfs_data_csi_raid6 --yes-i-really-really-mean-it
## creating authentication tokens
- this will create a client keyring named media
@@ -58,3 +150,78 @@ this will overwrite the current capabilities of a given client.user
mon 'allow r' \
mds 'allow rw path=/' \
osd 'allow rw pool=media_data'
## adding a new osd on new node
create the ceph conf (automate this?)
cat <<EOF | sudo tee /etc/ceph/ceph.conf
[global]
auth_client_required = cephx
auth_cluster_required = cephx
auth_service_required = cephx
fsid = de96a98f-3d23-465a-a899-86d3d67edab8
mon_allow_pool_delete = true
mon_initial_members = prodnxsr0009,prodnxsr0010,prodnxsr0011,prodnxsr0012,prodnxsr0013
mon_host = 198.18.23.9,198.18.23.10,198.18.23.11,198.18.23.12,198.18.23.13
ms_bind_ipv4 = true
ms_bind_ipv6 = false
osd_crush_chooseleaf_type = 1
osd_pool_default_min_size = 2
osd_pool_default_size = 3
osd_pool_default_pg_num = 128
public_network = 198.18.23.1/32,198.18.23.2/32,198.18.23.3/32,198.18.23.4/32,198.18.23.5/32,198.18.23.6/32,198.18.23.7/32,198.18.23.8/32,198.18.23.9/32,198.18.23.10/32,198.18.23.11/32,198.18.23.12/32,198.18.23.13/32
EOF
ssh to one of the monitor hosts, then transfer the keys required
sudo cat /etc/ceph/ceph.client.admin.keyring | ssh prodnxsr0003 'sudo tee /etc/ceph/ceph.client.admin.keyring'
sudo cat /var/lib/ceph/bootstrap-osd/ceph.keyring | ssh prodnxsr0003 'sudo tee /var/lib/ceph/bootstrap-osd/ceph.keyring'
assuming we are adding /dev/sda to the cluster, first zap the disk to remove partitions/lvm/metadata
sudo ceph-volume lvm zap /dev/sda --destroy
then add it to the cluster
sudo ceph-volume lvm create --data /dev/sda
## removing an osd
check what OSD IDs were on this host (if you know it)
sudo ceph osd tree
or check for any DOWN osds
sudo ceph osd stat
sudo ceph health detail
once you identify the old OSD ID, remove it with these steps, replace X with the actual OSD ID:
sudo ceph osd out osd.X
sudo ceph osd down osd.X
sudo ceph osd crush remove osd.X
sudo ceph auth del osd.X
sudo ceph osd rm osd.X
## maintenance mode for the cluster
from one node in the cluster disable recovery
sudo ceph osd set noout
sudo ceph osd set nobackfill
sudo ceph osd set norecover
sudo ceph osd set norebalance
sudo ceph osd set nodown
sudo ceph osd set pause
to undo the change, use unset
sudo ceph osd unset noout
sudo ceph osd unset nobackfill
sudo ceph osd unset norecover
sudo ceph osd unset norebalance
sudo ceph osd unset nodown
sudo ceph osd unset pause
+1
View File
@@ -30,6 +30,7 @@ hierarchy:
- "roles/%{::enc_role_tier1}.eyaml"
- "roles/%{::enc_role_tier1}.yaml"
- "virtual/%{facts.virtual}.yaml"
- "os/%{facts.os.name}/%{facts.os.name}%{facts.os.release.major}.%{facts.os.release.minor}.yaml"
- "os/%{facts.os.name}/%{facts.os.name}%{facts.os.release.major}.yaml"
- "os/%{facts.os.name}/all_releases.yaml"
- "common.eyaml"
+2 -1
View File
@@ -1,8 +1,9 @@
---
profiles::accounts::sysadmin::password: ENC[PKCS7,MIIBqQYJKoZIhvcNAQcDoIIBmjCCAZYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAoS7GyofFaXBNTWU+GtSiz4eCX/9j/sh3fDDRgOgNv1qpcQ87ZlTTenbHo9lxeURxKQ2HVVt7IsrBo/SC/WgipAKnliRkkIvo7nfAs+i+kEE8wakjAs0DcB4mhqtIZRuBkLG2Nay//DcG6cltVkbKEEKmKLMkDFZgTWreOZal8nDljpVe1S8QwtwP4/6hKTef5xsOnrisxuffWTXvwYJhj/VXrjdoH7EhtHGLybzEalglkVHEGft/WrrD/0bwJpmR0RegWI4HTsSvGiHgvf5DZJx8fXPZNPnicGtlfA9ccQPuVo17bY4Qf/WIc1A8Ssv4kHSbNIYJKRymI3UFb0Z4wzBsBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBBxDLb6pCGbittkcX6asd/gEBmMcUNupDjSECq5H09YA70eVwWWe0fBqxTxrr2cXCXtRKFvOk8SJmL0xHAWodaLN9+krTWHJcWbAK8JXEPC7rn]
profiles::accounts::root::password: ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAM79PRxeAZHrDcSm4eSFqU94/LjuSbdUmJWivX/Pa8GumoW2e/PT9nGHW3p98zHthMgCglk52PECQ+TBKjxr+9dTyNK5ePG6ZJEqSHNRqsPGm+kfQj/hlTmq8vOBaFM5GapD1iTHs5JFbGngI56swKBEVXW9+Z37BjQb2xJuyLsu5Bo/tA0BaOKuCtjq1a6E38bOX+nJ+YF1uZgV9ofAEh1YvkcTmnEWYXFRPWd7AaNcWn03V2pfhGqxc+xydak620I47P+FE+qIY72+aQ6tmLU3X9vyA1HLF2Tv572l4a2i+YIk6nAgQdi+hQKznqNL9M9YV+s1AcmcKLT7cfLrjsjA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCMWrdCWBQgtW3NOEpERwP+gBA3KDiqe4pQq6DwRfsEXQNZ]
profiles::accounts::root::password: ENC[PKCS7,MIIB2gYJKoZIhvcNAQcDoIIByzCCAccCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAIgzGQLoHrm7JSnWG4vdAtxSuETmnqbV7kUsQS8WCRUwFGenDFkps+OGMnOGEHLzMJzXihLfgfdWwTAI4fp48M+zhTMo9TQkdzZqtbFk3+RjV2jDF0wfe4kVUIpReOq+EkaDSkoRSG8V6hWvszhDHUrJBC9eDhomL0f3xNAWxmy5EIX/uMEvg9Ux5YX+E6k2pEIKnHNoVIaWDojlofSIzIqTSS7l3jQtJhs3YqBzLL1DsoF1kdn+Rwl5kcsKkhV+vzl76wEbpYVZW8lu4bFfP6QHMLPcep2tuUDMCDvARRXD7YyZcAtS7aMuqll+BLAszpWxAA7EU2hgvdr6t2uyVCTCBnAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQ4D5oDoyE6LPdjpVtGPoJD4BwfnQ9ORjYFPvHQmt+lgU4jMqh6BhqP0VN3lqVfUpOmiVMIqkO/cYtlwVLKEg36TPCHBSpqvhuahSF5saCVr8JY3xWOAmTSgnNjQOPlGrPnYWYbuRLxVRsU+KUkpAzR0c6VN0wYi6bI85Pcv8yHF3UYA==]
profiles::consul::client::secret_id_salt: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAS7pNFRX4onccFaR87zB/eFFORuF22j6xqjyeAqqjgEduYhkt6w5kkz+YfUoHUesU0Q6F2p6HrCSZ8yAsx5M25NCiud9P4hIpjKmOZ4zCNO7uhATh4AQDYw3BrdRwfO+c6jOl5wOiNLCfDBJ0sFT3akCvcuPS1xIoRJq4Gyn+uCbOsMbvSl25ld2xKt1/cqs8gc1d8mkpjwWto7t+qZSUFMCehTbehH3G4a3Q5rvfBoNwv42Wbs676BDcCurDaAzHNqE7pDbOWhGuVOBl+q+BU0Ri/CRkGcTViN9fr8Dc9SveVC6EPsMbw+05/8/NlfzQse3KAwQ34nR9tR2PQw5qEzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBB7LywscQtF7cG2nomfEsu9gDDVqJBFP1jAX2eGZ2crYS5gnBcsRwhc0HNo2/WWdhZprMW+vEJOOGXDelI53NxA3o0=]
profiles::consul::token::node_editor::secret_id: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAO8IIF2r18dFf0bVKEwjJUe1TmXHH0AIzsQHxkHwV7d37kvH1cY9rYw0TtdHn7GTxvotJG7GZbWvbunpBs1g2p2RPADiM6TMhbO8mJ0tAWLnMk7bQ221xu8Pc7KceqWmU17dmgNhVCohyfwJNqbA756TlHVgxGA0LtNrKoLOmgKGXAL1VYZoKEQnWq7xOpO+z3e1UfjoO6CvX/Od2hGYfUkHdro8mwRw4GFKzU7XeKFdAMUGpn5rVmY3xe+1ARXwGFaSrTHzk2n85pvwhPRlQ+OwqzyT19Qo2FNeAO6RoCRIFTtqbsjTWPUlseHIhw4Q5bHO1I0Mrlm5IHDESw/22IzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCEe9wD72qxnpeq5nCi/d7BgDCP29sDFObkFTabt2uZ/nF9MT1g+QOrrdFKgnG6ThnwH1hwpZPsSVgIs+yRQH8laB4=]
profiles::consul::server::acl_tokens_initial_management: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAi1UH7AZirJ1PdxWy+KEgS5ufm0wbn2xy9rkg14hKYpcVjBa4pOZpSLMGMiiUpBIqBytDMZM4ezYa/luktpkBImJbM/TE16beGtsacQGA+9eZk2Tihs9GR2qbAQiu5lLITiDlwNnf0GeWdqHM8CTeD68DczQF320d9U14/k6pG/7z+w/MGLcjsQoSuOFTm42JVn1BI46t1CYSCHMXQc/9Tfs+FzI+vumohI8DxAYBIuyzU5HBX/MntAsvD/yixMJS1pZL9WwgqZJC/wK34rVRB39DpxWf/WROrI+WLuSJwr7WBjaeF9Ju+89WKCgsI53EWhFTj8GgDZm/jqPoE478NjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAoACRzJdQKNYXZv6cghFIIgDAzB81DMcuY815nb8POtZpiA06jT/068AoZmSctHoFK/zW9tY229N5r1Tb+WHElqLk=]
profiles::consul::server::acl_tokens_default: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAh4Ag95xgkIZHL0gP9OLnZauih0dB1/2l9Jzw8mP3OiIv7fw23otHYONlS3Emtj7oxW8MKcZGKDCzwCT6T2p+V5wx1n15wr2J+FmL24VbclJwrMPQ4AdgP359B9h21uoyo7Zdy7RuuvLfkU1fWXbs3SeWbi2HJs1Ed1/oI1jzr3OgwMbVtbyzd1VuAXeZ9bHQG3IA8z+w/k5m61th0HTyHjw7eldQulbohDuwv545z9axHEoHKCRT2a3ZwBufV2ST6Dm3g9GERzXE9Adp9DQC5adqM74wfsujOMLK2QFJSSIOj2uCs1CpEnrNrQ8zjP3fudM2z3l7KdSHZazEamCSxTBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBY/Tn9tzEKYc5dxnzP2rP7gDBWKgVP3lf2T4Q0WPQt3ns0E6RUSO6OtBegb/5qDyohY2nsDeJTnMKOYzYt/J1PhnY=]
profiles::consul::server::acl_tokens_replication: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAEzTIxbaAR/TZYnC671aBhiahsfwf3ieyeSHpD5hQm40sMEF/fXlEDijq9i2ykPikm94074j1Uo4HNzv/V9GTf0NSC/64t61jJ/Ya3QKa5f/36+DcRj3lcETsSIyhWwmU+E+zkY8I2r68MtXAuvSoMSMZdpgWSkPx/3FFgZlrsg//bzDu69jS9cx4UK582N3A6QN4Uy/qwYtJcm+2iTQlqqgGRWGqnSgTirxhegxPbJGWTDoAEpAL4/DyF5/hqcUn6mgoSfAsHF3loPHOqN30lG+9o0THWJ9B8Gf4W/1X2UWA/avmUnqBnumGoz0p7AYdNgpW+qLl2rk4lyGYa4kvQjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBD9KSLH3Pn/1EIzgVJM+8VOgDDpKWzHfSVsfUMyTD0XIRPGclTdmxqCnsdhKNqmUfSjkYIf2nI9rQtSK6n42TYuO4k=]
profiles::dns::updater::key_secret: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAJ4GrN3W4zGfVygfji1MeGyAlmlFN45TVP5st6b66jSKeDYNg9BwdnXahUzkmKvFIYdPWyvXqJdvuyUNz7lWr1dw/pTNHrvqUKSvI0C5TOwmtrTwXtTvucDGs7c7FZDfgUxvLs/Vrp0ZdW3C81QXWNBI8vBfVZyiegPNq+5mX7mtcrFE7jZj1g1qwpg/30lrlCguPyXqnmdtBa7VAyU2Al1UZwkrKIYSAOb9GTnvM6bk5L26pW/NXGj+ffacwf58b4AiKCak5lhoCIInVnlogPuThxULN4RF+MYAVIlgwk159CR1abjWjioxvmP7XgjQUwUuTlgoLh9fDZa0amDeFZTBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBEb1BTjhuTN9wGrxc2rdQVgDCctNdt72UR/Hj4wteK7XIX6fF43+7FYKBZnPtyWIWalwDniH//H3gfsJ+ULqSb82w=]
+75 -1
View File
@@ -129,6 +129,9 @@ lookup_options:
profiles::ceph::client::keyrings:
merge:
strategy: deep
profiles::ceph::conf::config:
merge:
strategy: deep
profiles::nginx::simpleproxy::locations:
merge:
strategy: deep
@@ -143,6 +146,8 @@ lookup_options:
strategy: deep
profiles::etcd::node::initial_cluster_token:
convert_to: Sensitive
profiles::dns::updater::key_secret:
convert_to: Sensitive
sysctl::base::values:
merge:
strategy: deep
@@ -167,6 +172,12 @@ lookup_options:
postfix::virtuals:
merge:
strategy: deep
stalwart::postgresql_password:
convert_to: Sensitive
stalwart::s3_secret_key:
convert_to: Sensitive
stalwart::fallback_admin_password:
convert_to: Sensitive
facts_path: '/opt/puppetlabs/facter/facts.d'
@@ -197,8 +208,28 @@ vault::manage_config_dir: true
vault::disable_mlock: false
profiles::dns::base::nameservers:
- 198.18.19.16
- 198.18.200.7
profiles::dns::master::basedir: '/var/named/sources'
# dns record publishing. During the k8s cutover both methods run; set
# manage_export false once k8s is authoritative.
# - export: legacy exported-resources -> puppet DNS master
# - nsupdate: RFC2136 to the k8s bind-authoritative write endpoint (.9),
# inert until the TSIG key is set in eyaml:
# profiles::dns::updater::key_secret: ENC[...]
# (must match the key the bind-authoritative zones allow-update
# with; algorithm hmac-sha256)
# k8s is now authoritative: clients resolve via the k8s bind-resolvers
# (profiles::dns::base::nameservers 198.18.200.7, since #490), which forward the
# unkin.net/main.unkin.net/*.18.198.in-addr.arpa zones to the k8s
# bind-authoritative cluster fed by the nsupdate path below. The legacy
# exported-resources -> VM-master /var/named/sources files are no longer in any
# client's resolution path, so stop exporting them. Rollback: set back to true.
profiles::dns::updater::manage_export: false
profiles::dns::updater::manage_nsupdate: true
profiles::dns::updater::server: '198.18.200.9'
profiles::dns::updater::key_name: 'client-update'
profiles::dns::updater::key_algorithm: 'hmac-sha256'
#profiles::dns::base::ns_role: 'roles::infra::dns::resolver'
#profiles::dns::base::use_ns: 'region'
profiles::consul::server::members_role: roles::infra::storage::consul
@@ -398,6 +429,49 @@ profiles::ceph::conf::config:
198.18.23.5/32,198.18.23.6/32,198.18.23.7/32,198.18.23.8/32,
198.18.23.9/32,198.18.23.10/32,198.18.23.11/32,198.18.23.12/32,
198.18.23.13/32
client.rgw.ausyd1nxvm2115:
rgw_realm: unkin
rgw_zonegroup: au
rgw_zone: syd1
client.rgw.ausyd1nxvm2116:
rgw_realm: unkin
rgw_zonegroup: au
rgw_zone: syd1
client.rgw.ausyd1nxvm2117:
rgw_realm: unkin
rgw_zonegroup: au
rgw_zone: syd1
client.rgw.ausyd1nxvm2118:
rgw_realm: unkin
rgw_zonegroup: au
rgw_zone: syd1
client.rgw.ausyd1nxvm2119:
rgw_realm: unkin
rgw_zonegroup: au
rgw_zone: syd1
mds:
keyring: /var/lib/ceph/mds/ceph-$id/keyring
mds_standby_replay: true
mds.prodnxsr0009-1:
host: prodnxsr0009
mds.prodnxsr0009-2:
host: prodnxsr0009
mds.prodnxsr0010-1:
host: prodnxsr0010
mds.prodnxsr0010-2:
host: prodnxsr0010
mds.prodnxsr0011-1:
host: prodnxsr0011
mds.prodnxsr0011-2:
host: prodnxsr0011
mds.prodnxsr0012-1:
host: prodnxsr0012
mds.prodnxsr0012-2:
host: prodnxsr0012
mds.prodnxsr0013-1:
host: prodnxsr0013
mds.prodnxsr0013-2:
host: prodnxsr0013
#profiles::base::hosts::additional_hosts:
# - ip: 198.18.17.9
+2
View File
@@ -5,3 +5,5 @@ profiles_dns_upstream_forwarder_unkin:
- 198.18.19.15
profiles_dns_upstream_forwarder_consul:
- 198.18.19.14
profiles_dns_upstream_forwarder_k8s:
- 198.18.19.20
@@ -1,4 +1,7 @@
---
haproxy_server_k8s_syd1_traefik_internal: 'k8s-traefik-internal 198.18.200.4:443 ssl verify none check inter 2s rise 3 fall 2'
haproxy_server_k8s_syd1_traefik_external: 'k8s-traefik-external 198.18.199.0:443 ssl verify none check inter 2s rise 3 fall 2'
profiles::haproxy::dns::ipaddr: "%{hiera('anycast_ip')}"
profiles::haproxy::dns::vrrp_cnames:
- sonarr.main.unkin.net
@@ -11,6 +14,12 @@ profiles::haproxy::dns::vrrp_cnames:
- fafflix.unkin.net
- grafana.unkin.net
- dashboard.ceph.unkin.net
- mail-webadmin.main.unkin.net
- mail-in.main.unkin.net
- mail.main.unkin.net
- autoconfig.main.unkin.net
- autodiscover.main.unkin.net
- auth.unkin.net
profiles::haproxy::mappings:
fe_http:
@@ -29,6 +38,10 @@ profiles::haproxy::mappings:
- 'git.unkin.net be_gitea'
- 'grafana.unkin.net be_grafana'
- 'dashboard.ceph.unkin.net be_ceph_dashboard'
- 'mail-webadmin.main.unkin.net be_stalwart_webadmin'
- 'autoconfig.main.unkin.net be_stalwart_webadmin'
- 'autodiscovery.main.unkin.net be_stalwart_webadmin'
- 'auth.unkin.net be_k8s_kanidm'
fe_https:
ensure: present
mappings:
@@ -45,6 +58,10 @@ profiles::haproxy::mappings:
- 'git.unkin.net be_gitea'
- 'grafana.unkin.net be_grafana'
- 'dashboard.ceph.unkin.net be_ceph_dashboard'
- 'mail-webadmin.main.unkin.net be_stalwart_webadmin'
- 'autoconfig.main.unkin.net be_stalwart_webadmin'
- 'autodiscovery.main.unkin.net be_stalwart_webadmin'
- 'auth.unkin.net be_k8s_kanidm'
profiles::haproxy::frontends:
fe_http:
@@ -66,6 +83,10 @@ profiles::haproxy::frontends:
- 'acl_gitea req.hdr(host) -i git.unkin.net'
- 'acl_grafana req.hdr(host) -i grafana.unkin.net'
- 'acl_ceph_dashboard req.hdr(host) -i dashboard.ceph.unkin.net'
- 'acl_stalwart_webadmin req.hdr(host) -i mail-webadmin.main.unkin.net'
- 'acl_stalwart_webadmin req.hdr(host) -i autoconfig.main.unkin.net'
- 'acl_stalwart_webadmin req.hdr(host) -i autodiscovery.main.unkin.net'
- 'acl_kanidm req.hdr(host) -i auth.unkin.net'
- 'acl_internalsubnets src 198.18.0.0/16 10.10.12.0/24'
use_backend:
- "%[req.hdr(host),lower,map(/etc/haproxy/fe_https.map,be_default)]"
@@ -84,6 +105,8 @@ profiles::haproxy::frontends:
- 'set-header X-Frame-Options DENY if acl_gitea'
- 'set-header X-Frame-Options DENY if acl_grafana'
- 'set-header X-Frame-Options DENY if acl_ceph_dashboard'
- 'set-header X-Frame-Options DENY if acl_stalwart_webadmin'
- 'set-header X-Frame-Options DENY if acl_kanidm'
- 'set-header X-Content-Type-Options nosniff'
- 'set-header X-XSS-Protection 1;mode=block'
@@ -286,7 +309,103 @@ profiles::haproxy::backends:
- add-header X-Forwarded-Proto https if { dst_port 9443 }
redirect: 'scheme https if !{ ssl_fc }'
stick-table: 'type ip size 200k expire 30m'
be_stalwart_webadmin:
description: Backend for Stalwart Webadmin
collect_exported: false # handled in custom function
options:
balance: roundrobin
option:
- httpchk GET /
- forwardfor
- http-keep-alive
- prefer-last-server
cookie: SRVNAME insert indirect nocache
http-reuse: always
http-check:
- expect status 200
http-request:
- set-header X-Forwarded-Port %[dst_port]
- add-header X-Forwarded-Proto https if { dst_port 9443 }
redirect: 'scheme https if !{ ssl_fc }'
stick-table: 'type ip size 200k expire 30m'
be_k8s_kanidm:
description: Backend for Kanidm (auth.unkin.net via Kubernetes internal Traefik)
collect_exported: false
options:
balance: roundrobin
option:
- httpchk
- forwardfor
- http-keep-alive
- prefer-last-server
http-check:
- 'connect ssl sni auth.unkin.net'
- 'send meth GET uri /status ver HTTP/1.1 hdr Host auth.unkin.net'
- 'expect status 200'
http-reuse: always
http-request:
- set-header X-Forwarded-Port %[dst_port]
- add-header X-Forwarded-Proto https if { dst_port 443 }
redirect: 'scheme https if !{ ssl_fc }'
server: "%{lookup('haproxy_server_k8s_syd1_traefik_internal')} sni str(auth.unkin.net)"
be_stalwart_imap:
description: Backend for Stalwart IMAP (STARTTLS)
collect_exported: false
options:
mode: tcp
balance: roundrobin
option:
- tcp-check
- prefer-last-server
stick-table: 'type ip size 200k expire 30m'
stick: 'on src'
tcp-check:
- connect port 143 send-proxy
- expect string "* OK"
- send "A001 STARTTLS\r\n"
- expect rstring "A001 (OK|2.0.0)"
be_stalwart_imaps:
description: Backend for Stalwart IMAPS (implicit TLS)
collect_exported: false
options:
mode: tcp
balance: roundrobin
option:
- tcp-check
- prefer-last-server
stick-table: 'type ip size 200k expire 30m'
stick: 'on src'
tcp-check:
- connect ssl send-proxy
- expect string "* OK"
be_stalwart_smtp:
description: Backend for Stalwart SMTP
collect_exported: false
options:
mode: tcp
balance: roundrobin
option:
- tcp-check
- prefer-last-server
stick-table: 'type ip size 200k expire 30m'
stick: 'on src'
tcp-check:
- connect port 25 send-proxy
- expect string "220 "
be_stalwart_submission:
description: Backend for Stalwart SMTP Submission
collect_exported: false
options:
mode: tcp
balance: roundrobin
option:
- tcp-check
- prefer-last-server
stick-table: 'type ip size 200k expire 30m'
stick: 'on src'
tcp-check:
- connect port 587 send-proxy
- expect string "220 "
profiles::haproxy::certlist::enabled: true
profiles::haproxy::certlist::certificates:
@@ -302,6 +421,7 @@ profiles::haproxy::certlist::certificates:
- /etc/pki/tls/letsencrypt/git.unkin.net/fullchain_combined.pem
- /etc/pki/tls/letsencrypt/grafana.unkin.net/fullchain_combined.pem
- /etc/pki/tls/letsencrypt/dashboard.ceph.unkin.net/fullchain_combined.pem
- /etc/pki/tls/letsencrypt/auth.unkin.net/fullchain_combined.pem
- /etc/pki/tls/vault/certificate.pem
# additional altnames
@@ -309,6 +429,7 @@ profiles::pki::vault::alt_names:
- au-syd1-pve.main.unkin.net
- au-syd1-pve-api.main.unkin.net
- jellyfin.main.unkin.net
- mail-webadmin.main.unkin.net
# additional cnames
profiles::haproxy::dns::cnames:
@@ -330,3 +451,4 @@ certbot::client::domains:
- git.unkin.net
- grafana.unkin.net
- dashboard.ceph.unkin.net
- auth.unkin.net
@@ -0,0 +1,3 @@
---
# Canary for the puppet-on-k8s migration (roles::base test host).
profiles::puppet::migrate::enabled: true
+2 -15
View File
@@ -1,23 +1,10 @@
# hieradata/os/AlmaLinux/AlmaLinux8.yaml
---
crypto_policies::policy: 'DEFAULT'
almalinux-base-repo: almalinux
profiles::packages::include:
network-scripts: {}
profiles::yum::global::repos:
powertools:
name: powertools
descr: powertools repository
target: /etc/yum.repos.d/powertools.repo
baseurl: https://edgecache.query.consul/almalinux/%{facts.os.release.full}/PowerTools/%{facts.os.architecture}/os
gpgkey: http://edgecache.query.consul/almalinux/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
mirrorlist: absent
unkin:
name: unkin
descr: unkin repository
target: /etc/yum.repos.d/unkin.repo
baseurl: https://git.query.consul/api/packages/unkin/rpm/almalinux/el8
gpgkey: https://git.query.consul/api/packages/unkin/rpm/repository.key
gpgcheck: false
mirrorlist: absent
ensure: present
+2
View File
@@ -0,0 +1,2 @@
---
almalinux-base-repo: almalinux-vault
+2 -31
View File
@@ -1,36 +1,7 @@
# hieradata/os/AlmaLinux/AlmaLinux9.yaml
---
crypto_policies::policy: 'DEFAULT:SHA1'
almalinux-base-repo: almalinux
profiles::yum::global::repos:
baseos:
baseurl: https://packagerepo.service.consul/almalinux/%{facts.os.release.full}/baseos-daily/%{facts.os.architecture}/os/
gpgkey: https://packagerepo.service.consul/almalinux/%{facts.os.release.full}/baseos-daily/%{facts.os.architecture}/os//RPM-GPG-KEY-AlmaLinux-9
mirrorlist: absent
extras:
baseurl: https://packagerepo.service.consul/almalinux/%{facts.os.release.full}/extras-daily/%{facts.os.architecture}/os/
gpgkey: https://packagerepo.service.consul/almalinux/%{facts.os.release.full}/extras-daily/%{facts.os.architecture}/os//RPM-GPG-KEY-AlmaLinux-9
mirrorlist: absent
appstream:
baseurl: https://packagerepo.service.consul/almalinux/%{facts.os.release.full}/appstream-daily/%{facts.os.architecture}/os/
gpgkey: https://packagerepo.service.consul/almalinux/%{facts.os.release.full}/appstream-daily/%{facts.os.architecture}/os//RPM-GPG-KEY-AlmaLinux-9
mirrorlist: absent
highavailability:
baseurl: https://packagerepo.service.consul/almalinux/%{facts.os.release.full}/ha-daily/%{facts.os.architecture}/os/
gpgkey: https://packagerepo.service.consul/almalinux/%{facts.os.release.full}/ha-daily/%{facts.os.architecture}/os//RPM-GPG-KEY-AlmaLinux-9
mirrorlist: absent
crb:
name: crb
descr: crb repository
target: /etc/yum.repos.d/crb.repo
baseurl: https://packagerepo.service.consul/almalinux/%{facts.os.release.full}/crb-daily/%{facts.os.architecture}/os/
gpgkey: https://packagerepo.service.consul/almalinux/%{facts.os.release.full}/crb-daily/%{facts.os.architecture}/os//RPM-GPG-KEY-AlmaLinux-9
mirrorlist: absent
unkin:
name: unkin
descr: unkin repository
target: /etc/yum.repos.d/unkin.repo
baseurl: https://git.query.consul/api/packages/unkin/rpm/almalinux/el9
gpgkey: https://git.query.consul/api/packages/unkin/rpm/repository.key
gpgcheck: false
mirrorlist: absent
ensure: present
+230 -10
View File
@@ -23,36 +23,52 @@ profiles::yum::global::repos:
name: baseos
descr: baseos repository
target: /etc/yum.repos.d/baseos.repo
baseurl: https://edgecache.query.consul/almalinux/%{facts.os.release.full}/BaseOS/%{facts.os.architecture}/os
gpgkey: http://edgecache.query.consul/almalinux/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/BaseOS/%{facts.os.architecture}/os/
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/BaseOS/%{facts.os.architecture}/os/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
mirrorlist: absent
extras:
name: extras
descr: extras repository
target: /etc/yum.repos.d/extras.repo
baseurl: https://edgecache.query.consul/almalinux/%{facts.os.release.full}/extras/%{facts.os.architecture}/os
gpgkey: http://edgecache.query.consul/almalinux/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/extras/%{facts.os.architecture}/os/
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/extras/%{facts.os.architecture}/os/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
mirrorlist: absent
appstream:
name: appstream
descr: appstream repository
target: /etc/yum.repos.d/appstream.repo
baseurl: https://edgecache.query.consul/almalinux/%{facts.os.release.full}/AppStream/%{facts.os.architecture}/os
gpgkey: http://edgecache.query.consul/almalinux/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/AppStream/%{facts.os.architecture}/os/
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/AppStream/%{facts.os.architecture}/os/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
mirrorlist: absent
highavailability:
name: highavailability
descr: highavailability repository
target: /etc/yum.repos.d/highavailability.repo
baseurl: https://edgecache.query.consul/almalinux/%{facts.os.release.full}/HighAvailability/%{facts.os.architecture}/os
gpgkey: http://edgecache.query.consul/almalinux/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/HighAvailability/%{facts.os.architecture}/os/
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/HighAvailability/%{facts.os.architecture}/os/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
mirrorlist: absent
crb:
ensure: absent
name: crb
descr: crb repository
target: /etc/yum.repos.d/crb.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/CRB/%{facts.os.architecture}/os/
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/CRB/%{facts.os.architecture}/os/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
mirrorlist: absent
powertools:
ensure: absent
name: powertools
descr: powertools repository
target: /etc/yum.repos.d/powertools.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/PowerTools/%{facts.os.architecture}/os/
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/%{lookup('almalinux-base-repo')}/%{facts.os.release.full}/PowerTools/%{facts.os.architecture}/os/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
mirrorlist: absent
epel:
name: epel
descr: epel repository
target: /etc/yum.repos.d/epel.repo
baseurl: https://packagerepo.service.consul/epel/%{facts.os.release.major}/everything-daily/%{facts.os.architecture}/os/
gpgkey: https://packagerepo.service.consul/epel/%{facts.os.release.major}/everything-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-EPEL-%{facts.os.release.major}
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/epel/%{facts.os.release.major}/Everything/%{facts.os.architecture}
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/epel/RPM-GPG-KEY-EPEL-%{facts.os.release.major}
mirrorlist: absent
unkinben:
name: unkinben
@@ -62,3 +78,207 @@ profiles::yum::global::repos:
gpgkey: https://git.query.consul/api/packages/unkinben/rpm/repository.key
gpgcheck: false
mirrorlist: absent
rpm-internal:
name: rpm-internal
descr: rpm-internal repository
target: /etc/yum.repos.d/rpm-internal.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/local/rpm-internal/
gpgcheck: false
mirrorlist: absent
rpm-vendor:
name: rpm-vendor
descr: rpm-vendor repository
target: /etc/yum.repos.d/rpm-vendor.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/local/rpm-vendor-el%{facts.os.release.major}/
gpgcheck: false
mirrorlist: absent
# Additional repositories - default to absent, roles can override with ensure: present
# FRRouting repositories
frr-extras:
ensure: absent
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/frr/el%{facts.os.release.major}/extras
gpgcheck: false
mirrorlist: absent
frr-stable:
ensure: absent
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/frr/el%{facts.os.release.major}/frr
gpgcheck: false
mirrorlist: absent
# PostgreSQL repositories
postgresql-15:
ensure: absent
name: postgresql-15
descr: postgresql-15 repository
target: /etc/yum.repos.d/postgresql.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/postgresql/15/redhat/rhel-%{facts.os.release.major}-%{facts.os.architecture}
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/postgresql/keys/PGDG-RPM-GPG-KEY-RHEL
postgresql-17:
ensure: absent
name: postgresql-17
descr: postgresql-17 repository
target: /etc/yum.repos.d/postgresql.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/postgresql/17/redhat/rhel-%{facts.os.release.major}-%{facts.os.architecture}
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/postgresql/keys/PGDG-RPM-GPG-KEY-RHEL
postgresql-common:
ensure: absent
name: postgresql-common
descr: postgresql-common repository
target: /etc/yum.repos.d/postgresql.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/postgresql/common/redhat/rhel-%{facts.os.release.major}-%{facts.os.architecture}
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/postgresql/keys/PGDG-RPM-GPG-KEY-RHEL
# Ceph repositories
ceph:
ensure: absent
name: ceph
descr: ceph repository
target: /etc/yum.repos.d/ceph.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/ceph-reef/el%{facts.os.release.major}/%{facts.os.architecture}
gpgcheck: false
mirrorlist: absent
ceph-noarch:
ensure: absent
name: ceph-noarch
descr: ceph noarch repository
target: /etc/yum.repos.d/ceph.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/ceph-reef/el%{facts.os.release.major}/noarch
gpgcheck: false
mirrorlist: absent
# Rancher RKE2 repositories
rancher-rke2-common-latest:
ensure: absent
name: rancher-rke2-common
descr: rancher-rke2-common repository
target: /etc/yum.repos.d/rancher-rke2-common.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/rke2/rke2/latest/common/centos/%{facts.os.release.major}/noarch
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/rke2/public.key
gpgcheck: 1
mirrorlist: absent
rancher-rke2-1-33-latest:
ensure: absent
name: rancher-rke2-1.33-latest
descr: rancher-rke2-1.33-latest repository
target: /etc/yum.repos.d/rancher-rke2.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/rke2/rke2/latest/1.33/centos/%{facts.os.release.major}/%{facts.os.architecture}
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/rke2/public.key
gpgcheck: 1
mirrorlist: absent
# CentOS repositories for legacy systems
centos_8_advanced_virtualization:
ensure: absent
name: centos_8_advanced_virtualization
descr: centos_8_advanced_virtualization repository
target: /etc/yum.repos.d/centos.repo
baseurl: https://edgecache.query.consul/centos/8/virt/x86_64/advanced-virtualization
gpgkey: http://edgecache.query.consul/centos/RPM-GPG-KEY-CentOS-SIG-Virtualization
gpgcheck: 1
mirrorlist: absent
centos_8_ceph_pacific:
ensure: absent
name: centos_8_ceph_pacific
descr: centos_8_ceph_pacific repository
target: /etc/yum.repos.d/centos.repo
baseurl: https://edgecache.query.consul/centos/8/storage/x86_64/ceph-pacific
gpgkey: http://edgecache.query.consul/centos/RPM-GPG-KEY-CentOS-SIG-Storage
gpgcheck: 1
mirrorlist: absent
centos_8_rabbitmq_38:
ensure: absent
name: centos_8_rabbitmq_38
descr: centos_8_rabbitmq_38 repository
target: /etc/yum.repos.d/centos.repo
baseurl: https://edgecache.query.consul/centos/8/messaging/x86_64/rabbitmq-38
gpgkey: http://edgecache.query.consul/centos/RPM-GPG-KEY-CentOS-SIG-Messaging
gpgcheck: 1
mirrorlist: absent
centos_8_nfv_openvswitch:
ensure: absent
name: centos_8_nfv_openvswitch
descr: centos_8_nfv_openvswitch repository
target: /etc/yum.repos.d/centos.repo
baseurl: https://edgecache.query.consul/centos/8/nfv/x86_64/openvswitch-2
gpgkey: http://edgecache.query.consul/centos/RPM-GPG-KEY-CentOS-SIG-NFV
gpgcheck: 1
mirrorlist: absent
centos_8_openstack_xena:
ensure: absent
name: centos_8_openstack_xena
descr: centos_8_openstack_xena repository
target: /etc/yum.repos.d/centos.repo
baseurl: https://edgecache.query.consul/centos/8/cloud/x86_64/openstack-xena
gpgkey: http://edgecache.query.consul/centos/RPM-GPG-KEY-CentOS-SIG-Cloud
gpgcheck: 1
mirrorlist: absent
centos_8_opstools:
ensure: absent
name: centos_8_opstools
descr: centos_8_opstools repository
target: /etc/yum.repos.d/centos.repo
baseurl: https://edgecache.query.consul/centos/8/opstools/x86_64/collectd-5
gpgkey: http://edgecache.query.consul/centos/RPM-GPG-KEY-CentOS-SIG-OpsTools
gpgcheck: 1
mirrorlist: absent
centos_8_ovirt45:
ensure: absent
name: centos_8_ovirt45
descr: centos_8_ovirt45 repository
target: /etc/yum.repos.d/centos.repo
baseurl: https://edgecache.query.consul/centos/8/virt/x86_64/ovirt-45
gpgkey: http://edgecache.query.consul/centos/RPM-GPG-KEY-CentOS-SIG-Virtualization
gpgcheck: 1
mirrorlist: absent
centos_8_stream_gluster10:
ensure: absent
name: centos_8_stream_gluster10
descr: centos_8_stream_gluster10 repository
target: /etc/yum.repos.d/centos.repo
baseurl: https://edgecache.query.consul/centos/8-stream/storage/x86_64/gluster-10
gpgkey: http://edgecache.query.consul/centos/RPM-GPG-KEY-CentOS-SIG-Storage
gpgcheck: 1
mirrorlist: absent
# Additional repositories
zfs-kmod:
ensure: absent
name: zfs-kmod
descr: zfs-kmod repository
target: /etc/yum.repos.d/zfs.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/zfs/epel/%{facts.os.release.major}/kmod/%{facts.os.architecture}/
gpgcheck: false
mirrorlist: absent
rpmfusion-free:
ensure: absent
name: rpmfusion-free
descr: rpmfusion-free repository
target: /etc/yum.repos.d/rpmfusion-free.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/rpmfusion-free/el/updates/%{facts.os.release.major}/%{facts.os.architecture}/
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/rpmfusion-free/el/RPM-GPG-KEY-rpmfusion-free-el-%{facts.os.release.major}
gpgcheck: 1
mirrorlist: absent
rpmfusion-nonfree:
ensure: absent
name: rpmfusion-nonfree
descr: rpmfusion-nonfree repository
target: /etc/yum.repos.d/rpmfusion-nonfree.repo
baseurl: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/rpmfusion-nonfree/el/updates/%{facts.os.release.major}/%{facts.os.architecture}/
gpgkey: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/rpmfusion-nonfree/el/RPM-GPG-KEY-rpmfusion-nonfree-el-%{facts.os.release.major}
gpgcheck: 1
mirrorlist: absent
unkin:
name: unkin
descr: unkin repository
target: /etc/yum.repos.d/unkin.repo
baseurl: https://git.query.consul/api/packages/unkin/rpm/almalinux/el%{facts.os.release.major}
gpgkey: https://git.query.consul/api/packages/unkin/rpm/repository.key
gpgcheck: false
mirrorlist: absent
+2 -7
View File
@@ -3,13 +3,8 @@ hiera_include:
- profiles::nginx::simpleproxy
profiles::yum::global::repos:
ceph-reef:
name: ceph-reef
descr: ceph reef repository
target: /etc/yum.repos.d/ceph-reef.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/%{facts.os.architecture}
gpgcheck: 0,
mirrorlist: absent
ceph:
ensure: present
profiles::ceph::client::keyrings:
media:
+3 -19
View File
@@ -54,24 +54,8 @@ profiles::consul::client::node_rules:
profiles::yum::global::repos:
rpmfusion-free:
name: rpmfusion-free
descr: rpmfusion-free repository
target: /etc/yum.repos.d/rpmfusion.repo
baseurl: https://download1.rpmfusion.org/free/el/updates/%{facts.os.release.major}/%{facts.os.architecture}
gpgkey: https://download1.rpmfusion.org/free/el/RPM-GPG-KEY-rpmfusion-free-el-%{facts.os.release.major}
mirrorlist: absent
ensure: present
rpmfusion-nonfree:
name: rpmfusion-nonfree
descr: rpmfusion-nonfree repository
target: /etc/yum.repos.d/rpmfusion.repo
baseurl: https://download1.rpmfusion.org/nonfree/el/updates/%{facts.os.release.major}/%{facts.os.architecture}
gpgkey: https://download1.rpmfusion.org/nonfree/el/RPM-GPG-KEY-rpmfusion-nonfree-el-%{facts.os.release.major}
mirrorlist: absent
ensure: present
unkinben:
name: unkinben
descr: unkinben repository
target: /etc/yum.repos.d/unkin.repo
baseurl: https://git.query.consul/api/packages/unkinben/rpm/el8
gpgkey: https://git.query.consul/api/packages/unkinben/rpm/repository.key
gpgcheck: false
mirrorlist: absent
ensure: present
+2 -12
View File
@@ -72,16 +72,6 @@ profiles::consul::client::node_rules:
profiles::yum::global::repos:
rpmfusion-free:
name: rpmfusion-free
descr: rpmfusion-free repository
target: /etc/yum.repos.d/rpmfusion.repo
baseurl: https://download1.rpmfusion.org/free/el/updates/%{facts.os.release.major}/%{facts.os.architecture}
gpgkey: https://download1.rpmfusion.org/free/el/RPM-GPG-KEY-rpmfusion-free-el-%{facts.os.release.major}
mirrorlist: absent
ensure: present
rpmfusion-nonfree:
name: rpmfusion-nonfree
descr: rpmfusion-nonfree repository
target: /etc/yum.repos.d/rpmfusion.repo
baseurl: https://download1.rpmfusion.org/nonfree/el/updates/%{facts.os.release.major}/%{facts.os.architecture}
gpgkey: https://download1.rpmfusion.org/nonfree/el/RPM-GPG-KEY-rpmfusion-nonfree-el-%{facts.os.release.major}
mirrorlist: absent
ensure: present
+4 -24
View File
@@ -31,30 +31,10 @@ frrouting::daemons:
# additional repos
profiles::yum::global::repos:
ceph:
name: ceph
descr: ceph repository
target: /etc/yum.repos.d/ceph.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/%{facts.os.architecture}
gpgkey: https://download.ceph.com/keys/release.asc
mirrorlist: absent
ensure: present
ceph-noarch:
name: ceph-noarch
descr: ceph-noarch repository
target: /etc/yum.repos.d/ceph-noarch.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/noarch
gpgkey: https://download.ceph.com/keys/release.asc
mirrorlist: absent
ensure: present
frr-extras:
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
frr-stable:
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
+30
View File
@@ -66,6 +66,9 @@ glauth::users:
- 20025 # jupyterhub_admin
- 20026 # jupyterhub_user
- 20027 # grafana_user
- 20028 # k8s/au/syd1 operator
- 20029 # k8s/au/syd1 admin
- 20030 # k8s/au/syd1 root
loginshell: '/bin/bash'
homedir: '/home/benvin'
passsha256: 'd2434f6b4764ef75d5b7b96a876a32deedbd6aa726a109c3f32e823ca66f604a'
@@ -223,6 +226,24 @@ glauth::users:
loginshell: '/bin/bash'
homedir: '/home/debvin'
passsha256: 'cdac05ddb02e665d4ea65a974995f38a10236bc158731d92d78f6cde89b294a1'
jassol:
user_name: 'jassol'
givenname: 'Jason'
sn: 'Solomon'
mail: 'jassol@users.main.unkin.net'
uidnumber: 20010
primarygroup: 20000
othergroups:
- 20010 # jelly
- 20011 # sonarr
- 20012 # radarr
- 20013 # lidarr
- 20014 # readarr
- 20016 # nzbget
- 20027 # grafana user
loginshell: '/bin/bash'
homedir: '/home/jassol'
passsha256: 'd8e215d3c94b954e1318c9c7243ce72713f2fb1d006037724fe857c1fb7e88e9'
glauth::services:
svc_jellyfin:
@@ -367,3 +388,12 @@ glauth::groups:
grafana_user:
group_name: 'grafana_user'
gidnumber: 20027
kubernetes_au_syd1_cluster_operator:
group_name: 'kubernetes_au_syd1_cluster_operator'
gidnumber: 20028
kubernetes_au_syd1_cluster_admin:
group_name: 'kubernetes_au_syd1_cluster_admin'
gidnumber: 20029
kubernetes_au_syd1_cluster_root:
group_name: 'kubernetes_au_syd1_cluster_root'
gidnumber: 20030
+8 -13
View File
@@ -14,31 +14,26 @@ profiles::pki::vault::alt_names:
- radosgw.service.consul
- radosgw.query.consul
- "radosgw.service.%{facts.country}-%{facts.region}.consul"
# S3 endpoint name (s3.ceph.unkin.net CNAME -> radosgw.service.consul); needed
# on the cert so TLS validates for that hostname.
- s3.ceph.unkin.net
# additional repos
profiles::yum::global::repos:
ceph:
name: ceph
descr: ceph repository
target: /etc/yum.repos.d/ceph.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/%{facts.os.architecture}
gpgkey: https://download.ceph.com/keys/release.asc
mirrorlist: absent
ensure: present
ceph-noarch:
name: ceph-noarch
descr: ceph-noarch repository
target: /etc/yum.repos.d/ceph-noarch.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/noarch
gpgkey: https://download.ceph.com/keys/release.asc
mirrorlist: absent
ensure: present
# manage a simple nginx reverse proxy
profiles::nginx::simpleproxy::nginx_vhost: 'radosgw.service.consul'
profiles::nginx::simpleproxy::nginx_aliases:
- radosgw.service.au-syd1.consul
# nginx (443 -> radosgw:7480) must answer for the S3 endpoint name too.
- s3.ceph.unkin.net
profiles::nginx::simpleproxy::proxy_port: 7480
profiles::nginx::simpleproxy::proxy_path: '/'
nginx::client_max_body_size: 100M
nginx::client_max_body_size: 5000M
# manage consul service
consul::services:
+2 -12
View File
@@ -57,19 +57,9 @@ profiles::consul::client::node_rules:
# additional repos
profiles::yum::global::repos:
frr-extras:
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://packagerepo.service.consul/frr/el%{facts.os.release.major}/extras-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el%{facts.os.release.major}/extras-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
frr-stable:
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://packagerepo.service.consul/frr/el%{facts.os.release.major}/stable-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el%{facts.os.release.major}/stable-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
# cobbler settings
profiles::cobbler::params::service_cname: 'cobbler.main.unkin.net'
+2 -12
View File
@@ -41,19 +41,9 @@ profiles::consul::client::node_rules:
# additional repos
profiles::yum::global::repos:
frr-extras:
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
frr-stable:
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
profiles::dhcp::server::ntpservers:
- 0.au.pool.ntp.org
@@ -0,0 +1,2 @@
---
externaldns::externaldns_key_secret: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEABqbZiK1NDTU+w2k7orz2HrB0EXwun7hn4pR6TeCHMp2IfrkPxlQT+f1J9c0PqJaAKvnyz+Cx0xNCrlnONqk+J57f48kYKYV+Vw+L0AYHYFj8/TizY5CwLpJS2XKyfRd4iEsWMonvfIYn71t3+YuXm4dkoEqGekW93qCr/KFtjAu0K3e+ypyl4EJqWokiUs7IbcSBNvrjUkP4yR8F/wHVKM1E5yfr+D1+nmMmt7Ob/J+am14492TppE2C7Xadg4us+kdYtuBsv9kTSi1GwwqUDjbeJVmfK3pKHjXdF+PI07AFLzo5bBZTJOzQfQ4SywpH8R5BDQoUCyHiaskB5wrmSDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBB2LU9ZhefSg9PqqkwnfV65gDBvXuXco0moKCGjHqm5KcojWCK1BoS/+mltlr8kw9grZjN9jxHRLn1FjgBlq418c8w=]
@@ -0,0 +1,55 @@
---
hiera_include:
- externaldns
- frrouting
- exporters::frr_exporter
externaldns::bind_master_hostname: 'ausyd1nxvm2127.main.unkin.net'
externaldns::k8s_zones:
- 'k8s.syd1.au.unkin.net'
- '200.18.198.in-addr.arpa'
externaldns::slave_servers:
- 'ausyd1nxvm2128.main.unkin.net'
- 'ausyd1nxvm2129.main.unkin.net'
externaldns::externaldns_key_algorithm: 'hmac-sha256'
# networking
anycast_ip: 198.18.19.20
systemd::manage_networkd: true
systemd::manage_all_network_files: true
networking::interfaces:
eth0:
type: physical
forwarding: true
dhcp: true
anycast0:
type: dummy
ipaddress: "%{hiera('anycast_ip')}"
netmask: 255.255.255.255
mtu: 1500
# frrouting
exporters::frr_exporter::enable: true
frrouting::ospfd_router_id: "%{facts.networking.ip}"
frrouting::ospfd_redistribute:
- connected
frrouting::ospfd_interfaces:
eth0:
area: 0.0.0.0
anycast0:
area: 0.0.0.0
frrouting::daemons:
ospfd: true
# consul
profiles::consul::client::node_rules:
- resource: service
segment: frr_exporter
disposition: write
# additional repos
profiles::yum::global::repos:
frr-extras:
ensure: present
frr-stable:
ensure: present
+2 -12
View File
@@ -200,16 +200,6 @@ profiles::consul::client::node_rules:
# additional repos
profiles::yum::global::repos:
frr-extras:
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
frr-stable:
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
+16 -13
View File
@@ -6,8 +6,10 @@ hiera_include:
profiles::dns::resolver::acls:
acl-main.unkin.net:
addresses:
- 10.10.8.1/32
- 198.18.1.10/32
- 198.18.2.160/27
- 198.18.21.160/27
- 198.18.2.192/27
- 198.18.21.192/27
- 198.18.13.0/24
- 198.18.14.0/24
@@ -82,6 +84,11 @@ profiles::dns::resolver::zones:
- 10.10.16.32
- 10.10.16.33
forward: 'only'
k8s.syd1.au.unkin.net-forward:
domain: 'k8s.syd1.au.unkin.net'
zone_type: 'forward'
forwarders: "%{alias('profiles_dns_upstream_forwarder_k8s')}"
forward: 'only'
unkin.net-forward:
domain: 'unkin.net'
zone_type: 'forward'
@@ -172,6 +179,11 @@ profiles::dns::resolver::zones:
zone_type: 'forward'
forwarders: "%{alias('profiles_dns_upstream_forwarder_unkin')}"
forward: 'only'
200.18.198.in-addr.arpa-forward:
domain: '200.18.198.in-addr.arpa'
zone_type: 'forward'
forwarders: "%{alias('profiles_dns_upstream_forwarder_k8s')}"
forward: 'only'
consul-forward:
domain: 'consul'
zone_type: 'forward'
@@ -188,6 +200,7 @@ profiles::dns::resolver::views:
- network.unkin.net-forward
- prod.unkin.net-forward
- consul-forward
- k8s.syd1.au.unkin.net-forward
- 13.18.198.in-addr.arpa-forward
- 14.18.198.in-addr.arpa-forward
- 15.18.198.in-addr.arpa-forward
@@ -250,16 +263,6 @@ profiles::consul::client::node_rules:
# additional repos
profiles::yum::global::repos:
frr-extras:
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
frr-stable:
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
+2 -2
View File
@@ -8,9 +8,9 @@ docker::version: latest
docker::curl_ensure: false
docker::root_dir: /data/docker
profiles::gitea::runner::instance: https://git.unkin.net
profiles::gitea::runner::home: /data/runner
profiles::gitea::runner::version: '0.2.10'
profiles::gitea::runner::source: "https://gitea.com/gitea/act_runner/releases/download/v%{hiera('profiles::gitea::runner::version')}/act_runner-%{hiera('profiles::gitea::runner::version')}-linux-amd64"
profiles::gitea::runner::version: '0.2.12'
profiles::gitea::runner::config:
log:
level: info
+9 -3
View File
@@ -71,7 +71,7 @@ profiles::nginx::simpleproxy::nginx_aliases:
profiles::nginx::simpleproxy::proxy_port: 3000
profiles::nginx::simpleproxy::proxy_path: '/'
nginx::client_max_body_size: 1024M
nginx::client_max_body_size: 5144M
# enable external access via haproxy
profiles::gitea::haproxy::enable: true
@@ -82,8 +82,14 @@ profiles::sql::postgresdb::dbname: gitea
profiles::sql::postgresdb::dbuser: gitea
# deploy gitea
gitea::ensure: '1.22.4'
gitea::checksum: 'd549104f55067e6fb156e7ba060c9af488f36e12d5e747db7563fcc99eaf8532'
gitea::base_url: 'https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/gitea-dl/gitea'
gitea::install::checksums:
1.26.2:
linux:
amd64: 5b37937b625de69196748f7293eee1a7363f8637ae6e3da3c359bb380bd61a6a
gitea::ensure: '1.26.2'
gitea::checksum: '5b37937b625de69196748f7293eee1a7363f8637ae6e3da3c359bb380bd61a6a'
gitea::manage_user: false
gitea::manage_group: false
gitea::manage_home: false
+46 -12
View File
@@ -35,19 +35,9 @@ frrouting::daemons:
# additional repos
profiles::yum::global::repos:
frr-extras:
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
frr-stable:
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
# haproxy metrics
consul::services:
@@ -163,6 +153,50 @@ profiles::haproxy::frontends:
- 'set-header X-Forwarded-Proto https'
- 'set-header X-Real-IP %[src]'
- 'use-service prometheus-exporter if { path /metrics }'
fe_imap:
description: 'Frontend for Stalwart IMAP (STARTTLS)'
bind:
0.0.0.0:143: []
mode: 'tcp'
options:
log: global
default_backend: be_stalwart_imap
tcp-request:
- inspect-delay 5s
- content accept if { req_len 0 }
fe_imaps:
description: 'Frontend for Stalwart IMAPS (implicit TLS)'
bind:
0.0.0.0:993: []
mode: 'tcp'
options:
log: global
default_backend: be_stalwart_imaps
tcp-request:
- inspect-delay 5s
- content accept if { req_len 0 }
fe_smtp:
description: 'Frontend for Stalwart SMTP'
bind:
0.0.0.0:25: []
mode: 'tcp'
options:
log: global
default_backend: be_stalwart_smtp
tcp-request:
- inspect-delay 5s
- content accept if { req_len 0 }
fe_submission:
description: 'Frontend for Stalwart SMTP Submission'
bind:
0.0.0.0:587: []
mode: 'tcp'
options:
log: global
default_backend: be_stalwart_submission
tcp-request:
- inspect-delay 5s
- content accept if { req_len 0 }
profiles::haproxy::backends:
be_letsencrypt:
+10 -31
View File
@@ -5,6 +5,10 @@ hiera_include:
- incus
- zfs
- profiles::ceph::node
- profiles::ceph::mon
- profiles::ceph::mgr
- profiles::ceph::mds
- profiles::ceph::osd
- profiles::ceph::client
- profiles::ceph::dashboard
- profiles::storage::cephfsvols
@@ -85,46 +89,21 @@ profiles::consul::client::node_rules:
# additional repos
profiles::yum::global::repos:
ceph:
name: ceph
descr: ceph repository
target: /etc/yum.repos.d/ceph.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/%{facts.os.architecture}
gpgkey: https://download.ceph.com/keys/release.asc
mirrorlist: absent
ensure: present
ceph-noarch:
name: ceph-noarch
descr: ceph-noarch repository
target: /etc/yum.repos.d/ceph-noarch.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/noarch
gpgkey: https://download.ceph.com/keys/release.asc
mirrorlist: absent
ensure: present
frr-extras:
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
frr-stable:
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
zfs-kmod:
name: zfs-kmod
descr: zfs-kmod repository
target: /etc/yum.repos.d/zfs-kmod.repo
baseurl: https://packagerepo.service.consul/zfs/rhel9/kmod-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/zfs/rhel9/kmod-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-openzfs-2022
mirrorlist: absent
ensure: present
# dns
profiles::dns::base::primary_interface: loopback0
# dashboard/haproxy
profiles::ceph::dashboard::ipaddress: "%{hiera('networking_loopback0_ip')}"
profiles::ceph::dashboard::ipaddress: "%{hiera('networking_loopback2_ip')}"
# networking
systemd::manage_networkd: true
+74 -36
View File
@@ -2,6 +2,7 @@
hiera_include:
- profiles::selinux::setenforce
- profiles::ceph::node
- profiles::ceph::osd
- profiles::ceph::client
- exporters::frr_exporter
- frrouting
@@ -10,6 +11,62 @@ hiera_include:
# manage rke2
rke2::bootstrap_node: prodnxsr0001.main.unkin.net
rke2::join_url: https://join-k8s.service.consul:9345
rke2::manage_registries: true
rke2::registries:
docker.io:
endpoint:
- "https://artifactapi.k8s.syd1.au.unkin.net"
rewrite:
"^(.*)$": "dockerhub/$1"
disable-default-registry-endpoint: true
ghcr.io:
endpoint:
- "https://artifactapi.k8s.syd1.au.unkin.net"
rewrite:
"^(.*)$": "ghcr/$1"
disable-default-registry-endpoint: true
quay.io:
endpoint:
- "https://artifactapi.k8s.syd1.au.unkin.net"
rewrite:
"^(.*)$": "quay/$1"
disable-default-registry-endpoint: true
registry.k8s.io:
endpoint:
- "https://artifactapi.k8s.syd1.au.unkin.net"
rewrite:
"^(.*)$": "k8s-registry/$1"
disable-default-registry-endpoint: true
registry.gitlab.com:
endpoint:
- "https://artifactapi.k8s.syd1.au.unkin.net"
rewrite:
"^(.*)$": "gitlab/$1"
disable-default-registry-endpoint: true
docker.elastic.co:
endpoint:
- "https://artifactapi.k8s.syd1.au.unkin.net"
rewrite:
"^(.*)$": "elastic/$1"
disable-default-registry-endpoint: true
gcr.io:
endpoint:
- "https://artifactapi.k8s.syd1.au.unkin.net"
rewrite:
"^(.*)$": "gcr/$1"
disable-default-registry-endpoint: true
docker.litellm.ai:
endpoint:
- "https://artifactapi.k8s.syd1.au.unkin.net"
rewrite:
"^(.*)$": "litellm/$1"
disable-default-registry-endpoint: true
public.ecr.aws:
endpoint:
- "https://artifactapi.k8s.syd1.au.unkin.net"
rewrite:
"^(.*)$": "ecr-public/$1"
disable-default-registry-endpoint: true
rke2::config_hash:
bind-address: "%{hiera('networking_loopback0_ip')}"
node-ip: "%{hiera('networking_loopback0_ip')}"
@@ -47,47 +104,17 @@ profiles::ceph::client::mons:
# additional repos
profiles::yum::global::repos:
ceph:
name: ceph
descr: ceph repository
target: /etc/yum.repos.d/ceph.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/%{facts.os.architecture}
gpgkey: https://download.ceph.com/keys/release.asc
mirrorlist: absent
ensure: present
ceph-noarch:
name: ceph-noarch
descr: ceph-noarch repository
target: /etc/yum.repos.d/ceph-noarch.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/noarch
gpgkey: https://download.ceph.com/keys/release.asc
mirrorlist: absent
ensure: present
frr-extras:
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
frr-stable:
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
rancher-rke2-common-latest:
name: rancher-rke2-common-latest
descr: rancher-rke2-common-latest
target: /etc/yum.repos.d/rke2-common.repo
baseurl: https://packagerepo.service.consul/rke2/rhel%{facts.os.release.major}/common-daily/x86_64/os/
gpgkey: https://packagerepo.service.consul/rke2/rhel%{facts.os.release.major}/common-daily/x86_64/os/public.key
mirrorlist: absent
ensure: present
rancher-rke2-1-33-latest:
name: rancher-rke2-1-33-latest
descr: rancher-rke2-1-33-latest
target: /etc/yum.repos.d/rke2-1-33.repo
baseurl: https://packagerepo.service.consul/rke2/rhel%{facts.os.release.major}/1.33-daily/x86_64/os/
gpgkey: https://packagerepo.service.consul/rke2/rhel%{facts.os.release.major}/1.33-daily/x86_64/os/public.key
mirrorlist: absent
ensure: present
# dns
profiles::dns::base::primary_interface: loopback0
@@ -155,6 +182,17 @@ frrouting::ospf_exclude_k8s_enable: true
frrouting::k8s_cluster_cidr: '10.42.0.0/16' # RKE2 cluster-cidr (pods)
frrouting::k8s_service_cidr: '10.43.0.0/16' # RKE2 service-cidr
# sysctl recommendations
sysctl::base::values:
net.ipv4.conf.default.rp_filter:
value: '0'
net.ipv4.conf.all.rp_filter:
value: '0'
fs.inotify.max_user_watches:
value: '524288'
fs.inotify.max_user_instances:
value: '512'
# add loopback interfaces to ssh list
ssh::server::options:
ListenAddress:
+6 -3
View File
@@ -3,9 +3,6 @@
rke2::node_type: server
rke2::helm_install: true
rke2::helm_repos:
rancher-stable: https://releases.rancher.com/server-charts/stable
purelb: https://gitlab.com/api/v4/projects/20400619/packages/helm/stable
jetstack: https://charts.jetstack.io
harbor: https://helm.goharbor.io
traefik: https://traefik.github.io/charts
hashicorp: https://helm.releases.hashicorp.com
@@ -58,6 +55,12 @@ consul::services:
tcp: "%{hiera('networking_loopback0_ip')}:9345"
interval: '10s'
timeout: '1s'
- id: 'rke2_server_ping_check'
name: 'rke2 Server Ping Check'
http: "https://%{hiera('networking_loopback0_ip')}:9345/ping"
interval: '10s'
timeout: '3s'
tls_skip_verify: true
profiles::consul::client::node_rules:
- resource: service
segment: api-k8s
+6 -36
View File
@@ -47,47 +47,17 @@ profiles::ceph::client::mons:
# additional repos
profiles::yum::global::repos:
ceph:
name: ceph
descr: ceph repository
target: /etc/yum.repos.d/ceph.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/%{facts.os.architecture}
gpgkey: https://download.ceph.com/keys/release.asc
mirrorlist: absent
ensure: present
ceph-noarch:
name: ceph-noarch
descr: ceph-noarch repository
target: /etc/yum.repos.d/ceph-noarch.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/noarch
gpgkey: https://download.ceph.com/keys/release.asc
mirrorlist: absent
ensure: present
frr-extras:
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
frr-stable:
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
rancher-rke2-common-latest:
name: rancher-rke2-common-latest
descr: rancher-rke2-common-latest
target: /etc/yum.repos.d/rke2-common.repo
baseurl: https://rpm.rancher.io/rke2/latest/common/centos/%{facts.os.release.major}/noarch
gpgkey: https://rpm.rancher.io/public.key
mirrorlist: absent
ensure: present
rancher-rke2-1-33-latest:
name: rancher-rke2-1-33-latest
descr: rancher-rke2-1-33-latest
target: /etc/yum.repos.d/rke2-1-33.repo
baseurl: https://rpm.rancher.io/rke2/latest/1.33/centos/%{facts.os.release.major}/x86_64
gpgkey: https://rpm.rancher.io/public.key
mirrorlist: absent
ensure: present
# dns
profiles::dns::base::primary_interface: loopback0
+15
View File
@@ -14,6 +14,8 @@ victorialogs::node::options:
envflag.enable: 'true'
select.disable: 'undef'
storageNode.tls: 'undef'
syslog.listenAddr.tcp: ':21514'
syslog.timezone: 'Australia/Sydney'
storageNode:
- ausyd1nxvm2108.main.unkin.net:9428
- ausyd1nxvm2109.main.unkin.net:9428
@@ -45,7 +47,20 @@ consul::services:
tls_skip_verify: true
interval: '10s'
timeout: '1s'
syslog:
service_name: 'syslog'
address: "%{facts.networking.ip}"
port: 21514
checks:
- id: 'vlinsert_syslog_tcp_check'
name: 'VictoriaLogs Syslog TCP Check'
tcp: "%{facts.networking.fqdn}:21514"
interval: '30s'
timeout: '5s'
profiles::consul::client::node_rules:
- resource: service
segment: vlinsert
disposition: write
- resource: service
segment: syslog
disposition: write
+5
View File
@@ -0,0 +1,5 @@
---
profiles::sql::postgresdb::dbpass: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAEZkKX2ThGom2PffofEuRBHbyiq68PCsq0+19eSa02fpVPKgZ/5BEjzBhwvrt0BWZWsjYGhccFQ69DR+lTuqS50GcRSAiNQ2LDX2a3J1pu39oIKsNVmcJTza0f5T0VeI3A7sZkn7jL+NVz5ANp8V0EMfAjaduGQ7Jac+8dBsvTrLbJ+1AZVrjaKPxOI1+5tpE7qx35mM0oDVy0NwmlaVf8vbK6jyzyUJRs4Sb+mpioPi5sDxHgClzsQnu93HqqAIqR5UzsUv7MDMljOGYUF5ITyPU836I1LEZ9UfiVO7AikQ3A31LaSUWvwsxRHKxiQXJ7v6W/O+Nt3jdIR0eoqC5xTBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBC11+SUDLmz6bBrGyfYT9DPgDB3UhuhJ3kUruMTdRCW0Y6hoSBBQYCO+ZRFJToGTkz/BcxVw2Xtwjc7UmKmLodsDAo=]
stalwart::s3_access_key: ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAm1fkuVcAt4UKFnpljH0o3eb3x1r2ieEU4NUzuSx8DDdOv4rh8rkqghPGn1xs6LGd9zLprc9ZWFowXCP4I2L0gZ4PekI04rV4lL02xYechIah1JAntdwECEks7rmI4BbPabIUIkaHW4i/WtntRNvv38g9JjiWrvOoJSABEsiIVZL0ct6NykLgQk27r4rcP8j7ukNQqPCAA02d4y9CB/5g6RKtYkv6FwZfLA/rFTUIXhKJsNtTa9Gm1yhvb/Y859X4qvsSFymCm/B8+2Bz5H57lE0r6xOBBBS5PfpeQ2YRxmedlkj0HxRFpl2e1W94OazMbbI6dlXa5ceHqHXDZL78EzBMBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDhiBSQPgE+fwD1Y9Gc1wQ3gCCGeGdA4BKCvIhYaQmzv9wUFuNaO75qHrub0vY8Od1ilQ==]
stalwart::s3_secret_key: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAdFOGR2axfPIksXExnW8vAZBSBm8V/QqPtIMtuzleDLOGsOuyLgJAbHPZJoj/w5bBV9bBKMGfWs94GGbKZ2PafiJeCtqfFJnUAIpVBTZ5cfUhQXERAHcketMvKUi1J8jKLSFc9I3uTjIVcIasjk0oe7WmCPnoikjl1qJZ/lVDH0cXHevjMuohxEyyka5jzC0ixCOkxyqOV2LOqSc6J5d0WSsSWqw0lDmY7vJAtqNtH6y6ghKZo5zdLQOsF2Bseg3oVejRNqYwfUsaDnfiRwJS/Rm/TmtXb4i6Jn8coYplDaJHtxQSXJ+KvOy6LS7M8X5sQ/UZSRqcwM647Yg4pwVWqDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBKBF7hTs0e0FKdRpFYbx4kgDB0xkNe78n6VLbUTHX7vTw6J+K/mxf+XCV95/EIkvBbWBYuU8ZMHNQKMEExmci4C4o=]
stalwart::fallback_admin_password: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAMp9wmIhRwj5kxfUcvc+/q/oUs/vBhSqP19ZfErM4vLDK20VOBTnPhSP2lfVh9pqO0c2hpWFeuqBWMynghO+HUBJfAn29Vrc8a9iSBxQ3XuF/uiRq1inOKCQpdsU18TyCrYV9AJFNf9U20JuUoav79m7EKLHS07PHAZ0osqIYy93eXdCFhwXAGHijp4wMMQz/5z1F1mZoSrc1cXe3y8iBeAvvjnRfpw14gOKZBjmEGUbo7AIyc3wax5hbOQYf/v+Hd90JarvAufxGytg9WKO20cChWYbmYDnIkytVt3vHdHf4RT8M635l6qwLr/70O1MdE7bkrVRKP8M3KLyH072pJTBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDSJwptBDvPd0WpxiIovZsjgDBBwesNW+UNo4b0idhyqsyWL2rtO7wLStWHgUIvRFJACCrTKKqlu7sta6mhu/ZsnF0=]
+46
View File
@@ -0,0 +1,46 @@
---
hiera_include:
- stalwart
- profiles::sql::postgresdb
- profiles::stalwart::haproxy
# additional altnames
profiles::pki::vault::alt_names:
- mail.main.unkin.net
- mail-webadmin.main.unkin.net
- main-in.main.unkin.net
- autoconfig.main.unkin.net
- autodiscovery.main.unkin.net
# manage a pgsql database + user
profiles::sql::postgresdb::cluster_name: "patroni-shared-%{facts.environment}"
profiles::sql::postgresdb::dbname: stalwart
profiles::sql::postgresdb::dbuser: stalwart
# export backends to haproxy
profiles::stalwart::haproxy::enable: true
# Cluster role for node discovery
stalwart::cluster_role: "%{facts.enc_role}"
# PostgreSQL connection
stalwart::postgresql_host: "master.%{hiera('profiles::sql::postgresdb::cluster_name')}.service.%{facts.country}-%{facts.region}.consul"
stalwart::postgresql_database: "%{hiera('profiles::sql::postgresdb::dbname')}"
stalwart::postgresql_user: "%{hiera('profiles::sql::postgresdb::dbuser')}"
stalwart::postgresql_password: "%{hiera('profiles::sql::postgresdb::dbpass')}"
# S3/Ceph-RGW connection
stalwart::s3_endpoint: 'https://radosgw.service.consul'
stalwart::s3_bucket: 'stalwart-maildata'
stalwart::s3_region: "%{facts.region}"
# Domains and relay
stalwart::domains:
- 'mail.unkin.net'
stalwart::postfix_relay_host: 'out-mta.main.unkin.net'
stalwart::service_hostname: 'mail.main.unkin.net'
stalwart::manage_dns_records: false
## With load balancer:
#stalwart::manage_dns_records: true
#stalwart::loadbalancer_host: 'mail-lb.example.com'
+1 -1
View File
@@ -37,7 +37,7 @@ postfix::transports:
'main.unkin.net':
ensure: present
destination: 'relay'
nexthop: 'ausyd1nxvm2120.main.unkin.net:25'
nexthop: 'mail-in.main.unkin.net:25'
# postfix virtuals
postfix::virtuals:
@@ -11,6 +11,7 @@ profiles::metrics::grafana::db_name: "%{hiera('profiles::sql::postgresdb::dbname
profiles::metrics::grafana::db_user: "%{hiera('profiles::sql::postgresdb::dbuser')}"
profiles::metrics::grafana::db_pass: "%{hiera('profiles::sql::postgresdb::dbpass')}"
profiles::metrics::grafana::pgsql_backend: true
profiles::metrics::grafana::version: '13.0.2'
profiles::metrics::grafana::plugins:
victoriametrics-logs-datasource:
ensure: present
@@ -3,6 +3,16 @@ hiera_include:
- vmcluster::vmagent
vmcluster::vmagent::enable: true
vmcluster::vmagent::static_targets:
vyos_node:
targets:
- '198.18.21.160:9100'
scrape_interval: '15s'
metrics_path: '/metrics'
scheme: 'http'
labels:
instance: 'syrtvm0001.main.unkin.net'
job: 'vyos_node'
vmcluster::vmagent::options:
tls: 'true'
tlsCertFile: '/etc/pki/tls/vault/certificate.crt'
+2 -7
View File
@@ -24,13 +24,8 @@ frrouting::ospfd_interfaces:
area: 0.0.0.1
profiles::yum::global::repos:
ceph-reef:
name: ceph-reef
descr: ceph reef repository
target: /etc/yum.repos.d/ceph-reef.repo
baseurl: https://edgecache.query.consul/ceph/yum/el%{facts.os.release.major}/%{facts.os.architecture}
gpgcheck: 0,
mirrorlist: absent
ceph:
ensure: present
profiles::ceph::client::keyrings:
nomad:
+8 -40
View File
@@ -1,50 +1,18 @@
---
profiles::yum::global::repos:
centos_8_advanced_virtualization:
name: 'virt-advanced-virtualization'
descr: 'CentOS Advanced Virtualization'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/virt/x86_64/advancedvirt-common
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Virtualization'
ensure: present
centos_8_ceph_pacific:
name: 'storage-ceph-pacific'
descr: 'CentOS Ceph Pacific'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/storage/x86_64/ceph-pacific
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage'
ensure: present
centos_8_rabbitmq_38:
name: 'messaging-rabbitmq-38'
descr: 'CentOS RabbitMQ 38'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/messaging/x86_64/rabbitmq-38
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Messaging'
ensure: present
centos_8_nfv_openvswitch:
name: 'nfv-openvswitch-2'
descr: 'CentOS NFV OpenvSwitch'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/nfv/x86_64/openvswitch-2
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-NFV'
ensure: present
centos_8_openstack_xena:
name: 'cloud-openstack-xena'
descr: 'CentOS OpenStack Xena'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/cloud/x86_64/openstack-xena
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Cloud'
ensure: present
centos_8_opstools:
name: 'opstools-collectd-5'
descr: 'CentOS OpsTools - collectd'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/opstools/x86_64/collectd-5
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-OpsTools'
ensure: present
centos_8_ovirt45:
name: 'virt-ovirt-45'
descr: 'CentOS oVirt 4.5'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/virt/x86_64/ovirt-45
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Virtualization'
ensure: present
centos_8_stream_gluster10:
name: 'storage-gluster-10'
descr: 'CentOS oVirt 4.5 - Glusterfs 10'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/storage/x86_64/gluster-10
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage'
ensure: present
+8 -40
View File
@@ -9,50 +9,18 @@ sudo::purge_ignore:
profiles::yum::global::repos:
centos_8_advanced_virtualization:
name: 'virt-advanced-virtualization'
descr: 'CentOS Advanced Virtualization'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/virt/x86_64/advancedvirt-common
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Virtualization'
ensure: present
centos_8_ceph_pacific:
name: 'storage-ceph-pacific'
descr: 'CentOS Ceph Pacific'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/storage/x86_64/ceph-pacific
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage'
ensure: present
centos_8_rabbitmq_38:
name: 'messaging-rabbitmq-38'
descr: 'CentOS RabbitMQ 38'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/messaging/x86_64/rabbitmq-38
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Messaging'
ensure: present
centos_8_nfv_openvswitch:
name: 'nfv-openvswitch-2'
descr: 'CentOS NFV OpenvSwitch'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/nfv/x86_64/openvswitch-2
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-NFV'
ensure: present
centos_8_openstack_xena:
name: 'cloud-openstack-xena'
descr: 'CentOS OpenStack Xena'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/cloud/x86_64/openstack-xena
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Cloud'
ensure: present
centos_8_opstools:
name: 'opstools-collectd-5'
descr: 'CentOS OpsTools - collectd'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/opstools/x86_64/collectd-5
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-OpsTools'
ensure: present
centos_8_ovirt45:
name: 'virt-ovirt-45'
descr: 'CentOS oVirt 4.5'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/virt/x86_64/ovirt-45
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Virtualization'
ensure: present
centos_8_stream_gluster10:
name: 'storage-gluster-10'
descr: 'CentOS oVirt 4.5 - Glusterfs 10'
target: /etc/yum.repos.d/ovirt.repo
baseurl: https://edgecache.query.consul/centos/8-stream/storage/x86_64/gluster-10
gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage'
ensure: present
+1
View File
@@ -16,3 +16,4 @@ certbot::domains:
- git.unkin.net
- grafana.unkin.net
- dashboard.ceph.unkin.net
- auth.unkin.net
+1 -1
View File
@@ -26,7 +26,7 @@ profiles::puppet::cobbler_enc::packages:
- 'requests'
- 'PyYAML'
profiles::puppet::enc::repo: https://git.service.au-syd1.consul/unkinben/puppet-enc.git
profiles::puppet::r10k::r10k_repo: https://git.service.au-syd1.consul/unkin/puppet-r10k.git
profiles::puppet::r10k::r10k_repo: https://git.unkin.net/unkin/puppet-r10k.git
profiles::puppet::g10k::bin_path: '/usr/bin/g10k'
profiles::puppet::g10k::cfg_path: '/etc/puppetlabs/r10k/r10k.yaml'
profiles::puppet::g10k::environments_path: '/etc/puppetlabs/code/environments'
+2 -10
View File
@@ -62,14 +62,6 @@ profiles::consul::client::node_rules:
profiles::yum::global::repos:
postgresql-17:
name: postgresql-17
descr: postgresql-17 repository
target: /etc/yum.repos.d/postgresql.repo
baseurl: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/17-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/17-daily/%{facts.os.architecture}/os/PGDG-RPM-GPG-KEY-RHEL
ensure: present
postgresql-common:
name: postgresql-common
descr: postgresql-common repository
target: /etc/yum.repos.d/postgresql.repo
baseurl: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/common-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/common-daily/%{facts.os.architecture}/os/PGDG-RPM-GPG-KEY-RHEL
ensure: present
-238
View File
@@ -3,90 +3,6 @@ profiles::packages::include:
createrepo: {}
profiles::reposync::repos_list:
almalinux_9.6_baseos:
repository: 'baseos'
description: 'AlmaLinux 9.6 BaseOS'
osname: 'almalinux'
release: '9.6'
mirrorlist: 'https://mirrors.almalinux.org/mirrorlist/9.6/baseos'
gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux-9'
almalinux_9.6_appstream:
repository: 'appstream'
description: 'AlmaLinux 9.6 AppStream'
osname: 'almalinux'
release: '9.6'
mirrorlist: 'https://mirrors.almalinux.org/mirrorlist/9.6/appstream'
gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux-9'
almalinux_9.6_crb:
repository: 'crb'
description: 'AlmaLinux 9.6 CRB'
osname: 'almalinux'
release: '9.6'
mirrorlist: 'https://mirrors.almalinux.org/mirrorlist/9.6/crb'
gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux-9'
almalinux_9.6_ha:
repository: 'ha'
description: 'AlmaLinux 9.6 HighAvailability'
osname: 'almalinux'
release: '9.6'
mirrorlist: 'https://mirrors.almalinux.org/mirrorlist/9.6/highavailability'
gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux-9'
almalinux_9.6_extras:
repository: 'extras'
description: 'AlmaLinux 9.6 extras'
osname: 'almalinux'
release: '9.6'
mirrorlist: 'https://mirrors.almalinux.org/mirrorlist/9.6/extras'
gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux-9'
almalinux_9_5_baseos:
repository: 'baseos'
description: 'AlmaLinux 9.5 BaseOS'
osname: 'almalinux'
release: '9.5'
mirrorlist: 'https://mirrors.almalinux.org/mirrorlist/9.5/baseos'
gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux-9'
almalinux_9_5_appstream:
repository: 'appstream'
description: 'AlmaLinux 9.5 AppStream'
osname: 'almalinux'
release: '9.5'
mirrorlist: 'https://mirrors.almalinux.org/mirrorlist/9.5/appstream'
gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux-9'
almalinux_9_5_crb:
repository: 'crb'
description: 'AlmaLinux 9.5 CRB'
osname: 'almalinux'
release: '9.5'
mirrorlist: 'https://mirrors.almalinux.org/mirrorlist/9.5/crb'
gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux-9'
almalinux_9_5_ha:
repository: 'ha'
description: 'AlmaLinux 9.5 HighAvailability'
osname: 'almalinux'
release: '9.5'
mirrorlist: 'https://mirrors.almalinux.org/mirrorlist/9.5/highavailability'
gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux-9'
almalinux_9_5_extras:
repository: 'extras'
description: 'AlmaLinux 9.5 extras'
osname: 'almalinux'
release: '9.5'
mirrorlist: 'https://mirrors.almalinux.org/mirrorlist/9.5/extras'
gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux-9'
epel_8:
repository: 'everything'
description: 'EPEL8'
osname: 'epel'
release: '8'
mirrorlist: 'https://mirrors.fedoraproject.org/mirrorlist?repo=epel-8&arch=x86_64'
gpgkey: 'https://epel.mirror.digitalpacific.com.au/RPM-GPG-KEY-EPEL-8'
epel_9:
repository: 'everything'
description: 'EPEL9'
osname: 'epel'
release: '9'
mirrorlist: 'https://mirrors.fedoraproject.org/mirrorlist?repo=epel-9&arch=x86_64'
gpgkey: 'https://epel.mirror.digitalpacific.com.au/RPM-GPG-KEY-EPEL-9'
docker_stable_el8:
repository: 'stable'
description: 'Docker CE Stable EL8'
@@ -101,34 +17,6 @@ profiles::reposync::repos_list:
release: 'el9'
baseurl: 'https://download.docker.com/linux/centos/9/x86_64/stable/'
gpgkey: 'https://download.docker.com/linux/centos/gpg'
frr_stable_el8:
repository: 'stable'
description: 'FRR Stable EL8'
osname: 'frr'
release: 'el8'
baseurl: 'https://rpm.frrouting.org/repo/el8/frr/'
gpgkey: 'https://packagerepo.service.consul/frr/gpg/RPM-GPG-KEY-FRR'
frr_extras_el8:
repository: 'extras'
description: 'FRR Extras EL8'
osname: 'frr'
release: 'el8'
baseurl: 'https://rpm.frrouting.org/repo/el8/extras/'
gpgkey: 'https://packagerepo.service.consul/frr/gpg/RPM-GPG-KEY-FRR'
frr_stable_el9:
repository: 'stable'
description: 'FRR Stable EL9'
osname: 'frr'
release: 'el9'
baseurl: 'https://rpm.frrouting.org/repo/el9/frr/'
gpgkey: 'https://packagerepo.service.consul/frr/gpg/RPM-GPG-KEY-FRR'
frr_extras_el9:
repository: 'extras'
description: 'FRR Extras el9'
osname: 'frr'
release: 'el9'
baseurl: 'https://rpm.frrouting.org/repo/el9/extras/'
gpgkey: 'https://packagerepo.service.consul/frr/gpg/RPM-GPG-KEY-FRR'
k8s_1.32:
repository: '1.32'
description: 'Kubernetes 1.32'
@@ -143,62 +31,6 @@ profiles::reposync::repos_list:
release: '1.33'
baseurl: 'https://pkgs.k8s.io/core:/stable:/v1.33/rpm/'
gpgkey: 'https://pkgs.k8s.io/core:/stable:/v1.33/rpm/repodata/repomd.xml.key'
mariadb_11_8_el8:
repository: 'el8'
description: 'MariaDB 11.8'
osname: 'mariadb'
release: '11.8'
baseurl: 'http://mariadb.mirror.digitalpacific.com.au/yum/11.8/rhel8-amd64/'
gpgkey: 'https://mariadb.mirror.digitalpacific.com.au/yum/RPM-GPG-KEY-MariaDB'
mariadb_11_8_el9:
repository: 'el9'
description: 'MariaDB 11.8'
osname: 'mariadb'
release: '11.8'
baseurl: 'http://mariadb.mirror.digitalpacific.com.au/yum/11.8/rhel9-amd64/'
gpgkey: 'https://mariadb.mirror.digitalpacific.com.au/yum/RPM-GPG-KEY-MariaDB'
openvox7_el8:
repository: '8'
description: 'openvox 7 EL8'
osname: 'openvox7'
release: 'el'
baseurl: 'https://yum.voxpupuli.org/openvox7/el/8/x86_64/'
gpgkey: 'https://yum.voxpupuli.org/GPG-KEY-openvox.pub'
openvox7_el9:
repository: '9'
description: 'openvox 7 EL9'
osname: 'openvox7'
release: 'el'
baseurl: 'https://yum.voxpupuli.org/openvox7/el/9/x86_64/'
gpgkey: 'https://yum.voxpupuli.org/GPG-KEY-openvox.pub'
openvox7_el10:
repository: '10'
description: 'openvox 7 EL10'
osname: 'openvox7'
release: 'el'
baseurl: 'https://yum.voxpupuli.org/openvox7/el/10/x86_64/'
gpgkey: 'https://yum.voxpupuli.org/GPG-KEY-openvox.pub'
openvox8_el8:
repository: '8'
description: 'openvox 8 EL8'
osname: 'openvox8'
release: 'el'
baseurl: 'https://yum.voxpupuli.org/openvox8/el/8/x86_64/'
gpgkey: 'https://yum.voxpupuli.org/GPG-KEY-openvox.pub'
openvox8_el9:
repository: '9'
description: 'openvox 8 EL9'
osname: 'openvox8'
release: 'el'
baseurl: 'https://yum.voxpupuli.org/openvox8/el/9/x86_64/'
gpgkey: 'https://yum.voxpupuli.org/GPG-KEY-openvox.pub'
openvox8_el10:
repository: '10'
description: 'openvox 8 EL10'
osname: 'openvox8'
release: 'el'
baseurl: 'https://yum.voxpupuli.org/openvox8/el/10/x86_64/'
gpgkey: 'https://yum.voxpupuli.org/GPG-KEY-openvox.pub'
puppet7_el8:
repository: '8'
description: 'Puppet 7 EL8'
@@ -227,76 +59,6 @@ profiles::reposync::repos_list:
release: 'el'
baseurl: 'https://yum.puppet.com/puppet8/el/9/x86_64/'
gpgkey: 'https://yum.puppet.com/RPM-GPG-KEY-puppet-20250406'
postgresql_rhel8_common:
repository: 'common'
description: 'PostgreSQL Common RHEL 8'
osname: 'postgresql'
release: 'rhel8'
baseurl: 'https://download.postgresql.org/pub/repos/yum/common/redhat/rhel-8-x86_64/'
gpgkey: 'https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL'
postgresql_rhel9_common:
repository: 'common'
description: 'PostgreSQL Common RHEL 9'
osname: 'postgresql'
release: 'rhel9'
baseurl: 'https://download.postgresql.org/pub/repos/yum/common/redhat/rhel-9-x86_64/'
gpgkey: 'https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL'
postgresql_rhel8_15:
repository: '15'
description: 'PostgreSQL 15 RHEL 8'
osname: 'postgresql'
release: 'rhel8'
baseurl: 'https://download.postgresql.org/pub/repos/yum/15/redhat/rhel-8-x86_64/'
gpgkey: 'https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL'
postgresql_rhel9_15:
repository: '15'
description: 'PostgreSQL 15 RHEL 9'
osname: 'postgresql'
release: 'rhel9'
baseurl: 'https://download.postgresql.org/pub/repos/yum/15/redhat/rhel-9-x86_64/'
gpgkey: 'https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL'
postgresql_rhel8_16:
repository: '16'
description: 'PostgreSQL 16 RHEL 8'
osname: 'postgresql'
release: 'rhel8'
baseurl: 'https://download.postgresql.org/pub/repos/yum/16/redhat/rhel-8-x86_64/'
gpgkey: 'https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL'
postgresql_rhel9_16:
repository: '16'
description: 'PostgreSQL 16 RHEL 9'
osname: 'postgresql'
release: 'rhel9'
baseurl: 'https://download.postgresql.org/pub/repos/yum/16/redhat/rhel-9-x86_64/'
gpgkey: 'https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL'
postgresql_rhel8_17:
repository: '17'
description: 'PostgreSQL 17 RHEL 8'
osname: 'postgresql'
release: 'rhel8'
baseurl: 'https://download.postgresql.org/pub/repos/yum/17/redhat/rhel-8-x86_64/'
gpgkey: 'https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL'
postgresql_rhel9_17:
repository: '17'
description: 'PostgreSQL 17 RHEL 9'
osname: 'postgresql'
release: 'rhel9'
baseurl: 'https://download.postgresql.org/pub/repos/yum/17/redhat/rhel-9-x86_64/'
gpgkey: 'https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL'
rke2_common_el9:
repository: 'common'
description: 'RKE2 common RHEL 9'
osname: 'rke2'
release: "rhel9"
baseurl: "https://rpm.rancher.io/rke2/latest/common/centos/9/noarch"
gpgkey: "https://rpm.rancher.io/public.key"
rke2_1_33_el9:
repository: '1.33'
description: 'RKE2 1.33 RHEL 9'
osname: 'rke2'
release: "rhel9"
baseurl: "https://rpm.rancher.io/rke2/latest/1.33/centos/9/x86_64"
gpgkey: "https://rpm.rancher.io/public.key"
zfs_dkms_rhel8:
repository: 'dkms'
description: 'ZFS DKMS RHEL 8'
+2 -10
View File
@@ -1,17 +1,9 @@
---
profiles::yum::global::repos:
postgresql-15:
name: postgresql-15
descr: postgresql-15 repository
target: /etc/yum.repos.d/postgresql.repo
baseurl: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/15-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/15-daily/%{facts.os.architecture}/os/PGDG-RPM-GPG-KEY-RHEL
ensure: present
postgresql-common:
name: postgresql-common
descr: postgresql-common repository
target: /etc/yum.repos.d/postgresql.repo
baseurl: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/common-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/common-daily/%{facts.os.architecture}/os/PGDG-RPM-GPG-KEY-RHEL
ensure: present
profiles::sql::patroni::cluster_name: "patroni-%{facts.environment}"
profiles::sql::patroni::postgres_exporter_enabled: true
+2 -10
View File
@@ -47,14 +47,6 @@ profiles::consul::client::node_rules:
profiles::yum::global::repos:
postgresql-17:
name: postgresql-17
descr: postgresql-17 repository
target: /etc/yum.repos.d/postgresql.repo
baseurl: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/17-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/17-daily/%{facts.os.architecture}/os/PGDG-RPM-GPG-KEY-RHEL
ensure: present
postgresql-common:
name: postgresql-common
descr: postgresql-common repository
target: /etc/yum.repos.d/postgresql.repo
baseurl: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/common-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/postgresql/rhel%{facts.os.release.major}/common-daily/%{facts.os.architecture}/os/PGDG-RPM-GPG-KEY-RHEL
ensure: present
+5 -13
View File
@@ -29,6 +29,7 @@ profiles::consul::server::acl:
profiles::pki::vault::alt_names:
- consul.main.unkin.net
- consul.service.consul
- "consul.service.%{facts.country}-%{facts.region}.consul"
- consul
# manage a simple nginx reverse proxy
@@ -38,6 +39,7 @@ profiles::nginx::simpleproxy::nginx_aliases:
- consul.main.unkin.net
profiles::nginx::simpleproxy::proxy_port: 8500
profiles::nginx::simpleproxy::proxy_path: '/'
nginx::client_max_body_size: 512M
# consul
profiles::consul::client::node_rules:
@@ -134,19 +136,9 @@ frrouting::ospfd_interfaces:
frrouting::daemons:
ospfd: true
# additional repos
# additional repos - enable needed repositories
profiles::yum::global::repos:
frr-extras:
name: frr-extras
descr: frr-extras repository
target: /etc/yum.repos.d/frr-extras.repo
baseurl: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/extras-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
frr-stable:
name: frr-stable
descr: frr-stable repository
target: /etc/yum.repos.d/frr-stable.repo
baseurl: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os
gpgkey: https://packagerepo.service.consul/frr/el9/stable-daily/%{facts.os.architecture}/os/RPM-GPG-KEY-FRR
mirrorlist: absent
ensure: present
+17 -2
View File
@@ -2,10 +2,12 @@
profiles::vault::server::members_role: roles::infra::storage::vault
profiles::vault::server::members_lookup: true
profiles::vault::server::data_dir: /data/vault
profiles::vault::server::plugin_dir: /opt/openbao-plugins
profiles::vault::server::manage_storage_dir: true
profiles::vault::server::tls_disable: false
vault::package_name: openbao
vault::package_ensure: 2.4.1
profiles::vault::server::package_name: openbao
profiles::vault::server::package_ensure: 2.4.4
profiles::vault::server::disable_openbao: false
# additional altnames
profiles::pki::vault::alt_names:
@@ -23,3 +25,16 @@ profiles::nginx::simpleproxy::proxy_scheme: 'http'
profiles::nginx::simpleproxy::proxy_host: '127.0.0.1'
profiles::nginx::simpleproxy::proxy_port: 8200
profiles::nginx::simpleproxy::proxy_path: '/'
profiles::packages::include:
# openbao-plugins (base bundle) left unpinned; it tracks the openbao package.
openbao-plugins: {}
# Secrets plugins pinned to the exact version whose binary matches the sha256
# registered in terraform-vault (config/plugins/*.yaml). Bump both in lockstep
# on upgrade, or OpenBao refuses to launch the plugin after a restart.
openbao-plugin-secrets-litellm:
ensure: '0.1.1'
openbao-plugin-secrets-gpg:
ensure: '0.1.0'
openbao-plugin-secrets-rancher:
ensure: '0.1.1'
+15
View File
@@ -0,0 +1,15 @@
# ExternalDNS BIND module - automatically configures master or slave
class externaldns (
Stdlib::Fqdn $bind_master_hostname,
Array[Stdlib::Fqdn] $k8s_zones = [],
Array[Stdlib::Fqdn] $slave_servers = [],
String $externaldns_key_secret = '',
String $externaldns_key_algorithm = 'hmac-sha256',
) {
if $trusted['certname'] == $bind_master_hostname {
include externaldns::master
} else {
include externaldns::slave
}
}
+45
View File
@@ -0,0 +1,45 @@
# ExternalDNS BIND master server class
class externaldns::master inherits externaldns {
include bind
# Query PuppetDB for slave server IP addresses
$slave_ips = $externaldns::slave_servers.map |$fqdn| {
puppetdb_query("inventory[facts.networking.ip] { certname = '${fqdn}' }")[0]['facts.networking.ip']
}.filter |$ip| { $ip != undef }
# Create TSIG key for ExternalDNS authentication
bind::key { 'externaldns-key':
algorithm => $externaldns::externaldns_key_algorithm,
secret => $externaldns::externaldns_key_secret,
}
# Create ACL for slave servers
if !empty($slave_ips) {
bind::acl { 'dns-slaves':
addresses => $slave_ips,
}
}
# Create master zones for each Kubernetes domain
$externaldns::k8s_zones.each |$zone| {
bind::zone { $zone:
zone_type => 'master',
dynamic => true,
allow_updates => ['key externaldns-key'],
allow_transfers => empty($slave_ips) ? {
true => ['key externaldns-key'],
false => ['key externaldns-key','dns-slaves'],
},
ns_notify => !empty($slave_ips),
also_notify => $slave_ips,
dnssec => false,
}
}
# Create default view to include the zones
bind::view { 'externaldns':
recursion => false,
zones => $externaldns::k8s_zones,
}
}
+36
View File
@@ -0,0 +1,36 @@
# ExternalDNS BIND slave server class
class externaldns::slave inherits externaldns {
include bind
# Query PuppetDB for master server IP address
$query = "inventory[facts.networking.ip] { certname = '${externaldns::bind_master_hostname}' }"
$master_ip = puppetdb_query($query)[0]['facts.networking.ip']
# Create TSIG key for zone transfers (same as master)
bind::key { 'externaldns-key':
algorithm => $externaldns::externaldns_key_algorithm,
secret => $externaldns::externaldns_key_secret,
}
# Create ACL for master server
bind::acl { 'dns-master':
addresses => [$master_ip],
}
# Create slave zones for each Kubernetes domain
$externaldns::k8s_zones.each |$zone| {
bind::zone { $zone:
zone_type => 'slave',
masters => [$master_ip],
allow_notify => ['dns-master'],
ns_notify => false,
}
}
# Create default view to include the zones
bind::view { 'externaldns':
recursion => false,
zones => $externaldns::k8s_zones,
}
}
+6 -1
View File
@@ -22,7 +22,12 @@ class incus::cluster (
}
# if it is, find hosts, sort them so they dont cause changes every run
$servers_array = sort(query_nodes("enc_role='${members_role}' and region='${facts['region']}'", 'networking.fqdn'))
$servers_array = sort(puppetdb_query(
"facts[certname] {
name = 'enc_role' and value = '${members_role}' and
certname in facts[certname] { name = 'region' and value = '${facts['region']}' }
}"
).map |$fact| { $fact['certname'] })
# else use provided array from params
}else{
+56
View File
@@ -0,0 +1,56 @@
# frozen_string_literal: true
require 'facter'
# Detects active ceph service instances via systemctl and exposes facts
# for use in ceph service management profiles.
# rubocop:disable Style/ClassAndModuleChildren
module Unkin
module Ceph
# Detects active ceph service instances via systemctl and exposes Facter facts.
module Utils
TYPES = %w[mon mgr mds osd].freeze
def self.services
output = Facter::Core::Execution.execute(
'systemctl list-units "ceph*" --no-legend --plain --all 2>/dev/null',
on_fail: ''
)
parse_units(output)
end
def self.parse_units(output)
result = TYPES.each_with_object({}) { |type, hash| hash[type] = [] }
output.each_line do |line|
unit = line.split.first
next unless unit
match_unit(result, unit)
end
result
end
def self.match_unit(result, unit)
TYPES.each do |type|
match = unit.match(/\Aceph-#{type}@(.+)\.service\z/)
result[type] << "ceph-#{type}@#{match[1]}" if match
end
end
TYPES.each do |type|
define_singleton_method(:"#{type}?") { !services[type].empty? }
end
end
end
end
# rubocop:enable Style/ClassAndModuleChildren
Facter.add('ceph_services') do
setcode { Unkin::Ceph::Utils.services }
end
Unkin::Ceph::Utils::TYPES.each do |type|
Facter.add("is_ceph_#{type}") do
setcode { Unkin::Ceph::Utils.public_send(:"#{type}?") }
end
end
+88
View File
@@ -0,0 +1,88 @@
# frozen_string_literal: true
# lib/facter/dns_records.rb
#
# Reports this host's expected DNS records (assembled by profiles::dns::updater
# into its records file) versus what is currently deployed on the authoritative
# server, so puppet can detect drift and re-apply.
#
# Structured value:
# { server, count, expected => [{zone,fqdn,type,ttl,value}], in_sync,
# drift => [{...,deployed => [...]}] }
# Helpers for the dns_records fact.
module DnsRecordsFact
RECORDS_FILE = '/var/lib/dns-updater/records'
SERVER_FILE = '/var/lib/dns-updater/server'
module_function
# normalise a value for comparison: strip, drop trailing dot, downcase
def norm(value)
value.to_s.strip.chomp('.').downcase
end
def server
File.exist?(SERVER_FILE) ? File.read(SERVER_FILE).strip : nil
end
# a name relative to a zone (or @) as a fully-qualified name
def to_fqdn(name, zone)
return "#{zone}." if name.to_s.empty? || name == '@'
"#{name}.#{zone}."
end
# parse one "zone|name|type|ttl|value" line into a record hash (nil to skip)
def parse_line(line)
line = line.strip
return nil if line.empty? || line.start_with?('#')
zone, name, type, ttl, value = line.split('|', 5)
return nil unless zone && type && value
{ 'zone' => zone, 'fqdn' => to_fqdn(name, zone), 'type' => type, 'ttl' => ttl, 'value' => value }
end
# parse the records file into record hashes
def expected
return [] unless File.exist?(RECORDS_FILE)
File.readlines(RECORDS_FILE).filter_map { |line| parse_line(line) }
end
# the values currently deployed for a record, per the authoritative server
def deployed(record, srv)
cmd = ['dig', '+short', '+time=2', '+tries=1']
cmd << "@#{srv}" if srv && !srv.empty?
cmd += [record['fqdn'], record['type']]
out = Facter::Core::Execution.execute(cmd.join(' '), on_fail: '')
out.to_s.split("\n").map { |line| norm(line) }.reject(&:empty?)
end
def report
srv = server
exp = expected
drift = exp.filter_map do |record|
dep = deployed(record, srv)
record.merge('deployed' => dep) unless dep.include?(norm(record['value']))
end
{ 'server' => srv, 'count' => exp.length, 'expected' => exp, 'in_sync' => drift.empty?, 'drift' => drift }
end
end
Facter.add(:dns_records) do
confine kernel: 'Linux'
setcode do
File.exist?(DnsRecordsFact::RECORDS_FILE) ? DnsRecordsFact.report : nil
end
end
# Convenience boolean for `if $facts['dns_records_insync']` guards.
Facter.add(:dns_records_insync) do
confine kernel: 'Linux'
setcode do
v = Facter.value(:dns_records)
v.nil? ? nil : v['in_sync']
end
end
+6 -1
View File
@@ -20,7 +20,12 @@ class redisha::redis (
}
# if it is, find hosts, sort them so they dont cause changes every run
$servers_array = sort(query_nodes("enc_role='${redisha_members_role}' and region='${facts['region']}'", 'networking.fqdn'))
$servers_array = sort(puppetdb_query(
"facts[certname] {
name = 'enc_role' and value = '${redisha_members_role}' and
certname in facts[certname] { name = 'region' and value = '${facts['region']}' }
}"
).map |$fact| { $fact['certname'] })
# else use provided array from params
}else{
+6 -1
View File
@@ -23,7 +23,12 @@ class redisha::sentinel (
}
# if it is, find hosts, sort them so they dont cause changes every run
$servers_array = sort(query_nodes("enc_role='${redisha_members_role}' and region='${facts['region']}'", 'networking.fqdn'))
$servers_array = sort(puppetdb_query(
"facts[certname] {
name = 'enc_role' and value = '${redisha_members_role}' and
certname in facts[certname] { name = 'region' and value = '${facts['region']}' }
}"
).map |$fact| { $fact['certname'] })
# else use provided array from params
}else{
@@ -1,23 +0,0 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rancher
namespace: cattle-system
annotations:
kubernetes.io/ingress.class: nginx
spec:
tls:
- hosts: [rancher.main.unkin.net]
secretName: tls-rancher
rules:
- host: rancher.main.unkin.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: rancher
port:
number: 80
-45
View File
@@ -1,45 +0,0 @@
apiVersion: purelb.io/v1
kind: LBNodeAgent
metadata:
name: common
namespace: purelb
spec:
local:
extlbint: kube-lb0
localint: default
sendgarp: false
---
apiVersion: purelb.io/v1
kind: LBNodeAgent
metadata:
name: dmz
namespace: purelb
spec:
local:
extlbint: kube-lb0
localint: default
sendgarp: false
---
apiVersion: purelb.io/v1
kind: ServiceGroup
metadata:
name: dmz
namespace: purelb
spec:
local:
v4pools:
- subnet: 198.18.199.0/24
pool: 198.18.199.0/24
aggregation: /32
---
apiVersion: purelb.io/v1
kind: ServiceGroup
metadata:
name: common
namespace: purelb
spec:
local:
v4pools:
- subnet: 198.18.200.0/24
pool: 198.18.200.0/24
aggregation: /32
+20 -24
View File
@@ -7,6 +7,8 @@ class rke2::config (
Stdlib::Fqdn $bootstrap_node = $rke2::bootstrap_node,
String $node_token = $rke2::node_token,
Array[String[1]] $extra_config_files = $rke2::extra_config_files,
Boolean $manage_registries = $rke2::manage_registries,
Hash $registries = $rke2::registries,
){
# if its not the bootstrap node, add join path to config
@@ -28,6 +30,24 @@ class rke2::config (
$config = $config_hash
}
if $manage_registries {
file { '/etc/rancher/rke2/registries.yaml':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
content => epp('rke2/registries.yaml.epp', { registries => $registries }),
require => Package["rke2-${node_type}"],
notify => Service["rke2-${node_type}"],
}
}else{
file { '/etc/rancher/rke2/registries.yaml':
ensure => absent,
require => Package["rke2-${node_type}"],
notify => Service["rke2-${node_type}"],
}
}
# create the config file
file { $config_file:
ensure => file,
@@ -68,30 +88,6 @@ class rke2::config (
# on the controller nodes only
if $node_type == 'server' and $facts['k8s_masters'] and $facts['k8s_masters'] > 2 {
# wait for purelb helm to setup namespace
if 'purelb' in $facts['k8s_namespaces'] {
file {'/var/lib/rancher/rke2/server/manifests/purelb-config.yaml':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
source => 'puppet:///modules/rke2/purelb-config.yaml',
require => Service['rke2-server'],
}
}
# wait for rancher helm to setup namespace
if 'cattle-system' in $facts['k8s_namespaces'] {
file {'/var/lib/rancher/rke2/server/manifests/ingress-route-rancher.yaml':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
source => 'puppet:///modules/rke2/ingress-route-rancher.yaml',
require => Service['rke2-server'],
}
}
# manage extra config config (these are not dependent on helm)
$extra_config_files.each |$file| {
-38
View File
@@ -38,44 +38,6 @@ class rke2::helm (
}
}
}
# install specific helm charts to bootstrap environment
$plb_cmd = 'helm install purelb purelb/purelb \
--create-namespace \
--namespace=purelb \
--repository-config /etc/helm/repositories.yaml'
exec { 'install_purelb':
command => $plb_cmd,
path => ['/usr/bin', '/bin'],
environment => ['KUBECONFIG=/etc/rancher/rke2/rke2.yaml'],
unless => 'helm list -n purelb | grep -q ^purelb',
}
$cm_cmd = 'helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set crds.enabled=true \
--repository-config /etc/helm/repositories.yaml'
exec { 'install_cert_manager':
command => $cm_cmd,
path => ['/usr/bin', '/bin'],
environment => ['KUBECONFIG=/etc/rancher/rke2/rke2.yaml'],
unless => 'helm list -n cert-manager | grep -q ^cert-manager',
}
$r_cmd = 'helm install rancher rancher-stable/rancher \
--namespace cattle-system \
--create-namespace \
--set hostname=rancher.main.unkin.net \
--set bootstrapPassword=admin \
--set ingress.tls.source=secret \
--repository-config /etc/helm/repositories.yaml'
exec { 'install_rancher':
command => $r_cmd,
path => ['/usr/bin', '/bin'],
environment => ['KUBECONFIG=/etc/rancher/rke2/rke2.yaml'],
unless => 'helm list -n cattle-system | grep -q ^rancher',
}
}
}
}
+2
View File
@@ -12,6 +12,8 @@ class rke2 (
Hash $helm_repos = $rke2::params::helm_repos,
Array[String[1]] $extra_config_files = $rke2::params::extra_config_files,
Stdlib::HTTPUrl $container_archive_source = $rke2::params::container_archive_source,
Boolean $manage_registries = $rke2::params::manage_registries,
Hash $registries = $rke2::params::registries,
) inherits rke2::params {
include rke2::install
+1 -1
View File
@@ -30,7 +30,7 @@ class rke2::install (
# download required archive of containers
archive { '/var/lib/rancher/rke2/agent/images/rke2-images.linux-amd64.tar.zst':
ensure => present,
source => "https://github.com/rancher/rke2/releases/download/v${rke2_version}%2B${rke2_release}/rke2-images.linux-amd64.tar.zst",
source => "https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/github/rancher/rke2/releases/download/v${rke2_version}%2B${rke2_release}/rke2-images.linux-amd64.tar.zst",
require => [
Package["rke2-${node_type}"],
File['/var/lib/rancher/rke2/agent/images'],
+2
View File
@@ -12,4 +12,6 @@ class rke2::params (
Hash $helm_repos = {},
Array[String[1]] $extra_config_files = [],
Stdlib::HTTPUrl $container_archive_source = 'https://github.com/rancher/rke2/releases/download',
Boolean $manage_registries = false,
Hash $registries = {},
) {}
@@ -0,0 +1,20 @@
<%- | Hash $registries | -%>
---
# DO NOT MODIFY - MANAGED BY PUPPET
mirrors:
<%- $registries.each |$registry, $config| { -%>
<%= $registry %>:
endpoint:
<%- $config['endpoint'].each |$ep| { -%>
- "<%= $ep %>"
<%- } -%>
<%- if $config['rewrite'] { -%>
rewrite:
<%- $config['rewrite'].each |$pattern, $replacement| { -%>
"<%= $pattern %>": "<%= $replacement %>"
<%- } -%>
<%- } -%>
<%- if $config['disable-default-registry-endpoint'] { -%>
disable-default-registry-endpoint: true
<%- } -%>
<%- } -%>
+230
View File
@@ -0,0 +1,230 @@
# Stalwart Mail Server Module
This Puppet module manages Stalwart Mail Server, a modern, secure, and scalable mail server implementation that supports IMAP, JMAP, WebDAV, and SMTP protocols.
## Overview
The `stalwart` module provides a comprehensive solution for deploying Stalwart Mail Server in a clustered environment with:
- **PostgreSQL backend** for data, full-text search, and in-memory storage
- **S3/Ceph-RGW backend** for blob storage (emails, attachments, sieve scripts)
- **Automatic cluster discovery** using `query_nodes()`
- **DNS autodiscovery records** for email client configuration
- **TLS certificate management** integration
- **Postfix relay integration** for SMTP routing
## Features
-**Multi-node clustering** with peer-to-peer coordination
-**PostgreSQL authentication** with SQL directory backend
-**S3 blob storage** with compression support
-**IMAP/IMAPS protocols** for email access
-**HTTP/HTTPS protocols** for JMAP, WebDAV, and autodiscovery
-**SMTP relay** for postfix integration
-**DNS autodiscovery** record management
-**Automatic role distribution** across cluster nodes
-**TLS security** with Vault PKI integration
## Requirements
- **Puppet 6+** with `query_nodes()` function support
- **Stalwart RPM package** (creates user, directories, systemd service)
- **PostgreSQL cluster** for data storage
- **S3-compatible storage** (Ceph-RGW, MinIO, AWS S3)
- **DNS management** via `profiles::dns::record`
- **PKI management** via `profiles::pki::vault::alt_names`
## Usage
### Recommended Usage with Role
The recommended way to use this module is via the `roles::infra::mail::backend` role with hieradata configuration:
```puppet
include roles::infra::mail::backend
```
Configure all parameters in `hieradata/roles/infra/mail/backend.yaml` - see `examples/role-hieradata.yaml` for a complete example.
### Direct Class Usage
```puppet
class { 'stalwart':
node_id => 1,
cluster_role => 'mail-backend',
postgresql_host => 'pgsql.example.com',
postgresql_database => 'stalwart',
postgresql_user => 'stalwart',
postgresql_password => Sensitive('secretpassword'),
s3_endpoint => 'https://ceph-rgw.example.com',
s3_bucket => 'stalwart-blobs',
s3_access_key => 'accesskey',
s3_secret_key => Sensitive('secretkey'),
domains => ['example.com'],
postfix_relay_host => 'postfix.example.com',
}
```
## Hieradata Configuration
See `examples/role-hieradata.yaml` for a complete example of role-based hieradata configuration.
### Required Parameters
```yaml
# Cluster role for node discovery
stalwart::cluster_role: 'mail-backend'
# Optional: Unique node identifier (auto-calculated if not specified)
# stalwart::node_id: 1
# PostgreSQL connection
stalwart::postgresql_host: 'pgsql.example.com'
stalwart::postgresql_database: 'stalwart'
stalwart::postgresql_user: 'stalwart'
stalwart::postgresql_password: >
ENC[PKCS7,encrypted_password...]
# S3/Ceph-RGW connection
stalwart::s3_endpoint: 'https://ceph-rgw.example.com'
stalwart::s3_bucket: 'stalwart-blobs'
stalwart::s3_access_key: 'access_key'
stalwart::s3_secret_key: >
ENC[PKCS7,encrypted_secret...]
# Domains and relay
stalwart::domains:
- 'example.com'
stalwart::postfix_relay_host: 'postfix.example.com'
```
## Architecture
### Cluster Setup
The module automatically discovers cluster members using `query_nodes()` based on:
- `enc_role` matching `cluster_role` parameter
- `country` fact matching the node's country fact
- `region` fact matching the node's region fact
**Node ID Assignment:**
- Node IDs are **automatically extracted** from the last 4 digits of the hostname
- Example: `ausyd1nxvm1234` → node ID `1234`
- Manual override available via `stalwart::node_id` parameter if needed
- Hostname must end with 4 digits for automatic extraction to work
- Ensures unique IDs when following consistent hostname patterns
### Storage Layout
- **Data Store**: PostgreSQL (metadata, folders, settings)
- **Full-Text Search**: PostgreSQL (search indexes)
- **In-Memory Store**: PostgreSQL (caching, sessions)
- **Blob Store**: S3/Ceph-RGW (emails, attachments, files)
### Directory Structure (Created by RPM)
- **Config**: `/opt/stalwart/etc/config.toml`
- **Data**: `/var/lib/stalwart/` (queue, reports)
- **Logs**: `/var/log/stalwart/stalwart.log`
- **Binary**: `/opt/stalwart/bin/stalwart`
- **User**: `stalwart:stalwart` (system user)
### Network Ports
- **143**: IMAP (STARTTLS)
- **993**: IMAPS (implicit TLS)
- **443**: HTTPS (JMAP, WebDAV, autodiscovery)
- **2525**: SMTP relay (postfix communication)
- **11200**: Cluster coordination (peer-to-peer)
- **9090**: Prometheus metrics
### DNS Records
When `manage_dns_records: true`, the module creates:
- `autoconfig.domain.com` → server FQDN (Thunderbird)
- `autodiscover.domain.com` → server FQDN (Outlook)
- `_imap._tcp.domain.com` SRV record
- `_imaps._tcp.domain.com` SRV record
- `_caldav._tcp.domain.com` SRV record
- `_carddav._tcp.domain.com` SRV record
## PostgreSQL Schema
The module expects these tables in the PostgreSQL database:
```sql
CREATE TABLE accounts (
name TEXT PRIMARY KEY,
secret TEXT,
description TEXT,
type TEXT NOT NULL,
quota INTEGER DEFAULT 0,
active BOOLEAN DEFAULT true
);
CREATE TABLE group_members (
name TEXT NOT NULL,
member_of TEXT NOT NULL,
PRIMARY KEY (name, member_of)
);
CREATE TABLE emails (
name TEXT NOT NULL,
address TEXT NOT NULL,
type TEXT,
PRIMARY KEY (name, address)
);
```
## Security
- **TLS required** for all connections
- **PostgreSQL SSL** enabled by default
- **S3 HTTPS** endpoints required
- **Password hashing** supported (SHA512, BCRYPT, etc.)
- **Certificate management** via Vault PKI
### Fallback Administrator
Stalwart includes a fallback administrator account for initial setup and emergency access:
- **Default username**: `admin` (configurable via `stalwart::fallback_admin_user`)
- **Default password**: `admin` (configurable via `stalwart::fallback_admin_password`)
- **Purpose**: Initial server configuration and emergency access when directory services are unavailable
- **Security**: Password is automatically hashed using SHA-512 crypt format
**Important**: Change the default password in production by setting different hieradata values:
```yaml
stalwart::fallback_admin_password: "your-secure-password"
```
The fallback admin should only be used for initial setup and emergencies. Create regular admin accounts in PostgreSQL for day-to-day management.
## Monitoring
- **Prometheus metrics** on port 9090
- **Log files** in `/var/log/stalwart/`
- **Queue monitoring** in `/var/lib/stalwart/queue/`
- **Service status** via systemd (`stalwart.service`)
## Troubleshooting
### Cluster Formation Issues
- Verify `query_nodes()` returns expected nodes
- Check `country` and `region` facts are consistent
- Ensure `cluster_role` matches across all nodes
### Storage Connection Issues
- Test PostgreSQL connectivity and credentials
- Verify S3 endpoint accessibility and credentials
- Check network connectivity between nodes
### TLS Certificate Issues
- Ensure PKI alt_names include all required domains
- Verify certificate paths exist and are readable
- Check certificate expiration dates
## License
This module is part of the internal infrastructure management system.
+57
View File
@@ -0,0 +1,57 @@
# Example hieradata for profiles::mail::stalwart
# This shows the required and optional parameters for Stalwart configuration
# Required: Unique node ID for each server in the cluster (1, 2, 3, etc.)
profiles::mail::stalwart::node_id: 1
# Required: Cluster role name for query_nodes() discovery
profiles::mail::stalwart::cluster_role: 'mail-backend'
# Required: PostgreSQL connection settings
profiles::mail::stalwart::postgresql_host: 'pgsql.example.com'
profiles::mail::stalwart::postgresql_port: 5432
profiles::mail::stalwart::postgresql_database: 'stalwart'
profiles::mail::stalwart::postgresql_user: 'stalwart'
profiles::mail::stalwart::postgresql_password: >
ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAxample...]
profiles::mail::stalwart::postgresql_ssl: true
# Required: S3/Ceph-RGW connection settings
profiles::mail::stalwart::s3_endpoint: 'https://ceph-rgw.example.com'
profiles::mail::stalwart::s3_bucket: 'stalwart-blobs'
profiles::mail::stalwart::s3_region: 'default'
profiles::mail::stalwart::s3_access_key: 'stalwart_access_key'
profiles::mail::stalwart::s3_secret_key: >
ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAxample...]
profiles::mail::stalwart::s3_key_prefix: 'stalwart/'
# Required: Domains this mail backend serves
profiles::mail::stalwart::domains:
- 'example.com'
- 'mail.example.com'
# Required: Postfix relay host for SMTP delivery
profiles::mail::stalwart::postfix_relay_host: 'postfix.example.com'
# Optional: Protocol configuration (defaults shown)
profiles::mail::stalwart::enable_imap: true
profiles::mail::stalwart::enable_imap_tls: true
profiles::mail::stalwart::enable_http: true
profiles::mail::stalwart::enable_smtp_relay: true
# Optional: Management settings
profiles::mail::stalwart::manage_dns_records: true
profiles::mail::stalwart::log_level: 'info'
# Optional: TLS certificate paths (defaults shown)
profiles::mail::stalwart::tls_cert: '/etc/pki/tls/vault/certificate.crt'
profiles::mail::stalwart::tls_key: '/etc/pki/tls/vault/private.key'
# Example PKI alt_names configuration for TLS certificates
# This should include all domains and hostnames that need certificates
profiles::pki::vault::alt_names:
mail-backend:
- 'imap.example.com'
- 'mail.example.com'
- 'autoconfig.example.com'
- 'autodiscover.example.com'
@@ -0,0 +1,58 @@
# Example hieradata for roles::infra::mail::backend
# Place this in: hieradata/roles/infra/mail/backend.yaml
# Stalwart module configuration - all parameters passed directly to the module
# stalwart::node_id: 1234 # Optional - automatically extracted from last 4 digits of hostname
stalwart::cluster_role: 'mail-backend'
# PostgreSQL connection settings
stalwart::postgresql_host: 'pgsql.example.com'
stalwart::postgresql_port: 5432
stalwart::postgresql_database: 'stalwart'
stalwart::postgresql_user: 'stalwart'
stalwart::postgresql_password: >
ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAxample...]
stalwart::postgresql_ssl: true
# S3/Ceph-RGW connection settings
stalwart::s3_endpoint: 'https://ceph-rgw.example.com'
stalwart::s3_bucket: 'stalwart-blobs'
stalwart::s3_region: 'default'
stalwart::s3_access_key: 'stalwart_access_key'
stalwart::s3_secret_key: >
ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAxample...]
stalwart::s3_key_prefix: 'stalwart/'
# Domains this mail backend serves
stalwart::domains:
- 'example.com'
- 'mail.example.com'
# Postfix relay host for SMTP delivery
stalwart::postfix_relay_host: 'postfix.example.com'
# Optional protocol configuration (defaults shown)
stalwart::enable_imap: true
stalwart::enable_imap_tls: true
stalwart::enable_http: true
stalwart::enable_smtp_relay: true
# Optional management settings
stalwart::manage_dns_records: true
stalwart::log_level: 'info'
# Optional TLS certificate paths (defaults work with profiles::pki::vault)
# stalwart::tls_cert: '/etc/pki/tls/vault/certificate.crt'
# stalwart::tls_key: '/etc/pki/tls/vault/private.key'
# Optional path overrides (RPM package sets up these defaults)
# stalwart::config_dir: '/opt/stalwart/etc'
# stalwart::data_dir: '/var/lib/stalwart'
# PKI alt_names configuration for TLS certificates
# This should include all domains and hostnames that need certificates
profiles::pki::vault::alt_names:
- 'imap.example.com'
- 'mail.example.com'
- 'autoconfig.example.com'
- 'autodiscover.example.com'
+84
View File
@@ -0,0 +1,84 @@
# @summary Manages Stalwart Mail Server configuration
#
# @api private
class stalwart::config {
assert_private()
# Create base directories (package creates user/group and base dirs)
file { [$stalwart::config_dir, $stalwart::data_dir, $stalwart::webadmin_unpack_path]:
ensure => directory,
owner => 'stalwart',
group => 'stalwart',
mode => '0750',
}
# Ensure log directory exists
file { '/var/log/stalwart':
ensure => directory,
owner => 'stalwart',
group => 'stalwart',
mode => '0755',
}
# Main configuration file
file { "${stalwart::config_dir}/config.toml":
ensure => file,
owner => 'stalwart',
group => 'stalwart',
mode => '0640',
content => epp('stalwart/config.toml.epp', {
'cluster_size' => $stalwart::cluster_size,
'other_cluster_members' => $stalwart::other_cluster_members,
'haproxy_ips' => $stalwart::haproxy_ips,
'effective_node_id' => $stalwart::effective_node_id,
'bind_address' => $stalwart::bind_address,
'advertise_address' => $stalwart::advertise_address,
'postgresql_host' => $stalwart::postgresql_host,
'postgresql_port' => $stalwart::postgresql_port,
'postgresql_database' => $stalwart::postgresql_database,
'postgresql_user' => $stalwart::postgresql_user,
'postgresql_password' => $stalwart::postgresql_password.unwrap,
'postgresql_ssl' => $stalwart::postgresql_ssl,
's3_endpoint' => $stalwart::s3_endpoint,
's3_bucket' => $stalwart::s3_bucket,
's3_region' => $stalwart::s3_region,
's3_access_key' => $stalwart::s3_access_key,
's3_secret_key' => $stalwart::s3_secret_key.unwrap,
's3_key_prefix' => $stalwart::s3_key_prefix,
'domains' => $stalwart::domains,
'postfix_relay_host' => $stalwart::postfix_relay_host,
'enable_imap' => $stalwart::enable_imap,
'enable_imap_tls' => $stalwart::enable_imap_tls,
'enable_http' => $stalwart::enable_http,
'enable_smtp_submission' => $stalwart::enable_smtp_submission,
'data_dir' => $stalwart::data_dir,
'tls_cert' => $stalwart::tls_cert,
'tls_key' => $stalwart::tls_key,
'log_level' => $stalwart::log_level,
'service_hostname' => $stalwart::service_hostname,
'fallback_admin_user' => $stalwart::fallback_admin_user,
'fallback_admin_password' => $stalwart::fallback_admin_password,
'webadmin_unpack_path' => $stalwart::webadmin_unpack_path,
'webadmin_resource_url' => $stalwart::webadmin_resource_url,
'webadmin_auto_update' => $stalwart::webadmin_auto_update,
'node_facts' => $facts,
}),
notify => Service['stalwart'],
}
# Create directories for storage
file { "${stalwart::data_dir}/queue":
ensure => directory,
owner => 'stalwart',
group => 'stalwart',
mode => '0750',
}
file { "${stalwart::data_dir}/reports":
ensure => directory,
owner => 'stalwart',
group => 'stalwart',
mode => '0750',
}
}
+67
View File
@@ -0,0 +1,67 @@
# @summary Manages DNS autodiscovery records for Stalwart
#
# @param target_host
# FQDN to point DNS records to (defaults to current server)
#
# @api private
class stalwart::dns (
Stdlib::Fqdn $target_host = $facts['networking']['fqdn'],
) {
assert_private()
# Create autodiscovery DNS records for each domain
$stalwart::domains.each |$domain| {
# Autoconfig record for Thunderbird/Mozilla clients
profiles::dns::record { "autoconfig_${domain}":
record => "autoconfig.${domain}",
type => 'CNAME',
value => "${target_host}.",
zone => $domain,
order => 100,
}
# Autodiscover record for Outlook/Microsoft clients
profiles::dns::record { "autodiscover_${domain}":
record => "autodiscover.${domain}",
type => 'CNAME',
value => "${target_host}.",
zone => $domain,
order => 101,
}
# IMAP SRV records
profiles::dns::record { "imap_srv_${domain}":
record => "_imap._tcp.${domain}",
type => 'SRV',
value => "10 1 143 ${target_host}.",
zone => $domain,
order => 102,
}
profiles::dns::record { "imaps_srv_${domain}":
record => "_imaps._tcp.${domain}",
type => 'SRV',
value => "10 1 993 ${target_host}.",
zone => $domain,
order => 103,
}
# CalDAV and CardDAV SRV records
profiles::dns::record { "caldav_srv_${domain}":
record => "_caldav._tcp.${domain}",
type => 'SRV',
value => "10 1 443 ${target_host}.",
zone => $domain,
order => 104,
}
profiles::dns::record { "carddav_srv_${domain}":
record => "_carddav._tcp.${domain}",
type => 'SRV',
value => "10 1 443 ${target_host}.",
zone => $domain,
order => 105,
}
}
}
+264
View File
@@ -0,0 +1,264 @@
# @summary Main class for managing Stalwart Mail Server
#
# This class provides a comprehensive setup of Stalwart Mail Server with
# clustering, authentication, storage, and protocol support.
#
# @example Basic Stalwart setup
# class { 'stalwart':
# node_id => 1,
# postgresql_host => 'pgsql.example.com',
# postgresql_database => 'stalwart',
# postgresql_user => 'stalwart',
# postgresql_password => Sensitive('secretpassword'),
# s3_endpoint => 'https://ceph-rgw.example.com',
# s3_bucket => 'stalwart-blobs',
# s3_access_key => 'accesskey',
# s3_secret_key => Sensitive('secretkey'),
# domains => ['example.com'],
# postfix_relay_host => 'postfix.example.com',
# }
#
# @param node_id
# Unique identifier for this node in the cluster (1-N). If not specified,
# automatically calculated based on sorted position in cluster member list.
#
# @param cluster_role
# Role name for cluster member discovery via query_nodes()
#
#
# @param postgresql_host
# PostgreSQL server hostname/IP
#
# @param postgresql_port
# PostgreSQL server port
#
# @param postgresql_database
# PostgreSQL database name
#
# @param postgresql_user
# PostgreSQL username
#
# @param postgresql_password
# PostgreSQL password (Sensitive)
#
# @param postgresql_ssl
# Enable SSL/TLS for PostgreSQL connections
#
# @param s3_endpoint
# S3/Ceph-RGW endpoint URL
#
# @param s3_bucket
# S3 bucket name for blob storage
#
# @param s3_region
# S3 region
#
# @param s3_access_key
# S3 access key
#
# @param s3_secret_key
# S3 secret key (Sensitive)
#
# @param s3_key_prefix
# S3 key prefix for stalwart objects
#
# @param domains
# Array of domains this server handles
#
# @param postfix_relay_host
# Postfix relay host for SMTP delivery
#
# @param bind_address
# IP address to bind services to
#
# @param advertise_address
# IP address to advertise to cluster members
#
# @param enable_imap
# Enable IMAP protocol listener
#
# @param enable_imap_tls
# Enable IMAP over TLS listener
#
# @param enable_http
# Enable HTTP listener for JMAP/WebDAV/Autodiscovery
#
# @param enable_smtp_relay
# Enable SMTP for postfix relay communication
#
# @param enable_smtp_submission
# Enable SMTP submission listener on port 587
#
# @param haproxy_role
# Role name for HAProxy nodes to include in proxy trusted networks
#
# @param service_hostname
# Service hostname used for autoconfig/autodiscover and SMTP greeting
#
# @param package_ensure
# Package version to install
#
# @param config_dir
# Stalwart configuration directory
#
# @param data_dir
# Stalwart data directory
#
# @param log_level
# Logging verbosity level
#
# @param manage_firewall
# Whether to manage firewall rules
#
# @param tls_cert
# Path to TLS certificate file
#
# @param tls_key
# Path to TLS private key file
#
# @param manage_dns_records
# Whether to create DNS autodiscovery records
#
class stalwart (
String $cluster_role,
Stdlib::Host $postgresql_host,
String $postgresql_database,
String $postgresql_user,
Sensitive[String] $postgresql_password,
Stdlib::HTTPUrl $s3_endpoint,
String $s3_bucket,
String $s3_access_key,
Sensitive[String] $s3_secret_key,
Array[Stdlib::Fqdn] $domains,
Stdlib::Host $postfix_relay_host,
Optional[Integer] $node_id = undef,
Stdlib::Port $postgresql_port = 5432,
Boolean $postgresql_ssl = true,
String $s3_region = 'us-east-1',
String $s3_key_prefix = 'stalwart/',
Stdlib::IP::Address $bind_address = $facts['networking']['ip'],
Stdlib::IP::Address $advertise_address = $facts['networking']['ip'],
Boolean $enable_imap = true,
Boolean $enable_imap_tls = true,
Boolean $enable_http = true,
Boolean $enable_smtp_relay = true,
Boolean $enable_smtp_submission = true,
String $haproxy_role = 'roles::infra::halb::haproxy2',
Stdlib::Fqdn $service_hostname = $facts['networking']['fqdn'],
String $package_ensure = 'present',
Stdlib::Absolutepath $config_dir = '/opt/stalwart/etc',
Stdlib::Absolutepath $data_dir = '/var/lib/stalwart',
Enum['error','warn','info','debug','trace'] $log_level = 'info',
Boolean $manage_firewall = false,
Stdlib::Absolutepath $tls_cert = '/etc/pki/tls/vault/certificate.crt',
Stdlib::Absolutepath $tls_key = '/etc/pki/tls/vault/private.key',
Boolean $manage_dns_records = true,
Optional[Stdlib::Fqdn] $loadbalancer_host = undef,
String $fallback_admin_user = 'admin',
Sensitive[String] $fallback_admin_password = Sensitive('admin'),
Stdlib::Absolutepath $webadmin_unpack_path = "${data_dir}/webadmin",
Stdlib::HTTPUrl $webadmin_resource_url = 'https://github.com/stalwartlabs/webadmin/releases/latest/download/webadmin.zip',
Boolean $webadmin_auto_update = true,
) {
# Calculate node_id from last 4 digits of hostname if not provided
$my_fqdn = $facts['networking']['fqdn']
$hostname = $facts['networking']['hostname']
# Query cluster members for validation
$cluster_query = "enc_role='${cluster_role}' and country='${facts['country']}' and region='${facts['region']}'"
$cluster_members_raw = puppetdb_query(
"facts[certname] {
name = 'enc_role' and value = '${cluster_role}' and
certname in facts[certname] { name = 'country' and value = '${facts['country']}' } and
certname in facts[certname] { name = 'region' and value = '${facts['region']}' }
}"
).map |$fact| { $fact['certname'] }
$cluster_members = $cluster_members_raw ? {
undef => [],
default => $cluster_members_raw,
}
$sorted_cluster_members = sort($cluster_members)
# Calculate cluster information for templates
$other_cluster_members = $sorted_cluster_members.filter |$member| { $member != $my_fqdn }
$cluster_size = length($sorted_cluster_members)
# Query HAProxy nodes for proxy trusted networks
$haproxy_query = "enc_role='${haproxy_role}' and country='${facts['country']}' and region='${facts['region']}'"
$haproxy_members_raw = puppetdb_query(
"facts[certname,value] {
name = 'networking' and
certname in facts[certname] {
name = 'enc_role' and value = '${haproxy_role}'
} and
certname in facts[certname] {
name = 'country' and value = '${facts['country']}'
} and
certname in facts[certname] {
name = 'region' and value = '${facts['region']}'
}
}"
).map |$fact| { $fact['value']['ip'] }
$haproxy_ips = $haproxy_members_raw ? {
undef => [],
default => sort($haproxy_members_raw),
}
# Extract last 4 digits from hostname (e.g., ausyd1nxvm1234 -> 1234)
if $hostname =~ /^.*(\d{4})$/ {
$hostname_digits = $1
$calculated_node_id = Integer($hostname_digits)
} else {
fail("Unable to extract 4-digit node ID from hostname '${hostname}'. Hostname must end with 4 digits or specify node_id manually.")
}
# Use provided node_id or calculated one
$effective_node_id = $node_id ? {
undef => $calculated_node_id,
default => $node_id,
}
# Validate parameters
if $effective_node_id < 1 {
fail('node_id must be a positive integer')
}
if empty($domains) {
fail('At least one domain must be specified')
}
if !($my_fqdn in $sorted_cluster_members) {
fail("This node (${my_fqdn}) is not found in cluster members for role '${cluster_role}' in ${facts['country']}-${facts['region']}")
}
# Include sub-classes in dependency order
include stalwart::install
include stalwart::config
include stalwart::service
# Handle DNS records if requested
if $manage_dns_records {
if $loadbalancer_host {
# Only first node in cluster creates DNS records pointing to load balancer
if $my_fqdn == $sorted_cluster_members[0] {
class { 'stalwart::dns':
target_host => $loadbalancer_host,
}
}
} else {
# Current behavior: each server creates its own DNS records
include stalwart::dns
}
}
# Class ordering
Class['stalwart::install']
-> Class['stalwart::config']
-> Class['stalwart::service']
if $manage_dns_records {
Class['stalwart::service'] -> Class['stalwart::dns']
}
}
+11
View File
@@ -0,0 +1,11 @@
# @summary Manages Stalwart Mail Server package installation
#
# @api private
class stalwart::install {
assert_private()
# Install stalwart package (user/group created by package preinstall script)
package { 'stalwart':
ensure => $stalwart::package_ensure,
}
}
+26
View File
@@ -0,0 +1,26 @@
# @summary Manages Stalwart Mail Server service
#
# @api private
class stalwart::service {
assert_private()
# Service is installed by the RPM package
service { 'stalwart':
ensure => running,
enable => true,
subscribe => [
File[$stalwart::tls_cert],
File[$stalwart::tls_key],
],
}
# Add capability to bind to privileged ports (143, 443, 993)
systemd::manage_dropin { 'bind-capabilities.conf':
ensure => present,
unit => 'stalwart.service',
service_entry => {
'AmbientCapabilities' => 'CAP_NET_BIND_SERVICE',
},
notify => Service['stalwart'],
}
}
+296
View File
@@ -0,0 +1,296 @@
# Stalwart Mail Server Configuration
# Generated by Puppet - DO NOT EDIT MANUALLY
[server]
hostname = "<%= $service_hostname %>"
greeting = "Stalwart ESMTP"
[server.listener."smtp-relay"]
bind = ["<%= $bind_address %>:25"]
protocol = "smtp"
greeting = "Stalwart SMTP Relay"
<% if !$haproxy_ips.empty { -%>
[server.listener."smtp-relay".proxy]
trusted-networks = ["127.0.0.0/8", "::1"<% $haproxy_ips.each |$ip| { %>, "<%= $ip %>"<% } %>]
<% } -%>
<% if $enable_smtp_submission { -%>
[server.listener."submission"]
bind = ["<%= $bind_address %>:587"]
protocol = "smtp"
greeting = "Stalwart SMTP Submission"
tls.require = true
<% if !$haproxy_ips.empty { -%>
[server.listener."submission".proxy]
trusted-networks = ["127.0.0.0/8", "::1"<% $haproxy_ips.each |$ip| { %>, "<%= $ip %>"<% } %>]
<% } -%>
<% } -%>
<% if $enable_imap { -%>
[server.listener."imap"]
bind = ["<%= $bind_address %>:143"]
protocol = "imap"
<% if !$haproxy_ips.empty { -%>
[server.listener."imap".proxy]
trusted-networks = ["127.0.0.0/8", "::1"<% $haproxy_ips.each |$ip| { %>, "<%= $ip %>"<% } %>]
<% } -%>
<% } -%>
<% if $enable_imap_tls { -%>
[server.listener."imaps"]
bind = ["<%= $bind_address %>:993"]
protocol = "imap"
tls.implicit = true
<% if !$haproxy_ips.empty { -%>
[server.listener."imaps".proxy]
trusted-networks = ["127.0.0.0/8", "::1"<% $haproxy_ips.each |$ip| { %>, "<%= $ip %>"<% } %>]
<% } -%>
<% } -%>
<% if $enable_http { -%>
[server.listener."https"]
bind = ["<%= $bind_address %>:443"]
protocol = "http"
tls.implicit = true
<% if !$haproxy_ips.empty { -%>
[server.listener."https".proxy]
trusted-networks = ["127.0.0.0/8", "::1"<% $haproxy_ips.each |$ip| { %>, "<%= $ip %>"<% } %>]
<% } -%>
<% } -%>
[server.tls]
enable = true
implicit = false
certificate = "default"
[webadmin]
path = "<%= $webadmin_unpack_path %>"
auto-update = <%= $webadmin_auto_update %>
resource = "<%= $webadmin_resource_url %>"
# Cluster Configuration
[cluster]
node-id = <%= $effective_node_id %>
<% if $cluster_size > 1 { -%>
# Peer-to-peer coordination
[cluster.coordinator]
type = "peer-to-peer"
addr = "<%= $bind_address %>:11200"
advertise-addr = "<%= $advertise_address %>:11200"
<% $other_cluster_members.each |$node| { -%>
[[cluster.coordinator.peers]]
addr = "<%= $node %>:11200"
<% } -%>
# Cluster roles for 3-node setup
[cluster.roles.purge]
stores = ["1", "2", "3"]
accounts = ["1", "2"]
[cluster.roles.acme]
renew = ["1"]
[cluster.roles.metrics]
calculate = ["1", "2"]
push = ["1"]
[cluster.roles.push-notifications]
push-notifications = ["1", "3"]
[cluster.roles.fts-indexing]
fts-indexing = ["2", "3"]
[cluster.roles.bayes-training]
bayes-training = ["1"]
[cluster.roles.imip-processing]
imip-processing = ["2"]
[cluster.roles.calendar-alerts]
calendar-alerts = ["3"]
<% } -%>
# Storage Configuration
# PostgreSQL store for data, FTS, and in-memory
[store."postgresql"]
type = "postgresql"
host = "<%= $postgresql_host %>"
port = <%= $postgresql_port %>
database = "<%= $postgresql_database %>"
user = "<%= $postgresql_user %>"
password = "<%= $postgresql_password %>"
timeout = "15s"
[store."postgresql".tls]
enable = <%= $postgresql_ssl %>
allow-invalid-certs = false
[store."postgresql".pool]
max-connections = 10
[store."postgresql".purge]
frequency = "0 3 *"
# S3/Ceph-RGW store for blobs
[store."s3"]
type = "s3"
bucket = "<%= $s3_bucket %>"
region = "<%= $s3_region %>"
access-key = "<%= $s3_access_key %>"
secret-key = "<%= $s3_secret_key %>"
endpoint = "<%= $s3_endpoint %>"
timeout = "30s"
key-prefix = "<%= $s3_key_prefix %>"
compression = "lz4"
[store."s3".purge]
frequency = "30 5 *"
# Storage assignment
[storage]
data = "postgresql"
fts = "postgresql"
blob = "s3"
lookup = "postgresql"
directory = "internal"
in-memory = "postgresql"
# Directory configuration
[directory.internal]
type = "internal"
store = "postgresql"
# Authentication configuration
[authentication.fallback-admin]
user = "<%= $fallback_admin_user %>"
secret = "<%= pw_hash($fallback_admin_password.unwrap, 'SHA-512', 'stalwart') %>"
[authentication]
[authentication.directory]
directories = ["internal"]
# Authorization configuration
[authorization]
directory = "internal"
# JMAP configuration
[jmap]
directory = "internal"
[jmap.protocol]
request-max-size = 10485760
get.max-objects = 500
query.max-results = 5000
changes.max-results = 5000
upload.max-size = 50000000
upload.ttl = "1h"
# IMAP configuration
[imap]
directory = "internal"
[imap.protocol]
max-requests = 64
# Inbound rate limiting
[[queue.limiter.inbound]]
key = ["remote_ip"]
rate = "500/1s"
enable = true
# SMTP configuration for postfix relay
[session.data]
pipe.command = "sendmail"
pipe.arguments = ["-i", "-f", "{sender}", "{recipient}"]
# Outbound SMTP configuration
[queue]
path = "<%= $data_dir %>/queue"
[queue.schedule]
retry = ["2s", "5s", "1m", "5m", "15m", "30m", "1h", "2h"]
notify = ["1d", "3d"]
expire = "5d"
[session.extensions]
future-release = "7d"
# Relay configuration for postfix
[remote."postfix"]
address = "<%= $postfix_relay_host %>"
port = 25
protocol = "smtp"
# HTTP configuration
[server.http]
use-x-forwarded = false
permissive-cors = false
# Disable spam filtering (handled by postfix)
[session.ehlo]
reject-non-fqdn = false
[session.rcpt]
type = "internal"
store = "postgresql"
max-recipients = 25
[session.data]
max-messages = 10
max-message-size = 52428800
# TLS configuration
[certificate."default"]
cert = "%{file:<%= $tls_cert %>}%"
private-key = "%{file:<%= $tls_key %>}%"
default = true
# Logging configuration
[tracer]
type = "log"
level = "<%= $log_level %>"
ansi = false
multiline = true
[tracer.file]
path = "/var/log/stalwart/stalwart.log"
rotate = "daily"
keep = 30
# Report storage
[report]
path = "<%= $data_dir %>/reports"
hash = "sha256"
encrypt = false
# Metrics configuration
[metrics]
prometheus.enable = true
prometheus.port = 9090
# Queue routing configuration
[queue.strategy]
route = [ { if = "is_local_domain('', rcpt_domain)", then = "'local'" },
{ else = "'relay'" } ]
[queue.route."local"]
type = "local"
[queue.route."relay"]
type = "relay"
address = "<%= $postfix_relay_host %>"
port = 25
protocol = "smtp"
[queue.route."relay".tls]
implicit = false
allow-invalid-certs = false
+1
View File
@@ -10,6 +10,7 @@ class vmcluster::vmagent (
Stdlib::Absolutepath $vars_file = '/etc/default/vmagent',
String $consul_node_token = $facts['consul_node_token'],
Hash[String, Variant[String, Array[String]]] $options = {},
Hash[String, Hash] $static_targets = {},
) {
# if enabled, manage this service
@@ -35,3 +35,28 @@ scrape_configs:
- source_labels: [__meta_consul_tag_metrics_job]
target_label: job
action: replace
<% if @static_targets -%>
<% @static_targets.each do |job_name, config| -%>
- job_name: '<%= job_name %>'
static_configs:
<% config['targets'].each do |target| -%>
- targets: ['<%= target %>']
<% if config['labels'] -%>
labels:
<% config['labels'].each do |label_name, label_value| -%>
<%= label_name %>: '<%= label_value %>'
<% end -%>
<% end -%>
<% end -%>
<% if config['scrape_interval'] -%>
scrape_interval: <%= config['scrape_interval'] %>
<% end -%>
<% if config['metrics_path'] -%>
metrics_path: <%= config['metrics_path'] %>
<% end -%>
<% if config['scheme'] -%>
scheme: <%= config['scheme'] %>
<% end -%>
<% end -%>
<% end -%>
+4 -4
View File
@@ -1,12 +1,12 @@
# manage the root user
class profiles::accounts::root (
String $password,
Optional[Array[String]] $sshkeys = undef,
) {
if $sshkeys {
accounts::user { 'root':
sshkeys => $sshkeys,
}
accounts::user { 'root':
sshkeys => $sshkeys,
password => $password,
}
file {'/root/.config':
+3
View File
@@ -12,6 +12,9 @@ class profiles::base () {
# manage the puppet agent
include profiles::puppet::agent
include profiles::puppet::client
# k8s migration switch; ships disabled, flip its ::enabled boolean in
# hiera (node/role/common) to repoint a target onto puppet-on-k8s.
include profiles::puppet::migrate
# include the base profiles
include profiles::base::repos
+13
View File
@@ -0,0 +1,13 @@
class profiles::ceph::mds (
Boolean $ensure_running = true,
) {
if $ensure_running and $facts['is_ceph_mds'] {
$facts['ceph_services']['mds'].each |String $svc| {
service { $svc:
ensure => running,
enable => true,
}
}
}
}
+13
View File
@@ -0,0 +1,13 @@
class profiles::ceph::mgr (
Boolean $ensure_running = true,
) {
if $ensure_running and $facts['is_ceph_mgr'] {
$facts['ceph_services']['mgr'].each |String $svc| {
service { $svc:
ensure => running,
enable => true,
}
}
}
}
+13
View File
@@ -0,0 +1,13 @@
class profiles::ceph::mon (
Boolean $ensure_running = true,
) {
if $ensure_running and $facts['is_ceph_mon'] {
$facts['ceph_services']['mon'].each |String $svc| {
service { $svc:
ensure => running,
enable => true,
}
}
}
}
+13
View File
@@ -0,0 +1,13 @@
class profiles::ceph::osd (
Boolean $ensure_running = true,
) {
if $ensure_running and $facts['is_ceph_osd'] {
$facts['ceph_services']['osd'].each |String $svc| {
service { $svc:
ensure => running,
enable => true,
}
}
}
}
+4 -1
View File
@@ -68,7 +68,10 @@ class profiles::cobbler::config {
# export cnames for cobbler
if $is_cobbler_master {
profiles::dns::record { "${::facts['networking']['fqdn']}_${service_cname}_CNAME":
value => $::facts['networking']['hostname'],
# CNAME target must be a fully-qualified name (trailing dot): dns-updater
# parses the value with no $ORIGIN, so a bare label becomes root-absolute
# ("ausyd1nxvm2098.") and dead-ends in NXDOMAIN.
value => "${::facts['networking']['fqdn']}.",
type => 'CNAME',
record => "${service_cname}.",
zone => $::facts['networking']['domain'],
+6 -1
View File
@@ -28,7 +28,12 @@ class profiles::consul::client (
}
# if it is, find hosts, sort them so they dont cause changes every run
$servers_array = sort(query_nodes("enc_role='${members_role}' and region='${::facts['region']}'", 'networking.fqdn'))
$servers_array = sort(puppetdb_query(
"facts[certname] {
name = 'enc_role' and value = '${members_role}' and
certname in facts[certname] { name = 'region' and value = '${::facts['region']}' }
}"
).map |$fact| { $fact['certname'] })
# else use provided array from params
}else{

Some files were not shown because too many files have changed in this diff Show More