Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate Federated Identity Credentials for MIWI Cluster #3847

Open
wants to merge 58 commits into
base: kimorris27/ARO-4360-cluster-msi-changes
Choose a base branch
from

Conversation

gouthamMN
Copy link
Contributor

Which issue this PR addresses:

Fixes: https://issues.redhat.com/browse/ARO-4375

What this PR does / why we need it:

This PR perform the followings:

  1. Add/Create Role Assignments on each customer provided Platform Workload Identities over Managed Resource Group and Vnet Resource Group as mentioned in MIWI Test Matrix doc by reading the respective role definitions from PlatformWorkloadIdentityRoleSetProperties.PlatformWorkloadIdentityRole.RoleDefinitionID.
  2. Add/Create Azure Red Hat OpenShift Federated Credential Role Role assignment to Cluster MSI over Managed Resource Group and Vnet Resource Group for Workload Identity clusters.
  3. Create FederatedIdentityCredentials for each customer provided Platform Workload Identities during cluster install/create for each Service accounts in PlatformWorkloadIdentityRoleSetProperties.PlatformWorkloadIdentityRole.ServiceAccounts.
  4. Delete/Cleanup FederatedIdentityCredentials for each customer provided Platform Workload Identities that were created during cluster delete.

Test plan for issue:

  • New Unit tests are added.
  • e2e

Is there any documentation that needs to be updated for this PR?

No

How do you know this will function as expected in production?

  • If the e2e pass without errors

…dentials control plane and key vault data plane)
- Initialize the MSI dataplane client, using the mock MSI RP/stub if
  appropriate
- Initialize key vault store client (for MSI certificates; functionality
  is implemented in MSI dataplane module)
- Create a cluster MSI certificate and store it in the key vault during
  cluster bootstrap
- Instantiate an Azure SDK FederatedIdentityCredential client using the
  cluster MSI certificate
- Delete the cluster MSI certificate as needed during cluster deletion
already gone from the key vault (or was potentially never created)

Realized this case was not being handled correctly while I was working
on unit tests.
- Update doc comment for ensureClusterMsiCertificate
- Simplify conditional logic in MSI cert deletion
- Move `clusterMsiResourceId` function to `OpenShiftCluster` type
- When persisting the MSI cert to KV, use the `NotAfter` returned by the MSI RP (for the stub, just use an arbitrary value)
- Move `getClientOptions` functionality to `AROEnvironment` type
- Move logic for determining cluster MSI key vault name to `pkg/env`
- Pull cloud name mapping stuff out to `AROEnvironment` type
- Update msi-dataplane module to include new changes and use `UserAssignedIdentities` type to get Azure credential in `pkg/cluster/clustermsi.go`
- Fix typo in https URL in comment in `pkg/cluster/delete.go`
- Implement suggestion to use `errors.As` instead of a type assertion in `pkg/cluster/delete.go`
- Move new cluster MSI steps forward in bootstrap step order
- Move MSI dataplane client options stuff to pkg/env
- Explicitly check for a single cluster MSI in `ClusterMsiResourceId`
- Other small tweaks
…dentials control plane and key vault data plane)
- Initialize the MSI dataplane client, using the mock MSI RP/stub if
  appropriate
- Initialize key vault store client (for MSI certificates; functionality
  is implemented in MSI dataplane module)
- Create a cluster MSI certificate and store it in the key vault during
  cluster bootstrap
- Instantiate an Azure SDK FederatedIdentityCredential client using the
  cluster MSI certificate
- Delete the cluster MSI certificate as needed during cluster deletion
@gouthamMN gouthamMN added go Pull requests that update Go code chainsaw Pull requests or issues owned by Team Chainsaw labels Sep 17, 2024
Copy link

Please rebase pull request.

@github-actions github-actions bot added the needs-rebase branch needs a rebase label Sep 17, 2024
resources = append(resources, m.workloadIdentityResourceGroupRBAC(roleID, identity.ObjectID, managedRG))

if role.OperatorName != "StorageOperator" {
resources = append(resources, m.workloadIdentityResourceGroupRBAC(roleID, identity.ObjectID, vnetRG))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why are we handling the RBAC for vnetRG? The RBAC is only needed for the managedRG, FPSP won't have permissions for role assignment on vnetRG. And for managedRG, all the identities existing in platformWIRolesByRoleName will have a role assignment performed for their corresponding roles.

Copy link
Contributor Author

@gouthamMN gouthamMN Sep 18, 2024

Choose a reason for hiding this comment

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

I followed this MI/WI Test Matrix doc, which mention the scopes for each operator. So, should I assume, the customer will handle this for Vnet in production?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, the VNET is to be handled by customer, and that check will already done till this point as part of dynamic validation.


if m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
s = append(s,
steps.Action(m.generateFederatedIdentityCredentials),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure if the FederatedIdentityCredentials ensure need to be part of this PR or not. But for update flow, the credentials will need to be ensure such that they exists and with correct values of issuer, audience etc.

Copy link
Collaborator

@rajdeepc2792 rajdeepc2792 left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!!
Performed a quick review of the PR, added some comments for the federated credentials creation/deletion and RBAC part.
The review would be easier to do after the MSI PR is merged.

if [[ "${operatorName}" == "MachineApiOperator" || "${operatorName}" == "NetworkOperator" \
|| "${operatorName}" == "AzureFilesStorageOperator" || "${operatorName}" == "ServiceOperator" ]]; then
# Storage Operator don't require access to customer BYO virtual network
if [[ "${operatorName}" != "StorageOperator" ]]; then
Copy link
Contributor

Choose a reason for hiding this comment

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

What about image registry operator? or cloud controller manager?

@github-actions github-actions bot removed the needs-rebase branch needs a rebase label Sep 19, 2024
if m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
m.log.Printf("deleting cluster MSI certificate")
err = m.deleteClusterMsiCertificate(ctx)
if err != nil {
return err
}

err = m.deleteFederatedCredentials(ctx)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: we can call this "deleteIdentityFederations"

if err != nil {
return "", err
}
return fmt.Sprintf("%s-%s", m.doc.ID, identityResourceId.ResourceName), nil
Copy link
Contributor

Choose a reason for hiding this comment

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

Any justification for this naming convention?

Want to make sure it fits within the requirements for Azure resource naming. For example, how long is doc.ID?

@@ -444,6 +454,60 @@ func (m *manager) setMasterSubnetPolicies(ctx context.Context) error {
return err
}

func (m *manager) generateFederatedIdentityCredentials(ctx context.Context) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I'd call this federateIdentityCredentials - we aren't "generating" anything per say; we are "federating" the identities.

return fmt.Errorf("OIDCIssuer is nil for the cluster with ID: %s", m.doc.OpenShiftCluster.ID)
}

Issuer := to.StringPtr((string)(*m.doc.OpenShiftCluster.Properties.ClusterProfile.OIDCIssuer))
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: issuer := ...

identityResourceId.ResourceName,
federatedIdentityCredentialResourceName,
armmsi.FederatedIdentityCredential{
Properties: &armmsi.FederatedIdentityCredentialProperties{
Copy link
Contributor

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chainsaw Pull requests or issues owned by Team Chainsaw go Pull requests that update Go code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants