diff --git a/api/v1/aerospikecluster_validating_webhook.go b/api/v1/aerospikecluster_validating_webhook.go index f5f4f5f9c..1e060cd16 100644 --- a/api/v1/aerospikecluster_validating_webhook.go +++ b/api/v1/aerospikecluster_validating_webhook.go @@ -223,7 +223,7 @@ func (c *AerospikeCluster) validate(aslog logr.Logger) error { return err } - if err := validateRequiredFileStorageForFeatureConf( + if err := validateRequiredFileStorageForAerospikeConfig( rack.AerospikeConfig, &rack.Storage, ); err != nil { return err @@ -1797,7 +1797,7 @@ func validateRequiredFileStorageForMetadata( return nil } -func validateRequiredFileStorageForFeatureConf( +func validateRequiredFileStorageForAerospikeConfig( configSpec AerospikeConfigSpec, storage *AerospikeStorageSpec, ) error { featureKeyFilePaths := getFeatureKeyFilePaths(configSpec) @@ -1821,21 +1821,34 @@ func validateRequiredFileStorageForFeatureConf( } } - // CA cert related fields are not supported with Secret Manager, so check their mount volume - allPaths = append(allPaths, caPaths...) - if defaultPassFilePath != nil { - allPaths = append(allPaths, *defaultPassFilePath) + if !isSecretManagerPath(*defaultPassFilePath) { + allPaths = append(allPaths, *defaultPassFilePath) + } else { + return fmt.Errorf("default-password-file path doesn't support Secret Manager, path %s", *defaultPassFilePath) + } } + // CA cert related fields are not supported with Secret Manager, so check their mount volume + allPaths = append(allPaths, caPaths...) + for _, path := range allPaths { - if !storage.isVolumePresentForAerospikePath(filepath.Dir(path)) { + volume := storage.GetVolumeForAerospikePath(filepath.Dir(path)) + if volume == nil { return fmt.Errorf( "feature-key-file paths or tls paths or default-password-file path "+ - "are not mounted - create an entry for '%v' in 'storage.volumes'", + "are not mounted - create an entry for '%s' in 'storage.volumes'", path, ) } + + if defaultPassFilePath != nil && + (path == *defaultPassFilePath && volume.Source.Secret == nil) { + return fmt.Errorf( + "default-password-file path %s volume source should be secret in storage config, volume %v", + path, volume, + ) + } } return nil diff --git a/api/v1/storage.go b/api/v1/storage.go index e28ceba1d..074385228 100644 --- a/api/v1/storage.go +++ b/api/v1/storage.go @@ -203,12 +203,6 @@ func (s *AerospikeStorageSpec) getAerospikeStorageList(onlyPV bool) ( return blockStorageDeviceList, fileStorageList, nil } -// isVolumePresentForAerospikePath checks if configuration has a volume defined for given path for Aerospike server -// container. -func (s *AerospikeStorageSpec) isVolumePresentForAerospikePath(path string) bool { - return s.GetVolumeForAerospikePath(path) != nil -} - // GetVolumeForAerospikePath returns volume defined for given path for Aerospike server container. func (s *AerospikeStorageSpec) GetVolumeForAerospikePath(path string) *VolumeSpec { var matchedVolume *VolumeSpec diff --git a/test/access_control_test.go b/test/access_control_test.go index 87b7244e6..6ca87bf74 100644 --- a/test/access_control_test.go +++ b/test/access_control_test.go @@ -13,6 +13,7 @@ import ( "github.com/go-logr/logr" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" @@ -2161,6 +2162,28 @@ var _ = Describe( Expect(err).To(HaveOccurred()) }) + It("Should fail if volume source is not secret for default-password-file", func() { + aeroCluster := createDummyAerospikeCluster(clusterNamespacedName, 4) + racks := getDummyRackConf(1, 2) + aeroCluster.Spec.RackConfig.Racks = racks + aeroCluster.Spec.RackConfig.Namespaces = []string{"test"} + aeroCluster.Spec.AerospikeConfig.Value["security"] = map[string]interface{}{ + "default-password-file": "/etc/aerospike/defaultpass/password.conf", + } + aeroCluster.Spec.Storage.Volumes = append(aeroCluster.Spec.Storage.Volumes, asdbv1.VolumeSpec{ + Name: "defaultpass", + Source: asdbv1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + Aerospike: &asdbv1.AerospikeServerVolumeAttachment{ + Path: "/etc/aerospike/defaultpass", + }, + }) + + err := k8sClient.Create(ctx, aeroCluster) + Expect(err).To(HaveOccurred()) + }) + It("Should use default-password-file when configured", func() { By("Creating cluster") @@ -2168,6 +2191,10 @@ var _ = Describe( racks := getDummyRackConf(1, 2) aeroCluster.Spec.RackConfig.Racks = racks aeroCluster.Spec.RackConfig.Namespaces = []string{"test"} + // This file is already added in the storage volume backed by the secret. + aeroCluster.Spec.AerospikeConfig.Value["security"] = map[string]interface{}{ + "default-password-file": "/etc/aerospike/secret/password.conf", + } err := k8sClient.Create(ctx, aeroCluster) Expect(err).ToNot(HaveOccurred()) @@ -2194,15 +2221,20 @@ var _ = Describe( return cerr } - nodes := client.GetNodeNames() - if len(nodes) == 0 { - return fmt.Errorf("No nodes found") + if !client.IsConnected() { + return fmt.Errorf("Not connected") } - pkgLog.Info("Connected to cluster", "nodes", nodes) + pkgLog.Info("Connected to cluster") return nil }, 3*time.Minute).ShouldNot(HaveOccurred()) + + By("Try scaleup") + err = scaleUpClusterTest( + k8sClient, ctx, clusterNamespacedName, 1, + ) + Expect(err).ToNot(HaveOccurred()) }) }) }, diff --git a/test/cluster_helper.go b/test/cluster_helper.go index b9ac0d907..d29a0f96d 100644 --- a/test/cluster_helper.go +++ b/test/cluster_helper.go @@ -31,11 +31,13 @@ import ( const ( baseImage = "aerospike/aerospike-server-enterprise" - prevServerVersion = "6.4.0.0" - pre6Version = "5.7.0.17" - version6 = "6.0.0.5" + prevServerVersion = "7.0.0.0" latestServerVersion = "7.1.0.0" invalidVersion = "3.0.0.4" + + post6Version = "7.0.0.0" + pre6Version = "5.7.0.17" + version6 = "6.0.0.5" ) var ( @@ -45,9 +47,12 @@ var ( logger = logr.Discard() prevImage = fmt.Sprintf("%s:%s", baseImage, prevServerVersion) latestImage = fmt.Sprintf("%s:%s", baseImage, latestServerVersion) - version6Image = fmt.Sprintf("%s:%s", baseImage, version6) invalidImage = fmt.Sprintf("%s:%s", baseImage, invalidVersion) - pre6Image = fmt.Sprintf("%s:%s", baseImage, pre6Version) + + // Storage wipe test + post6Image = fmt.Sprintf("%s:%s", baseImage, post6Version) + version6Image = fmt.Sprintf("%s:%s", baseImage, version6) + pre6Image = fmt.Sprintf("%s:%s", baseImage, pre6Version) ) func rollingRestartClusterByEnablingTLS( @@ -1123,10 +1128,8 @@ func createDummyAerospikeCluster( "proto-fd-max": defaultProtofdmax, "auto-pin": "none", }, - "security": map[string]interface{}{ - "default-password-file": "/etc/aerospike/secret/password.conf", - }, - "network": getNetworkConfig(), + "security": map[string]interface{}{}, + "network": getNetworkConfig(), "namespaces": []interface{}{ getSCNamespaceConfig("test", "/test/dev/xvdf"), }, @@ -1467,7 +1470,7 @@ func aerospikeClusterCreateUpdate( ctx goctx.Context, ) error { return aerospikeClusterCreateUpdateWithTO( - k8sClient, desired, ctx, retryInterval, getTimeout(1), + k8sClient, desired, ctx, retryInterval, getTimeout(desired.Spec.Size), ) } diff --git a/test/storage_wipe_test.go b/test/storage_wipe_test.go index 24a604340..06c60c5e4 100644 --- a/test/storage_wipe_test.go +++ b/test/storage_wipe_test.go @@ -74,7 +74,7 @@ var _ = Describe( } aeroCluster := getStorageWipeAerospikeCluster( clusterNamespacedName, storageConfig, racks, - latestImage, getAerospikeClusterConfig(), + post6Image, getAerospikeClusterConfig(), ) aeroCluster.Spec.PodSpec = podSpec