feat(uptime-monitor): sync the UptimeRobot API key from OpenBao via ESO
Makes the key at OpenBao `infrastructure/uptime-robot`, field `api_key`, available as a Secret in the new `uptime-monitor` namespace and nowhere else. No new operator: this uses the External Secrets Operator and the `openbao` ClusterSecretStore the cluster already runs. Nothing is monitored by this commit. The namespace holds only the key; the IngressMonitorController, its ServiceAccount and its RBAC arrive separately (REN-6). * `data` + `property` instead of `dataFrom: extract`, so only the one field lands in the cluster rather than every field at the KV path. * Adds `uptime-monitor` to the ClusterSecretStore `conditions.namespaces` allowlist, sorted. Without this ESO reports "not allowed to reference ClusterSecretStore" and the Secret silently never syncs. * A DEDICATED Flux Kustomization rather than adding the ExternalSecret to infrastructure/post-crds. That path runs `wait: true` with no explicit healthChecks and 19 other Kustomizations dependOn it, so an ExternalSecret whose OpenBao path is not yet populated would never turn Ready and would stall most of the cluster. Here the blast radius of a missing key is this Kustomization alone, which nothing depends on. * No OpenBao policy change: eso-read already grants `homelab/data/*`. Co-Authored-By: Paperclip <noreply@paperclip.ing> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
committed by
atlas-bot
co-authored by
Paperclip
Claude Opus 5
parent
a833a9083a
commit
25cabaed76
@@ -0,0 +1,37 @@
|
||||
---
|
||||
# UptimeRobot API key for the IngressMonitorController (REN-2).
|
||||
#
|
||||
# OpenBao key infrastructure/uptime-robot, field `api_key`. `data` + `property`
|
||||
# rather than `dataFrom: extract` (the shape most ExternalSecrets in this repo
|
||||
# use) on purpose: extract copies EVERY field at the KV path into the cluster
|
||||
# Secret, so any field added there later — an account id, a second token —
|
||||
# would land in this namespace without anyone editing this file. Naming the one
|
||||
# field keeps the Secret to exactly what the controller needs. Same shape as
|
||||
# kubernetes/apps/wiki/externalsecrets.yaml.
|
||||
#
|
||||
# refreshInterval 1h matches the un-rotated ExternalSecrets here (velero,
|
||||
# wiki-*). The rotated ones use 10m so an automated roll propagates fast — if
|
||||
# kubernetes/infrastructure/openbao/rotation/ ever gains an uptime-robot
|
||||
# rotator, drop this to 10m and annotate the controller Deployment for
|
||||
# stakater/reloader, which the cluster already runs.
|
||||
#
|
||||
# The `eso` role already reads this path: eso-read grants `homelab/data/*`
|
||||
# (kubernetes/infrastructure/openbao/policies/eso-read.hcl:31). No OpenBao
|
||||
# policy change is needed for this key.
|
||||
apiVersion: external-secrets.io/v1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: uptime-robot-api-key
|
||||
namespace: uptime-monitor
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
kind: ClusterSecretStore
|
||||
name: openbao
|
||||
target:
|
||||
name: uptime-robot-api-key
|
||||
data:
|
||||
- secretKey: api-key
|
||||
remoteRef:
|
||||
key: infrastructure/uptime-robot
|
||||
property: api_key
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- externalsecret.yaml
|
||||
@@ -0,0 +1,44 @@
|
||||
# Automated uptime monitoring (REN-2): Stakater IngressMonitorController keeps
|
||||
# UptimeRobot monitors in sync with `monitor.stakater.com/enabled` annotations on
|
||||
# Ingress objects. This Kustomization starts with the API key only; the
|
||||
# controller, its ServiceAccount and its RBAC land here in REN-6.
|
||||
#
|
||||
# A DEDICATED Kustomization rather than adding the ExternalSecret to
|
||||
# ./kubernetes/infrastructure/post-crds, which is where the other
|
||||
# infrastructure-layer ExternalSecrets live. That directory is applied by the
|
||||
# `infrastructure-crds` Kustomization, which runs `wait: true` with no explicit
|
||||
# healthChecks, so EVERY object under it must go healthy or the whole
|
||||
# Kustomization reports NotReady — and 19 other Kustomizations in this directory
|
||||
# dependsOn it. An ExternalSecret whose OpenBao path is not yet populated never
|
||||
# turns Ready, so putting this key there would put `homelab/infrastructure/uptime-robot`
|
||||
# in the critical path of most of the cluster. Here, the only thing a missing or
|
||||
# misnamed key can stall is this Kustomization, which nothing depends on.
|
||||
#
|
||||
# Same reason `wait: true` is kept below rather than dropped: the wait is how a
|
||||
# key that failed to sync becomes visible, and it is safe precisely because the
|
||||
# blast radius is this Kustomization alone.
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: uptime-monitor
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 10m
|
||||
# 2m, not the 1m most app Kustomizations use: the one object here is an
|
||||
# ExternalSecret against a key a human may still be placing in OpenBao, and a
|
||||
# retry every minute against a 404 is just noise in the ESO and Flux logs.
|
||||
retryInterval: 2m
|
||||
timeout: 5m
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: flux-system
|
||||
path: ./kubernetes/apps/uptime-monitor
|
||||
prune: true
|
||||
wait: true
|
||||
dependsOn:
|
||||
# ESO itself, and the `uptime-monitor` namespace (declared centrally in
|
||||
# kubernetes/infrastructure/namespaces/namespaces.yaml).
|
||||
- name: infrastructure
|
||||
# The `openbao` ClusterSecretStore, including the conditions.namespaces
|
||||
# allowlist entry this namespace needs.
|
||||
- name: infrastructure-crds
|
||||
@@ -244,3 +244,19 @@ apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: paperclip
|
||||
---
|
||||
# IngressMonitorController, which syncs UptimeRobot monitors from Ingress
|
||||
# annotations (REN-2). Declared here rather than in the workload Kustomization
|
||||
# for the reason spelled out above `woodpecker`: the `infrastructure` KS creates
|
||||
# namespaces, and `infrastructure-crds` (post-crds, which includes
|
||||
# ../network-policies/) runs after it — so declaring it in the workload KS would
|
||||
# invert that order the moment this namespace gains a CiliumNetworkPolicy, which
|
||||
# it will when the controller arrives and needs scoped egress to the UptimeRobot
|
||||
# API. It holds nothing but the API key Secret until then.
|
||||
#
|
||||
# No pod-security labels: the controller needs no hostPath, hostNetwork or
|
||||
# privilege, so the cluster's default `baseline` enforcement is enough.
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: uptime-monitor
|
||||
|
||||
@@ -30,6 +30,7 @@ spec:
|
||||
- paperclip
|
||||
- paperless
|
||||
- trmnl
|
||||
- uptime-monitor # uptime-robot-api-key (apps/uptime-monitor/externalsecret.yaml)
|
||||
- velero
|
||||
- woodpecker # wp-pg barman creds; woodpecker moving out of `apps` (#433)
|
||||
- wordpress
|
||||
|
||||
Reference in New Issue
Block a user