diff --git a/controllers/csm_controller.go b/controllers/csm_controller.go index cb086824..875c8122 100644 --- a/controllers/csm_controller.go +++ b/controllers/csm_controller.go @@ -771,7 +771,7 @@ func (r *ContainerStorageModuleReconciler) SyncCSM(ctx context.Context, cr csmv1 modules.AddReverseProxyServiceName(&controller.Deployment) // Set the secret mount for powermax controller. - _, err := drivers.SetPowerMaxSecretMount(&controller.Deployment, cr) + err := drivers.DynamicallyMountPowermaxContent(&controller.Deployment, cr) if err != nil { return err } @@ -783,14 +783,14 @@ func (r *ContainerStorageModuleReconciler) SyncCSM(ctx context.Context, cr csmv1 log.Info("Injecting CSI ReverseProxy") dp, err := modules.ReverseProxyInjectDeployment(controller.Deployment, cr, operatorConfig) if err != nil { - return fmt.Errorf("injecting replication into deployment: %v", err) + return fmt.Errorf("unable to inject ReverseProxy into deployment: %v", err) } controller.Deployment = *dp } // Set the secret mount for powermax node. - _, err := drivers.SetPowerMaxSecretMount(&node.DaemonSetApplyConfig, cr) + err := drivers.DynamicallyMountPowermaxContent(&node.DaemonSetApplyConfig, cr) if err != nil { return err } @@ -1383,6 +1383,10 @@ func (r *ContainerStorageModuleReconciler) PreChecks(ctx context.Context, cr *cs if err != nil { return fmt.Errorf("failed powermax validation: %v", err) } + + // To ensure that we are handling minimal manifests correctly and consistent, we must reset DeployAsSidecar to the original value. + // This variable will be set correctly if the reverseproxy is found in the manifests. + modules.ResetDeployAsSidecar() default: // Go to checkUpgrade if it is standalone module i.e. app mobility or authorizatio proxy server if cr.HasModule(csmv1.ApplicationMobility) || cr.HasModule(csmv1.AuthorizationServer) { diff --git a/operatorconfig/driverconfig/powermax/v2.14.0/controller.yaml b/operatorconfig/driverconfig/powermax/v2.14.0/controller.yaml index b861e68f..0aecffca 100644 --- a/operatorconfig/driverconfig/powermax/v2.14.0/controller.yaml +++ b/operatorconfig/driverconfig/powermax/v2.14.0/controller.yaml @@ -250,16 +250,6 @@ spec: value: controller - name: X_CSI_POWERMAX_SKIP_CERTIFICATE_VALIDATION value: "true" - - name: X_CSI_POWERMAX_USER - valueFrom: - secretKeyRef: - key: username - name: powermax-creds - - name: X_CSI_POWERMAX_PASSWORD - valueFrom: - secretKeyRef: - key: password - name: powermax-creds - name: X_CSI_POWERMAX_DEBUG value: "" - name: X_CSI_GRPC_MAX_THREADS diff --git a/operatorconfig/driverconfig/powermax/v2.14.0/node.yaml b/operatorconfig/driverconfig/powermax/v2.14.0/node.yaml index b85ed8e1..5159574d 100644 --- a/operatorconfig/driverconfig/powermax/v2.14.0/node.yaml +++ b/operatorconfig/driverconfig/powermax/v2.14.0/node.yaml @@ -105,16 +105,6 @@ spec: value: "/plugins/powermax.emc.dell.com/disks" - name: X_CSI_POWERMAX_SKIP_CERTIFICATE_VALIDATION value: "true" - - name: X_CSI_POWERMAX_USER - valueFrom: - secretKeyRef: - name: powermax-creds - key: username - - name: X_CSI_POWERMAX_PASSWORD - valueFrom: - secretKeyRef: - name: powermax-creds - key: password - name: X_CSI_POWERMAX_NODENAME valueFrom: fieldRef: diff --git a/operatorconfig/moduleconfig/common/version-values.yaml b/operatorconfig/moduleconfig/common/version-values.yaml index 383274c5..44070117 100644 --- a/operatorconfig/moduleconfig/common/version-values.yaml +++ b/operatorconfig/moduleconfig/common/version-values.yaml @@ -61,3 +61,9 @@ powermax: replication: "v1.11.0" observability: "v1.11.0" resiliency: "v1.12.0" + v2.14.0: + csireverseproxy: "v2.13.0" + authorization: "v2.1.0" + replication: "v1.11.0" + observability: "v1.11.0" + resiliency: "v1.12.0" diff --git a/pkg/drivers/powermax.go b/pkg/drivers/powermax.go index 272d5a32..1544b867 100644 --- a/pkg/drivers/powermax.go +++ b/pkg/drivers/powermax.go @@ -17,6 +17,7 @@ import ( "fmt" "log" "os" + "slices" "strconv" "strings" @@ -91,7 +92,7 @@ func PrecheckPowerMax(ctx context.Context, cr *csmv1.ContainerStorageModule, ope secretName = cr.Spec.Driver.AuthSecret } - useReverseProxySecret := useReverseProxySecret(cr) + useReverseProxySecret := UseReverseProxySecret(cr) if useReverseProxySecret { log.Infof("[PrecheckPowerMax] Using Secret: %s", secretName) } else { @@ -121,7 +122,7 @@ func PrecheckPowerMax(ctx context.Context, cr *csmv1.ContainerStorageModule, ope return nil } -func useReverseProxySecret(cr *csmv1.ContainerStorageModule) bool { +func UseReverseProxySecret(cr *csmv1.ContainerStorageModule) bool { useSecret := false if cr.Spec.Driver.Common == nil { @@ -382,27 +383,31 @@ func ModifyPowermaxCR(yamlString string, cr csmv1.ContainerStorageModule, fileTy return yamlString } -func SetPowerMaxSecretMount(configuration interface{}, cr csmv1.ContainerStorageModule) (bool, error) { - if useReverseProxySecret(&cr) { - secretName := cr.Spec.Driver.AuthSecret +func DynamicallyMountPowermaxContent(configuration interface{}, cr csmv1.ContainerStorageModule) error { + var podTemplate *acorev1.PodTemplateSpecApplyConfiguration + switch configuration := configuration.(type) { + case *v1.DeploymentApplyConfiguration: + dp := configuration + podTemplate = dp.Spec.Template + case *v1.DaemonSetApplyConfiguration: + ds := configuration + podTemplate = ds.Spec.Template + } + + if podTemplate == nil { + return fmt.Errorf("invalid type passed through") + } + + secretName := cr.Name + "-creds" + if cr.Spec.Driver.AuthSecret != "" { + secretName = cr.Spec.Driver.AuthSecret + } + + if UseReverseProxySecret(&cr) { volumeName := CSIPowerMaxSecretVolumeName optional := false mountPath := CSIPowerMaxSecretMountPath - var podTemplate *acorev1.PodTemplateSpecApplyConfiguration - switch configuration := configuration.(type) { - case *v1.DeploymentApplyConfiguration: - dp := configuration - podTemplate = dp.Spec.Template - case *v1.DaemonSetApplyConfiguration: - ds := configuration - podTemplate = ds.Spec.Template - } - - if podTemplate == nil { - return false, fmt.Errorf("invalid type passed through") - } - // Adding volume podTemplate.Spec.Volumes = append(podTemplate.Spec.Volumes, acorev1.VolumeApplyConfiguration{ @@ -413,17 +418,24 @@ func SetPowerMaxSecretMount(configuration interface{}, cr csmv1.ContainerStorage // Adding volume mount for both the reverseproxy and driver for i, cnt := range podTemplate.Spec.Containers { if *cnt.Name == "driver" || *cnt.Name == "reverseproxy" { - SetPowerMaxSecretVariables(&podTemplate.Spec.Containers[i], volumeName, mountPath) + setPowermaxMountCredentialContent(&podTemplate.Spec.Containers[i], volumeName, mountPath) } } - return true, nil + return nil + } + + for i, cnt := range podTemplate.Spec.Containers { + if *cnt.Name == "driver" { + SetPowermaxConfigContent(&podTemplate.Spec.Containers[i], secretName) + break + } } - return false, nil + return nil } -func SetPowerMaxSecretVariables(ct *acorev1.ContainerApplyConfiguration, mN, mP string) { +func setPowermaxMountCredentialContent(ct *acorev1.ContainerApplyConfiguration, mN, mP string) { ct.VolumeMounts = append(ct.VolumeMounts, acorev1.VolumeMountApplyConfiguration{Name: &mN, MountPath: &mP}) volumeName := CSIPowerMaxSecretFilePath @@ -436,6 +448,46 @@ func SetPowerMaxSecretVariables(ct *acorev1.ContainerApplyConfiguration, mN, mP acorev1.EnvVarApplyConfiguration{Name: &useSecretEnv, Value: &useSecretValue}) } +func SetPowermaxConfigContent(ct *acorev1.ContainerApplyConfiguration, secretName string) { + userNameVariable := "X_CSI_POWERMAX_USER" + userNameKey := "username" + userPasswordVariable := "X_CSI_POWERMAX_PASSWORD" // #nosec G101 + userPasswordKey := "password" + dynamicallyAddEnvironmentVariable(ct, acorev1.EnvVarApplyConfiguration{ + Name: &userNameVariable, + ValueFrom: &acorev1.EnvVarSourceApplyConfiguration{ + SecretKeyRef: &acorev1.SecretKeySelectorApplyConfiguration{ + Key: &userNameKey, + LocalObjectReferenceApplyConfiguration: acorev1.LocalObjectReferenceApplyConfiguration{ + Name: &secretName, + }, + }, + }, + }) + + dynamicallyAddEnvironmentVariable(ct, acorev1.EnvVarApplyConfiguration{ + Name: &userPasswordVariable, + ValueFrom: &acorev1.EnvVarSourceApplyConfiguration{ + SecretKeyRef: &acorev1.SecretKeySelectorApplyConfiguration{ + Key: &userPasswordKey, + LocalObjectReferenceApplyConfiguration: acorev1.LocalObjectReferenceApplyConfiguration{ + Name: &secretName, + }, + }, + }, + }) +} + +func dynamicallyAddEnvironmentVariable(ct *acorev1.ContainerApplyConfiguration, envVar acorev1.EnvVarApplyConfiguration) { + contains := slices.ContainsFunc(ct.Env, + func(v acorev1.EnvVarApplyConfiguration) bool { return *(v.Name) == *(envVar.Name) }, + ) + + if !contains { + ct.Env = append(ct.Env, envVar) + } +} + func getApplyCertVolumePowermax(cr csmv1.ContainerStorageModule) (*acorev1.VolumeApplyConfiguration, error) { name := "certs" secretName := fmt.Sprintf("%s-%s", cr.Name, name) diff --git a/pkg/drivers/powermax_test.go b/pkg/drivers/powermax_test.go index 25800a0b..159ccd1b 100644 --- a/pkg/drivers/powermax_test.go +++ b/pkg/drivers/powermax_test.go @@ -85,7 +85,7 @@ func TestPrecheckPowerMax(t *testing.T) { } } -func TestSetPowerMaxSecretMount(t *testing.T) { +func TestDynamicallyMountPowermaxContent(t *testing.T) { containerName := "driver" volumeName := "myVolume" tests := []struct { @@ -95,7 +95,7 @@ func TestSetPowerMaxSecretMount(t *testing.T) { expectedErr error }{ { - name: "success: pass through deployment configuration", + name: "success: dynamically mount secret for deployment", configuration: &v1.DeploymentApplyConfiguration{ Spec: &v1.DeploymentSpecApplyConfiguration{ Template: &acorev1.PodTemplateSpecApplyConfiguration{ @@ -132,7 +132,44 @@ func TestSetPowerMaxSecretMount(t *testing.T) { expectedErr: nil, }, { - name: "success: pass through daemonset configuration", + name: "success: dynamically mount config content for deployment", + configuration: &v1.DeploymentApplyConfiguration{ + Spec: &v1.DeploymentSpecApplyConfiguration{ + Template: &acorev1.PodTemplateSpecApplyConfiguration{ + Spec: &acorev1.PodSpecApplyConfiguration{ + Volumes: []acorev1.VolumeApplyConfiguration{ + { + Name: &volumeName, + }, + }, + Containers: []acorev1.ContainerApplyConfiguration{ + { + Name: &containerName, + VolumeMounts: []acorev1.VolumeMountApplyConfiguration{ + { + Name: &volumeName, + }, + }, + }, + }, + }, + }, + }, + }, + cr: csmv1.ContainerStorageModule{ + Spec: csmv1.ContainerStorageModuleSpec{ + Driver: csmv1.Driver{ + AuthSecret: "powermax-config", + Common: &csmv1.ContainerTemplate{ + Envs: []corev1.EnvVar{{Name: "X_CSI_REVPROXY_USE_SECRET", Value: "false"}}, + }, + }, + }, + }, + expectedErr: nil, + }, + { + name: "success: dynamically mount secret for daemonset", configuration: &v1.DaemonSetApplyConfiguration{ Spec: &v1.DaemonSetSpecApplyConfiguration{ Template: &acorev1.PodTemplateSpecApplyConfiguration{ @@ -154,8 +191,8 @@ func TestSetPowerMaxSecretMount(t *testing.T) { }, { name: "success: empty envs", - configuration: &v1.ReplicaSetApplyConfiguration{ - Spec: &v1.ReplicaSetSpecApplyConfiguration{ + configuration: &v1.DeploymentApplyConfiguration{ + Spec: &v1.DeploymentSpecApplyConfiguration{ Template: &acorev1.PodTemplateSpecApplyConfiguration{ Spec: &acorev1.PodSpecApplyConfiguration{}, }, @@ -195,7 +232,7 @@ func TestSetPowerMaxSecretMount(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := SetPowerMaxSecretMount(tt.configuration, tt.cr) + err := DynamicallyMountPowermaxContent(tt.configuration, tt.cr) if tt.expectedErr == nil { assert.Nil(t, err) } else { diff --git a/pkg/modules/reverseproxy.go b/pkg/modules/reverseproxy.go index 6d2428b4..3703d43d 100644 --- a/pkg/modules/reverseproxy.go +++ b/pkg/modules/reverseproxy.go @@ -15,7 +15,6 @@ package modules import ( "context" "fmt" - "log" "os" "path/filepath" "slices" @@ -101,7 +100,13 @@ func ReverseProxyPrecheck(ctx context.Context, op utils.OperatorConfig, revproxy proxyConfigMap = env.Value } if env.Name == "DeployAsSidecar" { - deployAsSidecar, _ = strconv.ParseBool(env.Value) + das, err := strconv.ParseBool(env.Value) + if err != nil { + log.Warnf("Error parsing %s, %s. Deploying reverseproxy as sidecar.", env.Name, err.Error()) + das = true + } + + deployAsSidecar = das } } } @@ -113,8 +118,7 @@ func ReverseProxyPrecheck(ctx context.Context, op utils.OperatorConfig, revproxy } } - useSecret := getRevProxyUseSecret(revproxy) - if useSecret == "false" { + if !drivers.UseReverseProxySecret(&cr) { log.Infof("[ReverseProxyPrecheck] using configmap %s", proxyConfigMap) err = r.GetClient().Get(ctx, types.NamespacedName{Name: proxyConfigMap, Namespace: cr.GetNamespace()}, &corev1.ConfigMap{}) if err != nil { @@ -147,7 +151,7 @@ func ReverseProxyServer(ctx context.Context, isDeleting bool, op utils.OperatorC revProxyModule, _, _ := getRevproxyApplyCR(cr, op) secretSupported, _ := utils.MinVersionCheck("v2.13.0", revProxyModule.ConfigVersion) if secretSupported { - if getRevProxyUseSecret(*revProxyModule) == "true" { + if drivers.UseReverseProxySecret(&cr) { secretName := cr.Spec.Driver.AuthSecret deploymentSetReverseProxySecretMounts(dp, secretName) } else { @@ -324,18 +328,18 @@ func ReverseProxyInjectDeployment(dp v1.DeploymentApplyConfiguration, cr csmv1.C } } - // Dynamic secret/configMap mounting is only supported in v2.13.0 and above - secretSupported, _ := utils.MinVersionCheck("v2.13.0", revProxyModule.ConfigVersion) - useSecret := getRevProxyUseSecret(*revProxyModule) - if secretSupported && useSecret == "true" { - _, err = drivers.SetPowerMaxSecretMount(&dp, cr) + // Dynamic secret/configMap mounting is only supported in v2.14.0 and above + secretSupported, _ := utils.MinVersionCheck("v2.14.0", cr.Spec.Driver.ConfigVersion) + useSecret := drivers.UseReverseProxySecret(&cr) + if secretSupported && useSecret { + err = drivers.DynamicallyMountPowermaxContent(&dp, cr) if err != nil { return nil, err } } - if useSecret == "false" { - setReverseProxyConfigMapMounts(&dp, *revProxyModule, secretSupported) + if !useSecret { + setReverseProxyConfigMapMounts(&dp, *revProxyModule, cr) } return &dp, nil @@ -371,21 +375,33 @@ func deploymentSetReverseProxySecretMounts(dp *appsv1.Deployment, secretName str } } -func setReverseProxyConfigMapMounts(dp *v1.DeploymentApplyConfiguration, revProxyModule csmv1.Module, mountVolume bool) { +func setReverseProxyConfigMapMounts(dp *v1.DeploymentApplyConfiguration, revProxyModule csmv1.Module, cr csmv1.ContainerStorageModule) { // inject revProxy volumes in driver volumes revProxyVolume := getRevProxyVolumeComp(revProxyModule) dp.Spec.Template.Spec.Volumes = append(dp.Spec.Template.Spec.Volumes, revProxyVolume...) + volumeMount := acorev1.VolumeMountApplyConfiguration{Name: &RevProxyConfigMapVolName, MountPath: &RevProxyConfigMapMountPath} - if !mountVolume { - log.Printf("[setReverseProxyConfigMapMounts] Using older reverseProxy. Volume already mounted. Skipping reverseProxy injection") - return + secretName := cr.Name + "-creds" + if cr.Spec.Driver.AuthSecret != "" { + secretName = cr.Spec.Driver.AuthSecret } // Adding volume mount for i, cnt := range dp.Spec.Template.Spec.Containers { if *cnt.Name == "reverseproxy" { - dp.Spec.Template.Spec.Containers[i].VolumeMounts = append(dp.Spec.Template.Spec.Containers[i].VolumeMounts, - acorev1.VolumeMountApplyConfiguration{Name: &RevProxyConfigMapVolName, MountPath: &RevProxyConfigMapMountPath}) + contains := slices.ContainsFunc(dp.Spec.Template.Spec.Containers[i].VolumeMounts, + func(v acorev1.VolumeMountApplyConfiguration) bool { + // Cast to pull out value instead of comparing addresses. + return *(v.Name) == *(volumeMount.Name) + }, + ) + + if !contains { + dp.Spec.Template.Spec.Containers[i].VolumeMounts = append(dp.Spec.Template.Spec.Containers[i].VolumeMounts, + acorev1.VolumeMountApplyConfiguration{Name: &RevProxyConfigMapVolName, MountPath: &RevProxyConfigMapMountPath}) + } + } else if *cnt.Name == "driver" { + drivers.SetPowermaxConfigContent(&dp.Spec.Template.Spec.Containers[i], secretName) } } } @@ -439,20 +455,6 @@ func getRevProxyPort(revProxyModule csmv1.Module) string { return revProxyPort } -func getRevProxyUseSecret(revProxyModule csmv1.Module) string { - useSecret := "false" - for _, component := range revProxyModule.Components { - if component.Name == ReverseProxyServerComponent { - for _, env := range component.Envs { - if env.Name == drivers.CSIPowerMaxUseSecret { - useSecret = env.Value - } - } - } - } - return useSecret -} - func getRevProxyEnvVariable(revProxyModule csmv1.Module, envVar string) string { val := "" for _, component := range revProxyModule.Components { @@ -516,6 +518,7 @@ func getRevProxyVolumeComp(revProxyModule csmv1.Module) []acorev1.VolumeApplyCon func getRevproxyApplyCR(cr csmv1.ContainerStorageModule, op utils.OperatorConfig) (*csmv1.Module, *acorev1.ContainerApplyConfiguration, error) { var err error revProxyModule := cr.GetModule(csmv1.ReverseProxy) + // This is necessary for the minimal manifest, where the reverse proxy will not be included in the CSM CR. if len(revProxyModule.Name) == 0 { revProxyModule.Name = csmv1.ReverseProxy @@ -549,3 +552,7 @@ func AddReverseProxyServiceName(dp *v1.DeploymentApplyConfiguration) { var IsReverseProxySidecar = func() bool { return deployAsSidecar } + +func ResetDeployAsSidecar() { + deployAsSidecar = true +} diff --git a/pkg/modules/reverseproxy_test.go b/pkg/modules/reverseproxy_test.go index 55c7e169..10b6c32d 100644 --- a/pkg/modules/reverseproxy_test.go +++ b/pkg/modules/reverseproxy_test.go @@ -190,6 +190,8 @@ func TestReverseProxyPrecheck(t *testing.T) { panic(err) } + customResource.Spec.Driver.Common.Envs = append(customResource.Spec.Driver.Common.Envs, + corev1.EnvVar{Name: "X_CSI_REVPROXY_USE_SECRET", Value: "true"}) customResource.Spec.Modules[0].Components[0].Envs = append(customResource.Spec.Modules[0].Components[0].Envs, corev1.EnvVar{Name: "X_CSI_REVPROXY_USE_SECRET", Value: "true"}) @@ -300,6 +302,8 @@ func TestReverseProxyServer(t *testing.T) { panic(err) } + tmpCR.Spec.Driver.Common.Envs = append(tmpCR.Spec.Driver.Common.Envs, + corev1.EnvVar{Name: "X_CSI_REVPROXY_USE_SECRET", Value: "true"}) tmpCR.Spec.Modules[0].Components[0].Envs = append(tmpCR.Spec.Modules[0].Components[0].Envs, corev1.EnvVar{Name: "X_CSI_REVPROXY_USE_SECRET", Value: "true"}) @@ -313,6 +317,9 @@ func TestReverseProxyServer(t *testing.T) { panic(err) } + tmpCR.Spec.Driver.Common.Envs = append(tmpCR.Spec.Driver.Common.Envs, + corev1.EnvVar{Name: "X_CSI_REVPROXY_USE_SECRET", Value: "false"}) + tmpCR.Spec.Modules[0].Components[0].Envs = append(tmpCR.Spec.Modules[0].Components[0].Envs, corev1.EnvVar{Name: "X_CSI_REVPROXY_USE_SECRET", Value: "false"}) @@ -365,6 +372,8 @@ func TestReverseProxyInjectDeployment(t *testing.T) { panic(err) } + customResource.Spec.Driver.Common.Envs = append(customResource.Spec.Driver.Common.Envs, + corev1.EnvVar{Name: "X_CSI_REVPROXY_USE_SECRET", Value: "true"}) customResource.Spec.Modules[0].Components[0].Envs = append(customResource.Spec.Modules[0].Components[0].Envs, corev1.EnvVar{Name: "X_CSI_REVPROXY_USE_SECRET", Value: "true"}) @@ -382,6 +391,8 @@ func TestReverseProxyInjectDeployment(t *testing.T) { panic(err) } + customResource.Spec.Driver.Common.Envs = append(customResource.Spec.Driver.Common.Envs, + corev1.EnvVar{Name: "X_CSI_REVPROXY_USE_SECRET", Value: "false"}) customResource.Spec.Modules[0].Components[0].Envs = append(customResource.Spec.Modules[0].Components[0].Envs, corev1.EnvVar{Name: "X_CSI_REVPROXY_USE_SECRET", Value: "false"}) diff --git a/tests/e2e/steps/steps_def.go b/tests/e2e/steps/steps_def.go index c833d2ec..d44cc8bb 100644 --- a/tests/e2e/steps/steps_def.go +++ b/tests/e2e/steps/steps_def.go @@ -348,7 +348,10 @@ func (step *Step) validateMinimalCSMDriverSpec(res Resource, driverName string, if driver.CSIDriverType == "" { return fmt.Errorf("csiDriverType is missing") } - if driver.Replicas == 0 { + + // Ensure that the expected number of controller pods are running. + status := found.Status + if status.ControllerStatus.Failed > "0" { return fmt.Errorf("replicas should have a non-zero value") } @@ -360,7 +363,6 @@ func (step *Step) validateMinimalCSMDriverSpec(res Resource, driverName string, driver.Node != nil || driver.CSIDriverSpec != nil || driver.DNSPolicy != "" || - driver.Common != nil || driver.AuthSecret != "" || driver.TLSCertSecret != "" { return fmt.Errorf("unexpected fields found in Driver spec: %+v", driver) diff --git a/tests/e2e/testfiles/minimal-testfiles/scenarios.yaml b/tests/e2e/testfiles/minimal-testfiles/scenarios.yaml index 2ea7cc7a..923aa9df 100644 --- a/tests/e2e/testfiles/minimal-testfiles/scenarios.yaml +++ b/tests/e2e/testfiles/minimal-testfiles/scenarios.yaml @@ -887,6 +887,32 @@ run: - cert-csi test vio --sc op-e2e-pmax --chainLength 1 --chainNumber 1 +- scenario: "Install PowerMax Driver with Mount Credentials (Minimal)" + paths: + - "testfiles/minimal-testfiles/storage_csm_powermax_secret.yaml" + tags: + - "powermax" + steps: + - "Given an environment with k8s or openshift, and CSM operator installed" + - "Create storageclass with name [op-e2e-pmax] and template [testfiles/powermax-templates/powermax-storageclass-template.yaml] for [pmax]" + - "Set up secret with template [testfiles/powermax-templates/powermax-use-secret-template.yaml] name [powermax-creds] in namespace [powermax] for [pmaxUseSecret]" + - "Set up creds with template [testfiles/powermax-templates/powermax-array-config.yaml] for [pmaxArrayConfig]" + - "Apply custom resource [1]" + - "Validate custom resource [1]" + - "Validate [powermax] driver from CR [1] is installed" + - "Validate [powermax] driver spec from CR [1]" + - "Run custom test" + - "Enable forceRemoveDriver on CR [1]" + - "Delete custom resource [1]" + - "Validate [powermax] driver from CR [1] is not installed" + - "Restore template [testfiles/powermax-templates/powermax-storageclass-template.yaml] for [pmax]" + - "Restore template [testfiles/powermax-templates/powermax-use-secret-template.yaml] for [pmaxUseSecret]" + - "Restore template [testfiles/powermax-templates/powermax-array-config.yaml] for [pmaxArrayConfig]" + customTest: + - name: Cert CSI + run: + - cert-csi test vio --sc op-e2e-pmax --chainLength 1 --chainNumber 1 + - scenario: "Install PowerMax Driver (Minimal, With no forceRemoveDriver)" paths: - "testfiles/minimal-testfiles/storage_csm_powermax_with_no_forceRemoveDriver.yaml" diff --git a/tests/e2e/testfiles/minimal-testfiles/storage_csm_powermax_secret.yaml b/tests/e2e/testfiles/minimal-testfiles/storage_csm_powermax_secret.yaml new file mode 100644 index 00000000..e7f1d2f7 --- /dev/null +++ b/tests/e2e/testfiles/minimal-testfiles/storage_csm_powermax_secret.yaml @@ -0,0 +1,23 @@ +apiVersion: storage.dell.com/v1 +kind: ContainerStorageModule +metadata: + name: powermax + namespace: powermax +spec: + driver: + csiDriverType: "powermax" + configVersion: v2.14.0 + forceRemoveDriver: true + common: + envs: + - name: "X_CSI_REVPROXY_USE_SECRET" + value: "true" + modules: + - name: authorization + enabled: false + - name: resiliency + enabled: false + - name: replication + enabled: false + - name: observability + enabled: false