85 Commits

Author SHA1 Message Date
unkinben fd7fc8f41b refactor(ci): convert CRD schema generator to uv inline script
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/kubeconform Pipeline failed
2026-06-02 16:12:30 +10:00
unkinben 93581bfde2 feat(ci): add CRD schema generation for kubeconform validation
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/kubeconform Pipeline failed
Add scripts to extract OpenAPI v3 schemas from CRD definitions in all
kustomize overlays and write JSON schema files to ci/crd-schemas/ for
kubeconform validation. This allows kubeconform to validate CRD instances
(Elasticsearch, Kibana, CNPG Cluster, VictoriaMetrics, etc.) instead of
skipping or erroring on them.

- ci/generate-crd-schemas.py: extracts schemas from CRD YAML on stdin
- ci/generate-crd-schemas.sh: iterates overlays, pipes to Python script
- ci/validate-apps.sh, ci/validate-clusters.sh: add local schema-location fallback
- Makefile: add generate-schemas target
- add generate-schemas step to kubeconform woodpecker pipeline so schemas
2026-06-02 15:24:31 +10:00
unkinben 1b781e0885 feat(woodpecker): set workflow pod priority class to power (#175)
## Summary
Sets `WOODPECKER_BACKEND_K8S_PRIORITY_CLASS: power` on the Woodpecker agent so all CI pipeline pods are scheduled with the `power` PriorityClass (value 100, preemptionPolicy: Never).

This means pipeline pods can be evicted when the cluster is under pressure but won't preempt other workloads.

## Dependency
Requires the `power` PriorityClass to exist on the cluster — deploy PR #174 (priority-classes app) first.

## Test plan
- Trigger a pipeline run and confirm pods are created with `priorityClassName: power`
- `kubectl get pod -n woodpecker -o jsonpath='{.items[*].spec.priorityClassName}'`

Reviewed-on: #175
2026-05-26 23:58:57 +10:00
unkinben ede25a3858 feat(platform): add priority-classes app with low/power/medium/high classes (#174)
## Summary
- New `apps/base/priority-classes/` app with four `PriorityClass` objects managed via the `platform` ArgoCD project
- Adds `apps/overlays/*/priority-classes` to the platform ApplicationSet generator
- Adds `priority-classes` namespace to platform AppProject destinations (required even for cluster-scoped resources)

| Class | Value | PreemptionPolicy | Intent |
|---|---|---|---|
| `low` | 100 | Never | Background work; evictable, won't preempt others |
| `power` | 100 | Never | Compute-heavy but expendable (e.g. AI/ML workloads) |
| `medium` | 10000 | PreemptLowerPriority | Standard services |
| `high` | 100000 | PreemptLowerPriority | Critical services; preempts lower-priority pods |

`PriorityClass` is already in the platform project's `clusterResourceWhitelist` so no project policy changes were needed.

## Test plan
- ArgoCD syncs `platform-priority-classes` successfully
- `kubectl get priorityclasses low power medium high` shows all four classes

Reviewed-on: #174
2026-05-26 23:41:54 +10:00
unkinben f5f713fe86 feat(artifactapi): add open-webui/open-webui to ghcr immutable patterns (#173)
Part of #155 (prerequisite for open-webui deployment PR #172).

## Summary
- Adds `^open-webui/open-webui` to the `ghcr` remote's `immutable_patterns` in `remote-docker.yaml` so version-pinned open-webui image pulls are cached indefinitely through artifactapi

## Test plan
- artifactapi serves `ghcr.io/open-webui/open-webui:<version>` with `X-Artifact-Source: cache` on second fetch

Reviewed-on: #173
2026-05-26 23:28:27 +10:00
unkinben 3990fbfe06 feat(vault): switch to Kubernetes service registration (#171)
Replaces Consul service registration with the native Kubernetes provider so Vault labels its own pods with active/standby/perf-standby status without requiring a Consul dependency.

## Changes
- `values.yaml`: swap `service_registration "consul"` for `service_registration "kubernetes" {}`, add `VAULT_K8S_NAMESPACE` and `VAULT_K8S_POD_NAME` env vars via downward API
- `role_k8s-service-registration.yaml`: Role + RoleBinding granting the `vault` service account `get`/`update`/`patch` on pods
- `kustomization.yaml`: include new RBAC file

Reviewed-on: #171
2026-05-26 00:06:56 +10:00
unkinben d358098fff chore: update replication certs (#170)
- add replication certs for kanidm-0, kanidm-1 and kanidm-2

Reviewed-on: #170
2026-05-25 23:52:06 +10:00
unkinben 201e601737 feat: update kanidm replicaiton (#169)
- split to per-server configs
- remove init containers that attempted to automate the replication config
- add README.md

Reviewed-on: #169
2026-05-25 23:25:48 +10:00
unkinben d230d87ec9 feat(artifactapi): add conftest to GitHub generic remote cache (#168)
## Summary

- Adds `open-policy-agent/conftest/.*/conftest_.*_Linux_x86_64.tar.gz$` to the `github` remote immutable patterns in artifactapi

## Why

conftest v0.68.2 (https://github.com/open-policy-agent/conftest/releases/tag/v0.68.2) is now used for OPA policy checks in CI (see #167). Caching the release tarball in artifactapi reduces external dependency on GitHub during builds.

Reviewed-on: #168
2026-05-25 22:44:57 +10:00
unkinben 6497dab25e fix(puppet): remove explicit clusterIP: null from puppetdb Service (#166)
## Summary

- Removes `clusterIP: null` from the `puppetdb` Service spec

## Why

Setting `clusterIP: null` makes ArgoCD's desired state explicit about the field being null. Kubernetes assigns a real IP on creation and the field is immutable afterward. The null vs assigned-IP mismatch causes permanent OutOfSync on the puppetdb Service. Removing the field means ArgoCD no longer claims ownership of `clusterIP`, so the API server's value is authoritative.

Reviewed-on: #166
2026-05-25 22:44:24 +10:00
unkinben f403c6b05d fix(kanidm): add explicit group/kind/weight to TLSRoute refs (#165)
## Summary

- Adds `group: gateway.networking.k8s.io` and `kind: Gateway` to `parentRefs`
- Adds `group: ""`, `kind: Service`, and `weight: 1` to `backendRefs`

## Why

The Gateway API controller defaults these fields when creating/updating TLSRoute objects, so the live state always has them. ArgoCD diffs desired vs live by string comparison, causing the `kanidm` TLSRoute to show permanent OutOfSync. Same root cause as #162 (HTTPRoutes).

Reviewed-on: #165
2026-05-25 22:43:52 +10:00
unkinben ac8b8212bd fix(consul): normalize cpu limit to canonical string form (#164)
## Summary

- Changes `server.resources.limits.cpu` from `1000m` to `"1"` in consul Helm values

## Why

`1000m` (1000 milliCPU) is equivalent to `1` CPU, but Kubernetes normalizes the value to `"1"` when storing. ArgoCD diffs desired vs live by string comparison, so the mismatch causes a permanent OutOfSync on the `consul-server` StatefulSet. Same root cause as #163.

Reviewed-on: #164
2026-05-25 22:43:35 +10:00
unkinben dd282f59fb fix(litellm): normalize postgres cluster resource values (#163)
## Summary

- Changes `limits.memory` from `1024Mi` to `1Gi` (same value, canonical form)
- Changes `limits.cpu` from `1` (integer) to `"1"` (string, canonical form)

## Why

Kubernetes normalizes resource quantities on write — `1024Mi` becomes `1Gi` and integer `1` becomes string `"1"`. ArgoCD diffs by string comparison, so these equivalent values cause a permanent OutOfSync on the `litellm-postgres` Cluster.

Reviewed-on: #163
2026-05-24 23:30:10 +10:00
unkinben 1890dd4bda fix(gateways): add explicit group/kind/weight to all HTTPRoute refs (#162)
## Summary

- Adds `group: gateway.networking.k8s.io` and `kind: Gateway` to all `parentRefs` entries
- Adds `group: ""`, `kind: Service`, and `weight: 1` to all `backendRefs` entries
- Affects 9 HTTPRoute files across artifactapi, cattle-system, consul, kanidm, litellm, paperclip, puppet, and vault

## Why

ArgoCD diffs the desired manifest against the live Kubernetes object. The Gateway API controller defaults these fields when creating/updating objects, so the live state always has them — causing persistent OutOfSync for every HTTPRoute. Same root cause as #153 (certificateRefs).

## Test plan

- [ ] All affected ArgoCD applications show Synced after merge

Reviewed-on: #162
2026-05-24 20:32:37 +10:00
unkinben 6815b66010 fix(kanidm): use dockerhub image instead of ghcr.io (#161)
## Summary

- Changes both `config-init` init container and `kanidm` container images from `ghcr.io/kanidm/server:1.10.3` to `kanidm/server:1.10.3`

## Why

`kanidm/server` is published on Docker Hub, not ghcr.io. RKE2 rewrites dockerhub pulls through the artifactapi mirror automatically.

## Test plan

- [ ] Pods roll successfully after ArgoCD sync
- [ ] Verify kanidm cluster replication still healthy

Reviewed-on: #161
2026-05-24 20:27:21 +10:00
unkinben 7cbec33588 fix(artifactapi): move kanidm to dockerhub remote (#160)
## Summary

- Removes `^kanidm/` from the `ghcr` remote immutable_patterns
- Adds `^kanidm/` to the `dockerhub` remote immutable_patterns

## Why

`kanidm/server` is published on Docker Hub, not ghcr.io. Pulling via the `ghcr` cache was failing with 403 on anonymous token fetch → 502 Bad Gateway.

## Test plan

- [ ] `docker pull artifactapi.k8s.syd1.au.unkin.net/dockerhub/kanidm/server:1.10.3` succeeds after artifactapi redeploys

Reviewed-on: #160
2026-05-24 20:24:33 +10:00
unkinben 3756208ccd benvin/kanidm (#159)
Reviewed-on: #159
2026-05-24 19:55:22 +10:00
unkinben 6ce92e8ead benvin/artifactapi-mail-images (#158)
Reviewed-on: #158
2026-05-24 14:44:38 +10:00
unkinben af79d86db6 feat(artifactapi): cache stalwart webadmin zip (#157)
## Summary

- Adds \`stalwartlabs/webadmin/releases/latest/download/webadmin.zip\` to \`mutable_patterns\` in the \`github\` generic remote so the stalwart webadmin UI can be fetched through artifactapi rather than directly from GitHub.

## Notes

- Uses \`mutable_patterns\` (not \`immutable\`) because \`releases/latest\` resolves to whichever release is current and changes over time.
- Access URL: \`https://artifactapi.k8s.syd1.au.unkin.net/generic/github/stalwartlabs/webadmin/releases/latest/download/webadmin.zip\`

Reviewed-on: #157
2026-05-24 12:55:16 +10:00
unkinben 5f4c9225bb feat(artifactapi): add mail stack images to docker registry cache (#156)
- ghcr: stalwartlabs/stalwart (Stalwart mail server)
- dockerhub: rspamd/rspamd (spam filter), tozd/postfix (MTA gateway)

Reviewed-on: #156
2026-05-24 12:42:27 +10:00
unkinben cbc2c1cb9f fix(gateways): add explicit group: "" to all certificateRefs entries (#153)
The Gateway API admission server defaults certificateRefs[].group to ""
when it is omitted. ArgoCD diffed the desired state (no group field) against
the live state (group: "") and flagged every gateway as out of sync.

Fix: explicitly set group: "" in all certificateRefs entries so the
rendered manifest matches the API server's canonical form exactly.

Affected: artifactapi, cattle-system, consul, litellm, paperclip,
puppet (puppetboard + puppetdb), vault.

Reviewed-on: #153
2026-05-23 23:47:24 +10:00
unkinben c6f9893804 fix(argocd): add vault and consul to platform project destinations (#152)
Vault and consul namespaces were missing from the platform AppProject
allowed destinations, causing ArgoCD sync failures with:
  destination server 'https://kubernetes.default.svc' and namespace
  'vault' do not match any of the allowed destinations in project 'platform'

Reviewed-on: #152
2026-05-23 23:27:24 +10:00
unkinben e43fb742ad feat(artifactapi): add kanidm to ghcr docker immutable patterns (#151)
Prerequisite for kanidm deployment (PR benvin/kanidm).

Reviewed-on: #151
2026-05-23 23:09:38 +10:00
unkinben 11ac2ae91e feat(consul): deploy HashiCorp Consul 1.22.7 via Helm chart (5-replica cluster) (#149)
## Summary

- Deploys HashiCorp Consul 1.22.7 using Helm chart 1.9.7 with 5 server replicas
- Configuration modelled on production consul: \`datacenter=au-syd1\`, \`connect=true\`, \`raft_multiplier=10\`, HTTP on 8500, GRPC on 8502, HTTPS disabled
- 5-replica server cluster with \`bootstrapExpect=5\`
- 10Gi cephrbd-fast-delete PVC per server pod
- Gateway API: HTTPS gateway + HTTPRoute (443→consul-consul-ui:80→8500) at \`consul.k8s.syd1.au.unkin.net\`
- PodDisruptionBudget patched from \`policy/v1beta1\` to \`policy/v1\` (k8s 1.25+ compatibility)
- ArgoCD platform ApplicationSet updated to include consul overlay path
- Clients disabled (server-only deployment)
- ConnectInject disabled (can be enabled later for service mesh)

## Requires

- PR #147 (artifactapi: add hashicorp/consul to docker immutable patterns) to be merged first

## Test plan

- [ ] Sandbox tested in \`sandbox-consul\`: all 5 server pods 1/1 Running, cluster formed
- [ ] After merge: ArgoCD syncs consul namespace
- [ ] Verify \`consul.k8s.syd1.au.unkin.net\` is accessible via Gateway

Reviewed-on: #149
2026-05-23 22:40:49 +10:00
unkinben d2be521878 feat(vault): deploy HashiCorp Vault 2.0.1 via Helm chart (5-replica HA raft) (#148)
## Summary

- Deploys HashiCorp Vault 2.0.1 using Helm chart 0.32.0 in HA raft mode (5 replicas)
- Configuration modelled on production vault: \`disable_mlock=true\`, headless-DNS retry_join for all 5 pods
- IPC_LOCK capability added via \`server.statefulSet.securityContext.container\`
- 10Gi cephrbd-fast-delete PVC per pod via \`dataStorage\`
- Gateway API: HTTPS gateway + HTTPRoute (443→vault service port 8200) at \`vault.k8s.syd1.au.unkin.net\`
- ArgoCD platform ApplicationSet updated to include vault overlay path
- Injector disabled (no agent sidecar injection needed)

## Requires

- PR #147 (artifactapi: add hashicorp/vault to docker immutable patterns) to be merged first

## Test plan

- [ ] Sandbox tested in \`sandbox-vault\`: all 5 pods Running, raft cluster forming
- [ ] After merge: ArgoCD syncs vault namespace
- [ ] Operator runs \`vault operator init\` to initialize, then unseals all 5 nodes
- [ ] Verify \`vault.k8s.syd1.au.unkin.net\` is accessible via Gateway

Reviewed-on: #148
2026-05-23 22:39:41 +10:00
unkinben bcd4c1a722 feat(cert-manager): upgrade to v1.20.2 and enable Gateway API support (#150)
## Summary

- Upgrades cert-manager from v1.19.2 to v1.20.2
- Enables `enableGatewayAPI: true` via the `ControllerConfiguration` config block

## Why

cert-manager's Gateway API integration was not enabled. Without it, `cert-manager.io/*` annotations on Gateway resources are ignored and no certificates are issued. This is required for the consul and vault PRs (#148, #149) to have their TLS certs automatically provisioned from their Gateway annotations.

In v1.20.2, `ExperimentalGatewayAPISupport` is BETA and defaults to true — enabling `enableGatewayAPI` in the controller config activates the gateway-shim controller.

## Test plan

- [ ] cert-manager rolls out cleanly (v1.20.2 pods become Ready)
- [ ] After rollout, existing Gateway-annotated services (artifactapi, puppet, litellm) retain valid certs
- [ ] New Gateway resources with `cert-manager.io/cluster-issuer` annotations trigger Certificate creation

Reviewed-on: #150
2026-05-23 22:38:39 +10:00
unkinben 6d9530b1ee feat(artifactapi): add hashicorp/consul and hashicorp/vault to docker immutable patterns (#147)
## Summary

- Adds \`^hashicorp/consul\` and \`^hashicorp/vault\` to the dockerhub immutable_patterns in artifactapi's remote-docker.yaml
- Replaces the more specific \`^hashicorp/vault-secrets-operator\` pattern since \`^hashicorp/vault\` subsumes it
- Required for the benvin/vault and benvin/consul branches (vault:2.0.1 and consul:1.22.7)

## Test plan

- [ ] Verify artifactapi accepts requests for hashicorp/vault and hashicorp/consul images after merge

Reviewed-on: #147
2026-05-23 18:21:25 +10:00
unkinben dcea768c15 feat(woodpecker): upgrade to v3.14.1 (chart 3.6.3) (#146)
Reviewed-on: #146
2026-05-23 18:00:55 +10:00
unkinben e05f9bfd83 feat: increase litellm resources (#144)
finding litellm performance has dropped, crashed in multiple cases, and
then it had scaled to the maximum level using the majority of memory in
cluster.

- reduce the rate at which litellm autoscales
- increase the requests/limits to match usage

Reviewed-on: #144
2026-05-23 17:59:43 +10:00
unkinben 445d8b6e7e feat: add HTTP→HTTPS redirect to Gateway API services (#145)
Add port 80 HTTP listener and redirect HTTPRoute to artifactapi,
cattle-system (rancher), litellm, paperclip, and puppetboard — restoring
the redirect behaviour that existed on the previous nginx/traefik Ingress
resources.

Reviewed-on: #145
2026-05-23 17:34:07 +10:00
unkinben c2637da068 feat(artifactapi): migrate Ingress to Gateway API (#129)
## Summary

- Replace `Ingress` (nginx) with `Gateway` + `HTTPRoute` using `traefik-internal` GatewayClass
- TLS terminated at the Gateway listener; cert-manager provisions the certificate via `vault-issuer`
- external-dns annotations moved to the Gateway

## Notes

The original Ingress had nginx-specific annotations (`proxy-body-size: 10g`, `proxy-read-timeout: 600`) which are not portable to Gateway API. These can be re-introduced via a Traefik `Middleware` CRD if needed.

## Test plan

- [ ] ArgoCD syncs the app cleanly
- [ ] cert-manager issues the `artifactapi-tls` certificate
- [ ] external-dns creates the DNS record
- [ ] `https://artifactapi.k8s.syd1.au.unkin.net` is reachable

Reviewed-on: #129
2026-05-23 16:06:33 +10:00
unkinben 90ddd932fe feat(puppet): migrate puppetdb Ingress to Gateway API (#131)
## Summary

- Replace `Ingress` (nginx) with `Gateway` + `HTTPRoute` using `traefik-internal` GatewayClass
- TLS terminated at the Gateway listener; cert-manager provisions the certificate via `vault-issuer`
- external-dns annotations moved to the Gateway
- `ingress_puppetboard.yaml` is unchanged in this PR (separate PR)

## Test plan

- [ ] ArgoCD syncs the puppet app cleanly
- [ ] cert-manager issues the `puppetdb-tls` certificate
- [ ] external-dns creates the DNS record
- [ ] `https://puppetdb.k8s.syd1.au.unkin.net` is reachable

Reviewed-on: #131
2026-05-23 16:05:26 +10:00
unkinben 2c6d88aa6b feat(puppet): migrate puppetboard Ingress to Gateway API (#130)
## Summary

- Replace `Ingress` (nginx) with `Gateway` + `HTTPRoute` using `traefik-internal` GatewayClass
- TLS terminated at the Gateway listener; cert-manager provisions the certificate via `vault-issuer`
- external-dns annotations moved to the Gateway
- `ingress_puppetdb.yaml` is unchanged in this PR (separate PR)

## Test plan

- [ ] ArgoCD syncs the puppet app cleanly
- [ ] cert-manager issues the `puppetboard-tls` certificate
- [ ] external-dns creates the DNS record
- [ ] `https://puppetboard.k8s.syd1.au.unkin.net` is reachable

Reviewed-on: #130
2026-05-23 01:31:28 +10:00
unkinben 58368948d9 feat(paperclip): migrate Ingress to Gateway API (#133)
## Summary

- Replace `Ingress` (nginx) with `Gateway` + `HTTPRoute` using `traefik-internal` GatewayClass
- TLS terminated at the Gateway listener; cert-manager provisions the certificate via `vault-issuer`
- external-dns annotations moved to the Gateway

## Test plan

- [ ] ArgoCD syncs the paperclip app cleanly
- [ ] cert-manager issues the `paperclip-tls` certificate
- [ ] external-dns creates the DNS record
- [ ] `https://paperclip.k8s.syd1.au.unkin.net` is reachable

Reviewed-on: #133
2026-05-23 01:31:03 +10:00
unkinben 4f5c3f7ea0 feat(litellm): migrate Ingress to Gateway API (#134)
## Summary

- Replace `Ingress` (nginx) with `Gateway` + `HTTPRoute` using `traefik-internal` GatewayClass
- TLS terminated at the Gateway listener; cert-manager provisions the certificate via `vault-issuer`
- external-dns annotations moved to the Gateway

## Test plan

- [ ] ArgoCD syncs the litellm app cleanly
- [ ] cert-manager issues the `litellm-tls` certificate
- [ ] external-dns creates the DNS record
- [ ] `https://litellm.k8s.syd1.au.unkin.net` is reachable

Reviewed-on: #134
2026-05-23 01:29:54 +10:00
unkinben fd87cb96b5 feat(externaldns): upgrade to 1.21.1, fix sources for installed CRDs (#143)
## Changes

- Upgrade external-dns chart from 1.19.0 → 1.21.1 (app v0.19.0 → v0.21.0)
- Remove `gateway-tcproute` source — `TCPRoute` CRD is not installed, causing crash-loop
- Add `gateway-tlsroute` source — `TLSRoute` CRD is installed (Gateway API 1.5.1)

## Why

The pod was crash-looping every minute with `failed to list *v1alpha2.TCPRoute: the server could not find the requested resource` because the TCPRoute CRD doesn't exist in this cluster. TLSRoute was previously removed but its CRD does exist.

Reviewed-on: #143
2026-05-23 01:28:20 +10:00
unkinben d619f9195e benvin/externaldns_compatability (#142)
Reviewed-on: #142
2026-05-23 01:17:20 +10:00
unkinben 1944dbbfcd temp: enable debug logging on externaldns to diagnose TLSRoute sync timeout (#140)
Temporary: enable --log-level=debug to understand why the TLSRoute informer never reports HasSynced within the 1m interval. To be closed/reverted after root cause is found.
Reviewed-on: #140
2026-05-23 01:07:45 +10:00
unkinben 0940cc20f8 fix(traefik): listen on port 443 directly for Gateway API compatibility (#138)
## Problem

Gateway listeners with `port: 443` were rejected with `PortUnavailable: Cannot find entryPoint for Gateway: no matching entryPoint for port 443 and protocol "HTTPS"`.

Traefik matches Gateway listener ports against its internal entryPoint ports (pod-level), not the Service's `exposedPort`. The `websecure` entryPoint was configured on port `8443`, so port `443` listeners had no match.

## Fix

- `ports.websecure.port: 443` — Traefik now binds directly on 443
- `securityContext.capabilities.add: [NET_BIND_SERVICE]` — allows a non-root process to bind to privileged ports (<1024)

The Service `exposedPort` stays at `443`, so external connectivity is unchanged. All existing Gateway listeners (`port: 443`) are correct as-is.

Applies to both internal and external Traefik instances.

## Test plan

- [ ] Traefik pods restart cleanly
- [ ] `kubectl get gateway -A` shows listeners as `Programmed: True`
- [ ] `https://rancher.k8s.syd1.au.unkin.net` (already merged) is reachable

Reviewed-on: #138
2026-05-23 00:44:13 +10:00
unkinben 20ce2b1b92 feat(cattle-system): migrate rancher Ingress to Gateway API (#132)
## Summary

- Replace `Ingress` (nginx) with `Gateway` + `HTTPRoute` using `traefik-internal` GatewayClass
- TLS terminated at the Gateway listener; cert-manager provisions the certificate via `vault-issuer`
- external-dns annotations moved to the Gateway

## Test plan

- [ ] ArgoCD syncs the cattle-system app cleanly
- [ ] cert-manager issues the `rancher-tls` certificate
- [ ] external-dns creates the DNS record
- [ ] `https://rancher.k8s.syd1.au.unkin.net` is reachable

Reviewed-on: #132
2026-05-23 00:24:57 +10:00
unkinben 64dc5a0242 fix(traefik): add instance labels to GatewayClasses (#137)
## Problem

GatewayClasses were `Unknown` even after controllerName was fixed. The `kubernetesGateway` `labelSelector` applies to all watched resources, including GatewayClasses themselves. Since neither GatewayClass had a `traefik.io/instance` label, both Traefik instances filtered them out and never accepted them.

## Fix

- `gatewayclass-internal.yaml`: add `traefik.io/instance: internal`
- `gatewayclass-external.yaml`: add `traefik.io/instance: external`

## Test plan

- [ ] `kubectl get gatewayclass` shows both as `Accepted: True`

Reviewed-on: #137
2026-05-23 00:23:18 +10:00
unkinben 57c14d32c0 fix(traefik): remove invalid controllerName flag causing CrashLoopBackOff (#136)
## URGENT — Traefik pods are CrashLoopBackOff

The merged PR #135 added `--providers.kubernetesgateway.controllerName` as an `additionalArguments` entry. Traefik v3.7.0 does not support this flag and fails immediately on startup.

Old replica sets are still running (one pod each) but new pods cannot come up.

## Fix

- Remove `additionalArguments` from both `values-internal.yaml` and `values-external.yaml`
- Revert GatewayClass `controllerName` back to `traefik.io/gateway-controller` (the hardcoded Traefik default — no override mechanism exists in v3.7.0)

## After merge

GatewayClasses will remain `Unknown` until a separate solution for internal/external separation is implemented (the `labelSelector` approach needs further investigation).

Reviewed-on: #136
2026-05-22 23:58:56 +10:00
unkinben 2df359c4a9 fix(traefik): set controllerName on GatewayClasses and Traefik providers (#135)
## Problem

Both GatewayClasses (`traefik-internal`, `traefik-external`) were stuck as `Unknown`. Neither Traefik deployment had `controllerName` set in `kubernetesGateway`, so both defaulted to `traefik.io/gateway-controller` — which matched neither GatewayClass.

## Fix

- `gatewayclass-internal.yaml`: `controllerName: traefik.io/gateway-controller-internal`
- `gatewayclass-external.yaml`: `controllerName: traefik.io/gateway-controller-external`
- `values-internal.yaml`: added `controllerName: traefik.io/gateway-controller-internal`
- `values-external.yaml`: added `controllerName: traefik.io/gateway-controller-external`

## Test plan

- [ ] ArgoCD syncs traefik-system cleanly
- [ ] `kubectl get gatewayclass` shows both as `Accepted: True`

Reviewed-on: #135
2026-05-22 23:44:06 +10:00
unkinben f53a2dc4f8 fix: terraform_vault must be RFC1123 compliant (#128)
Reviewed-on: #128
2026-05-21 23:19:20 +10:00
unkinben c5dd3cc5cb feat: add terraform_vault role (#127)
this adds a service account that can be used to run the terraform_vault
workflows with, so that we can access the jwt to generate a token

Reviewed-on: #127
2026-05-21 23:13:48 +10:00
unkinben 462b2b3f4f feat(externaldns): add Gateway API sources for httproute, tlsroute, grpcroute, tcproute, udproute (#126)
Reviewed-on: #126
2026-05-18 00:11:33 +10:00
unkinben 73c9b3f603 fix(traefik): replace invalid controllername flag with labelSelector for v3 (#125)
Remove --providers.kubernetesgateway.controllername which does not exist in
Traefik v3, update GatewayClass controllerName to the standard v3 value, and
use labelSelector on each instance's kubernetesGateway provider to differentiate
internal vs external traffic.

Reviewed-on: #125
2026-05-18 00:03:12 +10:00
unkinben 9a01a9ef19 fix: enable gateway/ingress class on platform project (#124)
- add missing classes to platform required to deploy traefik system

Reviewed-on: #124
2026-05-17 23:56:12 +10:00
unkinben 53553ddcfd feat: deploy internal/external traefik routers (#119)
deploy traefik for internal and external applications. port forwarding
from the external routers will only occur to the IP of the
traefik-external service.

- traefik-internal and traefik-external added
- each is a different deployment

Reviewed-on: #119
2026-05-17 23:44:50 +10:00
unkinben 5d3ff3a0f4 feat(artifactapi): allow kubeconform and kustomize from GitHub (#123)
Adds immutable patterns for yannh/kubeconform and kubernetes-sigs/kustomize
to fix 403 Forbidden errors when downloading their Linux amd64 releases.

Reviewed-on: #123
2026-05-17 12:19:27 +10:00
unkinben c3002dc3c1 feat(artifactapi): allow kubecolor releases from GitHub (#122)
Reviewed-on: #122
2026-05-11 23:39:48 +10:00
unkinben 27db33536a feat(artifactapi): allow almalinux, debian, and fedora from Docker Hub (#121)
Reviewed-on: #121
2026-05-10 22:56:39 +10:00
unkinben 8a7068a1c4 feat(artifactapi): add argo-helm as a remote and virtual helm member (#120)
Reviewed-on: #120
2026-05-10 22:53:43 +10:00
unkinben 1cefd3b78e feat: change argocd crds source to artifactapi (#118)
- migrate argocd crds to come from the artifactapi service

Reviewed-on: #118
2026-05-10 21:12:44 +10:00
unkinben 842d774fc3 feat: deploy gatewayapi crds (#117)
- enable gateway api crds

Reviewed-on: #117
2026-05-10 21:05:56 +10:00
unkinben 4c8827ce35 feat: add traefik/gatewayapi (#116)
enable access to charts/containers/api-specs so that we can migrate from
nginx-ingress to gateway api and traefik

Reviewed-on: #116
2026-05-10 17:07:33 +10:00
unkinben 5e03215f4d chore: migrate reloader/reflector to virtual/helm (#115)
Reviewed-on: #115
2026-05-05 21:42:23 +10:00
unkinben 02ee82da1e feat: update vso to 1.3.0 (#114)
- updates the vso helm chart from 1.2.0 to 1.3.0

Reviewed-on: #114
2026-05-05 00:01:58 +10:00
unkinben 18c519f979 chore: remove hashicorp helm repo (#113)
- no longer required, this is in virtual/helm repo in artifactapi

Reviewed-on: #113
2026-05-03 23:51:44 +10:00
unkinben dd0e297c14 chore: mount vault CA for helm TLS trust and add ArgoCD self-management (#112)
- Patch argocd-repo-server to mount vault-ca-cert and set SSL_CERT_DIR
  so helm subprocesses trust the internal CA when pulling charts
- Add argocd Application pointing at clusters/au-syd1/bootstrap so
  ArgoCD manages its own install going forward

Reviewed-on: #112
2026-05-03 22:47:53 +10:00
unkinben 6fb98d66b0 chore: add vault CA cert to argocd-tls-certs-cm for helm TLS trust (#111)
Patches argocd-tls-certs-cm with the Vault CA chain so ArgoCD can
verify TLS when pulling Helm charts from artifactapi.k8s.syd1.au.unkin.net.

Reviewed-on: #111
2026-05-03 17:13:25 +10:00
unkinben bcea7df925 chore: swap vso to virtual helm repo (#109)
- testing if there will be any changes after merging, before merging all of them

Reviewed-on: #109
2026-05-03 16:49:53 +10:00
unkinben f45194282b chore: add resource requests/limits to workflows (#110)
have seen some contention on woodpecker jobs, because they are not being
scheduled correctly. we need to set correct limits/requests so that they
can be accurately scheduled.

- set limits/requests for all workflows

Reviewed-on: #110
2026-05-03 16:49:46 +10:00
unkinben 260b2d4364 chore: mount vault CA cert for Node.js TLS trust in paperclip (#108)
Mount the vault-ca-cert secret and set NODE_EXTRA_CA_CERTS so Node.js
trusts the internal CA chain when making outbound TLS connections.

Reviewed-on: #108
2026-05-03 00:10:08 +10:00
unkinben 156b545249 fix: set Host header on paperclip health probes to bypass hostname guard (#107)
The privateHostnameGuard middleware blocks requests where the Host header
is not in the allowlist. Kubelet httpGet probes use the pod IP as the
Host header, which is never in the allowlist. Setting Host: localhost
ensures probes are always permitted.

Reviewed-on: #107
2026-05-02 23:01:59 +10:00
unkinben 0883f327e9 chore: update trusted hostnames (#106)
- remove scheme from paperclip.k8s..
- add localhost (what probe is hitting)

Reviewed-on: #106
2026-05-02 22:40:21 +10:00
unkinben 04b7c04366 chore: fix livenessProbe for paperclip (#105)
Reviewed-on: #105
2026-05-02 22:28:52 +10:00
unkinben 9914186fd5 chore: additional papaerclip environemnt variables (#104)
https://github.com/paperclipai/paperclip/issues/3121
Reviewed-on: https://git.unkin.net/unkin/argocd-apps/pulls/104
2026-05-02 22:11:38 +10:00
unkinben f55b7065f1 fix: rename pgpooler to include rw (#103)
- undo previous change (target pgcluster name)
- actually rename the pgpooler

Reviewed-on: #103
2026-05-02 21:39:51 +10:00
unkinben 87a5a271c3 fix: set pgpooler name to include -rw (#102)
- this matches the credentials set for paperclip

Reviewed-on: #102
2026-05-02 21:35:23 +10:00
unkinben 8e7bc289f6 chore: enable access to paperclip namespace (#101)
Reviewed-on: #101
2026-05-02 21:30:59 +10:00
unkinben e156cd10bd feat: deploy paperclip to au-syd1 via ArgoCD (aitooling project) (#100)
Adds base manifests and au-syd1 overlay for Paperclip (AI agent
orchestration platform), following the litellm deployment pattern.
Updates aitooling ApplicationSet to include the paperclip path.

Closes #99

Reviewed-on: #100
2026-05-02 21:27:51 +10:00
unkinben fe714694bf chore: bump artifactapi to 2.7.2 (#98)
Reviewed-on: #98
2026-05-02 17:19:56 +10:00
unkinben 6138afb98b feat: add litellm-env configmap with STORE_MODEL_IN_DB=True (#97)
Reviewed-on: #97
2026-05-01 22:17:53 +10:00
unkinben 949ddb76e4 chore: litellm ooming (#95)
- update memory and cpu resources

Reviewed-on: #95
2026-05-01 21:54:00 +10:00
unkinben 5372914803 feat: add litellm to new aitooling ArgoCD project (#94)
Deploys LiteLLM proxy with CNPG PostgreSQL (3-instance HA), PgBouncer
pooler, and Redis cache. Introduces a dedicated aitooling AppProject and
ApplicationSet to keep AI tooling services separate from platform infra.

Reviewed-on: #94
2026-05-01 21:40:26 +10:00
unkinben 67bb54f092 fix: artifactapi remotes (#93)
- split each yaml into its own mount

Reviewed-on: #93
2026-05-01 21:17:16 +10:00
unkinben fc568dc8b5 feat: split artifactapi config into conf.d and update to v2.7.1 (#92)
Split monolithic remotes.yaml into per-type-package files under
resources/conf.d/ to align with artifactapi v2.7.1 directory loading.
Updated schema: virtuals/locals use dedicated top-level keys, type field
removed. Added helm remotes for all kustomize helmCharts repos and
OCI patterns to docker remotes. CONFIG_PATH now points to the directory.

Reviewed-on: #92
2026-04-30 23:59:01 +10:00
unkinben 1c2c18697d feat: update artifactapi to 2.3.0 (#91)
- update to mutable/immutable ttl/patterns
- reoganised paths to correct patterns

Reviewed-on: #91
2026-04-27 13:16:02 +10:00
unkinben f2af65bc92 fix: update include patterns (#90)
- hadolint and nvim were wrong, updating

Reviewed-on: #90
2026-04-26 16:20:53 +10:00
unkinben fdca69d99a feat: update github remotes (#89)
- enable access to all tagged, master and main branches as tar/gzip
- enable access to additional tool releases

Reviewed-on: #89
2026-04-26 16:05:57 +10:00
unkinben f80be18220 benvin/dockerremotes (#88)
Reviewed-on: #88
2026-04-25 22:34:59 +10:00
unkinben 3a6d93bc3c feat: add woodpeckerci/plugin-docker-buildx to WOODPECKER_PLUGINS_PRIVILEGED (#87)
Plugin is no longer privileged by default in Woodpecker; explicitly list
both the standard and latest-insecure variants.

Reviewed-on: #87
2026-04-25 20:48:46 +10:00
unkinben 7535d655fe feat: add docker remotes to artifactapi (#86)
- set artifactapi to specific version
- add dockerhub and ghcr to remotes

Reviewed-on: #86
2026-04-25 17:40:35 +10:00
unkinben 3fc9cfa41a feat: add claude-code remote (#85)
Reviewed-on: #85
2026-04-25 11:20:47 +10:00
127 changed files with 3512 additions and 457 deletions
+1
View File
@@ -1,2 +1,3 @@
manifests/
apps/**/charts/
ci/crd-schemas/
+1 -1
View File
@@ -6,7 +6,7 @@ repos:
- id: check-executables-have-shebangs
- id: check-json
- id: check-added-large-files
args: ['--maxkb=500']
args: ['--maxkb=2048']
- id: check-merge-conflict
- id: check-shebang-scripts-are-executable
- id: check-symlinks
+25
View File
@@ -2,7 +2,32 @@ when:
- event: pull_request
steps:
- name: generate-schemas
image: git.unkin.net/unkin/almalinux9-kubetest:20260319
commands:
- make generate-schemas
backend_options:
kubernetes:
serviceAccountName: default
resources:
requests:
memory: 512Mi
cpu: 1
limits:
memory: 2Gi
cpu: 2
- name: kubeconform
image: git.unkin.net/unkin/almalinux9-kubetest:20260319
commands:
- make kubeconform
backend_options:
kubernetes:
serviceAccountName: default
resources:
requests:
memory: 512Mi
cpu: 1
limits:
memory: 2Gi
cpu: 2
+10
View File
@@ -6,3 +6,13 @@ steps:
image: git.unkin.net/unkin/almalinux9-base:20260308
commands:
- uvx pre-commit run --all-files
backend_options:
kubernetes:
serviceAccountName: default
resources:
requests:
memory: 256Mi
cpu: 250m
limits:
memory: 1Gi
cpu: 1
+5
View File
@@ -11,6 +11,11 @@ kubeconform:
@ci/validate-apps.sh && \
ci/validate-clusters.sh
# Generate JSON schemas from CRD definitions for kubeconform
# Run when CRD versions change, then commit ci/crd-schemas/
generate-schemas:
@ci/generate-crd-schemas.sh
# Clean all generated manifests
clean:
@rm -rf manifests/
@@ -19,8 +19,8 @@ spec:
automountServiceAccountToken: true
containers:
- name: artifactapi
image: git.unkin.net/unkin/almalinux9-artifactapi:latest
imagePullPolicy: Always
image: git.unkin.net/unkin/artifactapi:v2.7.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
name: http
@@ -60,10 +60,30 @@ spec:
cpu: 100m
memory: 256Mi
volumeMounts:
- mountPath: /app/remotes.yaml
mountPropagation: None
- mountPath: /etc/artifactapi/conf.d/config.yaml
name: remotes-config
subPath: remotes.yaml
subPath: config.yaml
- mountPath: /etc/artifactapi/conf.d/local-generic.yaml
name: remotes-config
subPath: local-generic.yaml
- mountPath: /etc/artifactapi/conf.d/remote-alpine.yaml
name: remotes-config
subPath: remote-alpine.yaml
- mountPath: /etc/artifactapi/conf.d/remote-docker.yaml
name: remotes-config
subPath: remote-docker.yaml
- mountPath: /etc/artifactapi/conf.d/remote-generic.yaml
name: remotes-config
subPath: remote-generic.yaml
- mountPath: /etc/artifactapi/conf.d/remote-helm.yaml
name: remotes-config
subPath: remote-helm.yaml
- mountPath: /etc/artifactapi/conf.d/remote-rpm.yaml
name: remotes-config
subPath: remote-rpm.yaml
- mountPath: /etc/artifactapi/conf.d/virtual-helm.yaml
name: remotes-config
subPath: virtual-helm.yaml
restartPolicy: Always
volumes:
- configMap:
+1 -1
View File
@@ -5,7 +5,7 @@ metadata:
name: artifactapi-env
namespace: artifactapi
data:
CONFIG_PATH: /app/remotes.yaml
CONFIG_PATH: /etc/artifactapi/conf.d/
DBHOST: postgres-service
DBNAME: artifacts
DBPORT: "5432"
+37
View File
@@ -0,0 +1,37 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
labels:
traefik.io/instance: internal
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: artifactapi.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: artifactapi.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
name: artifactapi
namespace: artifactapi
spec:
gatewayClassName: traefik-internal
listeners:
- allowedRoutes:
namespaces:
from: Same
hostname: artifactapi.k8s.syd1.au.unkin.net
name: http
port: 80
protocol: HTTP
- allowedRoutes:
namespaces:
from: Same
hostname: artifactapi.k8s.syd1.au.unkin.net
name: https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: artifactapi-tls
mode: Terminate
+49
View File
@@ -0,0 +1,49 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: artifactapi-http-redirect
namespace: artifactapi
spec:
hostnames:
- artifactapi.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: artifactapi
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: artifactapi
namespace: artifactapi
spec:
hostnames:
- artifactapi.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: artifactapi
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: artifactapi-api
port: 80
weight: 1
matches:
- path:
type: PathPrefix
value: /
-32
View File
@@ -1,32 +0,0 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: artifactapi.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: artifactapi.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.0
nginx.ingress.kubernetes.io/proxy-body-size: 10g
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
name: artifactapi-ingress
namespace: artifactapi
spec:
ingressClassName: nginx
rules:
- host: artifactapi.k8s.syd1.au.unkin.net
http:
paths:
- backend:
service:
name: artifactapi-api
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- artifactapi.k8s.syd1.au.unkin.net
secretName: artifactapi-tls
+10 -2
View File
@@ -6,7 +6,8 @@ resources:
- artifactapi-deployment.yaml
- artifactapi-hpa.yaml
- configmap.yaml
- ingress.yaml
- gateway.yaml
- httproute.yaml
- namespace.yaml
- postgres-deployment.yaml
- pvc.yaml
@@ -18,6 +19,13 @@ resources:
configMapGenerator:
- name: remotes-config
files:
- resources/remotes.yaml
- resources/conf.d/config.yaml
- resources/conf.d/local-generic.yaml
- resources/conf.d/remote-generic.yaml
- resources/conf.d/remote-alpine.yaml
- resources/conf.d/remote-rpm.yaml
- resources/conf.d/remote-docker.yaml
- resources/conf.d/remote-helm.yaml
- resources/conf.d/virtual-helm.yaml
options:
disableNameSuffixHash: true
@@ -0,0 +1,3 @@
# Global artifactapi configuration.
# S3, Redis, and database connection settings are injected via environment variables.
# Add any top-level overrides here if needed.
@@ -0,0 +1,7 @@
locals:
local-generic:
package: "generic"
description: "Local generic file repository"
cache:
immutable_ttl: 0
mutable_ttl: 0
@@ -0,0 +1,10 @@
remotes:
alpine:
base_url: "https://dl-cdn.alpinelinux.org"
package: "alpine"
description: "Alpine Linux APK package repository"
immutable_patterns:
- ".*/x86_64/.*\\.apk$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
@@ -0,0 +1,103 @@
remotes:
ghcr:
base_url: "https://ghcr.io"
package: "docker"
description: "GitHub Container Registry"
immutable_patterns:
- "^cloudnative-pg/cloudnative-pg"
- "^emberstack/helm-charts"
- "^open-webui/open-webui"
- "^openvoxproject/"
- "^stakater/reloader"
- "^stalwartlabs/stalwart"
- "^voxpupuli/puppetboard"
- "^woodpecker-ci/helm"
cache:
immutable_ttl: 0
mutable_ttl: 300
dockerhub:
base_url: "https://registry-1.docker.io"
package: "docker"
description: "Docker Hub registry"
immutable_patterns:
- "^library/almalinux"
- "^library/busybox"
- "^library/debian"
- "^library/fedora"
- "^library/nginx"
- "^library/postgres"
- "^library/redis"
- "^beats/filebeat"
- "^bitnami/"
- "^curlimages/curl"
- "^emberstack/kubernetes-reflector"
- "^hashicorp/consul"
- "^hashicorp/vault"
- "^jfrog/"
- "^kanidm/"
- "^rancher/"
- "^rspamd/rspamd"
- "^tozd/postfix"
- "^traefik/"
- "^valkey/valkey"
- "^ubi9/ubi-minimal"
- "^victoriametrics/"
- "^woodpeckerci/"
cache:
immutable_ttl: 0
mutable_ttl: 300
quay:
base_url: "https://quay.io"
package: "docker"
description: "Quay.io container registry"
immutable_patterns:
- "^brancz/kube-rbac-proxy"
- "^cephcsi/cephcsi"
- "^jetstack/cert-manager-"
cache:
immutable_ttl: 0
mutable_ttl: 300
k8s-registry:
base_url: "https://registry.k8s.io"
package: "docker"
description: "Kubernetes container registry"
immutable_patterns:
- "^external-dns/external-dns"
- "^sig-storage/"
cache:
immutable_ttl: 0
mutable_ttl: 300
gitlab:
base_url: "https://registry.gitlab.com"
package: "docker"
description: "GitLab container registry"
immutable_patterns:
- "^purelb/purelb"
cache:
immutable_ttl: 0
mutable_ttl: 300
elastic:
base_url: "https://docker.elastic.co"
package: "docker"
description: "Elastic container registry"
immutable_patterns:
- "^eck/eck-operator"
cache:
immutable_ttl: 0
mutable_ttl: 300
gcr:
base_url: "https://gcr.io"
package: "docker"
description: "Google Container Registry"
immutable_patterns:
- "^k8s-staging-nfd/charts"
- "^k8s-staging-nfd/node-feature-discovery"
cache:
immutable_ttl: 0
mutable_ttl: 300
@@ -0,0 +1,132 @@
remotes:
github:
base_url: "https://github.com"
package: "generic"
description: "GitHub releases and files"
mutable_patterns:
- ".*/archive/refs/heads/.*.tar.gz$"
- "stalwartlabs/webadmin/releases/latest/download/webadmin.zip$"
immutable_patterns:
- ".*/archive/refs/tags/.*.tar.gz$"
- "ahmetb/kubectx/.*/kubectx_.*_linux_x86_64.tar.gz$"
- "ahmetb/kubectx/.*/kubens_.*_linux_x86_64.tar.gz$"
- "apple/foundationdb/.*/libfdb_c.x86_64.so$"
- "astral-sh/ruff/.*/ruff-x86_64-unknown-linux-gnu.tar.gz$"
- "astral-sh/uv/.*/uv-x86_64-unknown-linux-gnu.tar.gz$"
- "camptocamp/prometheus-puppetdb-exporter/.*/prometheus-puppetdb-exporter-.*.linux-amd64.tar.gz$"
- "coder/code-server/.*/code-server-.*-amd64.rpm$"
- "containernetworking/plugins/.*/cni-plugins-linux-amd64-.*.tgz"
- "dandavison/delta/.*/delta-.*-x86_64-unknown-linux-musl.tar.gz$"
- "ducaale/xh/.*/xh-.*-x86_64-unknown-linux-musl.tar.gz$"
- "etcd-io/etcd/.*/etcd-.*-linux-amd64.tar.gz$"
- "getsops/sops/.*/sops-v.*\\.linux\\.amd64$"
- "grafana/jsonnet-language-server/.*/jsonnet-language-server_.*_linux_amd64$"
- "gruntwork-io/boilerplate/.*/boilerplate_linux_amd64$"
- "gruntwork-io/terragrunt/.*terragrunt_linux_amd64.*"
- "hadolint/hadolint/.*/hadolint-linux-x86_64$"
- "helmfile/helmfile/.*/helmfile_.*_linux_amd64.tar.gz$"
- "helmfile/vals/.*/vals_.*_linux_amd64.tar.gz$"
- "jesseduffield/lazydocker/.*/lazydocker_.*_Linux_x86_64.tar.gz$"
- "kubecolor/kubecolor/.*/kubecolor_.*_linux_amd64.tar.gz$"
- "kubernetes-sigs/gateway-api/.*/standard-install.yaml$"
- "kubernetes-sigs/kustomize/.*/kustomize_.*_linux_amd64.tar.gz$"
- "lxc/incus/.*.tar.gz$"
- "mikefarah/yq/.*/yq_linux_amd64$"
- "neovim/neovim-releases/.*/nvim-linux-x86_64.tar.gz$"
- "neovim/neovim/.*/nvim-linux-x86_64.tar.gz$"
- "nzbgetcom/nzbget/.*/nzbget-.*.x86_64.rpm$"
- "onedr0p/exportarr/.*/exportarr_.*_linux_amd64.tar.gz$"
- "open-policy-agent/conftest/.*/conftest_.*_Linux_x86_64.tar.gz$"
- "openbao/openbao-plugins/.*/openbao-plugin-secrets-consul_linux_amd64_.*.tar.gz$"
- "openbao/openbao-plugins/.*/openbao-plugin-secrets-nomad_linux_amd64_.*.tar.gz$"
- "prometheus-community/bind_exporter/.*/bind_exporter-.*.linux-amd64.tar.gz$"
- "prometheus-community/pgbouncer_exporter/.*/pgbouncer_exporter-.*.linux-amd64.tar.gz$"
- "prometheus-community/postgres_exporter/.*/postgres_exporter-.*.linux-amd64.tar.gz$"
- "prometheus/node_exporter/.*/node_exporter-.*.linux-amd64.tar.gz$"
- "rancher/rke2/.*/rke2-images.linux-amd64.tar.zst$"
- "stalwartlabs/stalwart/.*/stalwart-cli-x86_64-unknown-linux-gnu.tar.gz$"
- "stalwartlabs/stalwart/.*/stalwart-foundationdb-x86_64-unknown-linux-gnu.tar.gz$"
- "stalwartlabs/stalwart/.*/stalwart-x86_64-unknown-linux-gnu.tar.gz$"
- "starship/starship/.*/starship-x86_64-unknown-linux-musl.tar.gz$"
- "stern/stern/.*/stern_.*_linux_amd64.tar.gz$"
- "terraform-linters/tflint/.*/tflint_linux_amd64.zip$"
- "tynany/frr_exporter/.*/frr_exporter-.*.linux-amd64.tar.gz$"
- "VictoriaMetrics/VictoriaLogs/.*/victoria-logs-linux-amd64-.*.tar.gz$"
- "VictoriaMetrics/VictoriaLogs/.*/vlutils-linux-amd64-.*.tar.gz$"
- "VictoriaMetrics/VictoriaMetrics/.*/victoria-logs-linux-amd64-.*.tar.gz$"
- "VictoriaMetrics/VictoriaMetrics/.*/victoria-metrics-linux-amd64-.*-cluster.tar.gz$"
- "VictoriaMetrics/VictoriaMetrics/.*/vlutils-linux-amd64-.*.tar.gz$"
- "VictoriaMetrics/VictoriaMetrics/.*/vmutils-linux-amd64-.*.tar.gz$"
- "xorpaul/g10k/.*/g10k-.*-linux-amd64.zip$"
- "yannh/kubeconform/.*/kubeconform-linux-amd64.tar.gz$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
github_user:
base_url: "https://raw.githubusercontent.com"
package: "generic"
description: "GitHub User Content"
immutable_patterns:
- "argoproj/argo-cd/.*.yaml$"
- "yannh/kubernetes-json-schema/master/.*.json$"
- "datreeio/CRDs-catalog/main/.*.json$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
gitea-dl:
base_url: "https://dl.gitea.com"
package: "generic"
description: "Gitea download site"
immutable_patterns:
- "act_runner/.*/act_runner-.*-linux-amd64$"
- "tea/.*/tea-.*-linux-amd64$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
hashicorp-releases:
base_url: "https://releases.hashicorp.com"
package: "generic"
description: "HashiCorp product releases"
immutable_patterns:
- "terraform/.*terraform_.*_linux_amd64\\.zip$"
- "terraform/.*terraform_.*_windows_amd64\\.zip$"
- "terraform/.*terraform_.*_darwin_amd64\\.zip$"
- "vault/.*vault_.*_linux_amd64\\.zip$"
- "vault/.*vault_.*_windows_amd64\\.zip$"
- "vault/.*vault_.*_darwin_amd64\\.zip$"
- "consul-cni/.*/consul-cni_.*_linux_amd64\\.zip$"
- "consul/.*/consul_.*_linux_amd64\\.zip$"
- "nomad-autoscaler/.*/nomad-autoscaler_.*_linux_amd64\\.zip$"
- "nomad/.*/nomad_.*_linux_amd64\\.zip$"
- "packer/.*/packer_.*_linux_amd64\\.zip$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
rarlab:
base_url: "https://www.rarlab.com"
package: "generic"
description: "RARLab"
immutable_patterns:
- "rar/rarlinux-x64-.*.tar.gz"
cache:
immutable_ttl: 0
mutable_ttl: 7200
claude-ai:
base_url: "https://downloads.claude.ai"
package: "generic"
description: "Anthropic Claude Code binary releases"
mutable_patterns:
- "claude-code-releases/.*/manifest.json$"
immutable_patterns:
- "claude-code-releases/.*/linux-x64/claude$"
- "claude-code-releases/.*/linux-arm64/claude$"
- "claude-code-releases/.*/linux-x64-musl/claude$"
- "claude-code-releases/.*/linux-arm64-musl/claude$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
@@ -0,0 +1,143 @@
remotes:
ceph-csi:
base_url: "https://ceph.github.io/csi-charts"
package: "helm"
description: "Ceph CSI driver Helm charts"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
cnpg:
base_url: "https://cloudnative-pg.github.io/charts"
package: "helm"
description: "CloudNativePG operator Helm charts"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
elastic-helm:
base_url: "https://helm.elastic.co"
package: "helm"
description: "Elastic stack Helm charts"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
external-dns:
base_url: "https://kubernetes-sigs.github.io/external-dns/"
package: "helm"
description: "ExternalDNS Helm charts"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
hashicorp-helm:
base_url: "https://helm.releases.hashicorp.com"
package: "helm"
description: "HashiCorp Helm charts (Vault Secrets Operator, etc.)"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
intel-helm:
base_url: "https://intel.github.io/helm-charts/"
package: "helm"
description: "Intel Helm charts (device plugins)"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
jetstack:
base_url: "https://charts.jetstack.io"
package: "helm"
description: "Jetstack Helm charts (cert-manager)"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
purelb:
base_url: "https://gitlab.com/api/v4/projects/20400619/packages/helm/stable"
package: "helm"
description: "PureLB load balancer Helm charts"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
rancher-stable:
base_url: "https://releases.rancher.com/server-charts/stable"
package: "helm"
description: "Rancher stable Helm charts"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
stakater:
base_url: "https://stakater.github.io/stakater-charts"
package: "helm"
description: "Stakater Helm charts (Reloader)"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
traefik:
base_url: "https://traefik.github.io/charts"
package: "helm"
description: "Traefik Helm charts"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
victoriametrics:
base_url: "https://victoriametrics.github.io/helm-charts/"
package: "helm"
description: "VictoriaMetrics observability Helm charts"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
argo-helm:
base_url: "https://argoproj.github.io/argo-helm"
package: "helm"
description: "Argo Project Helm charts (ArgoCD, Image Updater, Rollouts, etc.)"
check_mutable_updates: true
immutable_patterns:
- "\\.tgz$"
cache:
immutable_ttl: 0
mutable_ttl: 3600
@@ -0,0 +1,154 @@
remotes:
almalinux:
base_url: "https://gsl-syd.mm.fcix.net/almalinux"
package: "rpm"
description: "AlmaLinux RPM package repository"
immutable_patterns:
- ".*/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.sqlite.*$"
- ".*/repodata/.*\\.xml.*$"
- ".*/repodata/.*\\.yaml.*$"
- ".*/install.img"
- ".*/squashfs.img"
- ".*/updates.img"
- ".*/RPM-GPG-KEY-.*$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
ceph-reef:
base_url: "https://download.ceph.com/rpm-reef/"
package: "rpm"
description: "Ceph Reef 18"
immutable_patterns:
- ".*/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
ceph-squid:
base_url: "https://download.ceph.com/rpm-squid/"
package: "rpm"
description: "Ceph Squid 19"
immutable_patterns:
- ".*/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
ceph-tentacle:
base_url: "https://download.ceph.com/rpm-tentacle/"
package: "rpm"
description: "Ceph Tentacle 20"
immutable_patterns:
- ".*/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
epel:
base_url: "https://gsl-syd.mm.fcix.net/epel"
package: "rpm"
description: "EPEL (Extra Packages for Enterprise Linux)"
immutable_patterns:
- ".*/Everything/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.sqlite.*$"
- ".*/repodata/.*\\.xml.*$"
- ".*/repodata/.*\\.yaml.*$"
- "RPM-GPG-KEY-.*$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
fedora:
base_url: "https://gsl-syd.mm.fcix.net/fedora/linux"
package: "rpm"
description: "Fedora Linux RPM package repository"
immutable_patterns:
- "releases/.*/Everything/x86_64/.*\\.rpm$"
- "updates/.*/Everything/x86_64/.*\\.rpm$"
- "development/.*/Everything/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
frr:
base_url: "https://rpm.frrouting.org/repo"
package: "rpm"
description: "FRR RPM package repository"
immutable_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
mariadb:
base_url: "http://mariadb.mirror.digitalpacific.com.au/yum"
package: "rpm"
description: "MariaDB RPM package repository"
immutable_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
- ".*/RPM-GPG-KEY-.*$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
openvox:
base_url: "https://yum.voxpupuli.org"
package: "rpm"
description: "OpenVox RPM package repository"
immutable_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
- "GPG-KEY-.*$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
postgresql:
base_url: "https://download.postgresql.org/pub/repos/yum"
package: "rpm"
description: "PostgreSQL RPM package repository"
immutable_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
- ".*/RPM-GPG-KEY-.*$"
- ".*/PGDG-RPM-GPG-KEY-.*$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
rke2:
base_url: "https://rpm.rancher.io"
package: "rpm"
description: "RKE2 RPM package repository"
immutable_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
- "public.key$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
zfs:
base_url: "http://download.zfsonlinux.org"
package: "rpm"
description: "ZFS RPM package repository"
immutable_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
immutable_ttl: 0
mutable_ttl: 7200
@@ -0,0 +1,18 @@
virtuals:
helm:
package: "helm"
description: "Virtual repository merging all helm remotes — member order is priority order for duplicate chart+version"
members:
- ceph-csi
- cnpg
- elastic-helm
- external-dns
- hashicorp-helm
- intel-helm
- jetstack
- purelb
- rancher-stable
- stakater
- traefik
- victoriametrics
- argo-helm
@@ -1,287 +0,0 @@
remotes:
github:
base_url: "https://github.com"
type: "remote"
package: "generic"
description: "GitHub releases and files"
include_patterns:
- "apple/foundationdb/.*/libfdb_c.x86_64.so$"
- "astral-sh/ruff/.*/ruff-x86_64-unknown-linux-gnu.tar.gz$"
- "astral-sh/uv/.*/uv-x86_64-unknown-linux-gnu.tar.gz$"
- "camptocamp/prometheus-puppetdb-exporter/.*/prometheus-puppetdb-exporter-.*.linux-amd64.tar.gz$"
- "containernetworking/plugins/.*/cni-plugins-linux-amd64-.*.tgz"
- "ducaale/xh/.*/xh-.*-x86_64-unknown-linux-musl.tar.gz$"
- "etcd-io/etcd/.*/etcd-.*-linux-amd64.tar.gz$"
- "grafana/jsonnet-language-server/.*/jsonnet-language-server_.*_linux_amd64$"
- "gruntwork-io/boilerplate/.*/boilerplate_linux_amd64$"
- "gruntwork-io/terragrunt/.*terragrunt_linux_amd64.*"
- "helmfile/helmfile/.*/helmfile_.*_linux_amd64.tar.gz$"
- "helmfile/vals/.*/vals_.*_linux_amd64.tar.gz$"
- "lxc/incus/.*.tar.gz$"
- "nzbgetcom/nzbget/.*/nzbget-.*.x86_64.rpm$"
- "onedr0p/exportarr/.*/exportarr_.*_linux_amd64.tar.gz$"
- "openbao/openbao-plugins/.*/openbao-plugin-secrets-consul_linux_amd64_.*.tar.gz$"
- "openbao/openbao-plugins/.*/openbao-plugin-secrets-nomad_linux_amd64_.*.tar.gz$"
- "prometheus/node_exporter/.*/node_exporter-.*.linux-amd64.tar.gz$"
- "prometheus-community/bind_exporter/.*/bind_exporter-.*.linux-amd64.tar.gz$"
- "prometheus-community/pgbouncer_exporter/.*/pgbouncer_exporter-.*.linux-amd64.tar.gz$"
- "prometheus-community/postgres_exporter/.*/postgres_exporter-.*.linux-amd64.tar.gz$"
- "rancher/rke2/.*/rke2-images.linux-amd64.tar.zst$"
- "stalwartlabs/stalwart/.*/stalwart-cli-x86_64-unknown-linux-gnu.tar.gz$"
- "stalwartlabs/stalwart/.*/stalwart-foundationdb-x86_64-unknown-linux-gnu.tar.gz$"
- "stalwartlabs/stalwart/.*/stalwart-x86_64-unknown-linux-gnu.tar.gz$"
- "terraform-linters/tflint/.*/tflint_linux_amd64.zip$"
- "tynany/frr_exporter/.*/frr_exporter-.*.linux-amd64.tar.gz$"
- "VictoriaMetrics/VictoriaLogs/.*/victoria-logs-linux-amd64-.*.tar.gz$"
- "VictoriaMetrics/VictoriaLogs/.*/vlutils-linux-amd64-.*.tar.gz$"
- "VictoriaMetrics/VictoriaMetrics/.*/victoria-logs-linux-amd64-.*.tar.gz$"
- "VictoriaMetrics/VictoriaMetrics/.*/victoria-metrics-linux-amd64-.*-cluster.tar.gz$"
- "VictoriaMetrics/VictoriaMetrics/.*/vlutils-linux-amd64-.*.tar.gz$"
- "VictoriaMetrics/VictoriaMetrics/.*/vmutils-linux-amd64-.*.tar.gz$"
- "xorpaul/g10k/.*/g10k-.*-linux-amd64.zip$"
cache:
file_ttl: 0
index_ttl: 0
github_user:
base_url: "https://raw.githubusercontent.com"
type: "remote"
package: "generic"
description: "GitHub User Content"
include_patterns:
- "argoproj/argo-cd/.*.yaml$"
- "yannh/kubernetes-json-schema/master/.*.json$"
- "datreeio/CRDs-catalog/main/.*.json$"
cache:
file_ttl: 0
index_ttl: 0
gitea-dl:
base_url: "https://dl.gitea.com"
type: "remote"
package: "generic"
description: "Gitea download site"
include_patterns:
- "act_runner/.*/act_runner-.*-linux-amd64$"
- "tea/.*/tea-.*-linux-amd64$"
cache:
file_ttl: 0
index_ttl: 0
hashicorp-releases:
base_url: "https://releases.hashicorp.com"
type: "remote"
package: "generic"
description: "HashiCorp product releases"
include_patterns:
- "terraform/.*terraform_.*_linux_amd64\\.zip$"
- "terraform/.*terraform_.*_windows_amd64\\.zip$"
- "terraform/.*terraform_.*_darwin_amd64\\.zip$"
- "vault/.*vault_.*_linux_amd64\\.zip$"
- "vault/.*vault_.*_windows_amd64\\.zip$"
- "vault/.*vault_.*_darwin_amd64\\.zip$"
- "consul-cni/.*/consul-cni_.*_linux_amd64\\.zip$"
- "consul/.*/consul_.*_linux_amd64\\.zip$"
- "nomad-autoscaler/.*/nomad-autoscaler_.*_linux_amd64\\.zip$"
- "nomad/.*/nomad_.*_linux_amd64\\.zip$"
- "packer/.*/packer_.*_linux_amd64\\.zip$"
cache:
file_ttl: 0
index_ttl: 0
rarlab:
base_url: "https://www.rarlab.com"
type: "remote"
package: "generic"
description: "RARLab"
include_patterns:
- "rar/rarlinux-x64-.*.tar.gz"
cache:
file_ttl: 0
index_ttl: 0
alpine:
base_url: "https://dl-cdn.alpinelinux.org"
type: "remote"
package: "alpine"
description: "Alpine Linux APK package repository"
include_patterns:
- ".*/x86_64/.*\\.apk$"
cache:
file_ttl: 0
index_ttl: 7200
almalinux:
base_url: "https://gsl-syd.mm.fcix.net/almalinux"
type: "remote"
package: "rpm"
description: "AlmaLinux RPM package repository"
include_patterns:
- ".*/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.sqlite.*$"
- ".*/repodata/.*\\.xml.*$"
- ".*/repodata/.*\\.yaml.*$"
- ".*/install.img"
- ".*/squashfs.img"
- ".*/updates.img"
- ".*/RPM-GPG-KEY-.*$"
cache:
file_ttl: 0
index_ttl: 7200
ceph-reef:
base_url: "https://download.ceph.com/rpm-reef/"
type: "remote"
package: "rpm"
description: "Ceph Reef 18"
include_patterns:
- ".*/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
file_ttl: 0
index_ttl: 7200
ceph-squid:
base_url: "https://download.ceph.com/rpm-squid/"
type: "remote"
package: "rpm"
description: "Ceph Squid 19"
include_patterns:
- ".*/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
file_ttl: 0
index_ttl: 7200
ceph-tentacle:
base_url: "https://download.ceph.com/rpm-tentacle/"
type: "remote"
package: "rpm"
description: "Ceph Tentacle 20"
include_patterns:
- ".*/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
file_ttl: 0
index_ttl: 7200
epel:
base_url: "https://gsl-syd.mm.fcix.net/epel"
type: "remote"
package: "rpm"
description: "EPEL (Extra Packages for Enterprise Linux)"
include_patterns:
- ".*/Everything/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.sqlite.*$"
- ".*/repodata/.*\\.xml.*$"
- ".*/repodata/.*\\.yaml.*$"
- "RPM-GPG-KEY-.*$"
cache:
file_ttl: 0
index_ttl: 7200
fedora:
base_url: "https://gsl-syd.mm.fcix.net/fedora/linux"
type: "remote"
package: "rpm"
description: "Fedora Linux RPM package repository"
include_patterns:
- "releases/.*/Everything/x86_64/.*\\.rpm$"
- "updates/.*/Everything/x86_64/.*\\.rpm$"
- "development/.*/Everything/x86_64/.*\\.rpm$"
- ".*/noarch/.*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
file_ttl: 0
index_ttl: 7200
frr:
base_url: "https://rpm.frrouting.org/repo"
type: "remote"
package: "rpm"
description: "FRR RPM package repository"
include_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
file_ttl: 0
index_ttl: 7200
mariadb:
base_url: "http://mariadb.mirror.digitalpacific.com.au/yum"
type: "remote"
package: "rpm"
description: "MariaDB RPM package repository"
include_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
- ".*/RPM-GPG-KEY-.*$"
cache:
file_ttl: 0
index_ttl: 7200
openvox:
base_url: "https://yum.voxpupuli.org"
type: "remote"
package: "rpm"
description: "OpenVox RPM package repository"
include_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
- "GPG-KEY-.*$"
cache:
file_ttl: 0
index_ttl: 7200
postgresql:
base_url: "https://download.postgresql.org/pub/repos/yum"
type: "remote"
package: "rpm"
description: "PostgreSQL RPM package repository"
include_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
- ".*/RPM-GPG-KEY-.*$"
- ".*/PGDG-RPM-GPG-KEY-.*$"
cache:
file_ttl: 0
index_ttl: 7200
rke2:
base_url: "https://rpm.rancher.io"
type: "remote"
package: "rpm"
description: "RKE2 RPM package repository"
include_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
- "public.key$"
cache:
file_ttl: 0
index_ttl: 7200
zfs:
base_url: "http://download.zfsonlinux.org"
type: "remote"
package: "rpm"
description: "ZFS RPM package repository"
include_patterns:
- ".*\\.rpm$"
- ".*/repodata/.*\\.xml.*$"
cache:
file_ttl: 0
index_ttl: 7200
local-generic:
type: "local"
package: "generic"
description: "Local generic file repository"
cache:
file_ttl: 0
index_ttl: 0
+37
View File
@@ -0,0 +1,37 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
labels:
traefik.io/instance: internal
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: rancher.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: rancher.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: "198.18.200.4"
name: rancher
namespace: cattle-system
spec:
gatewayClassName: traefik-internal
listeners:
- allowedRoutes:
namespaces:
from: Same
hostname: rancher.k8s.syd1.au.unkin.net
name: http
port: 80
protocol: HTTP
- allowedRoutes:
namespaces:
from: Same
hostname: rancher.k8s.syd1.au.unkin.net
name: https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: rancher-tls
mode: Terminate
+49
View File
@@ -0,0 +1,49 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: rancher-http-redirect
namespace: cattle-system
spec:
hostnames:
- rancher.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: rancher
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: rancher
namespace: cattle-system
spec:
hostnames:
- rancher.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: rancher
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: rancher
port: 80
weight: 1
matches:
- path:
type: PathPrefix
value: /
-29
View File
@@ -1,29 +0,0 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rancher
namespace: cattle-system
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: rancher.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: rancher.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: "198.18.200.0"
spec:
ingressClassName: nginx
tls:
- hosts:
- rancher.k8s.syd1.au.unkin.net
secretName: rancher-tls
rules:
- host: rancher.k8s.syd1.au.unkin.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: rancher
port:
number: 80
+2 -1
View File
@@ -6,4 +6,5 @@ resources:
- namespace.yaml
- vaultauth.yaml
- vaultstaticsecret.yaml
- ingress.yaml
- gateway.yaml
- httproute.yaml
+53
View File
@@ -0,0 +1,53 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: consul
namespace: consul
labels:
app.kubernetes.io/name: consul
app.kubernetes.io/instance: consul
traefik.io/instance: internal
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: consul.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
cert-manager.io/alt-names: consul.service.consul
external-dns.alpha.kubernetes.io/hostname: consul.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
spec:
gatewayClassName: traefik-internal
listeners:
- name: http
port: 80
protocol: HTTP
hostname: consul.k8s.syd1.au.unkin.net
allowedRoutes:
namespaces:
from: Same
- name: https
port: 443
protocol: HTTPS
hostname: consul.k8s.syd1.au.unkin.net
allowedRoutes:
namespaces:
from: Same
tls:
mode: Terminate
certificateRefs:
- group: ""
kind: Secret
name: consul-tls
- name: consul-svc
port: 443
protocol: HTTPS
hostname: consul.service.consul
allowedRoutes:
namespaces:
from: Same
tls:
mode: Terminate
certificateRefs:
- group: ""
kind: Secret
name: consul-tls
+83
View File
@@ -0,0 +1,83 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: consul-http-redirect
namespace: consul
labels:
app.kubernetes.io/name: consul
app.kubernetes.io/instance: consul
spec:
hostnames:
- consul.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: consul
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: consul
namespace: consul
labels:
app.kubernetes.io/name: consul
app.kubernetes.io/instance: consul
spec:
hostnames:
- consul.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: consul
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: consul-ui
port: 80
weight: 1
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: consul-svc
namespace: consul
labels:
app.kubernetes.io/name: consul
app.kubernetes.io/instance: consul
spec:
hostnames:
- consul.service.consul
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: consul
sectionName: consul-svc
rules:
- backendRefs:
- group: ""
kind: Service
name: consul-ui
port: 80
weight: 1
matches:
- path:
type: PathPrefix
value: /
+8
View File
@@ -0,0 +1,8 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- gateway.yaml
- httproute.yaml
+5
View File
@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: consul
@@ -7,12 +7,12 @@ resources:
helmCharts:
- name: intel-device-plugins-operator
repo: https://intel.github.io/helm-charts/
repo: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm
version: "0.35.0"
releaseName: intel-device-plugins-operator
namespace: inteldeviceplugins-system
- name: intel-device-plugins-gpu
repo: https://intel.github.io/helm-charts/
repo: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm
version: "0.34.1"
releaseName: intel-gpu-plugin
namespace: inteldeviceplugins-system
+32
View File
@@ -0,0 +1,32 @@
# kanidm
Single-replica kanidm identity server deployment.
## Initial setup
After the pod starts for the first time, generate the admin and idm_admin credentials:
```bash
kubectl exec -n kanidm kanidm-0 -- /sbin/kanidmd recover-account admin
kubectl exec -n kanidm kanidm-0 -- /sbin/kanidmd recover-account idm_admin
```
## Adding replication
If replication is needed in the future:
1. Scale the StatefulSet to 3 replicas and add `podAntiAffinity` to spread across nodes.
2. Add a `[replication]` section to `configmap.yaml` per pod (origin is pod-specific:
`repl://kanidm-N.kanidm-headless.kanidm.svc.cluster.local:8444`).
3. Add the replication port (8444) back to the StatefulSet container ports and headless service.
4. Restore `rbac.yaml` for the cert-publisher sidecar, or exchange certificates manually:
```bash
# On each pod, get its replication certificate
kubectl exec -n kanidm kanidm-0 -- /sbin/kanidmd renew-replication-certificate
# Add each peer's certificate to the other pods' configs under:
# [replication."repl://<peer-fqdn>:8444"]
# type = "mutual-pull"
# partner_cert = "<cert>"
```
+26
View File
@@ -0,0 +1,26 @@
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: kanidm-tls
namespace: kanidm
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
spec:
secretName: kanidm-tls
issuerRef:
kind: ClusterIssuer
name: vault-issuer
commonName: auth.unkin.net
dnsNames:
- auth.unkin.net
- au.auth.unkin.net
- kanidm.k8s.syd1.au.unkin.net
- kanidm.kanidm.svc.cluster.local
- kanidm-0.kanidm-headless.kanidm.svc.cluster.local
- kanidm-1.kanidm-headless.kanidm.svc.cluster.local
- kanidm-2.kanidm-headless.kanidm.svc.cluster.local
privateKey:
algorithm: RSA
size: 4096
+30
View File
@@ -0,0 +1,30 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: kanidm
namespace: kanidm
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
traefik.io/instance: internal
annotations:
external-dns.alpha.kubernetes.io/hostname: kanidm.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
spec:
gatewayClassName: traefik-internal
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Same
- name: https-passthrough
port: 443
protocol: TLS
tls:
mode: Passthrough
allowedRoutes:
namespaces:
from: Same
+29
View File
@@ -0,0 +1,29 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: kanidm-http-redirect
namespace: kanidm
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
spec:
hostnames:
- kanidm.k8s.syd1.au.unkin.net
- auth.unkin.net
- au.auth.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: kanidm
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
+27
View File
@@ -0,0 +1,27 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- serviceaccount.yaml
- certificate.yaml
- service.yaml
- statefulset.yaml
- poddisruptionbudget.yaml
- gateway.yaml
- httproute.yaml
- tlsroute.yaml
configMapGenerator:
- name: kanidm-config
namespace: kanidm
options:
disableNameSuffixHash: true
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
files:
- server-0.toml=resources/server-0.toml
- server-1.toml=resources/server-1.toml
- server-2.toml=resources/server-2.toml
+5
View File
@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: kanidm
+15
View File
@@ -0,0 +1,15 @@
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: kanidm
namespace: kanidm
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
spec:
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
+37
View File
@@ -0,0 +1,37 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: kanidm-repl
namespace: kanidm
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kanidm-repl-certs"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kanidm-repl
namespace: kanidm
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
subjects:
- kind: ServiceAccount
name: kanidm
namespace: kanidm
roleRef:
kind: Role
name: kanidm-repl
apiGroup: rbac.authorization.k8s.io
+27
View File
@@ -0,0 +1,27 @@
version = "2"
domain = "auth.unkin.net"
origin = "https://auth.unkin.net"
bindaddress = "[::]:8443"
db_path = "/data/kanidm.db"
db_arc_size = 2048
tls_chain = "/data/tls/tls.crt"
tls_key = "/data/tls/tls.key"
log_level = "info"
[online_backup]
path = "/data/backups/"
schedule = "0 22 * * *"
versions = 7
[replication]
origin = "repl://kanidm-0.kanidm-headless.kanidm.svc.cluster.local:8444"
bindaddress = "[::]:8444"
[replication."repl://kanidm-1.kanidm-headless.kanidm.svc.cluster.local:8444"]
type = "mutual-pull"
partner_cert = "MIIB-TCCAZ-gAwIBAgIRASqOpORz60wiv7wF_7oBOxQwCgYIKoZIzj0EAwIwTDEtMCsGA1UEAwwkMmE4ZWE0ZTQtNzNlYi00YzIyLWJmYmMtMDVmZmJhMDEzYjE0MRswGQYDVQQKDBJLYW5pZG0gUmVwbGljYXRpb24wHhcNMjYwNTI1MTMyODM5WhcNMzAwNTI1MTMyODM5WjBMMS0wKwYDVQQDDCQyYThlYTRlNC03M2ViLTRjMjItYmZiYy0wNWZmYmEwMTNiMTQxGzAZBgNVBAoMEkthbmlkbSBSZXBsaWNhdGlvbjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFQP3zpFRt7TCOhzrUpOJBojn-sC2LmqZUub8P2ymVdIQbmoAyh4Q8Me0hNWJFyuFDnnqO06dt5I2iv0910-X6KjYjBgMCAGA1UdJQEB_wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATA8BgNVHREENTAzgjFrYW5pZG0tMS5rYW5pZG0taGVhZGxlc3Mua2FuaWRtLnN2Yy5jbHVzdGVyLmxvY2FsMAoGCCqGSM49BAMCA0gAMEUCIGjl58U6apcDjMEPIca8Wwg_JMfuMvV-uVcJI49Gl_9GAiEA2tFdb9rnFeBI7mwysScf5UsmY3ZziMD3UVm1vWN2IKs"
[replication."repl://kanidm-2.kanidm-headless.kanidm.svc.cluster.local:8444"]
type = "mutual-pull"
partner_cert = "MIIB-TCCAZ-gAwIBAgIRAeFGUAJbCkJ2vzf_Vv4qjeUwCgYIKoZIzj0EAwIwTDEtMCsGA1UEAwwkZTE0NjUwMDItNWIwYS00Mjc2LWJmMzctZmY1NmZlMmE4ZGU1MRswGQYDVQQKDBJLYW5pZG0gUmVwbGljYXRpb24wHhcNMjYwNTI1MTMyOTEwWhcNMzAwNTI1MTMyOTEwWjBMMS0wKwYDVQQDDCRlMTQ2NTAwMi01YjBhLTQyNzYtYmYzNy1mZjU2ZmUyYThkZTUxGzAZBgNVBAoMEkthbmlkbSBSZXBsaWNhdGlvbjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCrncHSbDNSV3_aOSZ14plbVfrvSXQQL9MOqvrDKlf_Q6WbcA8OrTUjs3Jt0Q2beWjC3Z5-5c9fGu8M_k2iVWf-jYjBgMCAGA1UdJQEB_wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATA8BgNVHREENTAzgjFrYW5pZG0tMi5rYW5pZG0taGVhZGxlc3Mua2FuaWRtLnN2Yy5jbHVzdGVyLmxvY2FsMAoGCCqGSM49BAMCA0gAMEUCIQDHY5Yl-bhDTuJaYnHSMSiSAEWPrDcRVzvfmOJukuJ1QQIgSwgyeSG3K0MY87DI1RDYAdZlpP1YOK3Yatj7-YSXPC0"
+27
View File
@@ -0,0 +1,27 @@
version = "2"
domain = "auth.unkin.net"
origin = "https://auth.unkin.net"
bindaddress = "[::]:8443"
db_path = "/data/kanidm.db"
db_arc_size = 2048
tls_chain = "/data/tls/tls.crt"
tls_key = "/data/tls/tls.key"
log_level = "info"
[online_backup]
path = "/data/backups/"
schedule = "0 22 * * *"
versions = 7
[replication]
origin = "repl://kanidm-1.kanidm-headless.kanidm.svc.cluster.local:8444"
bindaddress = "[::]:8444"
[replication."repl://kanidm-0.kanidm-headless.kanidm.svc.cluster.local:8444"]
type = "mutual-pull"
partner_cert = "MIIB-jCCAZ-gAwIBAgIRAVKuoPDpF0IBnvFjCwdK41EwCgYIKoZIzj0EAwIwTDEtMCsGA1UEAwwkNTJhZWEwZjAtZTkxNy00MjAxLTllZjEtNjMwYjA3NGFlMzUxMRswGQYDVQQKDBJLYW5pZG0gUmVwbGljYXRpb24wHhcNMjYwNTI1MTMzNzQ5WhcNMzAwNTI1MTMzNzQ5WjBMMS0wKwYDVQQDDCQ1MmFlYTBmMC1lOTE3LTQyMDEtOWVmMS02MzBiMDc0YWUzNTExGzAZBgNVBAoMEkthbmlkbSBSZXBsaWNhdGlvbjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGejqjk0Eet-RILHI236wHYqISdnPlebqnkuUTh4W2mCzkmqKibyjxGIUOs8LBrUeTR2DxVR1VV6H2rYQk2wdROjYjBgMCAGA1UdJQEB_wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATA8BgNVHREENTAzgjFrYW5pZG0tMC5rYW5pZG0taGVhZGxlc3Mua2FuaWRtLnN2Yy5jbHVzdGVyLmxvY2FsMAoGCCqGSM49BAMCA0kAMEYCIQCSkFj2A-KVWv2tKJLFzb18J5eWWKtsvWewZTn-FVnRnQIhAKJbt84IoZ9oXxgfp0VOLyVZiAgUgwMFS6JOfno3D-Nw"
[replication."repl://kanidm-2.kanidm-headless.kanidm.svc.cluster.local:8444"]
type = "mutual-pull"
partner_cert = "MIIB-TCCAZ-gAwIBAgIRAeFGUAJbCkJ2vzf_Vv4qjeUwCgYIKoZIzj0EAwIwTDEtMCsGA1UEAwwkZTE0NjUwMDItNWIwYS00Mjc2LWJmMzctZmY1NmZlMmE4ZGU1MRswGQYDVQQKDBJLYW5pZG0gUmVwbGljYXRpb24wHhcNMjYwNTI1MTMyOTEwWhcNMzAwNTI1MTMyOTEwWjBMMS0wKwYDVQQDDCRlMTQ2NTAwMi01YjBhLTQyNzYtYmYzNy1mZjU2ZmUyYThkZTUxGzAZBgNVBAoMEkthbmlkbSBSZXBsaWNhdGlvbjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCrncHSbDNSV3_aOSZ14plbVfrvSXQQL9MOqvrDKlf_Q6WbcA8OrTUjs3Jt0Q2beWjC3Z5-5c9fGu8M_k2iVWf-jYjBgMCAGA1UdJQEB_wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATA8BgNVHREENTAzgjFrYW5pZG0tMi5rYW5pZG0taGVhZGxlc3Mua2FuaWRtLnN2Yy5jbHVzdGVyLmxvY2FsMAoGCCqGSM49BAMCA0gAMEUCIQDHY5Yl-bhDTuJaYnHSMSiSAEWPrDcRVzvfmOJukuJ1QQIgSwgyeSG3K0MY87DI1RDYAdZlpP1YOK3Yatj7-YSXPC0"
+27
View File
@@ -0,0 +1,27 @@
version = "2"
domain = "auth.unkin.net"
origin = "https://auth.unkin.net"
bindaddress = "[::]:8443"
db_path = "/data/kanidm.db"
db_arc_size = 2048
tls_chain = "/data/tls/tls.crt"
tls_key = "/data/tls/tls.key"
log_level = "info"
[online_backup]
path = "/data/backups/"
schedule = "0 22 * * *"
versions = 7
[replication]
origin = "repl://kanidm-2.kanidm-headless.kanidm.svc.cluster.local:8444"
bindaddress = "[::]:8444"
[replication."repl://kanidm-0.kanidm-headless.kanidm.svc.cluster.local:8444"]
type = "mutual-pull"
partner_cert = "MIIB-jCCAZ-gAwIBAgIRAVKuoPDpF0IBnvFjCwdK41EwCgYIKoZIzj0EAwIwTDEtMCsGA1UEAwwkNTJhZWEwZjAtZTkxNy00MjAxLTllZjEtNjMwYjA3NGFlMzUxMRswGQYDVQQKDBJLYW5pZG0gUmVwbGljYXRpb24wHhcNMjYwNTI1MTMzNzQ5WhcNMzAwNTI1MTMzNzQ5WjBMMS0wKwYDVQQDDCQ1MmFlYTBmMC1lOTE3LTQyMDEtOWVmMS02MzBiMDc0YWUzNTExGzAZBgNVBAoMEkthbmlkbSBSZXBsaWNhdGlvbjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGejqjk0Eet-RILHI236wHYqISdnPlebqnkuUTh4W2mCzkmqKibyjxGIUOs8LBrUeTR2DxVR1VV6H2rYQk2wdROjYjBgMCAGA1UdJQEB_wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATA8BgNVHREENTAzgjFrYW5pZG0tMC5rYW5pZG0taGVhZGxlc3Mua2FuaWRtLnN2Yy5jbHVzdGVyLmxvY2FsMAoGCCqGSM49BAMCA0kAMEYCIQCSkFj2A-KVWv2tKJLFzb18J5eWWKtsvWewZTn-FVnRnQIhAKJbt84IoZ9oXxgfp0VOLyVZiAgUgwMFS6JOfno3D-Nw"
[replication."repl://kanidm-1.kanidm-headless.kanidm.svc.cluster.local:8444"]
type = "mutual-pull"
partner_cert = "MIIB-TCCAZ-gAwIBAgIRASqOpORz60wiv7wF_7oBOxQwCgYIKoZIzj0EAwIwTDEtMCsGA1UEAwwkMmE4ZWE0ZTQtNzNlYi00YzIyLWJmYmMtMDVmZmJhMDEzYjE0MRswGQYDVQQKDBJLYW5pZG0gUmVwbGljYXRpb24wHhcNMjYwNTI1MTMyODM5WhcNMzAwNTI1MTMyODM5WjBMMS0wKwYDVQQDDCQyYThlYTRlNC03M2ViLTRjMjItYmZiYy0wNWZmYmEwMTNiMTQxGzAZBgNVBAoMEkthbmlkbSBSZXBsaWNhdGlvbjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFQP3zpFRt7TCOhzrUpOJBojn-sC2LmqZUub8P2ymVdIQbmoAyh4Q8Me0hNWJFyuFDnnqO06dt5I2iv0910-X6KjYjBgMCAGA1UdJQEB_wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATA8BgNVHREENTAzgjFrYW5pZG0tMS5rYW5pZG0taGVhZGxlc3Mua2FuaWRtLnN2Yy5jbHVzdGVyLmxvY2FsMAoGCCqGSM49BAMCA0gAMEUCIGjl58U6apcDjMEPIca8Wwg_JMfuMvV-uVcJI49Gl_9GAiEA2tFdb9rnFeBI7mwysScf5UsmY3ZziMD3UVm1vWN2IKs"
+43
View File
@@ -0,0 +1,43 @@
---
apiVersion: v1
kind: Service
metadata:
name: kanidm
namespace: kanidm
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
spec:
type: ClusterIP
ports:
- name: https
port: 8443
targetPort: https
protocol: TCP
selector:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
---
apiVersion: v1
kind: Service
metadata:
name: kanidm-headless
namespace: kanidm
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
spec:
type: ClusterIP
clusterIP: None
ports:
- name: https
port: 8443
targetPort: https
protocol: TCP
- name: replication
port: 8444
targetPort: replication
protocol: TCP
selector:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
+9
View File
@@ -0,0 +1,9 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: kanidm
namespace: kanidm
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
+115
View File
@@ -0,0 +1,115 @@
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kanidm
namespace: kanidm
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
spec:
serviceName: kanidm-headless
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
template:
metadata:
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
spec:
serviceAccountName: kanidm
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
topologyKey: kubernetes.io/hostname
securityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
fsGroup: 1000
initContainers:
- name: config-init
image: busybox:1.36
command: ["/bin/sh", "-c"]
args:
- cp "/config-template/server-${POD_NAME##*-}.toml" /config/server.toml
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
volumeMounts:
- name: config-template
mountPath: /config-template
readOnly: true
- name: config
mountPath: /config
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
containers:
- name: kanidm
image: kanidm/server:1.10.3
command: ["/sbin/kanidmd"]
args: ["server", "-c", "/config/server.toml"]
ports:
- name: https
containerPort: 8443
protocol: TCP
- name: replication
containerPort: 8444
protocol: TCP
volumeMounts:
- name: data
mountPath: /data
- name: config
mountPath: /config
readOnly: true
- name: tls
mountPath: /data/tls
readOnly: true
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 1Gi
cpu: 500m
readinessProbe:
tcpSocket:
port: 8443
initialDelaySeconds: 15
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8443
initialDelaySeconds: 30
periodSeconds: 30
volumes:
- name: config-template
configMap:
name: kanidm-config
- name: config
emptyDir: {}
- name: tls
secret:
secretName: kanidm-tls
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
storageClassName: cephrbd-fast-delete
resources:
requests:
storage: 10Gi
+26
View File
@@ -0,0 +1,26 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: TLSRoute
metadata:
name: kanidm
namespace: kanidm
labels:
app.kubernetes.io/name: kanidm
app.kubernetes.io/instance: kanidm
spec:
hostnames:
- kanidm.k8s.syd1.au.unkin.net
- auth.unkin.net
- au.auth.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: kanidm
sectionName: https-passthrough
rules:
- backendRefs:
- group: ""
kind: Service
name: kanidm
port: 8443
weight: 1
+91
View File
@@ -0,0 +1,91 @@
---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: litellm-postgres
namespace: litellm
spec:
affinity:
podAntiAffinityType: preferred
bootstrap:
initdb:
database: litellm
encoding: UTF8
localeCType: C
localeCollate: C
owner: litellm
secret:
name: postgres-credentials
enablePDB: true
enableSuperuserAccess: false
failoverDelay: 0
imageName: ghcr.io/cloudnative-pg/postgresql:17-minimal-trixie
instances: 3
logLevel: info
maxSyncReplicas: 0
minSyncReplicas: 0
monitoring:
customQueriesConfigMap:
- key: queries
name: cnpg-default-monitoring
disableDefaultQueries: false
enablePodMonitor: false
postgresql:
parameters:
archive_mode: "on"
archive_timeout: 5min
dynamic_shared_memory_type: posix
effective_cache_size: 256MB
full_page_writes: "on"
log_destination: csvlog
log_directory: /controller/log
log_filename: postgres
log_rotation_age: "0"
log_rotation_size: "0"
log_truncate_on_rotation: "false"
logging_collector: "on"
max_connections: "200"
max_parallel_workers: "16"
max_replication_slots: "16"
max_worker_processes: "16"
shared_buffers: 128MB
shared_memory_type: mmap
ssl_max_protocol_version: TLSv1.3
ssl_min_protocol_version: TLSv1.3
wal_keep_size: 256MB
wal_level: logical
wal_log_hints: "on"
wal_receiver_timeout: 5s
wal_sender_timeout: 5s
syncReplicaElectionConstraint:
enabled: false
primaryUpdateMethod: restart
primaryUpdateStrategy: unsupervised
probes:
liveness:
isolationCheck:
connectionTimeout: 1000
enabled: true
requestTimeout: 1000
replicationSlots:
highAvailability:
enabled: true
slotPrefix: _cnpg_
synchronizeReplicas:
enabled: true
updateInterval: 30
resources:
limits:
cpu: "1"
memory: 1Gi
requests:
cpu: 250m
memory: 512Mi
smartShutdownTimeout: 180
startDelay: 3600
stopDelay: 1800
storage:
resizeInUseVolumes: true
size: 10Gi
storageClass: cephrbd-fast-delete
switchoverDelay: 3600
+33
View File
@@ -0,0 +1,33 @@
---
apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
name: litellm-postgres-pooler
namespace: litellm
spec:
cluster:
name: litellm-postgres
instances: 2
pgbouncer:
parameters:
default_pool_size: "100"
max_client_conn: "400"
paused: false
poolMode: session
template:
metadata:
labels:
app: pooler
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- pooler
topologyKey: kubernetes.io/hostname
containers: []
type: rw
+71
View File
@@ -0,0 +1,71 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: litellm
namespace: litellm
spec:
selector:
matchLabels:
app: litellm
template:
metadata:
annotations:
reloader.stakater.com/auto: "true"
labels:
app: litellm
spec:
containers:
- name: litellm
image: docker.litellm.ai/berriai/litellm-database:main-stable
imagePullPolicy: Always
args:
- --config
- /app/config.yaml
- --port
- "4000"
- --num_workers
- "8"
ports:
- containerPort: 4000
name: http
protocol: TCP
envFrom:
- secretRef:
name: litellm-credentials
- configMapRef:
name: litellm-env
livenessProbe:
httpGet:
path: /health/liveliness
port: 4000
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health/readiness
port: 4000
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
resources:
limits:
cpu: "2"
memory: 8Gi
requests:
cpu: 250m
memory: 6Gi
volumeMounts:
- mountPath: /app/config.yaml
name: config
subPath: config.yaml
restartPolicy: Always
volumes:
- name: config
configMap:
name: litellm-config
+37
View File
@@ -0,0 +1,37 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
labels:
traefik.io/instance: internal
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: litellm.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: litellm.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
name: litellm
namespace: litellm
spec:
gatewayClassName: traefik-internal
listeners:
- allowedRoutes:
namespaces:
from: Same
hostname: litellm.k8s.syd1.au.unkin.net
name: http
port: 80
protocol: HTTP
- allowedRoutes:
namespaces:
from: Same
hostname: litellm.k8s.syd1.au.unkin.net
name: https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: litellm-tls
mode: Terminate
+41
View File
@@ -0,0 +1,41 @@
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: litellm-hpa
namespace: litellm
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: litellm
minReplicas: 2
maxReplicas: 4
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
behavior:
scaleUp:
stabilizationWindowSeconds: 0
selectPolicy: Max
policies:
- type: Percent
value: 100
periodSeconds: 60
- type: Pods
value: 4
periodSeconds: 30
scaleDown:
stabilizationWindowSeconds: 300
selectPolicy: Min
policies:
- type: Percent
value: 30
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60
+49
View File
@@ -0,0 +1,49 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: litellm-http-redirect
namespace: litellm
spec:
hostnames:
- litellm.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: litellm
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: litellm
namespace: litellm
spec:
hostnames:
- litellm.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: litellm
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: litellm
port: 4000
weight: 1
matches:
- path:
type: PathPrefix
value: /
+29
View File
@@ -0,0 +1,29 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cnpg_cluster.yaml
- cnpg_pooler.yaml
- deployment.yaml
- hpa.yaml
- gateway.yaml
- httproute.yaml
- namespace.yaml
- redis-deployment.yaml
- redis-pvc.yaml
- services.yaml
- vaultauth.yaml
- vaultstaticsecret.yaml
configMapGenerator:
- name: litellm-config
files:
- config.yaml=resources/config.yaml
options:
disableNameSuffixHash: true
- name: litellm-env
literals:
- STORE_MODEL_IN_DB=True
options:
disableNameSuffixHash: true
+5
View File
@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: litellm
+67
View File
@@ -0,0 +1,67 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: litellm
spec:
replicas: 1
selector:
matchLabels:
app: redis
strategy:
type: Recreate
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
imagePullPolicy: IfNotPresent
command:
- redis-server
- --save
- "20"
- "1"
ports:
- containerPort: 6379
name: redis
protocol: TCP
livenessProbe:
exec:
command:
- redis-cli
- ping
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
exec:
command:
- redis-cli
- ping
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 50m
memory: 128Mi
volumeMounts:
- mountPath: /data
mountPropagation: None
name: data
restartPolicy: Always
volumes:
- name: data
persistentVolumeClaim:
claimName: litellm-redis-data
+14
View File
@@ -0,0 +1,14 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: litellm-redis-data
namespace: litellm
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: cephrbd-fast-delete
volumeMode: Filesystem
+15
View File
@@ -0,0 +1,15 @@
model_list: []
router_settings:
redis_host: redis-service
redis_port: 6379
general_settings:
use_redis_transaction_buffer: true
litellm_settings:
cache: true
cache_params:
type: redis
host: redis-service
port: 6379
+34
View File
@@ -0,0 +1,34 @@
---
apiVersion: v1
kind: Service
metadata:
name: litellm
namespace: litellm
spec:
internalTrafficPolicy: Cluster
ports:
- name: http
port: 4000
protocol: TCP
targetPort: http
selector:
app: litellm
sessionAffinity: None
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
namespace: litellm
spec:
internalTrafficPolicy: Cluster
ports:
- name: redis
port: 6379
protocol: TCP
targetPort: redis
selector:
app: redis
sessionAffinity: None
type: ClusterIP
+18
View File
@@ -0,0 +1,18 @@
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: default
namespace: litellm
spec:
allowedNamespaces:
- litellm
kubernetes:
audiences:
- vault
role: default
serviceAccount: default
tokenExpirationSeconds: 600
method: kubernetes
mount: k8s/au/syd1
vaultConnectionRef: vso-system/default
+34
View File
@@ -0,0 +1,34 @@
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: postgres-credentials
namespace: litellm
spec:
destination:
create: true
name: postgres-credentials
overwrite: true
hmacSecretData: true
mount: kv
path: kubernetes/namespace/litellm/default/postgres-credentials
refreshAfter: 5m
type: kv-v2
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: litellm-credentials
namespace: litellm
spec:
destination:
create: true
name: litellm-credentials
overwrite: true
hmacSecretData: true
mount: kv
path: kubernetes/namespace/litellm/default/litellm-credentials
refreshAfter: 5m
type: kv-v2
vaultAuthRef: default
+91
View File
@@ -0,0 +1,91 @@
---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: paperclip-postgres
namespace: paperclip
spec:
affinity:
podAntiAffinityType: preferred
bootstrap:
initdb:
database: paperclip
encoding: UTF8
localeCType: C
localeCollate: C
owner: paperclip
secret:
name: postgres-credentials
enablePDB: true
enableSuperuserAccess: false
failoverDelay: 0
imageName: ghcr.io/cloudnative-pg/postgresql:17-minimal-trixie
instances: 3
logLevel: info
maxSyncReplicas: 0
minSyncReplicas: 0
monitoring:
customQueriesConfigMap:
- key: queries
name: cnpg-default-monitoring
disableDefaultQueries: false
enablePodMonitor: false
postgresql:
parameters:
archive_mode: "on"
archive_timeout: 5min
dynamic_shared_memory_type: posix
effective_cache_size: 256MB
full_page_writes: "on"
log_destination: csvlog
log_directory: /controller/log
log_filename: postgres
log_rotation_age: "0"
log_rotation_size: "0"
log_truncate_on_rotation: "false"
logging_collector: "on"
max_connections: "200"
max_parallel_workers: "16"
max_replication_slots: "16"
max_worker_processes: "16"
shared_buffers: 128MB
shared_memory_type: mmap
ssl_max_protocol_version: TLSv1.3
ssl_min_protocol_version: TLSv1.3
wal_keep_size: 256MB
wal_level: logical
wal_log_hints: "on"
wal_receiver_timeout: 5s
wal_sender_timeout: 5s
syncReplicaElectionConstraint:
enabled: false
primaryUpdateMethod: restart
primaryUpdateStrategy: unsupervised
probes:
liveness:
isolationCheck:
connectionTimeout: 1000
enabled: true
requestTimeout: 1000
replicationSlots:
highAvailability:
enabled: true
slotPrefix: _cnpg_
synchronizeReplicas:
enabled: true
updateInterval: 30
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
smartShutdownTimeout: 180
startDelay: 3600
stopDelay: 1800
storage:
resizeInUseVolumes: true
size: 10Gi
storageClass: cephrbd-fast-delete
switchoverDelay: 3600
+33
View File
@@ -0,0 +1,33 @@
---
apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
name: paperclip-pooler-rw
namespace: paperclip
spec:
cluster:
name: paperclip-postgres
instances: 2
pgbouncer:
parameters:
default_pool_size: "100"
max_client_conn: "400"
paused: false
poolMode: session
template:
metadata:
labels:
app: pooler
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- pooler
topologyKey: kubernetes.io/hostname
containers: []
type: rw
+108
View File
@@ -0,0 +1,108 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: paperclip
namespace: paperclip
spec:
selector:
matchLabels:
app: paperclip
template:
metadata:
labels:
app: paperclip
spec:
containers:
- name: paperclip
image: ghcr.io/paperclipai/paperclip:latest
imagePullPolicy: Always
ports:
- containerPort: 3100
name: http
protocol: TCP
env:
- name: PORT
value: "3100"
- name: PAPERCLIP_BIND
value: custom
- name: PAPERCLIP_BIND_HOST
value: 0.0.0.0
- name: PAPERCLIP_API_URL
value: https://paperclip.k8s.syd1.au.unkin.net
- name: BETTER_AUTH_BASE_URL
value: https://paperclip.k8s.syd1.au.unkin.net
- name: PAPERCLIP_ALLOWED_HOSTNAMES
value: paperclip.k8s.syd1.au.unkin.net,localhost
- name: PAPERCLIP_HOME
value: /paperclip
- name: PAPERCLIP_INSTANCE_ID
value: default
- name: PAPERCLIP_DEPLOYMENT_MODE
value: authenticated
- name: PAPERCLIP_DEPLOYMENT_EXPOSURE
value: private
- name: SERVE_UI
value: "true"
- name: HEARTBEAT_SCHEDULER_ENABLED
value: "true"
- name: PAPERCLIP_MIGRATION_AUTO_APPLY
value: "true"
- name: PAPERCLIP_STORAGE_PROVIDER
value: s3
- name: PAPERCLIP_STORAGE_S3_BUCKET
value: paperclip
- name: PAPERCLIP_STORAGE_S3_REGION
value: us-east-1
- name: PAPERCLIP_STORAGE_S3_ENDPOINT
value: https://radosgw.service.consul
- name: PAPERCLIP_STORAGE_S3_FORCE_PATH_STYLE
value: "true"
- name: NODE_EXTRA_CA_CERTS
value: /etc/ssl/paperclip/ca.crt
envFrom:
- secretRef:
name: paperclip-credentials
volumeMounts:
- name: vault-ca-cert
mountPath: /etc/ssl/paperclip
readOnly: true
livenessProbe:
httpGet:
path: /api/health
port: 3100
httpHeaders:
- name: Host
value: localhost
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /api/health
port: 3100
httpHeaders:
- name: Host
value: localhost
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
resources:
limits:
cpu: "1"
memory: 2Gi
requests:
cpu: 250m
memory: 512Mi
volumes:
- name: vault-ca-cert
secret:
secretName: vault-ca-cert
items:
- key: ca.crt
path: ca.crt
restartPolicy: Always
+37
View File
@@ -0,0 +1,37 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
labels:
traefik.io/instance: internal
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: paperclip.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: paperclip.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
name: paperclip
namespace: paperclip
spec:
gatewayClassName: traefik-internal
listeners:
- allowedRoutes:
namespaces:
from: Same
hostname: paperclip.k8s.syd1.au.unkin.net
name: http
port: 80
protocol: HTTP
- allowedRoutes:
namespaces:
from: Same
hostname: paperclip.k8s.syd1.au.unkin.net
name: https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: paperclip-tls
mode: Terminate
+49
View File
@@ -0,0 +1,49 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: paperclip-http-redirect
namespace: paperclip
spec:
hostnames:
- paperclip.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: paperclip
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: paperclip
namespace: paperclip
spec:
hostnames:
- paperclip.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: paperclip
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: paperclip
port: 3100
weight: 1
matches:
- path:
type: PathPrefix
value: /
+14
View File
@@ -0,0 +1,14 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cnpg_cluster.yaml
- cnpg_pooler.yaml
- deployment.yaml
- gateway.yaml
- httproute.yaml
- namespace.yaml
- services.yaml
- vaultauth.yaml
- vaultstaticsecret.yaml
+5
View File
@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: paperclip
+17
View File
@@ -0,0 +1,17 @@
---
apiVersion: v1
kind: Service
metadata:
name: paperclip
namespace: paperclip
spec:
internalTrafficPolicy: Cluster
ports:
- name: http
port: 3100
protocol: TCP
targetPort: http
selector:
app: paperclip
sessionAffinity: None
type: ClusterIP
+18
View File
@@ -0,0 +1,18 @@
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: default
namespace: paperclip
spec:
allowedNamespaces:
- paperclip
kubernetes:
audiences:
- vault
role: default
serviceAccount: default
tokenExpirationSeconds: 600
method: kubernetes
mount: k8s/au/syd1
vaultConnectionRef: vso-system/default
@@ -0,0 +1,34 @@
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: postgres-credentials
namespace: paperclip
spec:
destination:
create: true
name: postgres-credentials
overwrite: true
hmacSecretData: true
mount: kv
path: kubernetes/namespace/paperclip/default/postgres-credentials
refreshAfter: 5m
type: kv-v2
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: paperclip-credentials
namespace: paperclip
spec:
destination:
create: true
name: paperclip-credentials
overwrite: true
hmacSecretData: true
mount: kv
path: kubernetes/namespace/paperclip/default/paperclip-credentials
refreshAfter: 5m
type: kv-v2
vaultAuthRef: default
@@ -0,0 +1,6 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- priorityclasses.yaml
@@ -0,0 +1,36 @@
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: low
value: 100
preemptionPolicy: Never
globalDefault: false
description: "Low-importance workloads. Can be evicted under pressure but will not preempt other pods."
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: power
value: 100
preemptionPolicy: Never
globalDefault: false
description: "Compute-heavy workloads with low scheduling importance. Evictable under pressure."
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: medium
value: 10000
preemptionPolicy: PreemptLowerPriority
globalDefault: false
description: "Standard workloads. Will preempt low-priority pods if the cluster is under pressure."
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high
value: 100000
preemptionPolicy: PreemptLowerPriority
globalDefault: false
description: "High-importance services. Will preempt medium- and low-priority pods if necessary."
+41
View File
@@ -0,0 +1,41 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: puppetboard.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: puppetboard.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
labels:
traefik.io/instance: internal
app.kubernetes.io/component: puppetboard
app.kubernetes.io/instance: puppetserver
app.kubernetes.io/name: puppetserver
app.kubernetes.io/version: 8.8.0
name: puppetboard
namespace: puppet
spec:
gatewayClassName: traefik-internal
listeners:
- allowedRoutes:
namespaces:
from: Same
hostname: puppetboard.k8s.syd1.au.unkin.net
name: http
port: 80
protocol: HTTP
- allowedRoutes:
namespaces:
from: Same
hostname: puppetboard.k8s.syd1.au.unkin.net
name: https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: puppetboard-tls
mode: Terminate
+34
View File
@@ -0,0 +1,34 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: puppetdb.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
external-dns.alpha.kubernetes.io/hostname: puppetdb.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
labels:
traefik.io/instance: internal
app.kubernetes.io/component: puppetdb
app.kubernetes.io/instance: puppetserver
app.kubernetes.io/name: puppetserver
app.kubernetes.io/version: 8.8.0
name: puppetdb
namespace: puppet
spec:
gatewayClassName: traefik-internal
listeners:
- allowedRoutes:
namespaces:
from: Same
hostname: puppetdb.k8s.syd1.au.unkin.net
name: https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: puppetdb-tls
mode: Terminate
@@ -0,0 +1,59 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
labels:
app.kubernetes.io/component: puppetboard
app.kubernetes.io/instance: puppetserver
app.kubernetes.io/name: puppetserver
app.kubernetes.io/version: 8.8.0
name: puppetboard-http-redirect
namespace: puppet
spec:
hostnames:
- puppetboard.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: puppetboard
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
labels:
app.kubernetes.io/component: puppetboard
app.kubernetes.io/instance: puppetserver
app.kubernetes.io/name: puppetserver
app.kubernetes.io/version: 8.8.0
name: puppetboard
namespace: puppet
spec:
hostnames:
- puppetboard.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: puppetboard
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: puppetboard
port: 80
weight: 1
matches:
- path:
type: PathPrefix
value: /
+30
View File
@@ -0,0 +1,30 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
labels:
app.kubernetes.io/component: puppetdb
app.kubernetes.io/instance: puppetserver
app.kubernetes.io/name: puppetserver
app.kubernetes.io/version: 8.8.0
name: puppetdb
namespace: puppet
spec:
hostnames:
- puppetdb.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: puppetdb
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: puppetdb
port: 8080
weight: 1
matches:
- path:
type: PathPrefix
value: /
-34
View File
@@ -1,34 +0,0 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
external-dns.alpha.kubernetes.io/hostname: puppetboard.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.0
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: puppetboard.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
labels:
app.kubernetes.io/component: puppetboard
app.kubernetes.io/instance: puppetserver
app.kubernetes.io/name: puppetserver
app.kubernetes.io/version: 8.8.0
name: puppetboard
namespace: puppet
spec:
rules:
- host: puppetboard.k8s.syd1.au.unkin.net
http:
paths:
- backend:
service:
name: puppetboard
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- puppetboard.k8s.syd1.au.unkin.net
secretName: puppetboard-tls
-34
View File
@@ -1,34 +0,0 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
external-dns.alpha.kubernetes.io/hostname: puppetdb.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.0
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: puppetdb.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
labels:
app.kubernetes.io/component: puppetdb
app.kubernetes.io/instance: puppetserver
app.kubernetes.io/name: puppetserver
app.kubernetes.io/version: 8.8.0
name: puppetdb
namespace: puppet
spec:
rules:
- host: puppetdb.k8s.syd1.au.unkin.net
http:
paths:
- backend:
service:
name: puppetdb
port:
number: 8080
path: /
pathType: Prefix
tls:
- hosts:
- puppetdb.k8s.syd1.au.unkin.net
secretName: puppetdb-tls
+4 -2
View File
@@ -25,8 +25,10 @@ resources:
- horizontalpodautoscaler_puppetserver-masters-autoscaler.yaml
- horizontalpodautoscaler_puppetserver-puppetboard-autoscaler.yaml
- horizontalpodautoscaler_puppetserver-puppetdb-autoscaler.yaml
- ingress_puppetboard.yaml
- ingress_puppetdb.yaml
- gateway_puppetboard.yaml
- httproute_puppetboard.yaml
- gateway_puppetdb.yaml
- httproute_puppetdb.yaml
- service_puppetserver-agents-to-puppet.yaml
- service_puppet-headless.yaml
- service_puppet.yaml
-1
View File
@@ -9,7 +9,6 @@ metadata:
name: puppetdb
namespace: puppet
spec:
clusterIP: null
ports:
- name: pdb-http
port: 8080
@@ -0,0 +1,9 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
labels:
traefik.io/instance: external
name: traefik-external
spec:
controllerName: traefik.io/gateway-controller
@@ -0,0 +1,9 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
labels:
traefik.io/instance: internal
name: traefik-internal
spec:
controllerName: traefik.io/gateway-controller
@@ -0,0 +1,8 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- gatewayclass-internal.yaml
- gatewayclass-external.yaml
+5
View File
@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: traefik-system
+52
View File
@@ -0,0 +1,52 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: vault
namespace: vault
labels:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
traefik.io/instance: internal
annotations:
cert-manager.io/cluster-issuer: vault-issuer
cert-manager.io/common-name: vault.k8s.syd1.au.unkin.net
cert-manager.io/private-key-size: "4096"
cert-manager.io/alt-names: vault.service.consul,vault.query.consul
external-dns.alpha.kubernetes.io/hostname: vault.k8s.syd1.au.unkin.net
external-dns.alpha.kubernetes.io/target: 198.18.200.4
spec:
gatewayClassName: traefik-internal
listeners:
- name: http
port: 80
protocol: HTTP
hostname: vault.k8s.syd1.au.unkin.net
allowedRoutes:
namespaces:
from: Same
- name: https
port: 443
protocol: HTTPS
hostname: vault.k8s.syd1.au.unkin.net
allowedRoutes:
namespaces:
from: Same
tls:
mode: Terminate
certificateRefs:
- group: ""
kind: Secret
name: vault-tls
- name: vault-direct
port: 8200
protocol: HTTPS
allowedRoutes:
namespaces:
from: Same
tls:
mode: Terminate
certificateRefs:
- group: ""
kind: Secret
name: vault-tls
+84
View File
@@ -0,0 +1,84 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vault-http-redirect
namespace: vault
labels:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
spec:
hostnames:
- vault.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: vault
sectionName: http
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vault
namespace: vault
labels:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
spec:
hostnames:
- vault.k8s.syd1.au.unkin.net
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: vault
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: vault
port: 8200
weight: 1
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vault-consul
namespace: vault
labels:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
spec:
hostnames:
- vault.service.consul
- vault.query.consul
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: vault
sectionName: vault-direct
rules:
- backendRefs:
- group: ""
kind: Service
name: vault
port: 8200
weight: 1
matches:
- path:
type: PathPrefix
value: /
+9
View File
@@ -0,0 +1,9 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- gateway.yaml
- httproute.yaml
- role_k8s-service-registration.yaml
+5
View File
@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: vault
@@ -0,0 +1,24 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: vault-k8s-service-registration
namespace: vault
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: vault-k8s-service-registration
namespace: vault
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: vault-k8s-service-registration
subjects:
- kind: ServiceAccount
name: vault
namespace: vault
+1
View File
@@ -6,5 +6,6 @@ resources:
- namespace.yaml
- cnpg_cluster.yaml
- cnpg_pooler.yaml
- serviceaccount_terraform_vault.yaml
- vaultauth.yaml
- vaultstaticsecret.yaml
@@ -0,0 +1,6 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: terraform-vault
namespace: woodpecker
@@ -7,7 +7,7 @@ resources:
helmCharts:
- name: rancher
repo: https://releases.rancher.com/server-charts/stable
repo: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm
version: "2.13.1"
releaseName: rancher
namespace: cattle-system
@@ -7,8 +7,8 @@ resources:
helmCharts:
- name: cert-manager
repo: https://charts.jetstack.io
version: "v1.19.2"
repo: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm
version: "v1.20.2"
releaseName: cert-manager
namespace: cert-manager
valuesFile: values.yaml
@@ -1,6 +1,11 @@
crds:
enabled: true
config:
apiVersion: controller.config.cert-manager.io/v1alpha1
kind: ControllerConfiguration
enableGatewayAPI: true
replicaCount: 2
resources:
@@ -7,7 +7,7 @@ resources:
helmCharts:
- name: cloudnative-pg
repo: https://cloudnative-pg.github.io/charts
repo: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm
version: "0.27.0"
releaseName: cloudnative-pg-operator
namespace: cnpg-system
@@ -0,0 +1,16 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../base/consul
helmCharts:
- name: consul
repo: https://helm.releases.hashicorp.com
version: "1.9.7"
releaseName: consul
namespace: consul
valuesFile: values.yaml
apiVersions:
- policy/v1/PodDisruptionBudget
+58
View File
@@ -0,0 +1,58 @@
global:
name: consul
datacenter: au-syd1
domain: consul
server:
image: hashicorp/consul:1.22.7
replicas: 5
bootstrapExpect: 5
storage: 10Gi
storageClass: cephrbd-fast-delete
connect: true
disruptionBudget:
maxUnavailable: 1
extraConfig: |
{
"disable_remote_exec": true,
"disable_update_check": true,
"performance": {
"raft_multiplier": 10
},
"ports": {
"dns": 8600,
"grpc": 8502,
"http": 8500,
"https": -1
},
"primary_datacenter": "au-syd1"
}
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 2Gi
cpu: "1"
client:
enabled: false
ui:
enabled: true
service:
type: ClusterIP
connectInject:
enabled: false
dns:
enabled: true
type: LoadBalancer
annotations: |
purelb.io/service-group: "common"
purelb.io/addresses: 198.18.200.5
@@ -9,7 +9,7 @@ resources:
helmCharts:
- name: eck-operator
repo: https://helm.elastic.co
repo: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm
version: "3.2.0"
releaseName: elastic-operator
namespace: elastic-system
@@ -7,8 +7,8 @@ resources:
helmCharts:
- name: external-dns
repo: https://kubernetes-sigs.github.io/external-dns/
version: "1.19.0"
repo: https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm
version: "1.21.1"
releaseName: externaldns
namespace: externaldns
valuesFile: values.yaml
@@ -24,6 +24,8 @@ policy: "sync"
sources:
- service
- ingress
- gateway-httproute
- gateway-grpcroute
# Environment variables for TSIG secret and algorithm from Vault
env:
@@ -49,3 +51,5 @@ extraArgs:
- --rfc2136-tsig-axfr
- --rfc2136-tsig-secret=$(EXTERNAL_DNS_RFC2136_TSIG_SECRET)
- --ingress-class=nginx
logLevel: debug
@@ -0,0 +1,6 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../base/kanidm
@@ -0,0 +1,6 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../base/litellm

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