diff --git a/assets/overlays/openstack-manila/base/config_secret.yaml b/assets/overlays/openstack-manila/base/config_secret.yaml new file mode 100644 index 000000000..3b6de1491 --- /dev/null +++ b/assets/overlays/openstack-manila/base/config_secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: csi-manila-secrets + namespace: openshift-manila-csi-driver +stringData: + os-cloud: openstack + os-cloudsFile: /etc/openstack/clouds.yaml + os-useClouds: "true" \ 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 new file mode 100644 index 000000000..722769994 --- /dev/null +++ b/assets/overlays/openstack-manila/generated/hypershift/config_secret.yaml @@ -0,0 +1,15 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from overlays/openstack-manila/base/config_secret.yaml +# +# + +apiVersion: v1 +kind: Secret +metadata: + name: csi-manila-secrets + namespace: openshift-manila-csi-driver +stringData: + os-cloud: openstack + os-cloudsFile: /etc/openstack/clouds.yaml + os-useClouds: "true" diff --git a/assets/overlays/openstack-manila/generated/hypershift/controller.yaml b/assets/overlays/openstack-manila/generated/hypershift/controller.yaml index 7ab727ad2..2e53a0e1e 100644 --- a/assets/overlays/openstack-manila/generated/hypershift/controller.yaml +++ b/assets/overlays/openstack-manila/generated/hypershift/controller.yaml @@ -146,6 +146,9 @@ spec: name: socket-dir - mountPath: /etc/kubernetes/static-pod-resources/configmaps/cloud-config name: cacert + - mountPath: /etc/openstack + name: cloud-credentials + readOnly: true - args: - --nodeid=$(NODE_ID) - --endpoint=unix://plugin/csi-nfs.sock @@ -364,6 +367,12 @@ spec: - name: metrics-serving-cert secret: secretName: manila-csi-driver-controller-metrics-serving-cert + - name: cloud-credentials + secret: + items: + - key: clouds.yaml + path: clouds.yaml + secretName: manila-cloud-credentials - configMap: items: - key: ca-bundle.pem diff --git a/assets/overlays/openstack-manila/generated/hypershift/manifests.yaml b/assets/overlays/openstack-manila/generated/hypershift/manifests.yaml index 204364ac9..73eb433d3 100644 --- a/assets/overlays/openstack-manila/generated/hypershift/manifests.yaml +++ b/assets/overlays/openstack-manila/generated/hypershift/manifests.yaml @@ -5,6 +5,7 @@ controllerStaticAssetNames: - controller_sa.yaml - service.yaml guestStaticAssetNames: +- config_secret.yaml - csidriver.yaml - lease_leader_election_binding.yaml - lease_leader_election_role.yaml diff --git a/assets/overlays/openstack-manila/generated/hypershift/node.yaml b/assets/overlays/openstack-manila/generated/hypershift/node.yaml index 4d75663e0..d4e48ab14 100644 --- a/assets/overlays/openstack-manila/generated/hypershift/node.yaml +++ b/assets/overlays/openstack-manila/generated/hypershift/node.yaml @@ -82,6 +82,9 @@ spec: readOnlyRootFilesystem: true terminationMessagePolicy: FallbackToLogsOnError volumeMounts: + - mountPath: /etc/openstack + name: cloud-credentials + readOnly: true - mountPath: /var/lib/kubelet/plugins/manila.csi.openstack.org name: plugin-dir - mountPath: /var/lib/kubelet/plugins/csi-nfsplugin @@ -189,6 +192,12 @@ spec: - name: metrics-serving-cert secret: secretName: manila-csi-driver-node-metrics-serving-cert + - name: cloud-credentials + secret: + items: + - key: clouds.yaml + path: clouds.yaml + secretName: manila-cloud-credentials - hostPath: path: /var/lib/kubelet/plugins/manila.csi.openstack.org type: DirectoryOrCreate diff --git a/assets/overlays/openstack-manila/generated/standalone/config_secret.yaml b/assets/overlays/openstack-manila/generated/standalone/config_secret.yaml new file mode 100644 index 000000000..722769994 --- /dev/null +++ b/assets/overlays/openstack-manila/generated/standalone/config_secret.yaml @@ -0,0 +1,15 @@ +# Generated file. Do not edit. Update using "make update". +# +# Loaded from overlays/openstack-manila/base/config_secret.yaml +# +# + +apiVersion: v1 +kind: Secret +metadata: + name: csi-manila-secrets + namespace: openshift-manila-csi-driver +stringData: + os-cloud: openstack + os-cloudsFile: /etc/openstack/clouds.yaml + os-useClouds: "true" diff --git a/assets/overlays/openstack-manila/generated/standalone/controller.yaml b/assets/overlays/openstack-manila/generated/standalone/controller.yaml index 4ee32b697..a238f2ae9 100644 --- a/assets/overlays/openstack-manila/generated/standalone/controller.yaml +++ b/assets/overlays/openstack-manila/generated/standalone/controller.yaml @@ -112,6 +112,9 @@ spec: name: socket-dir - mountPath: /etc/kubernetes/static-pod-resources/configmaps/cloud-config name: cacert + - mountPath: /etc/openstack + name: cloud-credentials + readOnly: true - args: - --nodeid=$(NODE_ID) - --endpoint=unix://plugin/csi-nfs.sock @@ -309,6 +312,12 @@ spec: - name: metrics-serving-cert secret: secretName: manila-csi-driver-controller-metrics-serving-cert + - name: cloud-credentials + secret: + items: + - key: clouds.yaml + path: clouds.yaml + secretName: manila-cloud-credentials - configMap: items: - key: ca-bundle.pem diff --git a/assets/overlays/openstack-manila/generated/standalone/manifests.yaml b/assets/overlays/openstack-manila/generated/standalone/manifests.yaml index baac27210..5c1d3cdb4 100644 --- a/assets/overlays/openstack-manila/generated/standalone/manifests.yaml +++ b/assets/overlays/openstack-manila/generated/standalone/manifests.yaml @@ -10,6 +10,7 @@ controllerStaticAssetNames: - service.yaml - servicemonitor.yaml guestStaticAssetNames: +- config_secret.yaml - csidriver.yaml - lease_leader_election_binding.yaml - lease_leader_election_role.yaml diff --git a/assets/overlays/openstack-manila/generated/standalone/node.yaml b/assets/overlays/openstack-manila/generated/standalone/node.yaml index 4d75663e0..d4e48ab14 100644 --- a/assets/overlays/openstack-manila/generated/standalone/node.yaml +++ b/assets/overlays/openstack-manila/generated/standalone/node.yaml @@ -82,6 +82,9 @@ spec: readOnlyRootFilesystem: true terminationMessagePolicy: FallbackToLogsOnError volumeMounts: + - mountPath: /etc/openstack + name: cloud-credentials + readOnly: true - mountPath: /var/lib/kubelet/plugins/manila.csi.openstack.org name: plugin-dir - mountPath: /var/lib/kubelet/plugins/csi-nfsplugin @@ -189,6 +192,12 @@ spec: - name: metrics-serving-cert secret: secretName: manila-csi-driver-node-metrics-serving-cert + - name: cloud-credentials + secret: + items: + - key: clouds.yaml + path: clouds.yaml + secretName: manila-cloud-credentials - hostPath: path: /var/lib/kubelet/plugins/manila.csi.openstack.org type: DirectoryOrCreate diff --git a/assets/overlays/openstack-manila/patches/controller_add_driver.yaml b/assets/overlays/openstack-manila/patches/controller_add_driver.yaml index 0b30487ab..7b0bfd429 100644 --- a/assets/overlays/openstack-manila/patches/controller_add_driver.yaml +++ b/assets/overlays/openstack-manila/patches/controller_add_driver.yaml @@ -82,6 +82,9 @@ spec: mountPath: /plugin - name: cacert mountPath: /etc/kubernetes/static-pod-resources/configmaps/cloud-config + - name: cloud-credentials + mountPath: /etc/openstack + readOnly: true resources: requests: cpu: 10m @@ -109,6 +112,12 @@ spec: memory: 50Mi terminationMessagePolicy: FallbackToLogsOnError volumes: + - name: cloud-credentials + secret: + secretName: manila-cloud-credentials + items: + - key: clouds.yaml + path: clouds.yaml - name: socket-dir emptyDir: {} - name: cacert diff --git a/assets/overlays/openstack-manila/patches/node_add_driver.yaml b/assets/overlays/openstack-manila/patches/node_add_driver.yaml index d131b6c9c..ecff0460f 100644 --- a/assets/overlays/openstack-manila/patches/node_add_driver.yaml +++ b/assets/overlays/openstack-manila/patches/node_add_driver.yaml @@ -59,6 +59,9 @@ spec: - name: MANILA_SHARE_PROTO value: NFS volumeMounts: + - name: cloud-credentials + mountPath: /etc/openstack + readOnly: true - name: plugin-dir mountPath: /var/lib/kubelet/plugins/manila.csi.openstack.org - name: fwd-plugin-dir @@ -88,6 +91,12 @@ spec: memory: 50Mi terminationMessagePolicy: FallbackToLogsOnError volumes: + - name: cloud-credentials + secret: + secretName: manila-cloud-credentials + items: + - key: clouds.yaml + path: clouds.yaml - name: registration-dir hostPath: path: /var/lib/kubelet/plugins_registry/ diff --git a/pkg/driver/openstack-manila/openstack_manila.go b/pkg/driver/openstack-manila/openstack_manila.go index 6610f6e60..2c903ded9 100644 --- a/pkg/driver/openstack-manila/openstack_manila.go +++ b/pkg/driver/openstack-manila/openstack_manila.go @@ -16,7 +16,6 @@ import ( "github.com/openshift/csi-operator/pkg/driver/common/operator" "github.com/openshift/csi-operator/pkg/generator" "github.com/openshift/csi-operator/pkg/openstack-manila/client" - "github.com/openshift/csi-operator/pkg/openstack-manila/secret" "github.com/openshift/csi-operator/pkg/openstack-manila/util" "github.com/openshift/csi-operator/pkg/operator/config" "github.com/openshift/library-go/pkg/controller/factory" @@ -98,6 +97,7 @@ func GetOpenStackManilaGeneratorConfig() *generator.CSIDriverGeneratorConfig { "overlays/openstack-manila/base/csidriver.yaml", "overlays/openstack-manila/base/volumesnapshotclass.yaml", "overlays/openstack-manila/base/node_nfs.yaml", + "overlays/openstack-manila/base/config_secret.yaml", ), AssetPatches: commongenerator.DefaultGuestAssetPatches, }, @@ -187,11 +187,7 @@ func GetOpenStackManilaOperatorControllerConfig(ctx context.Context, flavour gen } cfg.PreconditionInformers = []factory.Informer{c.GetCSIDriverInformer().Informer(), c.GetStorageClassInformer().Informer()} - secretSyncer, err := createSecretSyncer(c) - if err != nil { - return nil, err - } - cfg.ExtraControlPlaneControllers = append(cfg.ExtraControlPlaneControllers, configMapSyncer, secretSyncer, nfsCSIDriverController) + cfg.ExtraControlPlaneControllers = append(cfg.ExtraControlPlaneControllers, configMapSyncer, nfsCSIDriverController) cfg.ExtraReplacementsFunc = func() []string { pairs := []string{} @@ -324,19 +320,6 @@ func withCABundleDaemonSetHook(c *clients.Clients) (csidrivernodeservicecontroll return hook, informers } -func createSecretSyncer(c *clients.Clients) (factory.Controller, error) { - secretSyncController := secret.NewSecretSyncController( - c.OperatorClient, - c.KubeClient, - c.ControlPlaneKubeInformers, - c.ControlPlaneNamespace, - c.GuestNamespace, - resyncInterval, - c.EventRecorder) - - return secretSyncController, nil -} - func createConfigMapSyncer(c *clients.Clients) (factory.Controller, error) { // sync config map with OpenStack CA certificate to the operand namespace, // so the driver can get it as a ConfigMap volume. diff --git a/pkg/openstack-manila/secret/secretsync.go b/pkg/openstack-manila/secret/secretsync.go deleted file mode 100644 index 20c1a907b..000000000 --- a/pkg/openstack-manila/secret/secretsync.go +++ /dev/null @@ -1,191 +0,0 @@ -package secret - -import ( - "context" - "fmt" - "time" - - "github.com/gophercloud/utils/v2/openstack/clientconfig" - operatorv1 "github.com/openshift/api/operator/v1" - "github.com/openshift/csi-operator/pkg/openstack-manila/util" - "github.com/openshift/library-go/pkg/controller/factory" - "github.com/openshift/library-go/pkg/operator/events" - "github.com/openshift/library-go/pkg/operator/resource/resourceapply" - "github.com/openshift/library-go/pkg/operator/v1helpers" - "gopkg.in/yaml.v2" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - corelisters "k8s.io/client-go/listers/core/v1" - "k8s.io/klog/v2" -) - -// This SecretSyncController translates Secret provided by cloud-credential-operator into -// format required by the CSI driver. -type SecretSyncController struct { - operatorClient v1helpers.OperatorClient - kubeClient kubernetes.Interface - secretLister corelisters.SecretLister - eventRecorder events.Recorder - controlPlaneNamespace string - guestNamespace string -} - -const ( - // Name of key with clouds.yaml in Secret provided by cloud-credentials-operator. - cloudSecretKey = "clouds.yaml" - // Name of OpenStack in clouds.yaml - // Canonical path for custom ca certificates - cacertPath = "/etc/kubernetes/static-pod-resources/configmaps/cloud-config/ca-bundle.pem" -) - -func NewSecretSyncController( - operatorClient v1helpers.OperatorClient, - kubeClient kubernetes.Interface, - informers v1helpers.KubeInformersForNamespaces, - controlPlaneNamespace, - guestNamespace string, - resync time.Duration, - eventRecorder events.Recorder) factory.Controller { - - // Read secret from operator namespace and save the translated one to the operand namespace - secretInformer := informers.InformersFor(controlPlaneNamespace) - c := &SecretSyncController{ - operatorClient: operatorClient, - kubeClient: kubeClient, - secretLister: secretInformer.Core().V1().Secrets().Lister(), - eventRecorder: eventRecorder.WithComponentSuffix("SecretSync"), - controlPlaneNamespace: controlPlaneNamespace, - guestNamespace: guestNamespace, - } - return factory.New().WithSync(c.sync).ResyncEvery(resync).WithSyncDegradedOnError(operatorClient).WithInformers( - operatorClient.Informer(), - secretInformer.Core().V1().Secrets().Informer(), - ).ToController("SecretSync", eventRecorder) -} - -func (c *SecretSyncController) sync(ctx context.Context, syncCtx factory.SyncContext) error { - opSpec, _, _, err := c.operatorClient.GetOperatorState() - if err != nil { - return err - } - if opSpec.ManagementState != operatorv1.Managed { - return nil - } - - cloudSecret, err := c.secretLister.Secrets(c.controlPlaneNamespace).Get(util.CloudCredentialSecretName) - if err != nil { - if errors.IsNotFound(err) { - // TODO: report error after some while? - klog.V(2).Infof("Waiting for secret %s from cloud-credentials-operator", util.CloudCredentialSecretName) - return nil - } - return err - } - - driverSecret, err := c.translateSecret(cloudSecret) - if err != nil { - return err - } - - _, _, err = resourceapply.ApplySecret(ctx, c.kubeClient.CoreV1(), c.eventRecorder, driverSecret) - if err != nil { - return err - } - return nil -} - -func (c *SecretSyncController) translateSecret(cloudSecret *v1.Secret) (*v1.Secret, error) { - content, ok := cloudSecret.Data[cloudSecretKey] - if !ok { - return nil, fmt.Errorf("OpenStack credentials secret %s did not contain key %s", util.CloudCredentialSecretName, cloudSecretKey) - } - - var clouds clientconfig.Clouds - err := yaml.Unmarshal(content, &clouds) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal clouds credentials stored in secret %s: %s", util.CloudCredentialSecretName, err) - } - - cloud, ok := clouds.Clouds[util.CloudName] - if !ok { - return nil, fmt.Errorf("failed to parse clouds credentials stored in secret %s: cloud %s not found", util.CloudCredentialSecretName, util.CloudName) - } - - data := cloudToConf(cloud) - - // In the hypershift secret, the clouds.yaml field might not have the cacert defined. The content of the certificate - // is defined in the ca-bundle.pem field instead. - _, ok = cloudSecret.Data["ca-bundle.pem"] - if ok { - data["os-certAuthorityPath"] = []byte(cacertPath) - } - - secret := v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: util.ManilaSecretName, - Namespace: c.guestNamespace, - }, - Type: v1.SecretTypeOpaque, - Data: data, - } - - return &secret, nil -} - -func cloudToConf(cloud clientconfig.Cloud) map[string][]byte { - data := make(map[string][]byte) - - if cloud.AuthInfo.AuthURL != "" { - data["os-authURL"] = []byte(cloud.AuthInfo.AuthURL) - } - if cloud.RegionName != "" { - data["os-region"] = []byte(cloud.RegionName) - } - if cloud.AuthInfo.UserID != "" { - data["os-userID"] = []byte(cloud.AuthInfo.UserID) - } else if cloud.AuthInfo.Username != "" { - data["os-userName"] = []byte(cloud.AuthInfo.Username) - } - if cloud.AuthInfo.Password != "" { - data["os-password"] = []byte(cloud.AuthInfo.Password) - } - if cloud.AuthInfo.ApplicationCredentialID != "" { - data["os-applicationCredentialID"] = []byte(cloud.AuthInfo.ApplicationCredentialID) - } - if cloud.AuthInfo.ApplicationCredentialName != "" { - data["os-applicationCredentialName"] = []byte(cloud.AuthInfo.ApplicationCredentialName) - } - if cloud.AuthInfo.ApplicationCredentialSecret != "" { - data["os-applicationCredentialSecret"] = []byte(cloud.AuthInfo.ApplicationCredentialSecret) - } - if cloud.AuthInfo.ProjectID != "" { - data["os-projectID"] = []byte(cloud.AuthInfo.ProjectID) - } else if cloud.AuthInfo.ProjectName != "" { - data["os-projectName"] = []byte(cloud.AuthInfo.ProjectName) - } - if cloud.AuthInfo.DomainID != "" { - data["os-domainID"] = []byte(cloud.AuthInfo.DomainID) - } else if cloud.AuthInfo.DomainName != "" { - data["os-domainName"] = []byte(cloud.AuthInfo.DomainName) - } - if cloud.AuthInfo.ProjectDomainID != "" { - data["os-projectDomainID"] = []byte(cloud.AuthInfo.ProjectDomainID) - } else if cloud.AuthInfo.ProjectDomainName != "" { - data["os-projectDomainName"] = []byte(cloud.AuthInfo.ProjectDomainName) - } - if cloud.AuthInfo.UserDomainID != "" { - data["os-userDomainID"] = []byte(cloud.AuthInfo.UserDomainID) - data["os-domainID"] = []byte(cloud.AuthInfo.UserDomainID) - } else if cloud.AuthInfo.UserDomainName != "" { - data["os-userDomainName"] = []byte(cloud.AuthInfo.UserDomainName) - data["os-domainName"] = []byte(cloud.AuthInfo.UserDomainName) - } - if cloud.CACertFile != "" { - // Replace the original cert authority path from clouds.yaml with the canonical one - data["os-certAuthorityPath"] = []byte(cacertPath) - } - - return data -}