Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,5 @@ type AzureConfig struct {
LoadBalancerSku string `json:"loadBalancerSku"`
DisableOutboundSNAT bool `json:"disableOutboundSNAT"`
LoadBalancerName string `json:"loadBalancerName"`
AADClientCertPath string `json:"aadClientCertPath"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -4969,6 +4969,50 @@ func (r *HostedControlPlaneReconciler) reconcileCSISnapshotControllerOperator(ct
func (r *HostedControlPlaneReconciler) reconcileClusterStorageOperator(ctx context.Context, hcp *hyperv1.HostedControlPlane, releaseImageProvider, userReleaseImageProvider *imageprovider.SimpleReleaseImageProvider, createOrUpdate upsert.CreateOrUpdateFN) error {
params := storage.NewParams(hcp, userReleaseImageProvider.Version(), releaseImageProvider, userReleaseImageProvider, r.SetDefaultSecurityContext)

if hyperazureutil.IsAroHCP() {
// Reconcile SecretProviderClasses
azureDiskSecretProviderClass := manifests.ManagedAzureSecretProviderClass(config.ManagedAzureDiskCSISecretStoreProviderClassName, hcp.Namespace)
if _, err := createOrUpdate(ctx, r, azureDiskSecretProviderClass, func() error {
secretproviderclass.ReconcileManagedAzureSecretProviderClass(azureDiskSecretProviderClass, hcp, hcp.Spec.Platform.Azure.ManagedIdentities.ControlPlane.Disk.CertificateName)
return nil
}); err != nil {
return fmt.Errorf("failed to reconcile Azure Disk Secret Provider Class: %w", err)
}

azureFileSecretProviderClass := manifests.ManagedAzureSecretProviderClass(config.ManagedAzureFileCSISecretStoreProviderClassName, hcp.Namespace)
if _, err := createOrUpdate(ctx, r, azureFileSecretProviderClass, func() error {
secretproviderclass.ReconcileManagedAzureSecretProviderClass(azureFileSecretProviderClass, hcp, hcp.Spec.Platform.Azure.ManagedIdentities.ControlPlane.File.CertificateName)
return nil
}); err != nil {
return fmt.Errorf("failed to reconcile Azure File Secret Provider Class: %w", err)
}

// Get the credentials secret so we can retrieve the tenant ID for the configuration
credentialsSecret := manifests.AzureCredentialInformation(hcp.Namespace)
if err := r.Client.Get(ctx, client.ObjectKeyFromObject(credentialsSecret), credentialsSecret); err != nil {
return fmt.Errorf("failed to get Azure credentials secret: %w", err)
}
tenantID := string(credentialsSecret.Data["AZURE_TENANT_ID"])

// Reconcile the secret needed for azure-disk-csi-controller
// This is related to https://github.com/openshift/csi-operator/pull/290.
azureDiskCSISecret := manifests.AzureDiskConfigWithCredentials(hcp.Namespace)
if _, err := createOrUpdate(ctx, r, azureDiskCSISecret, func() error {
return storage.ReconcileAzureDiskCSISecret(azureDiskCSISecret, hcp, tenantID)
}); err != nil {
return fmt.Errorf("failed to reconcile Azure Disk CSI config: %w", err)
}

// Reconcile the secret needed for azure-disk-csi-controller
// This is related to https://github.com/openshift/csi-operator/pull/290.
azureFileCSISecret := manifests.AzureFileConfigWithCredentials(hcp.Namespace)
if _, err := createOrUpdate(ctx, r, azureDiskCSISecret, func() error {
return storage.ReconcileAzureFileCSISecret(azureFileCSISecret, hcp, tenantID)
}); err != nil {
return fmt.Errorf("failed to reconcile Azure File CSI config: %w", err)
}
}

if hcp.Spec.Platform.Type == hyperv1.AzurePlatform {
credentialsSecret := manifests.AzureCredentialInformation(hcp.Namespace)
if err := r.Client.Get(ctx, client.ObjectKeyFromObject(credentialsSecret), credentialsSecret); err != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package storage

import (
"encoding/json"
"fmt"

hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
"github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/cloud/azure"

corev1 "k8s.io/api/core/v1"
)

// initializeAzureCSIControllerConfig initializes an AzureConfig object which will be used to populate the secrets
// needed by azure-disk-csi-controller and azure-file-csi-controller.
func initializeAzureCSIControllerConfig(hcp *hyperv1.HostedControlPlane, tenantID string) azure.AzureConfig {
azureConfig := azure.AzureConfig{
Cloud: hcp.Spec.Platform.Azure.Cloud,
TenantID: tenantID,
SubscriptionID: hcp.Spec.Platform.Azure.SubscriptionID,
ResourceGroup: hcp.Spec.Platform.Azure.ResourceGroupName,
Location: hcp.Spec.Platform.Azure.Location,
}

return azureConfig
}

// ReconcileAzureDiskCSISecret reconciles the configuration for the secret as expected by azure-disk-csi-controller
func ReconcileAzureDiskCSISecret(secret *corev1.Secret, hcp *hyperv1.HostedControlPlane, tenantID string) error {
config := initializeAzureCSIControllerConfig(hcp, tenantID)
config.AADClientID = hcp.Spec.Platform.Azure.ManagedIdentities.ControlPlane.Disk.ClientID
config.AADClientCertPath = hcp.Spec.Platform.Azure.ManagedIdentities.ControlPlane.Disk.CertificateName

serializedConfig, err := json.MarshalIndent(config, "", " ")
if err != nil {
return fmt.Errorf("failed to serialize cloudconfig: %w", err)
}

if secret.Data == nil {
secret.Data = map[string][]byte{}
}
secret.Data[azure.CloudConfigKey] = serializedConfig
return nil
}

// ReconcileAzureFileCSISecret reconciles the configuration for the secret as expected by azure-file-csi-controller
func ReconcileAzureFileCSISecret(secret *corev1.Secret, hcp *hyperv1.HostedControlPlane, tenantID string) error {
config := initializeAzureCSIControllerConfig(hcp, tenantID)
config.AADClientID = hcp.Spec.Platform.Azure.ManagedIdentities.ControlPlane.File.ClientID
config.AADClientCertPath = hcp.Spec.Platform.Azure.ManagedIdentities.ControlPlane.File.CertificateName

serializedConfig, err := json.MarshalIndent(config, "", " ")
if err != nil {
return fmt.Errorf("failed to serialize cloudconfig: %w", err)
}

if secret.Data == nil {
secret.Data = map[string][]byte{}
}
secret.Data[azure.CloudConfigKey] = serializedConfig
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/kas"
"github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/storage/assets"
assets2 "github.com/openshift/hypershift/support/assets"
"github.com/openshift/hypershift/support/azureutil"
"github.com/openshift/hypershift/support/config"
"github.com/openshift/hypershift/support/util"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
Expand All @@ -31,6 +33,24 @@ func ReconcileOperatorDeployment(
case "cluster-storage-operator":
deployment.Spec.Template.Spec.Containers[i].Image = params.StorageOperatorImage
params.ImageReplacer.replaceEnvVars(deployment.Spec.Template.Spec.Containers[i].Env)

// For managed Azure, we need to supply a couple of environment variables for CSO to pass on to the CSI controllers for disk and file.
// CSO passes those on to the CSI deployment here - https://github.com/openshift/cluster-storage-operator/pull/517/files.
// CSI then mounts the Secrets Provider Class here - https://github.com/openshift/csi-operator/pull/309/files.
if azureutil.IsAroHCP() {
if deployment.Spec.Template.Spec.Containers[i].Env == nil {
deployment.Spec.Template.Spec.Containers[i].Env = make([]corev1.EnvVar, 0)
}
deployment.Spec.Template.Spec.Containers[i].Env = append(deployment.Spec.Template.Spec.Containers[i].Env,
corev1.EnvVar{
Name: "ARO_HCP_SECRET_PROVIDER_CLASS_FOR_DISK",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can we // doc and link who is consuming this magic variable?

Value: config.ManagedAzureDiskCSISecretStoreProviderClassName,
},
corev1.EnvVar{
Name: "ARO_HCP_SECRET_PROVIDER_CLASS_FOR_FILE",
Value: config.ManagedAzureFileCSISecretStoreProviderClassName,
})
}
}
}

Expand Down