Skip to content

Commit a1dd014

Browse files
committed
ARO-10859 throw an error for create/update flow whenever an unexpected platform identity is found
1 parent 8782376 commit a1dd014

File tree

6 files changed

+68
-37
lines changed

6 files changed

+68
-37
lines changed

pkg/cluster/deploybaseresources.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/Azure/ARO-RP/pkg/env"
2929
"github.com/Azure/ARO-RP/pkg/util/arm"
3030
"github.com/Azure/ARO-RP/pkg/util/oidcbuilder"
31+
"github.com/Azure/ARO-RP/pkg/util/platformworkloadidentity"
3132
"github.com/Azure/ARO-RP/pkg/util/pointerutils"
3233
"github.com/Azure/ARO-RP/pkg/util/stringutils"
3334
)
@@ -485,7 +486,7 @@ func (m *manager) federateIdentityCredentials(ctx context.Context) error {
485486

486487
platformWIRole, exists := platformWIRolesByRoleName[name]
487488
if !exists {
488-
continue
489+
return platformworkloadidentity.GetPlatformWorkloadIdentityMismatchError(m.doc.OpenShiftCluster, platformWIRolesByRoleName)
489490
}
490491

491492
for _, sa := range platformWIRole.ServiceAccounts {

pkg/cluster/deploybaseresources_additional.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/Azure/ARO-RP/pkg/api"
1818
"github.com/Azure/ARO-RP/pkg/util/arm"
1919
"github.com/Azure/ARO-RP/pkg/util/azureclient"
20+
"github.com/Azure/ARO-RP/pkg/util/platformworkloadidentity"
2021
"github.com/Azure/ARO-RP/pkg/util/rbac"
2122
"github.com/Azure/ARO-RP/pkg/util/stringutils"
2223
)
@@ -106,7 +107,7 @@ func (m *manager) platformWorkloadIdentityRBAC() ([]*arm.Resource, error) {
106107
for name, identity := range platformWorkloadIdentities {
107108
role, exists := platformWIRolesByRoleName[name]
108109
if !exists {
109-
continue
110+
return nil, platformworkloadidentity.GetPlatformWorkloadIdentityMismatchError(m.doc.OpenShiftCluster, platformWIRolesByRoleName)
110111
}
111112

112113
if strings.TrimSpace(identity.ObjectID) == "" {

pkg/cluster/deploybaseresources_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,7 +1811,7 @@ func TestGenerateFederatedIdentityCredentials(t *testing.T) {
18111811
wantErr: "OIDCIssuer is nil",
18121812
},
18131813
{
1814-
name: "Success - Operator name do not exists in PlatformWorkloadIdentityProfile",
1814+
name: "Fail - Operator name do not exists in PlatformWorkloadIdentityProfile",
18151815
oc: &api.OpenShiftClusterDocument{
18161816
ID: docID,
18171817
OpenShiftCluster: &api.OpenShiftCluster{
@@ -1857,7 +1857,7 @@ func TestGenerateFederatedIdentityCredentials(t *testing.T) {
18571857
},
18581858
)
18591859
},
1860-
wantErr: "",
1860+
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 '[CloudControllerManager]'", api.CloudErrorCodePlatformWorkloadIdentityMismatch, "4.14", "4.15"),
18611861
},
18621862
} {
18631863
uuidGen := deterministicuuid.NewTestUUIDGenerator(deterministicuuid.OPENSHIFT_VERSIONS)

pkg/cluster/workloadidentityresources.go

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -81,33 +81,35 @@ func (m *manager) generatePlatformWorkloadIdentitySecrets() ([]*corev1.Secret, e
8181

8282
secrets := []*corev1.Secret{}
8383
for name, identity := range m.doc.OpenShiftCluster.Properties.PlatformWorkloadIdentityProfile.PlatformWorkloadIdentities {
84-
if role, ok := roles[name]; ok {
85-
// Skip creating a secret for the ARO Operator. This will be
86-
// generated by the ARO Operator deployer instead
87-
// (see pkg/operator/deploy/deploy.go#generateOperatorIdentitySecret())
88-
if role.OperatorName == pkgoperator.OperatorIdentityName {
89-
continue
90-
}
91-
92-
secrets = append(secrets, &corev1.Secret{
93-
TypeMeta: metav1.TypeMeta{
94-
APIVersion: corev1.SchemeGroupVersion.Identifier(),
95-
Kind: "Secret",
96-
},
97-
ObjectMeta: metav1.ObjectMeta{
98-
Namespace: role.SecretLocation.Namespace,
99-
Name: role.SecretLocation.Name,
100-
},
101-
Type: corev1.SecretTypeOpaque,
102-
StringData: map[string]string{
103-
"azure_client_id": identity.ClientID,
104-
"azure_subscription_id": subscriptionId,
105-
"azure_tenant_id": tenantId,
106-
"azure_region": region,
107-
"azure_federated_token_file": azureFederatedTokenFileLocation,
108-
},
109-
})
84+
role, exists := roles[name]
85+
if !exists {
86+
return nil, platformworkloadidentity.GetPlatformWorkloadIdentityMismatchError(m.doc.OpenShiftCluster, roles)
11087
}
88+
// Skip creating a secret for the ARO Operator. This will be
89+
// generated by the ARO Operator deployer instead
90+
// (see pkg/operator/deploy/deploy.go#generateOperatorIdentitySecret())
91+
if role.OperatorName == pkgoperator.OperatorIdentityName {
92+
continue
93+
}
94+
95+
secrets = append(secrets, &corev1.Secret{
96+
TypeMeta: metav1.TypeMeta{
97+
APIVersion: corev1.SchemeGroupVersion.Identifier(),
98+
Kind: "Secret",
99+
},
100+
ObjectMeta: metav1.ObjectMeta{
101+
Namespace: role.SecretLocation.Namespace,
102+
Name: role.SecretLocation.Name,
103+
},
104+
Type: corev1.SecretTypeOpaque,
105+
StringData: map[string]string{
106+
"azure_client_id": identity.ClientID,
107+
"azure_subscription_id": subscriptionId,
108+
"azure_tenant_id": tenantId,
109+
"azure_region": region,
110+
"azure_federated_token_file": azureFederatedTokenFileLocation,
111+
},
112+
})
111113
}
112114

113115
return secrets, nil

pkg/cluster/workloadidentityresources_test.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ func TestGeneratePlatformWorkloadIdentitySecrets(t *testing.T) {
321321
identities map[string]api.PlatformWorkloadIdentity
322322
roles []api.PlatformWorkloadIdentityRole
323323
want []*corev1.Secret
324+
wantErr string
324325
}{
325326
{
326327
name: "no identities, no secrets",
@@ -394,17 +395,15 @@ func TestGeneratePlatformWorkloadIdentitySecrets(t *testing.T) {
394395
},
395396
},
396397
{
397-
name: "ignores identities with no role present",
398+
name: "error - identities with unexpected operator name present",
398399
identities: map[string]api.PlatformWorkloadIdentity{
399400
"foo": {
400401
ClientID: "00f00f00-0f00-0f00-0f00-f00f00f00f00",
401402
},
402-
"bar": {
403-
ClientID: "00ba4ba4-0ba4-0ba4-0ba4-ba4ba4ba4ba4",
404-
},
405403
},
406-
roles: []api.PlatformWorkloadIdentityRole{},
407-
want: []*corev1.Secret{},
404+
roles: []api.PlatformWorkloadIdentityRole{},
405+
want: []*corev1.Secret{},
406+
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"),
408407
},
409408
{
410409
name: "skips ARO operator identity",
@@ -466,6 +465,9 @@ func TestGeneratePlatformWorkloadIdentitySecrets(t *testing.T) {
466465
PlatformWorkloadIdentityProfile: &api.PlatformWorkloadIdentityProfile{
467466
PlatformWorkloadIdentities: tt.identities,
468467
},
468+
ClusterProfile: api.ClusterProfile{
469+
Version: "4.14.40",
470+
},
469471
},
470472
},
471473
},
@@ -484,7 +486,7 @@ func TestGeneratePlatformWorkloadIdentitySecrets(t *testing.T) {
484486
}
485487
got, err := m.generatePlatformWorkloadIdentitySecrets()
486488

487-
utilerror.AssertErrorMessage(t, err, "")
489+
utilerror.AssertErrorMessage(t, err, tt.wantErr)
488490
assert.ElementsMatch(t, got, tt.want)
489491
})
490492
}

pkg/util/platformworkloadidentity/platformworkloadidentityrolesbyversion.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,28 @@ func (service *PlatformWorkloadIdentityRolesByVersionService) GetPlatformWorkloa
8585
}
8686
return platformWorkloadIdentityRolesByRoleName
8787
}
88+
89+
func GetPlatformWorkloadIdentityMismatchError(oc *api.OpenShiftCluster, platformWorkloadIdentityRolesByRoleName map[string]api.PlatformWorkloadIdentityRole) error {
90+
requiredOperatorIdentities := []string{}
91+
for _, role := range platformWorkloadIdentityRolesByRoleName {
92+
requiredOperatorIdentities = append(requiredOperatorIdentities, role.OperatorName)
93+
}
94+
currentOpenShiftVersion, err := version.ParseVersion(oc.Properties.ClusterProfile.Version)
95+
if err != nil {
96+
return err
97+
}
98+
currentMinorVersion := currentOpenShiftVersion.MinorVersion()
99+
v := currentMinorVersion
100+
if oc.Properties.PlatformWorkloadIdentityProfile.UpgradeableTo != nil {
101+
upgradeableVersion, err := version.ParseVersion(string(*oc.Properties.PlatformWorkloadIdentityProfile.UpgradeableTo))
102+
if err != nil {
103+
return err
104+
}
105+
upgradeableMinorVersion := upgradeableVersion.MinorVersion()
106+
if currentMinorVersion != upgradeableMinorVersion && currentOpenShiftVersion.Lt(upgradeableVersion) {
107+
v = fmt.Sprintf("%s or %s", v, upgradeableMinorVersion)
108+
}
109+
}
110+
return api.NewCloudError(http.StatusBadRequest, api.CloudErrorCodePlatformWorkloadIdentityMismatch,
111+
"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 '%v'", v, requiredOperatorIdentities)
112+
}

0 commit comments

Comments
 (0)