Skip to content

feat: add controller that calculates Cluster Data Plane Identities extra information - #6592

Merged
openshift-merge-bot[bot] merged 1 commit into
Azure:mainfrom
redhat-chai-bot:feat/dataplane-operator-identities-info
Aug 20, 2026
Merged

feat: add controller that calculates Cluster Data Plane Identities extra information#6592
openshift-merge-bot[bot] merged 1 commit into
Azure:mainfrom
redhat-chai-bot:feat/dataplane-operator-identities-info

Conversation

@redhat-chai-bot

Copy link
Copy Markdown
Collaborator

Rebase of #6300 (single commit, original author preserved) onto current main, with the still-applicable review comments addressed.

This adds a backend controller that enriches ARO-HCP clusters with Azure data plane operator managed-identity metadata (ClientID / PrincipalID) by querying Azure UserAssignedIdentities using the cluster's Service Managed Identity, and persists the results onto ServiceProviderCluster.Status.

Rebase

Review comments addressed

  • uniqueDataPlaneOperatorResourceIDs now returns nil when any ResourceID is nil, as its doc states and callers/tests rely on (previously it called resourceID.String() unconditionally and could panic / never returned nil). This was the root cause of the original ci/prow/test-unit failure.
  • EarliestRecheckTime — explicit nil guard before DeepCopy() on first sync (defensive/intent-signaling per reviewer request).
  • types_serviceprovider_cluster.go — resolved the open TODOs in the new status field comment block, added // Written by: writer annotations and input/output labels on each new leaf field (per the cosmos-data-flow convention in CLAUDE.md), and clarified what a data plane operator is.

Comments intentionally not actioned

  • Items the original author explicitly dismissed as not applicable (empty-DataPlaneOperators short-circuit; ServiceManagedIdentity / ResourceID nil guards — "mandatory, always present from validated API").
  • desiredDataPlaneOperatorResourceIDsMatchSPC OperatorName validation / nil deref — already resolved by the author's prior redesign (the function compares lowercased resource-ID string keys and never dereferences a resourceID); changing it would break the passing tests and the current design.
  • Storage-location / "read from cache" changes — pending an unresolved design decision; left as-is.

Validation

  • make lint — 0 issues repo-wide.
  • make test — the branch-touched packages (backend/pkg/controllers/cluster/identity, internal/api/coreapi) pass; backend/pkg/app compiles and lints clean. (The only local failures were pre-existing tooling/ packages that require promtool/bicep/az on $PATH — they fail identically on a clean main checkout and are untouched by this change.)
  • make verify-deepcopy — passes (no drift; zz_generated.deepcopy.go regenerated via make deepcopy, not hand-edited).

Automated rebase + review-fix assist; please review before merge.


AI-generated. Review for accuracy.

David Eads (@deads2k) requested in Slack thread

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new backend cluster-watching controller that resolves Azure User Assigned Managed Identity metadata (ClientID/PrincipalID) for data plane operator identities configured on an HCP cluster and persists the resolved information to ServiceProviderCluster.Status.

Changes:

  • Introduces FetchDataPlaneOperatorsManagedIdentitiesInfo controller to query Azure UserAssignedIdentities using the cluster’s Service Managed Identity and store results under ServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities.
  • Extends ServiceProviderClusterStatus with new status structures for data plane operator managed identity resolution + recheck gating.
  • Regenerates deepcopy code and wires the controller into backend startup.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
internal/api/coreapi/zz_generated.deepcopy.go Regenerated deepcopy methods for the new ServiceProviderCluster status types.
internal/api/coreapi/types_serviceprovider_cluster.go Adds DataPlaneOperatorsManagedIdentities status fields and associated types + writer annotations.
backend/pkg/controllers/cluster/identity/fetch_data_plane_operators_managed_identities_info.go New controller implementing Azure lookups, deduping, persistence, and recheck gating.
backend/pkg/controllers/cluster/identity/fetch_data_plane_operators_managed_identities_info_test.go Unit tests for helper logic (matching/deduping/needsWork).
backend/pkg/app/backend.go Registers/runs the new controller under leader election.
Files not reviewed (1)
  • internal/api/coreapi/zz_generated.deepcopy.go: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI review requested due to automatic review settings August 19, 2026 15:54
