From 089fee38032f45064cc40cf809b5cc55a688478b Mon Sep 17 00:00:00 2001 From: Toby McLaughlin Date: Tue, 1 Sep 2020 21:23:04 +0930 Subject: [PATCH] Ensure kind cluster has RFC1123 compliant name (#20627) When creating a kind cluster, we must use a cluster name that is a valid Kubernetes resource name, and by extension, a valid DNS name. If not, kind cluster provisioning can fail when kind tries to create resources with invalid names. For example, if trying to create a cluster called "a_b" (underscores are not permitted), control-plane provisioning will fail with: host 'a_b-control-plane' must be [...] a valid RFC-1123 DNS subdomain --- dev-tools/mage/kubernetes/kind.go | 2 +- dev-tools/mage/kubernetes/kubernetes.go | 27 ++++++++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/dev-tools/mage/kubernetes/kind.go b/dev-tools/mage/kubernetes/kind.go index d74191e88cd1..c61c302b39bd 100644 --- a/dev-tools/mage/kubernetes/kind.go +++ b/dev-tools/mage/kubernetes/kind.go @@ -65,7 +65,7 @@ func (m *KindIntegrationTestStep) Setup(env map[string]string) error { return nil } - clusterName := kubernetesPodName() + clusterName := kubernetesClusterName() stdOut := ioutil.Discard stdErr := ioutil.Discard if mg.Verbose() { diff --git a/dev-tools/mage/kubernetes/kubernetes.go b/dev-tools/mage/kubernetes/kubernetes.go index e63166dabe90..9b25f316b2c5 100644 --- a/dev-tools/mage/kubernetes/kubernetes.go +++ b/dev-tools/mage/kubernetes/kubernetes.go @@ -24,6 +24,7 @@ import ( "log" "os" "path/filepath" + "regexp" "strings" "time" @@ -132,7 +133,7 @@ func (d *KubernetesIntegrationTester) Test(dir string, mageTarget string, env ma destDir := filepath.Join("/go/src", repo.CanonicalRootImportPath) workDir := filepath.Join(destDir, repo.SubDir) - remote, err := NewKubeRemote(kubeConfig, "default", kubernetesPodName(), workDir, destDir, repo.RootDir) + remote, err := NewKubeRemote(kubeConfig, "default", kubernetesClusterName(), workDir, destDir, repo.RootDir) if err != nil { return err } @@ -172,8 +173,8 @@ func waitKubeStateMetricsReadiness(env map[string]string, stdOut, stdErr io.Writ return nil } -// kubernetesPodName returns the pod name to use with kubernetes. -func kubernetesPodName() string { +// kubernetesClusterName generates a name for the Kubernetes cluster. +func kubernetesClusterName() string { commit, err := mage.CommitHash() if err != nil { panic(errors.Wrap(err, "failed to construct kind cluster name")) @@ -183,13 +184,29 @@ func kubernetesPodName() string { if err != nil { panic(errors.Wrap(err, "failed to construct kind cluster name")) } - version = strings.NewReplacer(".", "_").Replace(version) + version = strings.NewReplacer(".", "-").Replace(version) - clusterName := "{{.BeatName}}_{{.Version}}_{{.ShortCommit}}-{{.StackEnvironment}}" + clusterName := "{{.BeatName}}-{{.Version}}-{{.ShortCommit}}-{{.StackEnvironment}}" clusterName = mage.MustExpand(clusterName, map[string]interface{}{ "StackEnvironment": mage.StackEnvironment, "ShortCommit": commit[:10], "Version": version, }) + + // The cluster name may be used as a component of Kubernetes resource names. + // kind does this, for example. + // + // Since Kubernetes resources are required to have names that are valid DNS + // names, we should ensure that the cluster name also meets this criterion. + subDomainPattern := `^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$` + // Note that underscores, in particular, are not permitted. + matched, err := regexp.MatchString(subDomainPattern, clusterName) + if err != nil { + panic(errors.Wrap(err, "error while validating kind cluster name")) + } + if !matched { + panic("constructed invalid kind cluster name") + } + return clusterName }