From d4ada219427d476abe5167b25d4228fc78433c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Tue, 1 Sep 2026 09:31:58 +0200 Subject: [PATCH] manila: set os-certAuthorityPath in csi-manila-secrets for CA discovery The upstream Manila CSI driver (cloud-provider-openstack) has its own OpenStack client that reads CA certificates from the os-certAuthorityPath field in the CSI secret parameters, or the cacert field in clouds.yaml. It does NOT read the OS_CACERT environment variable. Neither field was set, so the driver fell back to the system cert pool. In HyperShift, the system cert pool on the management cluster may not include the guest cluster's OpenStack CA, causing TLS verification failures: failed to create Manila v2 client: failed to authenticate: tls: failed to verify certificate: x509: certificate signed by unknown authority Add os-certAuthorityPath to the csi-manila-secrets template with a ${MANILA_CA_CERT_PATH} placeholder. At operator startup, the ExtraReplacementsFunc reads the cloud config ConfigMap (cloud-provider-config in standalone, openstack-cloud-config in HyperShift) and replaces the placeholder with the CA cert mount path when the ConfigMap contains ca-bundle.pem, or with an empty string when no custom CA is present. An empty string causes the driver to skip the CA file and use the system trust store, which is the correct behavior for public CAs. --- .../openstack-manila/base/config_secret.yaml | 3 +- .../generated/hypershift/config_secret.yaml | 1 + .../generated/standalone/config_secret.yaml | 1 + .../openstack-manila/openstack_manila.go | 44 +++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/assets/overlays/openstack-manila/base/config_secret.yaml b/assets/overlays/openstack-manila/base/config_secret.yaml index 3b6de1491..77a74dabe 100644 --- a/assets/overlays/openstack-manila/base/config_secret.yaml +++ b/assets/overlays/openstack-manila/base/config_secret.yaml @@ -6,4 +6,5 @@ metadata: stringData: os-cloud: openstack os-cloudsFile: /etc/openstack/clouds.yaml - os-useClouds: "true" \ No newline at end of file + os-useClouds: "true" + os-certAuthorityPath: "${MANILA_CA_CERT_PATH}" \ No newline at end of file diff --git a/assets/overlays/openstack-manila/generated/hypershift/config_secret.yaml b/assets/overlays/openstack-manila/generated/hypershift/config_secret.yaml index 722769994..b7cc2f27f 100644 --- a/assets/overlays/openstack-manila/generated/hypershift/config_secret.yaml +++ b/assets/overlays/openstack-manila/generated/hypershift/config_secret.yaml @@ -10,6 +10,7 @@ metadata: name: csi-manila-secrets namespace: openshift-manila-csi-driver stringData: + os-certAuthorityPath: ${MANILA_CA_CERT_PATH} os-cloud: openstack os-cloudsFile: /etc/openstack/clouds.yaml os-useClouds: "true" diff --git a/assets/overlays/openstack-manila/generated/standalone/config_secret.yaml b/assets/overlays/openstack-manila/generated/standalone/config_secret.yaml index 722769994..b7cc2f27f 100644 --- a/assets/overlays/openstack-manila/generated/standalone/config_secret.yaml +++ b/assets/overlays/openstack-manila/generated/standalone/config_secret.yaml @@ -10,6 +10,7 @@ metadata: name: csi-manila-secrets namespace: openshift-manila-csi-driver stringData: + os-certAuthorityPath: ${MANILA_CA_CERT_PATH} os-cloud: openstack os-cloudsFile: /etc/openstack/clouds.yaml os-useClouds: "true" diff --git a/pkg/driver/openstack-manila/openstack_manila.go b/pkg/driver/openstack-manila/openstack_manila.go index f3dfdcf87..efffd2e42 100644 --- a/pkg/driver/openstack-manila/openstack_manila.go +++ b/pkg/driver/openstack-manila/openstack_manila.go @@ -43,6 +43,22 @@ const ( openshiftDefaultCloudConfigNamespace = "openshift-config" metricsCertSecretName = "manila-csi-driver-controller-metrics-serving-cert" nfsImageEnvName = "NFS_DRIVER_IMAGE" + + // caCertMountPath is the path where the cloud provider CA certificate is + // mounted in the controller Deployment and node DaemonSet. This must match + // the mountPath of the "cacert" volume in the deployment/daemonset + // templates. + caCertMountPath = "/etc/kubernetes/static-pod-resources/configmaps/cloud-config/ca-bundle.pem" + // caCertKey is the key in the cloud config ConfigMap that holds the CA + // certificate. + caCertKey = "ca-bundle.pem" + + // cloudConfigStandalone is the name of the cloud-provider ConfigMap in + // standalone deployments. + cloudConfigStandalone = "cloud-provider-config" + // cloudConfigHyperShift is the name of the cloud-provider ConfigMap in + // HyperShift deployments (the HyperShift operator uses a different name). + cloudConfigHyperShift = "openstack-cloud-config" ) // GetOpenStackManilaGeneratorConfig returns configuration for generating assets of Manila CSI driver operator. @@ -134,6 +150,14 @@ func GetOpenStackManilaOperatorControllerConfig(ctx context.Context, flavour gen cfg.AddDeploymentHookBuilders(c, withCABundleDeploymentHook) cfg.AddDaemonSetHookBuilders(c, withCABundleDaemonSetHook, withClusterWideProxyDaemonSetHook) + // Determine the cloud config ConfigMap name based on the cluster flavour. + // This ConfigMap holds the cloud provider CA cert used by the operator + // and the CSI driver. + cloudConfigName := cloudConfigStandalone + if flavour == generator.FlavourHyperShift { + cloudConfigName = cloudConfigHyperShift + } + cfg.DeploymentWatchedSecretNames = append(cfg.DeploymentWatchedSecretNames, metricsCertSecretName) cfg.StaleConditionsName = []string{ "ManilaDriverConditionalStaticResourcesController", @@ -208,6 +232,26 @@ func GetOpenStackManilaOperatorControllerConfig(ctx context.Context, flavour gen if nfsImage != "" { pairs = append(pairs, []string{"${NFS_DRIVER_IMAGE}", nfsImage}...) } + + // Set the CA cert path for the Manila CSI driver when the cloud + // provider CA certificate is available. The upstream Manila CSI + // driver reads os-certAuthorityPath from the CSI secret to find + // the CA bundle. We set it to the mounted cacert volume path + // when the cloud config ConfigMap has a ca-bundle.pem entry. + // When absent (e.g. public CA), we leave it empty so the driver + // skips the CA file and uses the system trust store. + caCertPath := "" + cm, err := c.ControlPlaneKubeClient.CoreV1().ConfigMaps(c.ControlPlaneNamespace).Get(ctx, cloudConfigName, metav1.GetOptions{}) + if err == nil { + if val, ok := cm.Data[caCertKey]; ok && len(val) > 0 { + caCertPath = caCertMountPath + klog.V(4).Infof("Cloud config ConfigMap %s/%s has %s, setting CA cert path to %s", c.ControlPlaneNamespace, cloudConfigName, caCertKey, caCertPath) + } + } else { + klog.V(4).Infof("Could not read cloud config ConfigMap %s/%s: %v", c.ControlPlaneNamespace, cloudConfigName, err) + } + pairs = append(pairs, []string{"${MANILA_CA_CERT_PATH}", caCertPath}...) + return pairs } return cfg, nil