Repository navigation
Feat : Expose Degraded Condition as Prometheus Metric for external auth - #7583
Mansi Mandhare (m-mandhare) wants to merge 2 commits into
Conversation
|
Pipeline controller notification This PR uses the pipeline controller for second-stage tests. Selection and triggering follow the repository configuration. Use |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: m-mandhare The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Skipping CI for Draft Pull Request. |
There was a problem hiding this comment.
🟡 Changes recommended
Duplicate registration can panic, and metric lifecycle handling can leave missing, stale, or inaccurate samples.
5 open findings
Use the injected metrics registry for controller registration · New Delete gauge labels when external auth resources are removed · New Record degraded status before reconciliation early returns · New Publish aggregate status only after successful persistence · New Queue deletion events to clean up stale degraded metrics · New
What changed in this PR
Adds a backend Prometheus gauge for external-auth degradation, supporting Grafana visibility for ARO-29559.
Changes:
- Records degradation by resource ID and controller.
- Allows syncers to handle missing external-auth resources.
- Adds gauge-value and deletion-path unit tests.
| File | Description |
|---|---|
| backend/pkg/utils/controllerutils/external_auth_watching_controller.go | Calls syncers for missing resources while skipping controller-document writes. |
| backend/pkg/controllers/externalauth/status/externalauth_userfacing_conditions_degraded_aggregator.go | Registers and updates the degradation gauge. |
| backend/pkg/controllers/externalauth/status/externalauth_userfacing_conditions_degraded_aggregator_test.go | Tests condition values and gauge reset on NotFound. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| // Always call syncer.SyncOnce so syncers can handle NotFound themselves | ||
| // (e.g., to set Prometheus gauge to 0 for deleted resources). | ||
| syncErr := c.syncer.SyncOnce(ctx, key) |
| resourcesDBClient: resourcesDBClient, | ||
| degradedGauge: promauto.With(legacyregistry.Registerer()).NewGaugeVec( | ||
| prometheus.GaugeOpts{ | ||
| Name: "backend_externalauth_degraded", |
There was a problem hiding this comment.
Nothing in observability reads backend_externalauth_degraded yet, including the dashboard in #7267, so can you link the panel or alert that will use it and the good/total query you have in mind?
| value = 1.0 | ||
| } | ||
|
|
||
| c.degradedGauge.With(prometheus.Labels{ |
There was a problem hiding this comment.
A missing client secret or a bad issuer URL from the customer sets this to 1 just like a service failure, so could we add a small reason label (customer config vs service) so the SLI can keep customer mistakes out of the error budget?
| replacement := existing.DeepCopy() | ||
| apimeta.SetStatusCondition(&replacement.Status.UserFacingConditions, aggregated) | ||
|
|
||
| // Record the gauge regardless of whether we write to Cosmos |
There was a problem hiding this comment.
The OIDC clients controller keeps the last condition when the HostedCluster is missing or ActiveVersions is empty, so a last-evaluated timestamp gauge would stop a stuck pipeline from looking healthy.
There was a problem hiding this comment.
Raised ticket for this changes - https://redhat.atlassian.net/browse/ARO-30411
| return nil | ||
| } | ||
|
|
||
| // recordDegradedGauge sets backend_externalauth_degraded to 1 if the |
There was a problem hiding this comment.
Right after a create or update a nil Status.Configuration flips this to 1, so how would the SLI tell normal rollout lag from a real failure, maybe with a grace window on operation phase?
|
|
||
| // Emit per-component degradation gauge. Clear all previous component | ||
| // series for this resource first so removed/renamed clients don't leak. | ||
| c.recordPerComponentGauges(externalAuth, degradedSet) |
|
|
||
| // clearPerComponentGauges removes all per-component series for the given | ||
| // external auth (e.g. when clients are empty or the version is unsupported). | ||
| func (c *externalAuthOIDCClientsDegradedController) clearPerComponentGauges(externalAuth *coreapi.ExternalAuth) { |
|
Scheduling tests matching the |
| "Unix timestamp when the external auth was created.", | ||
| ), | ||
| degraded: prometheus.NewGaugeVec(prometheus.GaugeOpts{ | ||
| Name: "backend_externalauth_degraded", |
There was a problem hiding this comment.
#7267 builds a 95 percent non-degraded SLI on this gauge, so could you add a reason label (customer config vs service) so a missing client secret or bad issuer URL stays out of the error budget?
There was a problem hiding this comment.
Currently degradation controller is not providing any reason label as customer config or service. Hence it is not possible to directly add it on metrics. First it has to add it in external auth userfacing condition controller. And this is also not correct according to current design
There was a problem hiding this comment.
Simon Wiencki (@swiencki) To get this information RFE ticker has been raised for Hypershift team. This changes will be needed from them. Hence cannot be added in this scope.
There was a problem hiding this comment.
Thanks, we can drop the scope from the pr but can we card a follow up in https://redhat.atlassian.net/browse/ARO-28393
| } | ||
|
|
||
| value := 0.0 | ||
| if cond.Status == metav1.ConditionTrue { |
There was a problem hiding this comment.
A nil Status.Configuration right after a create or update shows up as degraded, so how will the SLI tell normal rollout lag apart from a real failure?
There was a problem hiding this comment.
The nil-Configuration window only opens after four SyncOnce guards pass (ReadDesire observed, HC exists, ActiveVersions populated, version ≥ 4.20.41), so provision_state is still provisioning at that point. The SLI excludes it at the PromQL level with unless on (resource_id) backend_externalauth_provision_state{phase=~"accepted|provisioning"}, keeping the gauge as ground truth and the grace policy tunable without code changes. Updates to already-provisioned ExternalAuths don't hit this path at all since Configuration is already populated.
There was a problem hiding this comment.
That makes sense for the gauge, but I can't find the unless on (resource_id) backend_externalauth_provision_state{phase=~"accepted|provisioning"} exclusion in this PR, 7723 or main, so can you point me at where it lives or note it as a requirement for whichever PR adds the SLI?
There was a problem hiding this comment.
Added a provisioning-state guard that skips emitting the backend_externalauth_degraded gauge when the ExternalAuth's provisioning state is non-terminal (Accepted, Provisioning, Updating, Deleting, AwaitingSecret). The gauge is only emitted once the state reaches Succeeded, Failed, or Canceled.
51cc443 to
a98dfac
Compare
|
Scheduling tests matching the |
…ient status conditions
a98dfac to
8bc3ed4
Compare
|
/retest |
1. Remove Oldest Degraded Eval panel — metric (backend_externalauth_degraded_last_evaluation_seconds) does not exist on main or in Azure#7583 2. Remove or vector(0) from True Availability — show No data when backend_externalauth_degraded is absent instead of misleading 0% 3. Remove Error Budget Remaining, Error Budget Burn Rate, and Degraded Health Budget panels — these are point-in-time ratios with no window and count AwaitingSecret as bad; hold until windowed good/total rules from ARO-25935 exist 4. Add or vector(0) to Timeliness SLO numerator — show 0% when every create runs late, instead of No data 5. Apply exclude_subs filter to Create >15m, Update >10m, Delete >15m stuck stats, Active Operations table, and In-Flight Operation Duration — matches the stuck alerts which exclude internal subs Co-authored-by: Cursor <cursoragent@cursor.com>
1. Remove Oldest Degraded Eval panel — metric (backend_externalauth_degraded_last_evaluation_seconds) does not exist on main or in Azure#7583 2. Remove or vector(0) from True Availability — show No data when backend_externalauth_degraded is absent instead of misleading 0% 3. Remove Error Budget Remaining, Error Budget Burn Rate, and Degraded Health Budget panels — these are point-in-time ratios with no window and count AwaitingSecret as bad; hold until windowed good/total rules from ARO-25935 exist 4. Add or vector(0) to Timeliness SLO numerator — show 0% when every create runs late, instead of No data 5. Apply exclude_subs filter to Create >15m, Update >10m, Delete >15m stuck stats, Active Operations table, and In-Flight Operation Duration — matches the stuck alerts which exclude internal subs
| // transient Degraded=True that does not represent a real failure. Only | ||
| // emit the gauge once the provisioning state is terminal (Succeeded, | ||
| // Failed, or Canceled) so the SLI is not polluted by normal rollout lag. | ||
| if !externalAuth.Properties.ProvisioningState.IsTerminal() { |
There was a problem hiding this comment.
IsTerminal also skips Updating, so an already degraded ExternalAuth drops out of the gauge for the whole update even though updates never hit the nil Configuration case; could the skip be limited to Accepted, AwaitingSecret and Provisioning?
There was a problem hiding this comment.
AwaitingSecret is one of the degraded states. In the future, it will be labeled as a configuration issue, but explicitly skipping AwaitingSecret would not be a consistent behavior. Added only Accepted and provisioning
8bc3ed4 to
85ee984
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Production deletion bypasses ExternalAuth metric cleanup, leaving stale series exported, while provisioning-state filtering hides explicitly reported degraded failures.
4 open issues
1 resolved since last review
Review effort: Balanced
85ee984 to
08d348f
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
The production controller bypasses metric cleanup when an ExternalAuth is deleted, leaving stale component degradation metrics exported until restart, while the deletion test calls the inner syncer directly and misses this path.
4 open issues
Review effort: Balanced
|
Mansi Mandhare (@m-mandhare): The following test failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
|
Scheduling tests matching the |


Expose Degraded Condition as Prometheus Metric
What
Why
For Grafana dashboard visibility
Testing
Manual testing -
Testing is required for feature completion and tests should be part of the pull
request along with the feature changes.
Describe the testing provided. If you did not add tests, provide a clear
justification.