@redhat-chai-bot
Chai-bot (redhat-chai-bot) force-pushed the feat/dataplane-operator-identities-info branch from 034dd76 to 32dd9d5 Compare August 19, 2026 15:54
@redhat-chai-bot

Copy link
Copy Markdown
Collaborator Author

Pushed 32dd9d570 addressing both Copilot review comments:

  1. nil ServiceManagedIdentity guard — prevents a nil-pointer panic (backend crash) in the SMI client builder; returns a tracked/requeuing error instead.
  2. EarliestRecheckTime cleared on Get errors — ensures the workqueue actually retries after a partial/failed sync instead of being gated out by a stale future recheck time.

Added two unit tests covering both paths. Local validation: go test ./backend/pkg/controllers/cluster/identity/... passes (incl. the 2 new tests), make lint reports 0 issues repo-wide, and make verify is clean (no generated-file drift). History remains a single commit (original author preserved).


AI-generated. Review for accuracy.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • internal/api/coreapi/zz_generated.deepcopy.go: Generated file
Suppressed comments (2)

internal/api/coreapi/types_serviceprovider_cluster.go:338

  • The new status fields use JSON tags clientID/principalID, but existing API/Cosmos types consistently use clientId/principalId (e.g. internal/api/coreapi/identity.go:29-31, internal/api/coreapi/types_operation.go:45-48). Since this is a newly introduced persisted schema, aligning the tag casing avoids inconsistent field names across documents and potential consumer confusion.
	ClientID *string `json:"clientID,omitempty"`
	// PrincipalID is the Principal ID of the Azure User Assigned Managed Identity represented by ResourceID.
	// This field is an output: it is fetched from Azure and written here by the controller.
	// Written by: FetchDataPlaneOperatorsManagedIdentitiesInfoController
	PrincipalID *string `json:"principalID,omitempty"`

internal/api/coreapi/types_serviceprovider_cluster.go:244

  • This PR adds a new controller that reads/writes Cosmos fields on ServiceProviderCluster.Status, and adds a new persisted status field. Per CLAUDE.md:260-267, docs/cosmos-data-flow.md should be regenerated whenever changes touch backend/pkg/controllers/ or internal/api/types_*.go; the current docs/cosmos-data-flow.md has no mention of FetchDataPlaneOperatorsManagedIdentitiesInfo or dataPlaneOperatorsManagedIdentities.
	// cluster that runs in the cluster's data plane.
	// For example, the Cluster's CustomerProperties.Platform.OperatorsAuthentication.UserAssignedIdentities.DataPlaneOperators map
	// contains the set of required data plane operators associated to a Cluster.
	// Written by: FetchDataPlaneOperatorsManagedIdentitiesInfoController
	DataPlaneOperatorsManagedIdentities ServiceProviderClusterDataPlaneOperatorsManagedIdentities `json:"dataPlaneOperatorsManagedIdentities,omitempty"`

@redhat-chai-bot

Copy link
Copy Markdown
Collaborator Author

/retest e2e-parallel

The e2e-parallel failure on 32dd9d570 was a post-phase observability check — [aro-hcp-observability] [svc] alert FrontendPathLatency does not fire briefly fired (Sev3/warning, frontend PUT p99 latency > 1s, auto-resolved after ~9 min). This is a transient frontend-latency SLO flake unrelated to this PR's backend change (which only populates ServiceProviderCluster.Status). All other checks (lint, test-unit, verify, integration, CodeQL, images) are green. Retesting.


AI-generated. Review for accuracy.

return nil
}

existingServiceProviderCluster, err := corecosmosstorage.GetOrCreateServiceProviderCluster(ctx, c.resourcesDBClient, key.GetResourceID())

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, use a lister

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 83790720d. Switched the ServiceProviderCluster read to a lister too: added serviceProviderClusterLister corelisters.ServiceProviderClusterLister (from backendInformers.ServiceProviderClusters()), replacing GetOrCreateServiceProviderCluster with c.serviceProviderClusterLister.Get(...) plus if cosmosstorageutils.IsNotFoundError(err) { return nil }. On a missing SPC we now no-op and let the dedicated create-controller create it (then we pick it up on requeue) — matching the sibling serviceprovidercluster_properties_sync controller. resourcesDBClient is retained only for the Replace.


