From c188bc9be4888558829b330a08da6e88a7e8d663 Mon Sep 17 00:00:00 2001 From: Jessica Yuen <im.jessicayuen@gmail.com> Date: Wed, 15 Nov 2017 12:35:08 -0800 Subject: [PATCH] Normalize environment server URL As part of the environments feature, we want to be able to deploy to a specific cluster given the environment's URI. We cross-check against kubecfg for this URI's location. For fail-safe comparison, we probably want to normalize these URIs. --- cmd/root.go | 16 +++++++++++++--- metadata/environment.go | 6 ++++++ utils/strings.go | 10 ++++++++++ utils/strings_test.go | 28 ++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 52e777ff..3bedfd69 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -347,7 +347,12 @@ func overrideCluster(envName string, clientConfig clientcmd.ClientConfig, overri var servers = make(map[string]string) for name, cluster := range rawConfig.Clusters { - servers[cluster.Server] = name + server, err := utils.NormalizeURL(cluster.Server) + if err != nil { + return err + } + + servers[server] = name } // @@ -361,8 +366,13 @@ func overrideCluster(envName string, clientConfig clientcmd.ClientConfig, overri return err } - if _, ok := servers[env.Server]; ok { - clusterName := servers[env.Server] + server, err := utils.NormalizeURL(env.Server) + if err != nil { + return err + } + + if _, ok := servers[server]; ok { + clusterName := servers[server] log.Debugf("Overwriting --cluster flag with '%s'", clusterName) overrides.Context.Cluster = clusterName log.Debugf("Overwriting --namespace flag with '%s'", env.Namespace) diff --git a/metadata/environment.go b/metadata/environment.go index 18b1b019..efcb9035 100644 --- a/metadata/environment.go +++ b/metadata/environment.go @@ -30,6 +30,7 @@ import ( "github.com/ksonnet/ksonnet-lib/ksonnet-gen/ksonnet" "github.com/ksonnet/ksonnet-lib/ksonnet-gen/kubespec" param "github.com/ksonnet/ksonnet/metadata/params" + "github.com/ksonnet/ksonnet/utils" ) const ( @@ -492,6 +493,11 @@ params + { } func generateSpecData(server, namespace string) ([]byte, error) { + server, err := utils.NormalizeURL(server) + if err != nil { + return nil, err + } + // Format the spec json and return; preface keys with 2 space idents. return json.MarshalIndent(EnvironmentSpec{Server: server, Namespace: namespace}, "", " ") } diff --git a/utils/strings.go b/utils/strings.go index c15dd077..fdd28a96 100644 --- a/utils/strings.go +++ b/utils/strings.go @@ -18,6 +18,8 @@ package utils import ( "bytes" "strings" + + "github.com/PuerkitoBio/purell" ) // IsASCIIIdentifier takes a string and returns true if the string does not @@ -32,6 +34,14 @@ func IsASCIIIdentifier(s string) bool { return true } +// NormalizeURL uses purell's "usually safe normalization" algorithm to +// normalize URLs. This includes removing dot segments, removing trailing +// slashes, removing unnecessary escapes, removing default ports, and setting +// the URL to lowercase. +func NormalizeURL(s string) (string, error) { + return purell.NormalizeURLString(s, purell.FlagsUsuallySafeGreedy) +} + func PadRows(rows [][]string) (string, error) { maxRowLen := 0 for _, row := range rows { diff --git a/utils/strings_test.go b/utils/strings_test.go index 821608ab..3886e28c 100644 --- a/utils/strings_test.go +++ b/utils/strings_test.go @@ -53,6 +53,34 @@ func TestIsASCIIIdentifier(t *testing.T) { } } +func TestNormalizeURL(t *testing.T) { + tests := []struct { + input string + expected string + }{ + { + input: "host/path/./a/b/../c", + expected: "host/path/a/c", + }, + { + input: "HTTP://host", + expected: "http://host", + }, + { + input: "http://host:80", + expected: "http://host", + }, + } + for _, test := range tests { + normalized, err := NormalizeURL(test.input) + if err != nil { + t.Error(err) + } + + require.EqualValues(t, test.expected, normalized) + } +} + func TestPadRows(t *testing.T) { tests := []struct { input [][]string -- GitLab