Files
homelab/kubernetes/apps/gatus/configmap.yaml
T
atlas-botandClaude Opus 5.5 21a7583523
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ci/woodpecker/pr/pr-review Pipeline was successful
ci: cite YAML by anchor instead of line number, and guard it (REN-183)
Comments that pointed at other YAML as `file.yaml:N` went stale on any
edit above the cited line; three drift fixes had been merged by hand
(REN-181). The cited block now carries `# anchor: <name>` and the
comment cites `path.yaml#<name>`.

- Sweep: all 32 line-number citations in YAML comments converted.
  Several were already stale at head and now point at the right block
  (see PR). Vendored files (Flux gotk-components, IMC CRD) get no
  anchor; those two citations name the object/schema path instead.
- Guard: scripts/ci/yaml-citations.sh in ci-manifests-test.yml; fails
  on a line-number citation or a path#name whose file/anchor is gone.
  Self-test in ci-scripts-test.yml.
- CONTRIBUTING.md: the convention in three lines.

Comment-only under kubernetes/: every file parses to identical objects
before and after, so Flux applies nothing and no ConfigMap data changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 08:44:54 +00:00

286 lines
11 KiB
YAML

apiVersion: v1
kind: ConfigMap
metadata:
name: gatus-config
namespace: apps
# SECURITY (issue #206): status.renner.uno is PUBLIC and
# unauthenticated by design (kept public per owner decision — not Authentik-gated).
# To stop it disclosing the internal service estate, every endpoint below:
# * uses an OPAQUE display name (no product/vendor/hostname in `name`), and
# * sets `ui.hide-hostname/hide-url/hide-port/hide-conditions/hide-errors: true`
# so gatus scrubs the target hostname, URL, port, condition strings, and (on
# failure) error text — which would otherwise leak internal FQDNs/IPs such as
# mosquitto.home-assistant.svc.cluster.local or 10.2.40.1 — from the public
# results and the /api/v1/endpoints/statuses API.
# The public page therefore shows only: group, opaque label, up/down, response
# time. The real targets stay in `url` below (visible only to git/cluster-
# privileged operators) so every health check still runs unchanged.
#
# Opaque-label map (maintainer reference only — NOT served publicly):
# services group infrastructure group
# Web Service 1 = Authentik Infrastructure 1 = retired (was PBS 2)
# Web Service 2 = Gitea Infrastructure 2 = retired (was Proxmox VE)
# Web Service 3 = Immich Infrastructure 3 = UDM DNS (10.2.40.1)
# Web Service 4 = Woodpecker CI Infrastructure 4 = Mosquitto MQTT broker
# Web Service 5 = Grafana
# Web Service 6 = Home Assistant
# Web Service 7 = retired (was the NAS file UI; never Paperless, which
# this map claimed and which nothing here checks)
# Web Service 8 = Audiobookshelf
# Web Service 9 = Music Assistant
# Web Service 10 = TRMNL
# Web Service 11 = Paperless (gate-level only, see its entry)
#
# CORRECTION (REN-21, 2026-09-25) to the Web Service 11 comment further down,
# which claims that an in-cluster probe of the paperless ClusterIP "needs a
# CiliumNetworkPolicy first — the monitoring probes get away without one only
# because their targets share a namespace with the prober".
#
# That is wrong, and it was wrong when written. It is stated here rather than
# fixed in place because the sentence lives inside the `config.yaml: |` block
# scalar below: any edit to it changes ConfigMap DATA, and
# `configmap.reloader.stakater.com/reload: gatus-config`
# (deployment.yaml#reloader) would then roll the gatus Deployment — a
# production restart for a comment. This header is outside `data:`, so it is
# inert; the served config is byte-identical.
#
# * ../../infrastructure/network-policies/paperless-ns.yaml#monitoring-admit
# ALREADY admits the whole monitoring namespace on every port, and
# monitoring is where
# blackbox-exporter runs. Cilium unions the allow rules of every CNP
# selecting an endpoint, so no extra policy is required.
# * The in-cluster paperless probe therefore exists, added with no change
# to the paperless namespace:
# monitoring-rules/probes-blackbox.yaml, target
# http://paperless.paperless.svc.cluster.local:80/accounts/login/
# * The claim does NOT generalise to gatus itself. Gatus runs in `apps`,
# which is a different source namespace; a gatus-sourced in-cluster check
# would need its own allow, exactly as
# cnp-cross-namespace-allow-apps-gatus-to-monitored-services describes.
#
# The Web Service 11 entry below stays a reachability-only check on purpose.
# The app-health half of the pair is the blackbox probe named above.
data:
# anchor: gatus-endpoints
config.yaml: |
storage:
type: sqlite
path: /data/gatus.db
ui:
title: Homelab Status
description: Service health monitoring
endpoints:
# Web Services
- name: Web Service 1
group: services
url: https://auth.renner.uno/-/health/ready/
interval: 60s
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[STATUS] == 200"
- "[RESPONSE_TIME] < 2000"
- name: Web Service 2
group: services
url: https://gitea.renner.uno/api/v1/settings/api
interval: 60s
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[STATUS] == 200"
- "[RESPONSE_TIME] < 2000"
- name: Web Service 3
group: services
url: https://immich.renner.uno/api/server/ping
interval: 60s
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[STATUS] == 200"
- "[BODY].res == pong"
- name: Web Service 4
group: services
url: https://ci.renner.uno/healthz
interval: 60s
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[STATUS] == any(200, 204)"
- name: Web Service 5
group: services
url: https://dash.renner.uno/api/health
interval: 60s
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[STATUS] == 200"
- "[BODY].database == ok"
- name: Web Service 6
group: services
url: https://home.renner.uno
interval: 60s
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[STATUS] == any(200, 301, 302)"
# Removed 2026-08-28: the NAS file UI (file.renner.uno). Its Ingress and
# ExternalName Service were deleted in #696 because they pointed at
# nas-1, which is powered off; this check outlived them and had been
# reporting failure on the public page since.
- name: Web Service 8
group: services
url: https://audiobooks.renner.uno/healthcheck
interval: 60s
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[STATUS] == 200"
- name: Web Service 9
group: services
url: https://music.renner.uno
interval: 60s
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[STATUS] == any(200, 301, 302)"
# Terminus admin UI. Checks the TLS route only — the cleartext
# device endpoint (trmnl-device.renner.uno) is the same pod, so a
# failure here covers both. Terminus exposes no health endpoint, so
# this is a root-page check: the login page answers 200, and an
# unauthenticated request may redirect.
- name: Web Service 10
group: services
url: https://trmnl.renner.uno
interval: 60s
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[STATUS] == any(200, 301, 302)"
# Paperless sits entirely behind the Authentik gate — every path,
# including /api/, answers 302 to unauthenticated callers, so there is no
# endpoint that proves the app rather than the gate. This check is
# therefore reachability only: DNS, TLS, Traefik and the outpost. It
# stays green if paperless itself is dead behind a live gate.
#
# Closing that blind spot needs an in-cluster probe of the paperless
# ClusterIP, which crosses a namespace boundary and so needs a
# CiliumNetworkPolicy first — the monitoring probes get away without one
# only because their targets share a namespace with the prober.
- name: Web Service 11
group: services
url: https://paperless.renner.uno
interval: 60s
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[STATUS] == any(200, 301, 302)"
# Removed 2026-05-21: Jellyfin (media.renner.uno), Wiki (wiki.renner.uno),
# InfluxDB (influx.renner.uno) — hostnames NXDOMAIN, no Ingress; services
# no longer deployed. Re-add when/if they come back.
# pbs.obg.renner.uno is the OFFSITE PBS (10.3.40.96, ~50ms WAN).
# Removed from in-cluster gatus 2026-05-20 — checking it from
# inside the cluster routes DNS+TCP through several hops that
# have non-deterministic loss; gatus reported false failures and
# spammed CoreDNS/k8s-gateway with AAAA i/o timeouts (no AAAA
# record exists, the lookup times out instead of resolving to
# NoData). Monitor the offsite PBS from the offsite side or via a
# check that doesn't depend on this cluster's DNS path.
# Removed 2026-08-28: PBS 2 (pbs2.renner.uno:8007) — it has no clients
# left. Its two were the PVE cluster, retired to bare-metal Talos, and
# nas-1, powered off and dropped from the repo. Checking the liveness of
# a backup server that nothing backs up to reports on nothing. Re-add
# alongside the first host that is declared to back up to it.
- name: Infrastructure 3
group: infrastructure
url: 10.2.40.1
interval: 30s
dns:
query-name: udm.renner.uno
query-type: A
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[DNS_RCODE] == NOERROR"
- "[RESPONSE_TIME] < 500"
# Mosquitto MQTT broker (ClusterIP, home-assistant ns). A TCP-connect
# check on :1883: the broker's image tag is auto-bumped by Flux
# image-automation straight to master (no CI gate), and the deployment
# is a single Recreate/rolling pod, so a bad bump that fails to come up
# would otherwise be silent. This turns that into an alert.
- name: Infrastructure 4
group: infrastructure
url: tcp://mosquitto.home-assistant.svc.cluster.local:1883
interval: 60s
ui:
hide-hostname: true
hide-url: true
hide-port: true
hide-conditions: true
hide-errors: true
conditions:
- "[CONNECTED] == true"
# Removed 2026-05-21: PostgreSQL HA (VIP) tcp://10.2.40.135:5432 —
# VIP no longer responds (no TCP, no ICMP). Re-add if it returns.