-
Notifications
You must be signed in to change notification settings - Fork 169
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ARO-4376 add dynamic validation for platformworkloadidentityprofile
- Loading branch information
1 parent
e548102
commit e80c020
Showing
6 changed files
with
207 additions
and
14 deletions.
There are no files selected for viewing
This file contains 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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains 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
This file contains 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
134 changes: 134 additions & 0 deletions
134
pkg/validate/dynamic/platformworkloadidentityprofile.go
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package dynamic | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
|
||
sdkauthorization "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3" | ||
"github.com/Azure/go-autorest/autorest/azure" | ||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/Azure/ARO-RP/pkg/api" | ||
"github.com/Azure/ARO-RP/pkg/database" | ||
"github.com/Azure/ARO-RP/pkg/util/rbac" | ||
) | ||
|
||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the Apache License 2.0. | ||
|
||
type fakeT struct{} | ||
|
||
func (t fakeT) Errorf(string, ...interface{}) {} | ||
|
||
func (dv *dynamic) ValidatePlatformWorkloadIdentityProfile(ctx context.Context, oc *api.OpenShiftCluster, dbPlatformWorkloadIdentityRoleSets database.PlatformWorkloadIdentityRoleSets) error { | ||
dv.log.Print("ValidatePlatformWorkloadIdentityProfile") | ||
|
||
if oc.Properties.PlatformWorkloadIdentityProfile == nil || oc.Properties.ServicePrincipalProfile != nil { | ||
return nil | ||
} | ||
|
||
requestedInstallVersion := oc.Properties.ClusterProfile.Version | ||
platformIdentitiesActionsMap := map[string][]string{} | ||
var roles []api.PlatformWorkloadIdentityRole | ||
|
||
docs, err := dbPlatformWorkloadIdentityRoleSets.ListAll(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, doc := range docs.PlatformWorkloadIdentityRoleSetDocuments { | ||
if requestedInstallVersion == doc.PlatformWorkloadIdentityRoleSet.Properties.OpenShiftVersion { | ||
roles = doc.PlatformWorkloadIdentityRoleSet.Properties.PlatformWorkloadIdentityRoles | ||
} | ||
} | ||
|
||
requiredOperatorIdentities := []string{} | ||
recievedOperatorIdentities := []string{} | ||
for _, role := range roles { | ||
requiredOperatorIdentities = append(requiredOperatorIdentities, role.OperatorName) | ||
// platformIdentitiesRoleMap[role.OperatorName] = role | ||
} | ||
for _, role := range oc.Properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities { | ||
recievedOperatorIdentities = append(recievedOperatorIdentities, role.OperatorName) | ||
} | ||
ok := assert.ElementsMatch(fakeT{}, requiredOperatorIdentities, recievedOperatorIdentities) | ||
if !ok { | ||
return api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodePlatformWorkloadIdentityMismatch, | ||
"properties.ValidatePlatformWorkloadIdentityProfile.PlatformWorkloadIdentities", "There's a mismatch between the required and expected set of platform workload identities for the requested OpenShift version '%s'.", requestedInstallVersion) | ||
} | ||
|
||
err = dv.validateClusterMSI(ctx, oc) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, role := range roles { | ||
definition, err := dv.roleDefinitions.GetByID(ctx, role.RoleDefinitionID, &sdkauthorization.RoleDefinitionsClientGetByIDOptions{}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if len(definition.Properties.Permissions) <= 0 { | ||
return api.NewCloudError(http.StatusInternalServerError, api.CloudErrorCodeInvalidClusterMSICount, | ||
"dynamic.ValidatePlatformWorkloadIdentityProfile", "No Permissions exists for the role %s", role.RoleDefinitionID) | ||
} | ||
|
||
actions := []string{} | ||
for _, action := range definition.Properties.Permissions[0].Actions { | ||
actions = append(actions, *action) | ||
} | ||
platformIdentitiesActionsMap[role.OperatorName] = actions | ||
} | ||
|
||
dv.platformIdentities = oc.Properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities | ||
dv.platformIdentitiesActionsMap = platformIdentitiesActionsMap | ||
return nil | ||
} | ||
|
||
func (dv *dynamic) validateClusterMSI(ctx context.Context, oc *api.OpenShiftCluster) error { | ||
if len(oc.Identity.UserAssignedIdentities) <= 0 { | ||
return api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidClusterMSICount, | ||
"identity.userAssignedIdentities", "No OpenShift Cluster associated User Assigned Identity is provided for the Workload Identity OpenShift cluster creation") | ||
} | ||
|
||
if len(oc.Identity.UserAssignedIdentities) > 1 { | ||
return api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodeInvalidClusterMSICount, | ||
"identity.userAssignedIdentities", "More than one OpenShift Cluster associated User Assigned Identity are provided for the Workload Identity OpenShift cluster creation") | ||
} | ||
|
||
for _, identity := range oc.Identity.UserAssignedIdentities { | ||
return dv.validateClusterMSIPermissions(ctx, identity.PrincipalID, oc.Properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (dv *dynamic) validateClusterMSIPermissions(ctx context.Context, oid string, platformIdentities []api.PlatformWorkloadIdentity) error { | ||
definition, err := dv.roleDefinitions.GetByID(ctx, rbac.RoleAzureRedHatOpenShiftFederatedCredentialRole, &sdkauthorization.RoleDefinitionsClientGetByIDOptions{}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if len(definition.Properties.Permissions) <= 0 { | ||
return api.NewCloudError(http.StatusInternalServerError, api.CloudErrorCodeInvalidClusterMSICount, | ||
"dynamic.validateClusterMSIPermissions", "No Permissions exists for the role %s", rbac.RoleAzureRedHatOpenShiftFederatedCredentialRole) | ||
} | ||
|
||
actions := []string{} | ||
for _, action := range definition.Properties.Permissions[0].Actions { | ||
actions = append(actions, *action) | ||
} | ||
|
||
for _, platformIdentity := range platformIdentities { | ||
pid, err := azure.ParseResourceID(platformIdentity.ResourceID) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = dv.validateActionsByOID(ctx, &pid, actions, &oid) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} |
This file contains 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