AI-generated. Review for accuracy.

}

func (c *fetchDataPlaneOperatorsManagedIdentitiesInfoSyncer) SyncOnce(ctx context.Context, key controllerutils.HCPClusterKey) error {
existingCluster, err := c.resourcesDBClient.HCPClusters(key.SubscriptionID, key.ResourceGroupName).Get(ctx, key.HCPClusterName)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, use a lister

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 83790720d. Switched the HCPCluster read to the informer-backed lister: added a clusterLister corelisters.ClusterLister field, populated from the backendInformers the constructor already receives (_, clusterLister := backendInformers.Clusters()), and replaced the direct resourcesDBClient.HCPClusters(...).Get with c.clusterLister.Get(ctx, ...). No backend.go wiring change needed.


AI-generated. Review for accuracy.

func (c *fetchDataPlaneOperatorsManagedIdentitiesInfoSyncer) needsWork(spc *coreapi.ServiceProviderCluster, desiredDataPlaneOperatorsResourceIDStrs map[string]struct{}) bool {
// Only honor EarliestRecheckTime when the desired identity set still matches
// SPC. Any mismatch should fall through to return true and query Azure.
if c.desiredDataPlaneOperatorResourceIDsMatchSPC(desiredDataPlaneOperatorsResourceIDStrs, spc) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't abbreviate serviceProviderCluster as spc anywhere.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 83790720d. Spelled out serviceProviderCluster everywhere it was abbreviated spc in the controller and its test — including the function desiredDataPlaneOperatorResourceIDsMatchSPCdesiredDataPlaneOperatorResourceIDsMatchServiceProviderCluster, all params/locals (spc, spcIdentities, matchingSPCIdentities, updatedSPC), the test function name, and the SPC references in doc comments.


AI-generated. Review for accuracy.

// Accumulate Get failures and keep going so successfully resolved identities
// can still be persisted. Preserve any previously resolved ClientID/PrincipalID
// so a transient failure does not wipe known values.
if existingIdentity := existingServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities.Identities[identityResourceIDStr]; existingIdentity != nil {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, don't do this. If we got an error, then clear the data. It doesn't matter what kind of error it was or if we have previous data. That way we never have stale data. You can create a struct member for "RetrievalError" that contains the first 1024 characters of the failure.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 83790720d. Added RetrievalError *string (json retrievalError,omitempty, with a // Written by: annotation) to ServiceProviderClusterDataPlaneOperatorManagedIdentity, and regenerated deepcopy. On a Get error we now clear ClientID/PrincipalID and set RetrievalError to the first 1024 chars (rune-safe) of the failure — no stale data is ever retained. Non-NotFound errors are still accumulated (fatal → EarliestRecheckTime cleared so the workqueue retries); a successful Get clears RetrievalError back to nil.

One judgment call I'd like your read on: I also set RetrievalError on the Azure ResourceNotFound branch (kept non-fatal, as today) so that whenever ClientID/PrincipalID are nil there's always an explanation for why. If you'd prefer ResourceNotFound to stay a clean "known-absent" signal with no RetrievalError, I'll restrict it to the transient-error branch only — just say the word.


AI-generated. Review for accuracy.

Copilot AI review requested due to automatic review settings August 19, 2026 20:22
@redhat-chai-bot
Chai-bot (redhat-chai-bot) force-pushed the feat/dataplane-operator-identities-info branch from 32dd9d5 to 8379072 Compare August 19, 2026 20:22
@redhat-chai-bot

Copy link
Copy Markdown
Collaborator Author

/test e2e-parallel


AI-generated. Review for accuracy.

@redhat-chai-bot

Copy link
Copy Markdown
Collaborator Author

Pushed 83790720d addressing David Eads (@deads2k)'s review:

  • Use listers, not direct DB getsHCPCluster and ServiceProviderCluster are now read via informer-backed listers (clusterLister / serviceProviderClusterLister), matching the sibling serviceprovidercluster_properties_sync controller. On a missing SPC we no-op and rely on the create-controller (no more inline get-or-create).
  • No spc abbreviation — spelled out serviceProviderCluster throughout the controller and tests, including the …MatchSPC function name.
  • Clear data on any Get error + RetrievalError field — never retain stale ClientID/PrincipalID; record the first 1024 chars of the failure in a new RetrievalError status field (deepcopy regenerated). One open question about the ResourceNotFound branch noted inline.

Validation: go test for the identity + coreapi packages passes, make lint 0 issues repo-wide, make verify clean (deepcopy in sync). Single commit, original author preserved.


AI-generated. Review for accuracy.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • internal/api/coreapi/zz_generated.deepcopy.go: Generated file
Suppressed comments (2)

backend/pkg/controllers/cluster/identity/fetch_data_plane_operators_managed_identities_info.go:227

  • ServiceManagedIdentity is guarded unconditionally before building the Azure client, but DataPlaneOperators can be empty/nil in the core model (and uniqueDataPlaneOperatorResourceIDs returns an empty set in that case). That means this controller can repeatedly return an error for clusters that have no data-plane operator identities to resolve (because SMI is nil), even though there is no work to do. Consider only requiring/building the SMI-backed UserAssignedIdentitiesClient when len(identitiesToSync) > 0 so empty desired sets can no-op/clear status without needing a Service Managed Identity.
	smiResourceID := existingCluster.CustomerProperties.Platform.OperatorsAuthentication.UserAssignedIdentities.ServiceManagedIdentity
	if smiResourceID == nil {
		// ServiceManagedIdentity is optional in the cluster model (*azcorearm.ResourceID with
		// omitempty). The SMI client builder dereferences smiResourceID.String() internally, so a
		// nil value would panic and crash the backend process. Return a tracked error instead so the

internal/api/coreapi/types_serviceprovider_cluster.go:245

  • This PR adds a new Cosmos-persisted status subtree (status.dataPlaneOperatorsManagedIdentities) written by a new backend controller. Per CLAUDE.md, changes that add Cosmos reads/writes or new Cosmos-stored fields must be reflected in docs/cosmos-data-flow.md, but that doc currently has no entry for this field/controller.
	// For example, the Cluster's CustomerProperties.Platform.OperatorsAuthentication.UserAssignedIdentities.DataPlaneOperators map
	// contains the set of required data plane operators associated to a Cluster.
	// Written by: FetchDataPlaneOperatorsManagedIdentitiesInfoController
	DataPlaneOperatorsManagedIdentities ServiceProviderClusterDataPlaneOperatorsManagedIdentities `json:"dataPlaneOperatorsManagedIdentities,omitempty"`
}

Copilot AI review requested due to automatic review settings August 19, 2026 21:36
@redhat-chai-bot
Chai-bot (redhat-chai-bot) force-pushed the feat/dataplane-operator-identities-info branch from 8379072 to 918949f Compare August 19, 2026 21:36
@redhat-chai-bot

Copy link
Copy Markdown
Collaborator Author

Pushed 918949f3b folding in the two Copilot suggestions (both non-blocking, but tidied up while here):

  • JSON tag casing — new status fields now use clientId / principalId to match the repo standard (verified: identity.go, types_operation.go, types_externalauth.go all use the lowercase-d form; these two fields were the only outliers). Go field names unchanged, so no deepcopy impact. resourceID left as-is (repo is genuinely mixed on that one and it's out of scope).
  • docs/cosmos-data-flow.md — added a FetchDataPlaneOperatorsManagedIdentitiesInfo controller entry plus the ServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities writer mapping, following the file's existing format (no generator exists for this doc).

make lint 0 issues, make verify clean, identity + coreapi tests pass. Still a single commit (original author preserved). CI re-running.


AI-generated. Review for accuracy.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • internal/api/coreapi/zz_generated.deepcopy.go: Generated file
Suppressed comments (1)

internal/api/coreapi/types_serviceprovider_cluster.go:322

  • This comment describes a data plane operator as a "customer operator", while the earlier field comment describes it as a Kubernetes operator. Please align the terminology, and consider wrapping the long sentence for readability.
// A cluster's data plane operator is a customer operator associated to the cluster that runs in the cluster's data plane.

Comment on lines +239 to +240
// A cluster's data plane operator is a kubernetes operator associated to the
// cluster that runs in the cluster's data plane.
Comment on lines +294 to +301
if cosmosstorageutils.IsPreconditionFailedError(err) {
// Status (including any new DataPlaneOperatorsManagedIdentitiesEarliestRecheckTime) was not written.
// needsWork will still see the previously persisted value.
return errors.Join(errs...)
}
if err != nil {
// Same as precondition failure: DataPlaneOperatorsManagedIdentitiesEarliestRecheckTime was not
// persisted, so needsWork will still see the previously persisted value.
@deads2k

Copy link
Copy Markdown
Collaborator

/approve

@machi1990

Copy link
Copy Markdown
Collaborator

/lgtm

@redhat-chai-bot

Copy link
Copy Markdown
Collaborator Author

/test lint

(The ci/prow/lint failure was a CI infra flake — the job failed at namespace initialization (the object has been modified ... reason: initializing_namespace) after 0s; golangci-lint never ran. Re-triggering.)


AI-generated. Review for accuracy.

@deads2k

Copy link
Copy Markdown
Collaborator

digging into latency debugging. New page shows rule of small numbers. in the meantime.

/retest

…tra information

We add a controller that retrieves the Client ID and Principal ID associated to the
Data Plane operators identities associated to the ARO-HCP Cluster.

We leverage the Service Managed Identity associated to the ARO-HCP Cluster to retrieve
the Data Plane operators identities information. We use Azure Go SDK's
UserAssignedIdentities API to retrieve it. This is a different method than what's done
for MSI based identities where the Managed Identities Data Plane service is used instead.
This is because for the MSI based identities, on the environments where the managed identities
data plane service is not available, we use the mi mock identity instead, which includes
its clientid+principalid instead of the ones associated to the identities passed in the
cluster payload. By using the mock managed identities data plane client we retrieve
that transparently. We do that also because that identity/information is the one that
needs to be used by the control plane operators themselves on the control plane side.

Address still-applicable review comments (rebased onto latest main):
- uniqueDataPlaneOperatorResourceIDs now returns nil when any desired ResourceID
  is nil, as its doc states and as SyncOnce (identitiesToSync == nil) and the unit
  tests rely on; previously it called ResourceID.String() unconditionally and
  panicked on a nil entry.
- Guard against a nil cluster ServiceManagedIdentity in SyncOnce before building
  the Service Managed Identity client. The SMI client builder dereferences
  smiResourceID.String() internally, so a nil ServiceManagedIdentity (optional in
  the cluster model) would panic and crash the backend; return a tracked error so
  the workqueue retries once it is populated.
- Clear EarliestRecheckTime to nil on accumulated Azure Get failures (initialize it
  to nil and only set the jittered recheck time in the success branch). Previously a
  future EarliestRecheckTime could be persisted alongside a partial update after the
  desired identity set changed, and needsWork would then suppress workqueue retries
  until that future time even though SyncOnce returned an error.
- internal/api/coreapi: add explicit "Written by:" annotations to the
  ResourceID/ClientID/PrincipalID leaf fields and clarify input vs output, per the
  CLAUDE.md cosmos-data-flow convention.
- Fix gci import grouping in the controller unit test so `make lint` passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 20, 2026 18:08
@redhat-chai-bot
Chai-bot (redhat-chai-bot) force-pushed the feat/dataplane-operator-identities-info branch from 918949f to de749e6 Compare August 20, 2026 18:08
@openshift-ci openshift-ci Bot removed the lgtm label Aug 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • internal/api/coreapi/zz_generated.deepcopy.go: Generated file

Comment on lines +389 to +393
// RetrievalError, when non-nil, is the error (truncated to the first 1024 characters) from the
// most recent attempt to retrieve this identity's metadata from Azure. When set, ClientID and
// PrincipalID are nil because the last retrieval attempt failed - either the identity was not
// found in Azure or the Get call returned an error - and any previously resolved values are no
// longer trustworthy. It is nil when the last retrieval succeeded.
Comment thread docs/cosmos-data-flow.md
| Read | `HCPOpenShiftCluster` | <ul><li>`ServiceProviderProperties.DeletionTimestamp` (SyncOnce: must be nil)</li><li>`CustomerProperties.Platform.OperatorsAuthentication.UserAssignedIdentities.DataPlaneOperators` (desired identity ResourceIDs, deduplicated + lowercased)</li><li>`CustomerProperties.Platform.OperatorsAuthentication.UserAssignedIdentities.ServiceManagedIdentity` (SyncOnce: must not be nil)</li><li>`ServiceProviderProperties.ManagedIdentitiesDataPlaneIdentityURL` (used to build the SMI client)</li><li>`ID` (subscription / resource group / name)</li></ul> |
| Read | `ServiceProviderCluster` | <ul><li>`Status.DataPlaneOperatorsManagedIdentities.Identities` (needsWork: compared to the desired ResourceID set)</li><li>`Status.DataPlaneOperatorsManagedIdentities.EarliestRecheckTime` (needsWork: honored only when identities match)</li></ul> |
| Read | Azure (UserAssignedIdentitiesClient) | <ul><li>`Get` once per unique ResourceID -> `Properties.ClientID`, `Properties.PrincipalID`</li></ul> |
| **Write** | **`ServiceProviderCluster`** | <ul><li>**`Status.DataPlaneOperatorsManagedIdentities.Identities[<lowercased resourceID>]`** = `{ResourceID, ClientID, PrincipalID, RetrievalError}` — ClientID/PrincipalID from Azure on success (RetrievalError nil); on any Get failure (including ResourceNotFound) ClientID/PrincipalID are cleared (nil) and RetrievalError is set to the first 1024 chars of the error. Identities no longer present on the cluster are pruned.</li><li>**`Status.DataPlaneOperatorsManagedIdentities.EarliestRecheckTime`** = now + jittered 12h interval when all Gets succeed; left nil (cleared) when any Get error is accumulated, so the next needsWork re-queries Azure</li></ul> |
Comment on lines +272 to +290
// For ClientID and PrincipalID of the identity, we set the value returned from the Azure API as is. This includes the cases where the
// value is nil or empty. RetrievalError is left nil because the retrieval succeeded.
replacementIdentity.ClientID = currentMI.Properties.ClientID
replacementIdentity.PrincipalID = currentMI.Properties.PrincipalID
}

if len(errs) == 0 {
// Set an earliest recheck time for the controller so we do not hit the Azure API too often.
// The value below is only honored once Replace persists it. A Replace failure leaves Cosmos
// unchanged, so needsWork will still see the previously persisted value (if any).
// On Get failures we skip this branch entirely: EarliestRecheckTime stays nil (see the
// replacement initialization above), so needsWork keeps returning true and the workqueue
// retry re-queries Azure instead of waiting out a stale recheck interval.
recheckAt := metav1.NewTime(c.clock.Now().Add(wait.Jitter(
dataPlaneOperatorsManagedIdentitiesRecheckInterval,
dataPlaneOperatorsManagedIdentitiesRecheckJitter,
)))
replacement.Status.DataPlaneOperatorsManagedIdentities.EarliestRecheckTime = &recheckAt
}
Comment on lines +40 to +42
const (
fetchDataPlaneOperatorsManagedIdentitiesInfoControllerName = "FetchDataPlaneOperatorsManagedIdentitiesInfo"

@deads2k

Copy link
Copy Markdown
Collaborator

/lgtm

@openshift-ci

openshift-ci Bot commented Aug 20, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: deads2k, machi1990, redhat-chai-bot

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot
openshift-merge-bot Bot merged commit 6d80f4d into Azure:main Aug 20, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants