fix(crossplane-observability): derive the provider job label from the PodMonitor the chart ships - #290
Merged
Conversation
… PodMonitor the chart ships `crossplane.providers.job` defaulted to `crossplane-providers` — a plausible-looking name that no PodMonitor can ever produce. Prometheus-operator derives a PodMonitor's job label as `<namespace>/<name>`, so the chart's own provider scrape lands under `crossplane-system/<release>-crossplane-observability-providers`, and the 11 rules filtering on `job="crossplane-providers"` matched nothing. Enabling `providerPodMonitor` therefore produced a working scrape and still-empty rules, with nothing anywhere reporting a problem. Fixed the way the core half already works — by deriving the coupling instead of asking two settings to agree. `crossplane.core.job` names the Service, so core is self-consistent by construction; `crossplane.providers.job` now defaults to empty, meaning "the PodMonitor this chart ships", and is computed from the rendered object. An explicit value still wins, which is the case that matters when a platform scrape already covers the provider pods. Guarded so it cannot regress: validate.sh step 1c walks the all-enabled render and asserts every shipped monitor's job label is one the rules actually query — a ServiceMonitor's being the Service name, a PodMonitor's being `<namespace>/<name>`. Confirmed it fails on the old default before the fix. The promtool unit tests render with an explicit job so their fixtures stay independent of the release name; they test rule logic, step 1c tests the wiring. This is the second half of making the addon work without per-cluster values: the saap-catalog wrapper currently carries `job: crossplane-system/crossplane-providers-and-functions`, which describes one cluster's hand-applied PodMonitor and is wrong everywhere else. With this it can drop the override entirely. Refs SA-8539, #283 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
rasheedamir
approved these changes
Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
crossplane.providers.jobnow defaults to empty, meaning "the PodMonitor this chart ships", and is derived from the rendered object. An explicit value still wins.Follows #289 (merged, published
0.0.8) — together these are the two chart-side prerequisites for turning the scrape on in the saap-catalog wrapper baseline, so the addon works from a ksp upgrade with no per-cluster values.Why
The old default was
crossplane-providers— a plausible-looking name no PodMonitor can ever produce. Prometheus-operator derives a PodMonitor's job label as<namespace>/<name>, so the chart's own provider scrape lands undercrossplane-system/<release>-crossplane-observability-providers, while 11 rules filtered onjob="crossplane-providers".Enabling
providerPodMonitortherefore gave you a working scrape and still-empty rules, and nothing reported a problem: the objects are valid, the PromQL parses, the rules evaluate — against no series, forever. This is the same silent-empty failure class as #288 (no Service to select) and #289 (a selector matching no pods), and it is why eu-2's dashboard is empty today.How
The core half already avoids this by construction:
crossplane.core.jobnames the Service, and prometheus-operator takes a ServiceMonitor's job from the Service — one value, no agreement to maintain. The provider half now works the same way via acrossplane-observability.providersJobhelper:crossplane.providers.job<namespace>/<fullname>-providers— the chart's own PodMonitorproviderPodMonitoroff so both don't scrape)Regression guard
New
validate.shstep 1c walks the all-enabled render and asserts every shipped monitor's job label is one the rules actually query — a ServiceMonitor's being the Service name, a PodMonitor's being<namespace>/<name>:Verified it fails on the old default before the fix — reinstating
job: crossplane-providersgives:The scope is deliberately narrow — only the couplings this chart owns — so
crossplane.inventory.job(ksm-crossplane, an external exporter) is not flagged.The promtool unit tests now render with an explicit job, keeping their 16 fixture series independent of the release name: they test rule logic, step 1c tests the wiring.
Verification
./tests/validate.shfully green — lint, both renders, step 1c,promtool check/test rules(11 groups / 29 rules), metric gate 18/28 captured, dashboard JSON + 39 panel queries, kubeconform strict 25/25.Not verified live: both cluster tokens are expired this session. The claim being made is about how prometheus-operator names jobs and what this chart renders, both of which are checked in the render — and the live evidence for the trap is already recorded (eu-2's deployed rules query
crossplane-system/crossplane-providers-and-functions, us-2's hand-applied PodMonitor name, which the chart never produces).Follow-up (not in this PR)
The saap-catalog wrapper pins
crossplane.providers.job: crossplane-system/crossplane-providers-and-functions— a description of one cluster's hand-applied PodMonitor, wrong on every other cluster. With this merged it can drop the override and enable the chart's own monitors instead.Refs SA-8539, #283. Follows #288, #289.
🤖 Generated with Claude Code