Skip to content

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

Open
Miguel Soriano (miguelsorianod) wants to merge 2 commits into
Azure:mainfrom
miguelsorianod:msoriano-fetchinfo-dataplaneoperators-mis
Open

feat: add controller that calculates Cluster Data Plane Identities extra information#6300
Miguel Soriano (miguelsorianod) wants to merge 2 commits into
Azure:mainfrom
miguelsorianod:msoriano-fetchinfo-dataplaneoperators-mis

Conversation

@miguelsorianod

Copy link
Copy Markdown
Collaborator

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 (#3820). This is because for the control plane 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.

Copilot AI lite review requested due to automatic review settings July 28, 2026 11:40
@openshift-ci

openshift-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: miguelsorianod

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

@miguelsorianod

Copy link
Copy Markdown
Collaborator Author

/hold for now

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

This PR adds backend-side reconciliation 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 (SMI), and persists the results onto ServiceProviderCluster.Status.

Changes:

  • Add a new backend controller that reads data plane operator identity resource IDs from the cluster document and resolves identity metadata via Azure’s UserAssignedIdentities API.
  • Extend ServiceProviderClusterStatus with a DataPlaneOperatorsManagedIdentities map and generate the corresponding deepcopy methods.
  • Wire the new controller into backend startup under leader election.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 7 comments.

File Description
internal/api/zz_generated.deepcopy.go Adds deepcopy support for the new status map value type.
internal/api/types_serviceprovider_cluster.go Introduces DataPlaneOperatorsManagedIdentities status field and its value struct.
backend/pkg/controllers/fetch_data_plane_operators_managed_identities_info.go New controller that resolves ClientID/PrincipalID for data plane operator identities and writes to ServiceProviderCluster.Status.
backend/pkg/app/backend.go Registers and runs the new controller in the backend controller set.
Files not reviewed (1)
  • internal/api/zz_generated.deepcopy.go: Generated file
Comments suppressed due to low confidence (1)

backend/pkg/controllers/fetch_data_plane_operators_managed_identities_info.go:80

  • Use the controller name constant here instead of a string literal (see CLAUDE.md:201).
		"FetchDataPlaneOperatorsManagedIdentitiesInfo",

Comment on lines +201 to +205
// DataPlaneOperatorsManagedIdentities is a map of data plane operator managed identities.
// The key is the Azure Resource ID of the managed identity
// TODO do we want the key to be the operator name or the Azure Resource ID?
// TODO do we want to store both the operator name and the Azure Resource ID?
DataPlaneOperatorsManagedIdentities map[string]*ServiceProviderClusterDataPlaneOperatorManagedIdentity `json:"dataPlaneOperatorsManagedIdentities,omitempty"`
// to an operator.
func NewFetchDataPlaneOperatorsManagedIdentitiesInfoController(
resourcesDBClient database.ResourcesDBClient,
activeOperationLister listers.ActiveOperationLister,
Comment on lines +91 to +97
func (c *fetchDataPlaneOperatorsManagedIdentitiesInfoSyncer) needsWork(cluster *api.HCPOpenShiftCluster) bool {
if cluster.ServiceProviderProperties.DeletionTimestamp != nil {
return false
}

return true
}

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.

There will always be dataplane operators configured. This does not apply

Comment thread backend/pkg/controllers/fetch_data_plane_operators_managed_identities_info.go Outdated
Comment on lines +99 to +105
func (c *fetchDataPlaneOperatorsManagedIdentitiesInfoSyncer) SyncOnce(ctx context.Context, key controllerutils.HCPClusterKey) error {
existingCluster, err := c.resourcesDBClient.HCPClusters(key.SubscriptionID, key.ResourceGroupName).Get(ctx, key.HCPClusterName)
if database.IsNotFoundError(err) {
return nil // cluster doesn't exist, no work to do
}
if err != nil {
return utils.TrackError(fmt.Errorf("failed to get Cluster: %w", err))

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.

Waiting until design is agreed upon

@@ -0,0 +1,200 @@
// Copyright 2026 Microsoft Corporation

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.

TODO decide file location

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.

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.

a controllers/cluster/identity directory seems logical in the new structure.

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.

Changed to there

Copilot AI review requested due to automatic review settings July 28, 2026 12:00
@miguelsorianod
Miguel Soriano (miguelsorianod) force-pushed the msoriano-fetchinfo-dataplaneoperators-mis branch from ef423bb to 61e2bf3 Compare July 28, 2026 12:00

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 3 out of 4 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • internal/api/zz_generated.deepcopy.go: Generated file
Comments suppressed due to low confidence (4)

internal/api/types_serviceprovider_cluster.go:205

  • This new Cosmos-persisted status field is missing the required Written by: annotation used elsewhere in this file for ServiceProviderCluster leaf fields (e.g. HostedClusterNamespace/ControlPlaneNamespace/ServingCABundle). Please add the controller name so writers are auditable and docs generation stays accurate.
	// DataPlaneOperatorsManagedIdentities is a map of data plane operator managed identities.
	// The key is the Azure Resource ID of the managed identity
	// TODO do we want the key to be the operator name or the Azure Resource ID?
	// TODO do we want to store both the operator name and the Azure Resource ID?
	DataPlaneOperatorsManagedIdentities map[string]*ServiceProviderClusterDataPlaneOperatorManagedIdentity `json:"dataPlaneOperatorsManagedIdentities,omitempty"`

backend/pkg/controllers/fetch_data_plane_operators_managed_identities_info.go:185

  • When any identity lookup fails or returns missing ClientID/PrincipalID, this controller currently builds a partial/empty replacement map and still writes it to ServiceProviderCluster, which can delete previously-correct identity info due to transient Azure errors. Consider skipping the Replace when there were syncErrors so status doesn’t flap/lose data.
	if equality.Semantic.DeepEqual(replacement.Status.DataPlaneOperatorsManagedIdentities, existingServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities) {
		return errors.Join(syncErrors...)
	}

internal/api/types_serviceprovider_cluster.go:213

  • The new ServiceProviderClusterDataPlaneOperatorManagedIdentity fields are persisted to Cosmos but don’t include the per-leaf Written by: annotations required by the repo’s Cosmos data-flow conventions. Please annotate each leaf field with its writer (this controller) so future write-path changes are discoverable.
	OperatorName string                `json:"operatorName"`
	ResourceID   *azcorearm.ResourceID `json:"resourceID,omitempty"`
	ClientID     string                `json:"clientID,omitempty"`
	PrincipalID  string                `json:"principalID,omitempty"`
}

backend/pkg/controllers/fetch_data_plane_operators_managed_identities_info.go:193

  • This PR introduces a new Cosmos write-path for ServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities, but docs/cosmos-data-flow.md doesn’t currently document this field/writer (no matches for DataPlaneOperatorsManagedIdentities). Please regenerate/update the cosmos data flow documentation to include this new status field and its writer controller.
	_, err = c.resourcesDBClient.ServiceProviderClusters(existingCluster.ID.SubscriptionID, existingCluster.ID.ResourceGroupName, existingCluster.ID.Name).Replace(ctx, replacement, nil)
	if database.IsPreconditionFailedError(err) {
		return errors.Join(syncErrors...)
	}
	if err != nil {
		syncErrors = append(syncErrors, utils.TrackError(fmt.Errorf("failed to replace ServiceProviderCluster: %w", err)))
	}

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 3 out of 4 changed files in this pull request and generated no new comments.

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

internal/api/types_serviceprovider_cluster.go:209

  • New Cosmos-persisted fields should follow the established "Written by:" annotation pattern, and the open TODO questions here suggest the storage key/shape is not finalized. Please either resolve the design choice in this PR (and document it in the comment) or link to a tracked issue, and add a "Written by:" line for this field.
	// DataPlaneOperatorsManagedIdentities is a map of data plane operator managed identities.
	// The key is the Azure Resource ID of the managed identity
	// TODO do we want the key to be the operator name or the Azure Resource ID?
	// TODO do we want to store both the operator name and the Azure Resource ID?
	DataPlaneOperatorsManagedIdentities map[string]*ServiceProviderClusterDataPlaneOperatorManagedIdentity `json:"dataPlaneOperatorsManagedIdentities,omitempty"`

internal/api/types_serviceprovider_cluster.go:263

  • Per the internal API/Cosmos conventions in this repo, each leaf field stored in Cosmos should include a "Written by:" annotation so future readers can trace which controller/endpoint owns the data. These new fields are missing those annotations.
	OperatorName string                `json:"operatorName"`
	ResourceID   *azcorearm.ResourceID `json:"resourceID,omitempty"`
	ClientID     string                `json:"clientID,omitempty"`
	PrincipalID  string                `json:"principalID,omitempty"`
}

backend/pkg/controllers/fetch_data_plane_operators_managed_identities_info.go:185

  • As implemented, any transient Azure Get error (or missing properties) will cause this controller to write a partial map and implicitly delete previously-synced entries from ServiceProviderCluster.Status. That can cause status flapping and unnecessary Cosmos writes, and can temporarily remove data that was previously correct. Consider skipping the Replace entirely when syncErrors is non-empty so status only moves forward when a full successful read occurs.
	if equality.Semantic.DeepEqual(replacement.Status.DataPlaneOperatorsManagedIdentities, existingServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities) {
		return errors.Join(syncErrors...)
	}

backend/pkg/controllers/fetch_data_plane_operators_managed_identities_info.go:64

  • This controller adds a new Cosmos write path (ServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities). The repo requires keeping docs/cosmos-data-flow.md in sync with Cosmos reads/writes; please update that document to include this new writer and field.
// NewFetchDataPlaneOperatorsManagedIdentitiesInfoController creates a cluster-watching
// controller that keeps ServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities
// in sync with the cluster's CustomerProperties data plane operator managed identities.
//
// On each sync it:
//  1. Reads every operator -> ResourceID entry from
//     Cluster.CustomerProperties.Platform.OperatorsAuthentication.UserAssignedIdentities.DataPlaneOperators.
//  2. Uses the cluster's Service Managed Identity to call Azure UserAssignedIdentitiesClient Get for each
//     ResourceID and resolve ClientID and PrincipalID.
//  3. Rebuilds Status.DataPlaneOperatorsManagedIdentities as a full desired map keyed
//     by ResourceID (operator name, ResourceID, ClientID, PrincipalID). Entries that
//     are no longer present on the cluster are pruned. Identities whose Azure Get
//     fails or returns empty ClientID/PrincipalID are omitted from the written map
//     and surfaced as sync errors so the controller retries. This means that if for some reason
//     the SPC had an entry with the info and the API had an issue and/or stopped returning some of the expected
//     info we delete the entry from the SPC.
//  4. Writes the ServiceProviderCluster only when the desired map differs from status.

@deads2k David Eads (deads2k) left a comment

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.

needs earliest recheck time. otherwise some doc needs updating and its a reasonable start.

// the cluster, including deny assignments and the managed resource group.
AzureResources AzureResources `json:"azureResources,omitempty"`

// DataPlaneOperatorsManagedIdentities is a map of data plane operator managed identities.

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.

What is a data plane operator? Provide a few examples. Everyone seems to have a different definition of what these are.

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.

I updated the doc in general. Let me know if it's now more clear

Comment on lines +261 to +262
ClientID string `json:"clientID,omitempty"`
PrincipalID string `json:"principalID,omitempty"`

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.

document what these are and whether they are input or output.

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.

updated doc

// the HCPCluster resource. For now we put it in the ServiceProviderCluster resource.
// Maybe on the Cluster's ServiceProviderProperties because it would ensure that we can leverage ETag to ensure we calculated from
// the content of the Cluster?
existingServiceProviderCluster, err := database.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.

just read from the cache.

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.

👍 . Waiting to do the change until we decide whether we need to store it in ServiceProviderCluster or in Cluster's ServiceProviderProperties

}

func (c *fetchDataPlaneOperatorsManagedIdentitiesInfoSyncer) needsWork(cluster *api.HCPOpenShiftCluster) bool {
return cluster.ServiceProviderProperties.DeletionTimestamp == 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.

how often do we really need to check this? EarliestRecheckTime *metav1.Time seems like a good fit here.

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.

Added an EarliestRecheckTime. Converted the original map to a struct that contains the map + earliestrechecktime (the recheck is at the overall map level)

Comment on lines +140 to +144
// TODO as of now if there's any error processing the identity, if it's missing properties or any of the expected info we remove the identity
// from the SPC. This means that if for some reason the SPC had an entry with the info and the API stopped returning it we are deleting it.
// Alternatives could be:
// - Keep what's in the SPC for that entry in that case
// - Write what we can. This makes us having the PrincipalID and ClientID attributes as pointers instead.

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.

I'm willing to start anywhere, but for the alternatives it's probably best to decide which outcome is likely to result in the best secure behavior possible in most cases.

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.

It depends on what do we understand by "best secure behavior":

What do we want to do when we find unexpected missing parts of the expected result or issues processing the result: we can keep what's before to not "unset" if there was something, or simply consider it as not existing, and at what granularity?

@miguelsorianod Miguel Soriano (miguelsorianod) Aug 11, 2026

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.

For now what I've done is:

  • We only perform a Cosmos replace if we've been able to successfully call the Azure API for all identities.
  • When the previous point occurs, we copy the value returned by the Azure API as-is for the ClientID and PrincipalID. At the Go type level they are string pointers so we are storing them in Cosmos as string pointers too
  • For an identity Azure API call result, if the result is that the identity is not found then we still persist it in Cosmos but we set it with the ClientID and PrincipalID as nil.

This behavior is similar to what's done for the MSI-based identities. In that case, the MIDataplane service always returns a response even if the managed identity does not exist. When it does not exist the result is returned and the ClientID and PrincipalID that it returns is nil.
The all-or-nothing behavior is also similar to what's done for the MSI-based identities. For those, to save API calls we request all the information in a single call. For this PR, the UserAssignedIdentities client does not allow batching the request so we need to perform N calls, but we imitate the all-or-nothing approach of the MSI-based identities controller.

@@ -0,0 +1,200 @@
// Copyright 2026 Microsoft Corporation

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.

a controllers/cluster/identity directory seems logical in the new structure.

Copilot AI review requested due to automatic review settings August 4, 2026 12:31
@miguelsorianod
Miguel Soriano (miguelsorianod) force-pushed the msoriano-fetchinfo-dataplaneoperators-mis branch from 5227da6 to 2f48e12 Compare August 4, 2026 12:31
@miguelsorianod

Copy link
Copy Markdown
Collaborator Author

a controllers/cluster/identity directory seems logical in the new structure.
moved there 👍

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 3 out of 4 changed files in this pull request and generated no new comments.

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

internal/api/types_serviceprovider_cluster.go:237

  • Same as above: the Written by: annotations should match the controller name (FetchDataPlaneOperatorsManagedIdentitiesInfo) rather than using a ...Controller suffix, to stay consistent with other internal/api writer annotations.
	// Identities is a map containing extra information about the Azure User
	// Assigned Managed Identities associated to the cluster's data plane
	// operators. The key is the Azure Resource ID of the Azure User Assigned
	// Managed Identity associated to a data plane operator.
	// Written by: FetchDataPlaneOperatorsManagedIdentitiesInfoController
	Identities map[string]*ServiceProviderClusterDataPlaneOperatorManagedIdentity `json:"identities,omitempty"`
	// EarliestRecheckTime is the earliest time at which the controller should
	// re-query Azure for ClientID/PrincipalID of Identities. Nil means recheck
	// immediately. The same recheck time applies across all elements of Identities.
	// This allows the controller to avoid repeatedly hitting an Azure API to
	// recheck that the desired state is true.
	// Controllers should set this field with substantial jitter: without another
	// concern, jitter of 50% is considered normal so that any storms are quickly
	// dissipated. Additionally, long recheck times are recommended for resources
	// outside of their active phases. Order of at least six hours is, with
	// durations up to 24 hours considered normal.
	// Written by: FetchDataPlaneOperatorsManagedIdentitiesInfoController
	EarliestRecheckTime *metav1.Time `json:"earliestRecheckTime,omitempty"`

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

  • This file lives under backend/pkg/controllers/cluster/identity/, but declares package controllers. All other cluster controller subdirectories use a package name matching the directory (e.g. deletion/placement/properties all use package <dir>), so this is inconsistent and makes imports/navigation confusing.
package controllers

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

  • dataPlaneOperatorsManagedIdentitiesRecheckInterval is set to 60s, but both the status field docs and this controller’s own doc comment describe using a “long” recheck window (6–24h recommended) to avoid repeatedly hitting Azure. A 1-minute steady-state recheck will likely cause unnecessary Azure traffic and throttling risk.
	// dataPlaneOperatorsManagedIdentitiesRecheckInterval is the base interval
	// before re-querying Azure for ClientID/PrincipalID when the desired set of
	// identities is already fully resolved. Combined with
	// dataPlaneOperatorsManagedIdentitiesRecheckJitter via wait.Jitter.
	dataPlaneOperatorsManagedIdentitiesRecheckInterval = 60 * time.Second
	dataPlaneOperatorsManagedIdentitiesRecheckJitter   = 0.5

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

  • This change adds new Cosmos write behavior (ServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities) from a backend controller, but docs/cosmos-data-flow.md does not yet document this field/controller. Per repo conventions, Cosmos read/write paths should be kept in sync in that doc.
// fetchDataPlaneOperatorsManagedIdentitiesInfoSyncer reconciles
// ServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities from the
// cluster's configured data plane operator managed identities.
type fetchDataPlaneOperatorsManagedIdentitiesInfoSyncer struct {
	clock             utilsclock.PassiveClock
	resourcesDBClient database.ResourcesDBClient

	smiClientBuilder azureclient.ServiceManagedIdentityClientBuilder
}

internal/api/types_serviceprovider_cluster.go:213

  • The Written by: annotations here include a ...Controller suffix, but elsewhere in internal/api writer annotations use the controller name (e.g. ServiceProviderClusterPropertiesSync, BackfillClusterUID) rather than the constructor/function name. Since the controller name is FetchDataPlaneOperatorsManagedIdentitiesInfo, these annotations should match it for consistent searching and tooling.

This issue also appears on line 220 of the same file.

	// DataPlaneOperatorsManagedIdentities tracks resolved ClientID/PrincipalID for
	// the Azure User Assigned Managed Identities associated to the cluster's data
	// plane operators, plus when Azure should next be re-queried for that info.
	// A cluster's data plane operator is a kubernetes operator associated to the
	// 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"`

internal/api/types_serviceprovider_cluster.go:303

  • This new Cosmos-persisted struct doesn’t follow the // Written by: annotation pattern used elsewhere in internal/api types (and referenced by the Cosmos data-flow docs). It would be better to add explicit Written by: lines for each field, and use the controller name FetchDataPlaneOperatorsManagedIdentitiesInfo consistently.
// ServiceProviderClusterDataPlaneOperatorManagedIdentity contains extra information
// about the Azure User Assigned Managed Identity associated to a cluster's data plane operator.
// A cluster's data plane operator is a kubernetes operator associated to the cluster that runs in the cluster's data plane.
type ServiceProviderClusterDataPlaneOperatorManagedIdentity struct {
	// OperatorName is the name of the data plane operator associated to the Azure User Assigned Managed Identity.
	// The set of recognized operator names by the service is located in internal/azure/cluster_scoped_identities_config.go.
	// Its value comes from the Cluster's CustomerProperties.
	OperatorName string `json:"operatorName"`
	// ResourceID is the Azure Resource ID of the Azure User Assigned Managed Identity that is associated to the corresponding
	// data plane operator (keyed by OperatorName). Its value comes from the Cluster's CustomerProperties.
	ResourceID *azcorearm.ResourceID `json:"resourceID,omitempty"`
	// ClientID is Client ID of the Azure User Assigned Managed Identity represented by ResourceID.
	// Fetched from Azure and written here by the FetchDataPlaneOperatorsManagedIdentitiesInfoController.
	ClientID string `json:"clientID,omitempty"`
	// PrincipalID Principal ID of the Azure User Assigned Managed Identity represented by ResourceID.
	// Fetched from Azure and written here by the FetchDataPlaneOperatorsManagedIdentitiesInfoController.
	PrincipalID string `json:"principalID,omitempty"`
}

Copilot AI review requested due to automatic review settings August 11, 2026 11:52
@miguelsorianod
Miguel Soriano (miguelsorianod) force-pushed the msoriano-fetchinfo-dataplaneoperators-mis branch from 2f48e12 to b7f834b Compare August 11, 2026 11:52

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 3 out of 4 changed files in this pull request and generated 1 comment.

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

internal/api/coreapi/types_serviceprovider_cluster.go:227

  • This change introduces a new Cosmos-written field (ServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities) and a new backend controller writing it, but docs/cosmos-data-flow.md does not mention this read/write path. Please update the data-flow doc so it stays accurate for ops/debugging.
	// DataPlaneOperatorsManagedIdentities tracks resolved ClientID/PrincipalID for
	// the Azure User Assigned Managed Identities associated to the cluster's data
	// plane operators, plus when Azure should next be re-queried for that info.
	// 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 +177 to +181
replacement := existingServiceProviderCluster.DeepCopy()
replacement.Status.DataPlaneOperatorsManagedIdentities = coreapi.ServiceProviderClusterDataPlaneOperatorsManagedIdentities{
Identities: make(map[string]*coreapi.ServiceProviderClusterDataPlaneOperatorManagedIdentity),
EarliestRecheckTime: existingServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities.EarliestRecheckTime.DeepCopy(),
}
Copilot AI review requested due to automatic review settings August 11, 2026 12:33
@miguelsorianod
Miguel Soriano (miguelsorianod) force-pushed the msoriano-fetchinfo-dataplaneoperators-mis branch from b7f834b to 1d24267 Compare August 11, 2026 12:33

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 3 out of 4 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:56

  • This change adds a new backend controller that writes ServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities, but docs/cosmos-data-flow.md doesn’t appear to document this controller/field write yet. Per CLAUDE.md, changes under backend/pkg/controllers/ require regenerating/updating the Cosmos data flow doc so the read/write map stays accurate.
// fetchDataPlaneOperatorsManagedIdentitiesInfoSyncer reconciles
// ServiceProviderCluster.Status.DataPlaneOperatorsManagedIdentities from the
// cluster's configured data plane operator managed identities.
type fetchDataPlaneOperatorsManagedIdentitiesInfoSyncer struct {
	clock             utilsclock.PassiveClock
	resourcesDBClient corecosmosstorage.ResourcesDBClient

	smiClientBuilder azureclient.ServiceManagedIdentityClientBuilder
}

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

  • Typo in comment: "eror" -> "error".
			// If we fail to get the identity, we return an eror instead of accumulating it. This means that we only update the information

@openshift-ci

openshift-ci Bot commented Aug 11, 2026

Copy link
Copy Markdown

Miguel Soriano (@miguelsorianod): The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-parallel 1d24267 link true /test e2e-parallel

Full PR test history. Your PR dashboard.

Details

Instructions 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.

@openshift-ci

openshift-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown

PR needs rebase.

Details

Instructions 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.

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.

4 participants