Commit Graph
2 Commits
Author SHA1 Message Date
jakman85andClaude Opus 5 81f627167d docs(obs): record that the gate-sidecar scrape works — four places still said it did not
gate / gate (pull_request) Successful in 1m48s
gate / conformance (pull_request) Has been skipped
PR #49 (merged 21c88b0) fixed the blocked scrape and it is verified working on prod
2026-10-05: all 6 targets up == 1, health=up, lastError='', lastScrapeDuration 0.001-0.006s
against 10.0s and "context deadline exceeded" before. oauth2_proxy_* is in the TSDB for
these namespaces for the first time (5 metric names, 148 series).

Four places in the tree still asserted the pre-fix state as current, in the present tense,
in the files a reader consults first:

  platform/oauth2-proxy/podmonitor.yaml  "READ THIS BEFORE BELIEVING THE TARGETS ARE UP:
    THE SCRAPE IS CURRENTLY DENIED BY NETWORKPOLICY" and "SO THE TARGETS BELOW WILL READ
    up == 0 UNTIL AN INGRESS ALLOWANCE LANDS". The first actively instructs the reader to
    disbelieve a correct up == 1. Now a STATUS block with the post-fix numbers, with the
    diagnosis kept below it under an explicit HISTORY heading because it is why the fix is
    shaped the way it is.
  catalog/render.py:159  "THIS IS THE PREREQUISITE ONLY, AND IT IS NOT YET SCRAPED".
  catalog/render.py:1365  the same claim on the sidecar arg.
  platform/oauth2-proxy/README.md  its subsections are dated and so are honest records, but
    a reader hits the stale body long before any correction. A SUPERSEDED pointer now sits
    under the heading and an Update 2026-10-05 section carries the before/after.

The "not scraped" claims are corrected; the "a flag alone is not enough" warning is KEPT
deliberately, because that part is still true and "flag without ingress allowance" is
exactly what caused the 63.7h outage.

Two substantive errors fixed while there, not just tense. The README's "three things are
needed" listed a Service port and a ServiceMonitor — wrong, a PodMonitor targets pod ports
directly, which is why no Service exposes 44180 and the renderer needed no Service change;
following it would have sent someone to edit Service rendering for nothing. And
podmonitor.yaml deferred the fix to "the catalog/renderer, in flight on another branch" —
no such branch existed; it now names r_monitoring_ingress_policy, with a new CRAFTY section
explaining the one namespace this file cannot help.

Comments only in render.py, so the rendered output is byte-identical: no apps/ file and no
golden changes, and therefore no sensitive path and no human approval needed — the opposite
of the PR this documents.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-10-05 21:18:33 -05:00
jakman85andClaude Opus 5 b156ee6cfa fix(obs): open 44180 to ns monitoring so the forward-auth gate sidecars are actually scrapable
gate / gate (pull_request) Successful in 1m51s
gate / conformance (pull_request) Has been skipped
platform/oauth2-proxy/podmonitor.yaml landed 2026-10-02 and discovered six targets that
have never once scraped. Measured on prod 2026-10-04: all six read health=down with
lastError "context deadline exceeded" and lastScrapeDuration exactly 10.0s — the
configured scrapeTimeout, i.e. packets DROPPED rather than refused.

Cause: every app namespace ships a default-deny NetworkPolicy with
policyTypes: [Ingress, Egress] and NO ingress key at all (deny-all-ingress), and the only
ingress allowance is <app>-allow-gateway-ingress: fromEntities: [ingress] -> 4180.
Prometheus matched no clause. Verified identical in all six of jackett, radarr, sonarr,
qbittorrent, pihole, crafty; zero namespaces had any -allow-monitoring-scrape object.

render.py already had the right idiom — r_monitoring_ingress_policy — but it returned None
unless the service declared observability.metricsEndpoint, and NO ServiceDefinition in this
catalog declares one. It was wired in at the call site and had never emitted a single
object on any branch: correct, and entirely latent.

It now also fires for the forward-auth gate sidecar's own metrics port, keyed on
_needs_oauth2_sidecar — deliberately the same condition the scrape keys on, since
podmonitor.yaml selects pods purely by the auth-mode label, so a target exists iff the
sidecar exists. Keying on observability.metrics instead would let metrics: false produce a
discovered-but-blocked target: the same "two halves authored apart" failure this function
exists to prevent.

Rendered here rather than in platform/oauth2-proxy because that tier would have to name app
namespaces created by the sibling apps-wave-0/1 tiers — it would apply on a running cluster
and fail on a cold bootstrap. podmonitor.yaml's header records that objection; rendering
per-app dissolves it.

Five CNPs result, one per forward-auth app, each opening only 44180 to only ns monitoring.
apps/ re-rendered with the invocation it was generated by (--no-image-automation, verified
byte-identical beforehand); --emit-waves deliberately not run, so no wave kustomization moved.

Three L1 goldens are regenerated with it (+63 lines, -0): a renderer change that adds an
object necessarily drifts the goldens that pin the renderer's output. The first gate run
caught container-workload-render and egress-class-render as FAIL with exactly this CNP as
the drift. default-deny-baseline-render's golden regenerated byte-identical, which is the
evidence that the regen is faithful and not a rubber stamp.

That puts conformance/** in the diff, which is a sensitive path: this PR needs a non-author
approving review. The local gate cannot see that — offline it reports approval-policy green
(N/A).

Local toolbox gate: rc 3 UNDETERMINED, not 0. Every stage that ran is green and l1 went
FAIL -> pass with the goldens; the only not-run stage is gitea-settings (no
GITEA_SETTINGS_TOKEN). L2/L3 conformance is UNVERIFIED for all 8 touched requirements.

Not verified: that the scrape now succeeds. Nothing is applied until Flux reconciles main.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-10-04 16:05:44 -05:00