зеркало из https://github.com/Azure/ARO-RP.git
Fix MIWI Cluster update flow to add new openshift operator identity (#4037)
* ARO-13916 fix new operator identity addition flow for miwi cluster update * ARO-13916 add the federateIdentityCredentials step back to update * ARO-13916 populate client/object IDs after dynamic validation * ARO-13916 update dynamic validation unit test cases * ARO-13916 persist user assigned identities with client and object id after dynamic validation
This commit is contained in:
Родитель
e723a443a3
Коммит
bcc519c399
|
@ -137,6 +137,7 @@ type manager struct {
|
|||
openShiftClusterDocumentVersioner openShiftClusterDocumentVersioner
|
||||
|
||||
platformWorkloadIdentityRolesByVersion platformworkloadidentity.PlatformWorkloadIdentityRolesByVersion
|
||||
platformWorkloadIdentities map[string]api.PlatformWorkloadIdentity
|
||||
}
|
||||
|
||||
// New returns a cluster manager
|
||||
|
|
|
@ -220,6 +220,7 @@ func (m *manager) Update(ctx context.Context) error {
|
|||
steps.Action(m.fixupClusterMsiTenantID),
|
||||
steps.Action(m.ensureClusterMsiCertificate),
|
||||
steps.Action(m.initializeClusterMsiClients),
|
||||
steps.Action(m.platformWorkloadIdentityIDs),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -228,7 +229,7 @@ func (m *manager) Update(ctx context.Context) error {
|
|||
if m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
||||
s = append(s,
|
||||
steps.AuthorizationRetryingAction(m.fpAuthorizer, m.clusterIdentityIDs),
|
||||
steps.AuthorizationRetryingAction(m.fpAuthorizer, m.platformWorkloadIdentityIDs),
|
||||
steps.AuthorizationRetryingAction(m.fpAuthorizer, m.persistPlatformWorkloadIdentityIDs),
|
||||
steps.Action(m.federateIdentityCredentials),
|
||||
)
|
||||
} else {
|
||||
|
@ -238,8 +239,7 @@ func (m *manager) Update(ctx context.Context) error {
|
|||
steps.AuthorizationRetryingAction(m.fpAuthorizer, m.fixupClusterSPObjectID),
|
||||
|
||||
// CSP credentials rotation flow steps
|
||||
steps.Action(m.createOrUpdateClusterServicePrincipalRBAC),
|
||||
)
|
||||
steps.Action(m.createOrUpdateClusterServicePrincipalRBAC))
|
||||
}
|
||||
|
||||
s = append(s,
|
||||
|
@ -347,8 +347,16 @@ func (m *manager) bootstrap() []steps.Step {
|
|||
s = append(s,
|
||||
steps.Action(m.ensureClusterMsiCertificate),
|
||||
steps.Action(m.initializeClusterMsiClients),
|
||||
steps.Action(m.platformWorkloadIdentityIDs),
|
||||
)
|
||||
}
|
||||
|
||||
s = append(s, steps.AuthorizationRetryingAction(m.fpAuthorizer, m.validateResources))
|
||||
|
||||
if m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
||||
s = append(s,
|
||||
steps.AuthorizationRetryingAction(m.fpAuthorizer, m.clusterIdentityIDs),
|
||||
steps.AuthorizationRetryingAction(m.fpAuthorizer, m.platformWorkloadIdentityIDs),
|
||||
steps.AuthorizationRetryingAction(m.fpAuthorizer, m.persistPlatformWorkloadIdentityIDs),
|
||||
)
|
||||
} else {
|
||||
s = append(s,
|
||||
|
@ -356,9 +364,7 @@ func (m *manager) bootstrap() []steps.Step {
|
|||
steps.AuthorizationRetryingAction(m.fpAuthorizer, m.clusterSPObjectID),
|
||||
)
|
||||
}
|
||||
|
||||
s = append(s,
|
||||
steps.AuthorizationRetryingAction(m.fpAuthorizer, m.validateResources),
|
||||
steps.Action(m.ensurePreconfiguredNSG),
|
||||
steps.Action(m.ensureACRToken),
|
||||
steps.Action(m.ensureInfraID),
|
||||
|
|
|
@ -13,8 +13,20 @@ import (
|
|||
"github.com/Azure/ARO-RP/pkg/api"
|
||||
)
|
||||
|
||||
func (m *manager) persistPlatformWorkloadIdentityIDs(ctx context.Context) (err error) {
|
||||
if !m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
||||
return fmt.Errorf("persistPlatformWorkloadIdentityIDs called for CSP cluster")
|
||||
}
|
||||
|
||||
m.doc, err = m.db.PatchWithLease(ctx, m.doc.Key, func(doc *api.OpenShiftClusterDocument) error {
|
||||
doc.OpenShiftCluster.Properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities = m.platformWorkloadIdentities
|
||||
return nil
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *manager) platformWorkloadIdentityIDs(ctx context.Context) error {
|
||||
var err error
|
||||
if !m.doc.OpenShiftCluster.UsesWorkloadIdentity() {
|
||||
return fmt.Errorf("platformWorkloadIdentityIDs called for CSP cluster")
|
||||
}
|
||||
|
@ -40,10 +52,6 @@ func (m *manager) platformWorkloadIdentityIDs(ctx context.Context) error {
|
|||
}
|
||||
}
|
||||
|
||||
m.doc, err = m.db.PatchWithLease(ctx, m.doc.Key, func(doc *api.OpenShiftClusterDocument) error {
|
||||
doc.OpenShiftCluster.Properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities = updatedIdentities
|
||||
return nil
|
||||
})
|
||||
|
||||
return err
|
||||
m.platformWorkloadIdentities = updatedIdentities
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -186,6 +186,11 @@ func TestPlatformWorkloadIdentityIDs(t *testing.T) {
|
|||
err := m.platformWorkloadIdentityIDs(ctx)
|
||||
utilerror.AssertErrorMessage(t, err, tt.wantErr)
|
||||
|
||||
if err == nil {
|
||||
err = m.persistPlatformWorkloadIdentityIDs(ctx)
|
||||
utilerror.AssertErrorMessage(t, err, tt.wantErr)
|
||||
}
|
||||
|
||||
if tt.wantIdentities != nil {
|
||||
assert.Equal(t, *tt.wantIdentities, m.doc.OpenShiftCluster.Properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@ func (m *manager) validateResources(ctx context.Context) error {
|
|||
clusterMSICredential = m.userAssignedIdentities.GetClusterMSICredential()
|
||||
}
|
||||
return validate.NewOpenShiftClusterDynamicValidator(
|
||||
m.log, m.env, m.doc.OpenShiftCluster, m.subscriptionDoc, m.fpAuthorizer, m.armRoleDefinitions, m.clusterMsiFederatedIdentityCredentials, m.platformWorkloadIdentityRolesByVersion, clusterMSICredential,
|
||||
m.log, m.env, m.doc.OpenShiftCluster, m.subscriptionDoc, m.fpAuthorizer, m.armRoleDefinitions, m.clusterMsiFederatedIdentityCredentials, m.platformWorkloadIdentities, m.platformWorkloadIdentityRolesByVersion, clusterMSICredential,
|
||||
).Dynamic(ctx)
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ func (m *manager) generateWorkloadIdentityResources() (map[string]kruntime.Objec
|
|||
}
|
||||
|
||||
resources := map[string]kruntime.Object{}
|
||||
if platformWorkloadIdentitySecrets, err := m.generatePlatformWorkloadIdentitySecrets(); err != nil {
|
||||
if platformWorkloadIdentitySecrets, _, err := m.generatePlatformWorkloadIdentitySecretsAndNamespaces(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
for _, secret := range platformWorkloadIdentitySecrets {
|
||||
|
@ -60,19 +60,22 @@ func (m *manager) generateWorkloadIdentityResources() (map[string]kruntime.Objec
|
|||
}
|
||||
|
||||
func (m *manager) deployPlatformWorkloadIdentitySecrets(ctx context.Context) error {
|
||||
secrets, err := m.generatePlatformWorkloadIdentitySecrets()
|
||||
secrets, namespaces, err := m.generatePlatformWorkloadIdentitySecretsAndNamespaces()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resources := make([]kruntime.Object, len(secrets))
|
||||
for i, secret := range secrets {
|
||||
resources[i] = secret
|
||||
resources := []kruntime.Object{}
|
||||
for _, namespace := range namespaces {
|
||||
resources = append(resources, namespace)
|
||||
}
|
||||
for _, secret := range secrets {
|
||||
resources = append(resources, secret)
|
||||
}
|
||||
|
||||
return m.ch.Ensure(ctx, resources...)
|
||||
}
|
||||
|
||||
func (m *manager) generatePlatformWorkloadIdentitySecrets() ([]*corev1.Secret, error) {
|
||||
func (m *manager) generatePlatformWorkloadIdentitySecretsAndNamespaces() ([]*corev1.Secret, []*corev1.Namespace, error) {
|
||||
subscriptionId := m.subscriptionDoc.ID
|
||||
tenantId := m.subscriptionDoc.Subscription.Properties.TenantID
|
||||
region := m.doc.OpenShiftCluster.Location
|
||||
|
@ -80,10 +83,11 @@ func (m *manager) generatePlatformWorkloadIdentitySecrets() ([]*corev1.Secret, e
|
|||
roles := m.platformWorkloadIdentityRolesByVersion.GetPlatformWorkloadIdentityRolesByRoleName()
|
||||
|
||||
secrets := []*corev1.Secret{}
|
||||
namespaces := []*corev1.Namespace{}
|
||||
for name, identity := range m.doc.OpenShiftCluster.Properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities {
|
||||
role, exists := roles[name]
|
||||
if !exists {
|
||||
return nil, platformworkloadidentity.GetPlatformWorkloadIdentityMismatchError(m.doc.OpenShiftCluster, roles)
|
||||
return nil, nil, platformworkloadidentity.GetPlatformWorkloadIdentityMismatchError(m.doc.OpenShiftCluster, roles)
|
||||
}
|
||||
// Skip creating a secret for the ARO Operator. This will be
|
||||
// generated by the ARO Operator deployer instead
|
||||
|
@ -110,9 +114,19 @@ func (m *manager) generatePlatformWorkloadIdentitySecrets() ([]*corev1.Secret, e
|
|||
"azure_federated_token_file": azureFederatedTokenFileLocation,
|
||||
},
|
||||
})
|
||||
|
||||
namespaces = append(namespaces, &corev1.Namespace{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: corev1.SchemeGroupVersion.Identifier(),
|
||||
Kind: "Namespace",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: role.SecretLocation.Namespace,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return secrets, nil
|
||||
return secrets, namespaces, nil
|
||||
}
|
||||
|
||||
func (m *manager) generateCloudCredentialOperatorSecret() (*corev1.Secret, error) {
|
||||
|
|
|
@ -317,17 +317,19 @@ func TestGeneratePlatformWorkloadIdentitySecrets(t *testing.T) {
|
|||
location := "eastus"
|
||||
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
identities map[string]api.PlatformWorkloadIdentity
|
||||
roles []api.PlatformWorkloadIdentityRole
|
||||
want []*corev1.Secret
|
||||
wantErr string
|
||||
name string
|
||||
identities map[string]api.PlatformWorkloadIdentity
|
||||
roles []api.PlatformWorkloadIdentityRole
|
||||
wantSecrets []*corev1.Secret
|
||||
wantNamespaces []*corev1.Namespace
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "no identities, no secrets",
|
||||
identities: map[string]api.PlatformWorkloadIdentity{},
|
||||
roles: []api.PlatformWorkloadIdentityRole{},
|
||||
want: []*corev1.Secret{},
|
||||
name: "no identities, no secrets",
|
||||
identities: map[string]api.PlatformWorkloadIdentity{},
|
||||
roles: []api.PlatformWorkloadIdentityRole{},
|
||||
wantSecrets: []*corev1.Secret{},
|
||||
wantNamespaces: []*corev1.Namespace{},
|
||||
},
|
||||
{
|
||||
name: "converts cluster PWIs if a role definition is present",
|
||||
|
@ -355,7 +357,7 @@ func TestGeneratePlatformWorkloadIdentitySecrets(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
want: []*corev1.Secret{
|
||||
wantSecrets: []*corev1.Secret{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
|
@ -393,6 +395,26 @@ func TestGeneratePlatformWorkloadIdentitySecrets(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
wantNamespaces: []*corev1.Namespace{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "Namespace",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "openshift-foo",
|
||||
},
|
||||
},
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "Namespace",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "openshift-bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error - identities with unexpected operator name present",
|
||||
|
@ -401,9 +423,10 @@ func TestGeneratePlatformWorkloadIdentitySecrets(t *testing.T) {
|
|||
ClientID: "00f00f00-0f00-0f00-0f00-f00f00f00f00",
|
||||
},
|
||||
},
|
||||
roles: []api.PlatformWorkloadIdentityRole{},
|
||||
want: []*corev1.Secret{},
|
||||
wantErr: fmt.Sprintf("400: %s: properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities: There's a mismatch between the required and expected set of platform workload identities for the requested OpenShift minor version '%s'. The required platform workload identities are '[]'", api.CloudErrorCodePlatformWorkloadIdentityMismatch, "4.14"),
|
||||
roles: []api.PlatformWorkloadIdentityRole{},
|
||||
wantSecrets: []*corev1.Secret{},
|
||||
wantNamespaces: []*corev1.Namespace{},
|
||||
wantErr: fmt.Sprintf("400: %s: properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities: There's a mismatch between the required and expected set of platform workload identities for the requested OpenShift minor version '%s'. The required platform workload identities are '[]'", api.CloudErrorCodePlatformWorkloadIdentityMismatch, "4.14"),
|
||||
},
|
||||
{
|
||||
name: "skips ARO operator identity",
|
||||
|
@ -431,7 +454,7 @@ func TestGeneratePlatformWorkloadIdentitySecrets(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
want: []*corev1.Secret{
|
||||
wantSecrets: []*corev1.Secret{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
|
@ -451,6 +474,17 @@ func TestGeneratePlatformWorkloadIdentitySecrets(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
wantNamespaces: []*corev1.Namespace{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "Namespace",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "openshift-foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
@ -484,10 +518,11 @@ func TestGeneratePlatformWorkloadIdentitySecrets(t *testing.T) {
|
|||
controller, tt.roles,
|
||||
),
|
||||
}
|
||||
got, err := m.generatePlatformWorkloadIdentitySecrets()
|
||||
gotSecrets, gotNamespaces, err := m.generatePlatformWorkloadIdentitySecretsAndNamespaces()
|
||||
|
||||
utilerror.AssertErrorMessage(t, err, tt.wantErr)
|
||||
assert.ElementsMatch(t, got, tt.want)
|
||||
assert.ElementsMatch(t, gotSecrets, tt.wantSecrets)
|
||||
assert.ElementsMatch(t, gotNamespaces, tt.wantNamespaces)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,17 +139,17 @@ func (mr *MockDynamicMockRecorder) ValidateLoadBalancerProfile(ctx, oc any) *gom
|
|||
}
|
||||
|
||||
// ValidatePlatformWorkloadIdentityProfile mocks base method.
|
||||
func (m *MockDynamic) ValidatePlatformWorkloadIdentityProfile(ctx context.Context, oc *api.OpenShiftCluster, platformWorkloadIdentityRolesByRoleName map[string]api.PlatformWorkloadIdentityRole, roleDefinitions armauthorization.RoleDefinitionsClient, clusterMsiFederatedIdentityCredentials armmsi.FederatedIdentityCredentialsClient) error {
|
||||
func (m *MockDynamic) ValidatePlatformWorkloadIdentityProfile(ctx context.Context, oc *api.OpenShiftCluster, platformWorkloadIdentityRolesByRoleName map[string]api.PlatformWorkloadIdentityRole, roleDefinitions armauthorization.RoleDefinitionsClient, clusterMsiFederatedIdentityCredentials armmsi.FederatedIdentityCredentialsClient, platformWorkloadIdentities map[string]api.PlatformWorkloadIdentity) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidatePlatformWorkloadIdentityProfile", ctx, oc, platformWorkloadIdentityRolesByRoleName, roleDefinitions, clusterMsiFederatedIdentityCredentials)
|
||||
ret := m.ctrl.Call(m, "ValidatePlatformWorkloadIdentityProfile", ctx, oc, platformWorkloadIdentityRolesByRoleName, roleDefinitions, clusterMsiFederatedIdentityCredentials, platformWorkloadIdentities)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ValidatePlatformWorkloadIdentityProfile indicates an expected call of ValidatePlatformWorkloadIdentityProfile.
|
||||
func (mr *MockDynamicMockRecorder) ValidatePlatformWorkloadIdentityProfile(ctx, oc, platformWorkloadIdentityRolesByRoleName, roleDefinitions, clusterMsiFederatedIdentityCredentials any) *gomock.Call {
|
||||
func (mr *MockDynamicMockRecorder) ValidatePlatformWorkloadIdentityProfile(ctx, oc, platformWorkloadIdentityRolesByRoleName, roleDefinitions, clusterMsiFederatedIdentityCredentials, platformWorkloadIdentities any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatePlatformWorkloadIdentityProfile", reflect.TypeOf((*MockDynamic)(nil).ValidatePlatformWorkloadIdentityProfile), ctx, oc, platformWorkloadIdentityRolesByRoleName, roleDefinitions, clusterMsiFederatedIdentityCredentials)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatePlatformWorkloadIdentityProfile", reflect.TypeOf((*MockDynamic)(nil).ValidatePlatformWorkloadIdentityProfile), ctx, oc, platformWorkloadIdentityRolesByRoleName, roleDefinitions, clusterMsiFederatedIdentityCredentials, platformWorkloadIdentities)
|
||||
}
|
||||
|
||||
// ValidatePreConfiguredNSGs mocks base method.
|
||||
|
|
|
@ -88,6 +88,7 @@ type Dynamic interface {
|
|||
platformWorkloadIdentityRolesByRoleName map[string]api.PlatformWorkloadIdentityRole,
|
||||
roleDefinitions armauthorization.RoleDefinitionsClient,
|
||||
clusterMsiFederatedIdentityCredentials armmsi.FederatedIdentityCredentialsClient,
|
||||
platformWorkloadIdentities map[string]api.PlatformWorkloadIdentity,
|
||||
) error
|
||||
}
|
||||
|
||||
|
|
|
@ -30,11 +30,12 @@ func (dv *dynamic) ValidatePlatformWorkloadIdentityProfile(
|
|||
platformWorkloadIdentityRolesByRoleName map[string]api.PlatformWorkloadIdentityRole,
|
||||
roleDefinitions armauthorization.RoleDefinitionsClient,
|
||||
clusterMsiFederatedIdentityCredentials armmsi.FederatedIdentityCredentialsClient,
|
||||
) error {
|
||||
platformWorkloadIdentities map[string]api.PlatformWorkloadIdentity, // Platform Workload Identities with object and client IDs
|
||||
) (err error) {
|
||||
dv.log.Print("ValidatePlatformWorkloadIdentityProfile")
|
||||
|
||||
dv.platformIdentitiesActionsMap = map[string][]string{}
|
||||
dv.platformIdentities = oc.Properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities
|
||||
dv.platformIdentities = platformWorkloadIdentities
|
||||
|
||||
// Check if any required platform identity is missing
|
||||
if len(dv.platformIdentities) != len(platformWorkloadIdentityRolesByRoleName) {
|
||||
|
|
|
@ -270,6 +270,8 @@ func TestValidatePlatformWorkloadIdentityProfile(t *testing.T) {
|
|||
desiredPlatformWorkloadIdentities := map[string]api.PlatformWorkloadIdentity{
|
||||
"Dummy1": {
|
||||
ResourceID: platformIdentity1,
|
||||
ObjectID: dummyObjectId,
|
||||
ClientID: dummyClientId,
|
||||
},
|
||||
}
|
||||
desiredPlatformWorkloadIdentitiesMap := map[string]api.PlatformWorkloadIdentityRole{
|
||||
|
@ -471,11 +473,7 @@ func TestValidatePlatformWorkloadIdentityProfile(t *testing.T) {
|
|||
roleDefinitions.EXPECT().GetByID(ctx, gomock.Any(), &sdkauthorization.RoleDefinitionsClientGetByIDOptions{}).AnyTimes().Return(platformIdentityRequiredPermissions, nil)
|
||||
federatedIdentityCredentials.EXPECT().List(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return([]*sdkmsi.FederatedIdentityCredential{}, nil)
|
||||
},
|
||||
wantPlatformIdentities: map[string]api.PlatformWorkloadIdentity{
|
||||
"Dummy1": {
|
||||
ResourceID: platformIdentity1,
|
||||
},
|
||||
},
|
||||
wantPlatformIdentities: desiredPlatformWorkloadIdentities,
|
||||
wantPlatformIdentitiesActionsMap: map[string][]string{
|
||||
"Dummy1": platformIdentityRequiredPermissionsList,
|
||||
},
|
||||
|
@ -855,7 +853,6 @@ func TestValidatePlatformWorkloadIdentityProfile(t *testing.T) {
|
|||
},
|
||||
mocks: func(roleDefinitions *mock_armauthorization.MockRoleDefinitionsClient, federatedIdentityCredentials *mock_armmsi.MockFederatedIdentityCredentialsClient) {
|
||||
roleDefinitions.EXPECT().GetByID(ctx, gomock.Any(), &sdkauthorization.RoleDefinitionsClientGetByIDOptions{}).AnyTimes().Return(platformIdentityRequiredPermissions, nil)
|
||||
|
||||
federatedIdentityCredentials.EXPECT().List(gomock.Any(), gomock.Eq(platformIdentity1ResourceId.ResourceGroup), gomock.Eq(platformIdentity1ResourceId.ResourceName), gomock.Any()).
|
||||
Return([]*sdkmsi.FederatedIdentityCredential{{Name: &expectedPlatformIdentity1FederatedCredName}}, nil)
|
||||
},
|
||||
|
@ -884,6 +881,8 @@ func TestValidatePlatformWorkloadIdentityProfile(t *testing.T) {
|
|||
UserAssignedIdentities: clusterMSI,
|
||||
},
|
||||
},
|
||||
mocks: func(roleDefinitions *mock_armauthorization.MockRoleDefinitionsClient, federatedIdentityCredentials *mock_armmsi.MockFederatedIdentityCredentialsClient) {
|
||||
},
|
||||
wantErr: fmt.Sprintf("400: %s: properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities: There's a mismatch between the required and expected set of platform workload identities for the requested OpenShift minor version '%s or %s'. The required platform workload identities are '[Dummy3]'", api.CloudErrorCodePlatformWorkloadIdentityMismatch, "4.14", "4.15"),
|
||||
},
|
||||
{
|
||||
|
@ -909,6 +908,8 @@ func TestValidatePlatformWorkloadIdentityProfile(t *testing.T) {
|
|||
UserAssignedIdentities: clusterMSI,
|
||||
},
|
||||
},
|
||||
mocks: func(roleDefinitions *mock_armauthorization.MockRoleDefinitionsClient, federatedIdentityCredentials *mock_armmsi.MockFederatedIdentityCredentialsClient) {
|
||||
},
|
||||
wantErr: fmt.Sprintf("400: %s: properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities: There's a mismatch between the required and expected set of platform workload identities for the requested OpenShift minor version '%s'. The required platform workload identities are '[Dummy3]'", api.CloudErrorCodePlatformWorkloadIdentityMismatch, "4.14"),
|
||||
},
|
||||
{
|
||||
|
@ -934,6 +935,8 @@ func TestValidatePlatformWorkloadIdentityProfile(t *testing.T) {
|
|||
UserAssignedIdentities: clusterMSI,
|
||||
},
|
||||
},
|
||||
mocks: func(roleDefinitions *mock_armauthorization.MockRoleDefinitionsClient, federatedIdentityCredentials *mock_armmsi.MockFederatedIdentityCredentialsClient) {
|
||||
},
|
||||
wantErr: fmt.Sprintf("400: %s: properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities: There's a mismatch between the required and expected set of platform workload identities for the requested OpenShift minor version '%s'. The required platform workload identities are '[Dummy3]'", api.CloudErrorCodePlatformWorkloadIdentityMismatch, "4.14"),
|
||||
},
|
||||
{
|
||||
|
@ -954,6 +957,8 @@ func TestValidatePlatformWorkloadIdentityProfile(t *testing.T) {
|
|||
UserAssignedIdentities: clusterMSI,
|
||||
},
|
||||
},
|
||||
mocks: func(roleDefinitions *mock_armauthorization.MockRoleDefinitionsClient, federatedIdentityCredentials *mock_armmsi.MockFederatedIdentityCredentialsClient) {
|
||||
},
|
||||
wantErr: fmt.Sprintf("400: %s: properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities: There's a mismatch between the required and expected set of platform workload identities for the requested OpenShift minor version '%s'. The required platform workload identities are '[Dummy1]'", api.CloudErrorCodePlatformWorkloadIdentityMismatch, "4.14"),
|
||||
},
|
||||
{
|
||||
|
@ -981,6 +986,8 @@ func TestValidatePlatformWorkloadIdentityProfile(t *testing.T) {
|
|||
UserAssignedIdentities: clusterMSI,
|
||||
},
|
||||
},
|
||||
mocks: func(roleDefinitions *mock_armauthorization.MockRoleDefinitionsClient, federatedIdentityCredentials *mock_armmsi.MockFederatedIdentityCredentialsClient) {
|
||||
},
|
||||
wantErr: fmt.Sprintf("400: %s: properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities: There's a mismatch between the required and expected set of platform workload identities for the requested OpenShift minor version '%s'. The required platform workload identities are '[Dummy1]'", api.CloudErrorCodePlatformWorkloadIdentityMismatch, "4.14"),
|
||||
},
|
||||
{
|
||||
|
@ -1077,7 +1084,18 @@ func TestValidatePlatformWorkloadIdentityProfile(t *testing.T) {
|
|||
tt.mocks(roleDefinitions, federatedIdentityCredentials)
|
||||
}
|
||||
|
||||
err := dv.ValidatePlatformWorkloadIdentityProfile(ctx, tt.oc, tt.platformIdentityRoles, roleDefinitions, federatedIdentityCredentials)
|
||||
pwis := tt.oc.Properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities
|
||||
updatedIdentities := make(map[string]api.PlatformWorkloadIdentity, len(pwis))
|
||||
|
||||
for operatorName, pwi := range pwis {
|
||||
updatedIdentities[operatorName] = api.PlatformWorkloadIdentity{
|
||||
ResourceID: pwi.ResourceID,
|
||||
ClientID: dummyClientId,
|
||||
ObjectID: dummyObjectId,
|
||||
}
|
||||
}
|
||||
|
||||
err := dv.ValidatePlatformWorkloadIdentityProfile(ctx, tt.oc, tt.platformIdentityRoles, roleDefinitions, federatedIdentityCredentials, updatedIdentities)
|
||||
utilerror.AssertErrorMessage(t, err, tt.wantErr)
|
||||
|
||||
if tt.wantPlatformIdentities != nil && !reflect.DeepEqual(tt.wantPlatformIdentities, dv.platformIdentities) {
|
||||
|
|
|
@ -40,6 +40,7 @@ func NewOpenShiftClusterDynamicValidator(
|
|||
fpAuthorizer autorest.Authorizer,
|
||||
roleDefinitions armauthorization.RoleDefinitionsClient,
|
||||
clusterMsiFederatedIdentityCredentials armmsi.FederatedIdentityCredentialsClient,
|
||||
platformWorkloadIdentities map[string]api.PlatformWorkloadIdentity,
|
||||
platformWorkloadIdentityRolesByVersion platformworkloadidentity.PlatformWorkloadIdentityRolesByVersion,
|
||||
clusterMSICredential azcore.TokenCredential,
|
||||
) OpenShiftClusterDynamicValidator {
|
||||
|
@ -54,6 +55,7 @@ func NewOpenShiftClusterDynamicValidator(
|
|||
clusterMsiFederatedIdentityCredentials: clusterMsiFederatedIdentityCredentials,
|
||||
platformWorkloadIdentityRolesByVersion: platformWorkloadIdentityRolesByVersion,
|
||||
clusterMSICredential: clusterMSICredential,
|
||||
platformWorkloadIdentities: platformWorkloadIdentities,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,6 +70,7 @@ type openShiftClusterDynamicValidator struct {
|
|||
clusterMsiFederatedIdentityCredentials armmsi.FederatedIdentityCredentialsClient
|
||||
platformWorkloadIdentityRolesByVersion platformworkloadidentity.PlatformWorkloadIdentityRolesByVersion
|
||||
clusterMSICredential azcore.TokenCredential
|
||||
platformWorkloadIdentities map[string]api.PlatformWorkloadIdentity
|
||||
}
|
||||
|
||||
// ensureAccessTokenClaims can detect an error when the service principal (fp, cluster sp) has accidentally deleted from
|
||||
|
@ -220,7 +223,7 @@ func (dv *openShiftClusterDynamicValidator) Dynamic(ctx context.Context) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = spDynamic.ValidatePlatformWorkloadIdentityProfile(ctx, dv.oc, dv.platformWorkloadIdentityRolesByVersion.GetPlatformWorkloadIdentityRolesByRoleName(), dv.roleDefinitions, dv.clusterMsiFederatedIdentityCredentials)
|
||||
err = spDynamic.ValidatePlatformWorkloadIdentityProfile(ctx, dv.oc, dv.platformWorkloadIdentityRolesByVersion.GetPlatformWorkloadIdentityRolesByRoleName(), dv.roleDefinitions, dv.clusterMsiFederatedIdentityCredentials, dv.platformWorkloadIdentities)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче