diff --git a/discovery/cmd/kubernetes-discoverer/main.go b/discovery/cmd/kubernetes-discoverer/main.go index 371c577c..0bc03998 100644 --- a/discovery/cmd/kubernetes-discoverer/main.go +++ b/discovery/cmd/kubernetes-discoverer/main.go @@ -80,9 +80,10 @@ func main() { } // Verify cluster name is passed - if clusterName == "" { - log.Fatalf("The Kubernetes cluster name must be provided using the `--cluster-name` flag") + if util.IsInvalidClusterName(clusterName) { + log.Fatalf("The Kubernetes cluster name must be provided using the `--cluster-name` flag or the one passed is invalid") } + log.Infof("ClusterName is: %s", clusterName) // Discovered cluster is passed if discovererKubeCfgFile == "" { diff --git a/discovery/cmd/openstack-discoverer/main.go b/discovery/cmd/openstack-discoverer/main.go index 29ba31a1..d5126c2a 100644 --- a/discovery/cmd/openstack-discoverer/main.go +++ b/discovery/cmd/openstack-discoverer/main.go @@ -85,9 +85,11 @@ func main() { discovererMetrics = localmetrics.NewMetrics() discovererMetrics.RegisterPrometheus() - if clusterName == "" { - log.Fatal("The OpenStack cluster name must be provided using the --cluster-name flag") + // Verify cluster name is passed + if util.IsInvalidClusterName(clusterName) { + log.Fatalf("The Kubernetes cluster name must be provided using the `--cluster-name` flag or the one passed is invalid") } + log.Infof("ClusterName is: %s", clusterName) gimbalKubeClient, err := k8s.NewClient(gimbalKubeCfgFile, log) if err != nil { diff --git a/discovery/pkg/util/log_format.go b/discovery/pkg/util/util.go similarity index 70% rename from discovery/pkg/util/log_format.go rename to discovery/pkg/util/util.go index 9c4c166f..705b7d48 100644 --- a/discovery/pkg/util/log_format.go +++ b/discovery/pkg/util/util.go @@ -13,7 +13,12 @@ limitations under the License. package util -import "github.com/sirupsen/logrus" +import ( + "log" + "regexp" + + "github.com/sirupsen/logrus" +) // GetFormatter returns a textformatter to customize logs func GetFormatter() *logrus.TextFormatter { @@ -21,3 +26,12 @@ func GetFormatter() *logrus.TextFormatter { FullTimestamp: true, } } + +// IsInvalidClusterName returns true if valid cluster name +func IsInvalidClusterName(clustername string) bool { + matched, err := regexp.MatchString("^[a-z]([-a-z0-9]*[a-z0-9])?$", clustername) + if err != nil { + log.Fatal(err) + } + return !matched +} diff --git a/discovery/pkg/util/util_test.go b/discovery/pkg/util/util_test.go new file mode 100644 index 00000000..37583654 --- /dev/null +++ b/discovery/pkg/util/util_test.go @@ -0,0 +1,85 @@ +// Copyright © 2018 Heptio +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package util + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTranslateService(t *testing.T) { + tests := []struct { + name string + clusterName string + expected bool + }{ + { + name: "empty string", + clusterName: "", + expected: true, + }, + { + name: "simple", + clusterName: "mycluster", + expected: false, + }, + { + name: "hyphen", + clusterName: "my-cluster", + expected: false, + }, + { + name: "underscore", + clusterName: "my_cluster", + expected: true, + }, + { + name: "multiple underscores", + clusterName: "my----cluster", + expected: false, + }, + { + name: "can't start with underscores", + clusterName: "-mycluster", + expected: true, + }, + { + name: "can't end with underscores", + clusterName: "mycluster-", + expected: true, + }, + { + name: "special chars", + clusterName: "!@!mycl^%$uster**", + expected: true, + }, + { + name: "special chars with hyphen & underscore", + clusterName: "!@!my-cl^%$ust_er**", + expected: true, + }, + { + name: "whitespace", + clusterName: " my cluster ", + expected: true, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got := IsInvalidClusterName(tc.clusterName) + assert.EqualValues(t, tc.expected, got) + }) + } +} diff --git a/docs/kubernetes-discoverer.md b/docs/kubernetes-discoverer.md index ac3491cf..c75c3b57 100644 --- a/docs/kubernetes-discoverer.md +++ b/docs/kubernetes-discoverer.md @@ -22,7 +22,7 @@ Arguments are available to customize the discoverer, most have defaults but othe | num-threads | 2 | Specify number of threads to use when processing queue items | gimbal-kubecfg-file | "" | Location of kubecfg file for access to Kubernetes cluster hosting Gimbal | discover-kubecfg-file | "" | Location of kubecfg file for access to remote Kubernetes cluster to watch for services / endpoints -| cluster-name | "" | Name of cluster scraping for services & endpoints +| cluster-name | "" | Name of cluster scraping for services & endpoints (Cannot start or end with a hyphen and must be lowercase alpha-numeric) | debug | false | Enable debug logging ### Credentials diff --git a/docs/openstack-discoverer.md b/docs/openstack-discoverer.md index c2d47d44..1083a04c 100644 --- a/docs/openstack-discoverer.md +++ b/docs/openstack-discoverer.md @@ -21,7 +21,7 @@ Arguments are available to customize the discoverer, most have defaults but othe | version | false | Show version, build information and quit | num-threads | 2 | Specify number of threads to use when processing queue items | gimbal-kubecfg-file | "" | Location of kubecfg file for access to Kubernetes cluster hosting Gimbal -| cluster-name | "" | Name of cluster scraping for services & endpoints +| cluster-name | "" | Name of cluster scraping for services & endpoints (Cannot start or end with a hyphen and must be lowercase alpha-numeric) | debug | false | Enable debug logging | reconciliation-period | 30s | The interval of time between reconciliation loop runs | http-client-timeout | 5s | The HTTP client request timeout