From 811b78c4e959e45ef093244ccee86217cbd97fda Mon Sep 17 00:00:00 2001 From: Olivier Michallat Date: Fri, 15 Mar 2024 15:47:03 -0700 Subject: [PATCH] Reject cluster creation if a DC has an invalid name (fixes #1141) --- .../k8ssandra/v1alpha1/k8ssandracluster_webhook.go | 11 ++++++++++- .../v1alpha1/k8ssandracluster_webhook_test.go | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/apis/k8ssandra/v1alpha1/k8ssandracluster_webhook.go b/apis/k8ssandra/v1alpha1/k8ssandracluster_webhook.go index 97e4b1b30..a0b0c2321 100644 --- a/apis/k8ssandra/v1alpha1/k8ssandracluster_webhook.go +++ b/apis/k8ssandra/v1alpha1/k8ssandracluster_webhook.go @@ -18,6 +18,8 @@ package v1alpha1 import ( "fmt" + "k8s.io/apimachinery/pkg/util/validation" + "strings" "github.com/Masterminds/semver/v3" "github.com/k8ssandra/k8ssandra-operator/pkg/clientcache" @@ -69,8 +71,15 @@ func (r *K8ssandraCluster) ValidateCreate() error { func (r *K8ssandraCluster) validateK8ssandraCluster() error { hasClusterStorageConfig := r.Spec.Cassandra.DatacenterOptions.StorageConfig != nil - // Verify given k8s-contexts are correct for _, dc := range r.Spec.Cassandra.Datacenters { + dns1035Errs := validation.IsDNS1035Label(dc.Meta.Name) + if len(dns1035Errs) > 0 { + return fmt.Errorf( + "invalid DC name (you might want to use datacenterName to override the name used in Cassandra): %s", + strings.Join(dns1035Errs, ", ")) + } + + // Verify given k8s-context is correct _, err := clientCache.GetRemoteClient(dc.K8sContext) if err != nil { // No client found for this context name, reject diff --git a/apis/k8ssandra/v1alpha1/k8ssandracluster_webhook_test.go b/apis/k8ssandra/v1alpha1/k8ssandracluster_webhook_test.go index 1f86cce89..aed36c9ed 100644 --- a/apis/k8ssandra/v1alpha1/k8ssandracluster_webhook_test.go +++ b/apis/k8ssandra/v1alpha1/k8ssandracluster_webhook_test.go @@ -147,6 +147,7 @@ func TestWebhook(t *testing.T) { t.Run("NumTokensValidationInUpdate", testNumTokensInUpdate) t.Run("StsNameTooLong", testStsNameTooLong) t.Run("MedusaPrefixMissing", testMedusaPrefixMissing) + t.Run("InvalidDcName", testInvalidDcName) } func testContextValidation(t *testing.T) { @@ -219,6 +220,7 @@ func testStorageConfigValidation(t *testing.T) { required.NoError(err) cluster.Spec.Cassandra.Datacenters = append(cluster.Spec.Cassandra.Datacenters, CassandraDatacenterTemplate{ + Meta: EmbeddedObjectMeta{Name: "dc2"}, K8sContext: "envtest", Size: 1, }) @@ -376,6 +378,7 @@ func createClusterObjWithCassandraConfig(name, namespace string) *K8ssandraClust Datacenters: []CassandraDatacenterTemplate{ { + Meta: EmbeddedObjectMeta{Name: "dc1"}, K8sContext: "envtest", Size: 1, }, @@ -451,3 +454,14 @@ func testMedusaPrefixMissing(t *testing.T) { err = k8sClient.Create(ctx, clusterWithPrefix) required.NoError(err) } + +func testInvalidDcName(t *testing.T) { + required := require.New(t) + createNamespace(required, "ns") + + clusterWithBadDcName := createMinimalClusterObj("bad-dc-name", "ns") + clusterWithBadDcName.Spec.Cassandra.Datacenters[0].Meta.Name = "DC1" + err := k8sClient.Create(ctx, clusterWithBadDcName) + required.Error(err) + required.Contains(err.Error(), "invalid DC name") +}