diff --git a/pkg/hive/install.go b/pkg/hive/install.go index c95b9219839..a391bb1c6e6 100644 --- a/pkg/hive/install.go +++ b/pkg/hive/install.go @@ -79,6 +79,10 @@ func (c *clusterManager) Install(ctx context.Context, sub *api.SubscriptionDocum if err != nil { return err } + boundSASigningKeySecret, err := boundSASigningKeySecret(doc.OpenShiftCluster.Properties.HiveProfile.Namespace, doc.OpenShiftCluster) + if err != nil { + return err + } resources := []kruntime.Object{ azureCredentialSecret, @@ -89,6 +93,13 @@ func (c *clusterManager) Install(ctx context.Context, sub *api.SubscriptionDocum cd, } + if boundSASigningKeySecret != nil { + resources = append(resources, boundSASigningKeySecret) + cd.Spec.BoundServiceAccountSignkingKeySecretRef = &corev1.LocalObjectReference{ + Name: boundSASigningKeySecret.ObjectMeta.Name, + } + } + err = dynamichelper.Prepare(resources) if err != nil { return err diff --git a/pkg/hive/resources.go b/pkg/hive/resources.go index fa8a90b7adb..47e71f0420b 100644 --- a/pkg/hive/resources.go +++ b/pkg/hive/resources.go @@ -22,10 +22,12 @@ import ( // Changing values of these constants most likely would require // some sort of migration on the Hive cluster for existing clusters. const ( - ClusterDeploymentName = "cluster" - aroServiceKubeconfigSecretName = "aro-service-kubeconfig-secret" - clusterServicePrincipalSecretName = "cluster-service-principal-secret" - clusterManifestsSecretName = "cluster-manifests-secret" + ClusterDeploymentName = "cluster" + aroServiceKubeconfigSecretName = "aro-service-kubeconfig-secret" + clusterServicePrincipalSecretName = "cluster-service-principal-secret" + clusterManifestsSecretName = "cluster-manifests-secret" + boundServiceAccountSigningKeySecretName = "bound-service-account-signing-key" + boundServiceAccountSigningKeySecretKey = "bound-service-account-signing-key.key" ) var ( @@ -144,6 +146,26 @@ func clusterManifestsSecret(namespace string, customManifests map[string]kruntim return secret, nil } +func boundSASigningKeySecret(namespace string, oc *api.OpenShiftCluster) (*corev1.Secret, error) { + if !oc.UsesWorkloadIdentity() { + // no secret required - Hive ClusterDeployment should not reference this secret + return nil, nil + } + if oc.Properties.ClusterProfile.BoundServiceAccountSigningKey == nil { + return nil, fmt.Errorf("properties.clusterProfile.boundServiceAccountSigningKey not set") + } + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: boundServiceAccountSigningKeySecretName, + Namespace: namespace, + }, + StringData: map[string]string{ + boundServiceAccountSigningKeySecretKey: string(*oc.Properties.ClusterProfile.BoundServiceAccountSigningKey), + }, + Type: corev1.SecretTypeOpaque, + }, nil +} + func envSecret(namespace string, isDevelopment bool) *corev1.Secret { stringdata := map[string]string{} diff --git a/pkg/hive/resources_test.go b/pkg/hive/resources_test.go index 69ecd50ba54..ae1858873b6 100644 --- a/pkg/hive/resources_test.go +++ b/pkg/hive/resources_test.go @@ -7,11 +7,14 @@ import ( "testing" "github.com/go-test/deep" + "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kruntime "k8s.io/apimachinery/pkg/runtime" "github.com/Azure/ARO-RP/pkg/api" + "github.com/Azure/ARO-RP/pkg/util/pointerutils" + utilerror "github.com/Azure/ARO-RP/test/util/error" ) func TestInstallConfigMap(t *testing.T) { @@ -112,3 +115,59 @@ func TestClusterAzureSecret(t *testing.T) { }) } } + +func TestBoundSASigningKeySecret(t *testing.T) { + testNamespace := "aro-UUID" + for _, tt := range []struct { + name string + oc *api.OpenShiftCluster + wantSecret *corev1.Secret + wantErr string + }{ + { + name: "csp cluster - returns nil", + oc: &api.OpenShiftCluster{ + Properties: api.OpenShiftClusterProperties{ + ServicePrincipalProfile: &api.ServicePrincipalProfile{}, + }, + }, + }, + { + name: "miwi cluster - boundServiceAccountSigningKey not set - returns error", + oc: &api.OpenShiftCluster{ + Properties: api.OpenShiftClusterProperties{ + PlatformWorkloadIdentityProfile: &api.PlatformWorkloadIdentityProfile{}, + ClusterProfile: api.ClusterProfile{}, + }, + }, + wantErr: "properties.clusterProfile.boundServiceAccountSigningKey not set", + }, + { + name: "miwi cluster - creates secret with bound-service-account-signing-key.key contents", + oc: &api.OpenShiftCluster{ + Properties: api.OpenShiftClusterProperties{ + PlatformWorkloadIdentityProfile: &api.PlatformWorkloadIdentityProfile{}, + ClusterProfile: api.ClusterProfile{ + BoundServiceAccountSigningKey: pointerutils.ToPtr(api.SecureString("fakeboundserviceaccountsigningkey")), + }, + }, + }, + wantSecret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: boundServiceAccountSigningKeySecretName, + Namespace: testNamespace, + }, + Type: corev1.SecretTypeOpaque, + StringData: map[string]string{ + boundServiceAccountSigningKeySecretKey: "fakeboundserviceaccountsigningkey", + }, + }, + }, + } { + t.Run(tt.name, func(t *testing.T) { + secret, err := boundSASigningKeySecret(testNamespace, tt.oc) + utilerror.AssertErrorMessage(t, err, tt.wantErr) + assert.Equal(t, tt.wantSecret, secret) + }) + } +}