From 581b63ac221da95ad4a3c224ae4ff7299dbebc95 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 7 May 2019 16:04:37 -0700 Subject: [PATCH 01/25] Fixed API connectivity with http(s) proxy --- cmd/minikube/cmd/start.go | 52 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 30398856dbe1..ce6041a94a61 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -222,6 +222,7 @@ func runStart(cmd *cobra.Command, args []string) { host, preexisting := startHost(m, config.MachineConfig) ip := validateNetwork(host) + updateNoProxy(ip) // Save IP to configuration file for subsequent use config.KubernetesConfig.NodeIP = ip if err := saveConfig(config); err != nil { @@ -514,6 +515,53 @@ func startHost(api libmachine.API, mc cfg.MachineConfig) (*host.Host, bool) { return host, exists } +// isInNoProxy checks if ip is included in NO_PROXY env variable. +func isInNoProxy(ip string) (bool, string) { + v := os.Getenv("NO_PROXY") + + if v == "" { + return false, "" + } + + // Checking for when provided IP doesn't have CIDIR subnet. + if strings.Contains(v, ip) { + return true, v + } + + // Checking if the ip is included in the CIDIR subnet ranges + noProxyBlocks := strings.Split(v, ",") + for _, b := range noProxyBlocks { + if yes, _ := isInBlock(ip, b); yes { + return true, v + } + } + + return false, v +} + +// isInBlock checks if ip is a CIDIR block +func isInBlock(ip string, block string) (bool, error) { + _, b, err := net.ParseCIDR(block) + if err != nil { + return false, err + } + i := net.ParseIP(ip) + if b.Contains(i) { + return false, nil + } + return false, nil +} + +// updateNoProxy is used to whitelist minikube's VM ip from going through proxy +// It updates NO_PROXY environment variable, for the current run. +func updateNoProxy(ip string) error { + yes, v := isInNoProxy(ip) + if yes { // skip if already whitelisted + return nil + } + return os.Setenv("NO_PROXY", fmt.Sprintf("%s,%s/32", v, ip)) +} + // validateNetwork tries to catch network problems as soon as possible func validateNetwork(h *host.Host) string { ip, err := h.Driver.GetIP() @@ -529,6 +577,10 @@ func validateNetwork(h *host.Host) string { optSeen = true } console.OutStyle("option", "%s=%s", k, v) + npSet, _ := isInNoProxy(ip) + if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !npSet { + console.Warning("You are using a proxy, You need to add minikube IP to the NO_PROXY. Use `export NO_PROXY=$NO_PROXY,%s/32`", ip) + } } } From 0529f0b95abcee5e806d8ebd8ee4cb25183923fa Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 8 May 2019 15:17:50 -0700 Subject: [PATCH 02/25] Added more comment --- cmd/minikube/cmd/start.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index ce6041a94a61..cb70808b8ccf 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -222,6 +222,7 @@ func runStart(cmd *cobra.Command, args []string) { host, preexisting := startHost(m, config.MachineConfig) ip := validateNetwork(host) + // Makes minikube node ip to bypass http(s) proxy. since it is local traffic. updateNoProxy(ip) // Save IP to configuration file for subsequent use config.KubernetesConfig.NodeIP = ip @@ -524,11 +525,13 @@ func isInNoProxy(ip string) (bool, string) { } // Checking for when provided IP doesn't have CIDIR subnet. + // For example 192.168.39.224 if strings.Contains(v, ip) { return true, v } // Checking if the ip is included in the CIDIR subnet ranges + // For example 192.168.39.15/24 noProxyBlocks := strings.Split(v, ",") for _, b := range noProxyBlocks { if yes, _ := isInBlock(ip, b); yes { @@ -577,7 +580,7 @@ func validateNetwork(h *host.Host) string { optSeen = true } console.OutStyle("option", "%s=%s", k, v) - npSet, _ := isInNoProxy(ip) + npSet, _ := isInNoProxy(ip) // Skip warning if already set if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !npSet { console.Warning("You are using a proxy, You need to add minikube IP to the NO_PROXY. Use `export NO_PROXY=$NO_PROXY,%s/32`", ip) } From 8bc0010716c066e0f65a72a2eaaea1ea3c0cb7dd Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 9 May 2019 17:29:52 -0700 Subject: [PATCH 03/25] Fix dashboard behind proxy and refactor --- cmd/minikube/cmd/dashboard.go | 8 ++- cmd/minikube/cmd/start.go | 65 +++----------------- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 1 + pkg/minikube/proxy/cidir.go | 32 ++++++++++ pkg/minikube/proxy/cidir_test.go | 48 +++++++++++++++ pkg/minikube/proxy/env.go | 20 ++++++ pkg/minikube/proxy/noproxy.go | 58 +++++++++++++++++ 7 files changed, 173 insertions(+), 59 deletions(-) create mode 100644 pkg/minikube/proxy/cidir.go create mode 100644 pkg/minikube/proxy/cidir_test.go create mode 100644 pkg/minikube/proxy/env.go create mode 100644 pkg/minikube/proxy/noproxy.go diff --git a/cmd/minikube/cmd/dashboard.go b/cmd/minikube/cmd/dashboard.go index 1f773e903ad1..95ce8e30db2e 100644 --- a/cmd/minikube/cmd/dashboard.go +++ b/cmd/minikube/cmd/dashboard.go @@ -32,9 +32,11 @@ import ( configcmd "k8s.io/minikube/cmd/minikube/cmd/config" "k8s.io/minikube/pkg/minikube/cluster" "k8s.io/minikube/pkg/minikube/config" + pkg_config "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/console" "k8s.io/minikube/pkg/minikube/exit" "k8s.io/minikube/pkg/minikube/machine" + "k8s.io/minikube/pkg/minikube/proxy" "k8s.io/minikube/pkg/minikube/service" "k8s.io/minikube/pkg/util" ) @@ -52,11 +54,13 @@ var dashboardCmd = &cobra.Command{ Short: "Access the kubernetes dashboard running within the minikube cluster", Long: `Access the kubernetes dashboard running within the minikube cluster`, Run: func(cmd *cobra.Command, args []string) { + cc, err := pkg_config.Load() + proxy.UpdateNoProxy(cc.KubernetesConfig.NodeIP) + kubectl, err := exec.LookPath("kubectl") if err != nil { exit.WithCode(exit.NoInput, "kubectl not found in PATH, but is required for the dashboard. Installation guide: https://kubernetes.io/docs/tasks/tools/install-kubectl/") } - api, err := machine.NewAPIClient() defer func() { err := api.Close() @@ -117,7 +121,9 @@ var dashboardCmd = &cobra.Command{ func kubectlProxy(path string) (*exec.Cmd, string, error) { // port=0 picks a random system port // config.GetMachineName() respects the -p (profile) flag + cmd := exec.Command(path, "--context", config.GetMachineName(), "proxy", "--port=0") + stdoutPipe, err := cmd.StdoutPipe() if err != nil { return nil, "", errors.Wrap(err, "cmd stdout") diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index cb70808b8ccf..19b1a58a050e 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -51,6 +51,7 @@ import ( "k8s.io/minikube/pkg/minikube/exit" "k8s.io/minikube/pkg/minikube/logs" "k8s.io/minikube/pkg/minikube/machine" + "k8s.io/minikube/pkg/minikube/proxy" pkgutil "k8s.io/minikube/pkg/util" "k8s.io/minikube/pkg/version" ) @@ -102,9 +103,6 @@ var ( apiServerNames []string apiServerIPs []net.IP extraOptions pkgutil.ExtraOptionSlice - - // proxyVars are variables we plumb through to the underlying container runtime - proxyVars = []string{"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY"} ) func init() { @@ -223,7 +221,7 @@ func runStart(cmd *cobra.Command, args []string) { ip := validateNetwork(host) // Makes minikube node ip to bypass http(s) proxy. since it is local traffic. - updateNoProxy(ip) + proxy.UpdateNoProxy(ip) // Save IP to configuration file for subsequent use config.KubernetesConfig.NodeIP = ip if err := saveConfig(config); err != nil { @@ -385,7 +383,7 @@ func generateConfig(cmd *cobra.Command, k8sVersion string) (cfg.Config, error) { // Feed Docker our host proxy environment by default, so that it can pull images if _, ok := r.(*cruntime.Docker); ok { if !cmd.Flags().Changed("docker-env") { - for _, k := range proxyVars { + for _, k := range proxy.EnvVars { if v := os.Getenv(k); v != "" { dockerEnv = append(dockerEnv, fmt.Sprintf("%s=%s", k, v)) } @@ -516,55 +514,6 @@ func startHost(api libmachine.API, mc cfg.MachineConfig) (*host.Host, bool) { return host, exists } -// isInNoProxy checks if ip is included in NO_PROXY env variable. -func isInNoProxy(ip string) (bool, string) { - v := os.Getenv("NO_PROXY") - - if v == "" { - return false, "" - } - - // Checking for when provided IP doesn't have CIDIR subnet. - // For example 192.168.39.224 - if strings.Contains(v, ip) { - return true, v - } - - // Checking if the ip is included in the CIDIR subnet ranges - // For example 192.168.39.15/24 - noProxyBlocks := strings.Split(v, ",") - for _, b := range noProxyBlocks { - if yes, _ := isInBlock(ip, b); yes { - return true, v - } - } - - return false, v -} - -// isInBlock checks if ip is a CIDIR block -func isInBlock(ip string, block string) (bool, error) { - _, b, err := net.ParseCIDR(block) - if err != nil { - return false, err - } - i := net.ParseIP(ip) - if b.Contains(i) { - return false, nil - } - return false, nil -} - -// updateNoProxy is used to whitelist minikube's VM ip from going through proxy -// It updates NO_PROXY environment variable, for the current run. -func updateNoProxy(ip string) error { - yes, v := isInNoProxy(ip) - if yes { // skip if already whitelisted - return nil - } - return os.Setenv("NO_PROXY", fmt.Sprintf("%s,%s/32", v, ip)) -} - // validateNetwork tries to catch network problems as soon as possible func validateNetwork(h *host.Host) string { ip, err := h.Driver.GetIP() @@ -573,16 +522,16 @@ func validateNetwork(h *host.Host) string { } optSeen := false - for _, k := range proxyVars { + for _, k := range proxy.EnvVars { if v := os.Getenv(k); v != "" { if !optSeen { console.OutStyle("internet", "Found network options:") optSeen = true } console.OutStyle("option", "%s=%s", k, v) - npSet, _ := isInNoProxy(ip) // Skip warning if already set - if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !npSet { - console.Warning("You are using a proxy, You need to add minikube IP to the NO_PROXY. Use `export NO_PROXY=$NO_PROXY,%s/32`", ip) + isNp, _ := proxy.IsInNoProxyEnv(ip) // Skip warning if minikube ip is already in NO_PROXY + if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !isNp { + console.Warning("You are using a proxy, You need to add minikube IP to the NO_PROXY. Use `export NO_PROXY=$NO_PROXY,%s`", ip) } } } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 81d99dcfda6f..09f0da7708ba 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -123,6 +123,7 @@ func (k *Bootstrapper) GetAPIServerStatus(ip net.IP, apiserverPort int) (string, url := fmt.Sprintf("https://%s:%d/healthz", ip, apiserverPort) // To avoid: x509: certificate signed by unknown authority tr := &http.Transport{ + Proxy: nil, // To avoid connectiv issue if http(s)_proxy is set. TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} diff --git a/pkg/minikube/proxy/cidir.go b/pkg/minikube/proxy/cidir.go new file mode 100644 index 000000000000..8943940513d7 --- /dev/null +++ b/pkg/minikube/proxy/cidir.go @@ -0,0 +1,32 @@ +/* +Copyright 2019 The Kubernetes Authors All rights reserved. + +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 proxy + +import "net" + +// isInBlock checks if ip is a CIDIR block +func isInBlock(ip string, block string) (bool, error) { + _, b, err := net.ParseCIDR(block) + if err != nil { + return false, err + } + i := net.ParseIP(ip) + if b.Contains(i) { + return true, nil + } + return false, nil +} diff --git a/pkg/minikube/proxy/cidir_test.go b/pkg/minikube/proxy/cidir_test.go new file mode 100644 index 000000000000..db60cf3bc98b --- /dev/null +++ b/pkg/minikube/proxy/cidir_test.go @@ -0,0 +1,48 @@ +/* +Copyright 2019 The Kubernetes Authors All rights reserved. + +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 proxy + +import ( + "testing" +) + +var bTests = []struct { + ip string + block string + expectedResult bool + expectedErr error +}{ + {"", "192.168.0.1/32", false, nil}, + {"192.168.0.1", "192.168.0.1/32", true, nil}, + {"192.168.0.2", "192.168.0.1/32", false, nil}, + {"192.168.0.1", "192.168.0.1/18", true, nil}, + {"abcd", "192.168.0.1/18", false, nil}, +} + +func TestIsInBlock(t *testing.T) { + + for _, tt := range bTests { + actualR, actualErr := isInBlock(tt.ip, tt.block) + if actualR != tt.expectedResult { + t.Errorf("isInBlock(%s,%s): expected %t, actual %t", tt.ip, tt.block, tt.expectedResult, actualR) + } + if actualErr != tt.expectedErr { + t.Errorf("isInBlock(%s,%s): expected error %s, err %s", tt.ip, tt.block, tt.expectedErr, actualErr) + } + } + +} diff --git a/pkg/minikube/proxy/env.go b/pkg/minikube/proxy/env.go new file mode 100644 index 000000000000..d810e22d814e --- /dev/null +++ b/pkg/minikube/proxy/env.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 The Kubernetes Authors All rights reserved. + +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 proxy + +// EnvVars are variables we plumb through to the underlying container runtime +var EnvVars = []string{"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY"} diff --git a/pkg/minikube/proxy/noproxy.go b/pkg/minikube/proxy/noproxy.go new file mode 100644 index 000000000000..e38b238d3cd4 --- /dev/null +++ b/pkg/minikube/proxy/noproxy.go @@ -0,0 +1,58 @@ +/* +Copyright 2019 The Kubernetes Authors All rights reserved. + +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 proxy + +import ( + "fmt" + "os" + "strings" +) + +// UpdateNoProxy is used to whitelist minikube's VM ip from going through proxy +// It updates NO_PROXY environment variable, for the current run. +func UpdateNoProxy(ip string) error { + yes, v := IsInNoProxyEnv(ip) + if yes { // skip if already whitelisted + return nil + } + return os.Setenv("NO_PROXY", fmt.Sprintf("%s,%s", v, ip)) +} + +// IsInNoProxyEnv checks if ip is set in NO_PROXY env variable +// Checks for both IP and IP ranges +func IsInNoProxyEnv(ip string) (bool, string) { + v := os.Getenv("NO_PROXY") + + if v == "" { + return false, "" + } + + // Checking for IP explicitly, i.e., 192.168.39.224 + if strings.Contains(v, ip) { + return true, v + } + + // Checks if ip included in IP ranges, i.e., 192.168.39.13/24 + noProxyBlocks := strings.Split(v, ",") + for _, b := range noProxyBlocks { + if yes, _ := isInBlock(ip, b); yes { + return true, v + } + } + + return false, v +} From 6a433d01bf566ad2a68b607c532576e79c3c447d Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 14 May 2019 20:16:44 -0700 Subject: [PATCH 04/25] Fixing K8S Client Config with TranportWrap --- cmd/minikube/cmd/dashboard.go | 6 +- cmd/minikube/cmd/start.go | 9 ++- pkg/minikube/proxy/cidir.go | 32 ----------- pkg/minikube/proxy/cidir_test.go | 48 ---------------- pkg/minikube/proxy/env.go | 20 ------- pkg/minikube/proxy/noproxy.go | 58 ------------------- pkg/minikube/proxy/proxy.go | 99 ++++++++++++++++++++++++++++++++ pkg/minikube/proxy/proxy_test.go | 76 ++++++++++++++++++++++++ pkg/util/kubernetes.go | 22 +++++++ 9 files changed, 208 insertions(+), 162 deletions(-) delete mode 100644 pkg/minikube/proxy/cidir.go delete mode 100644 pkg/minikube/proxy/cidir_test.go delete mode 100644 pkg/minikube/proxy/env.go delete mode 100644 pkg/minikube/proxy/noproxy.go create mode 100644 pkg/minikube/proxy/proxy.go create mode 100644 pkg/minikube/proxy/proxy_test.go diff --git a/cmd/minikube/cmd/dashboard.go b/cmd/minikube/cmd/dashboard.go index 95ce8e30db2e..7d2a9247822c 100644 --- a/cmd/minikube/cmd/dashboard.go +++ b/cmd/minikube/cmd/dashboard.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "net/http" + "os" "os/exec" "regexp" "time" @@ -55,7 +56,10 @@ var dashboardCmd = &cobra.Command{ Long: `Access the kubernetes dashboard running within the minikube cluster`, Run: func(cmd *cobra.Command, args []string) { cc, err := pkg_config.Load() - proxy.UpdateNoProxy(cc.KubernetesConfig.NodeIP) + if err != nil && !os.IsNotExist(err) { + console.ErrLn("Error loading profile config: %v", err) + } + proxy.UpdateEnv(cc.KubernetesConfig.NodeIP, "NO_PROXY") kubectl, err := exec.LookPath("kubectl") if err != nil { diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 19b1a58a050e..f0413b18818e 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -221,7 +221,10 @@ func runStart(cmd *cobra.Command, args []string) { ip := validateNetwork(host) // Makes minikube node ip to bypass http(s) proxy. since it is local traffic. - proxy.UpdateNoProxy(ip) + err = proxy.UpdateEnv(ip, "NO_PROXY") + if err != nil { + console.ErrStyle("Failed to set NO_PROXY Env. please Use `export NO_PROXY=$NO_PROXY,%s`.", ip) + } // Save IP to configuration file for subsequent use config.KubernetesConfig.NodeIP = ip if err := saveConfig(config); err != nil { @@ -529,8 +532,8 @@ func validateNetwork(h *host.Host) string { optSeen = true } console.OutStyle("option", "%s=%s", k, v) - isNp, _ := proxy.IsInNoProxyEnv(ip) // Skip warning if minikube ip is already in NO_PROXY - if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !isNp { + npIsSet := proxy.CheckEnv(ip, "NO_PROXY") // Skip warning if minikube ip is already in NO_PROXY + if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !npIsSet { console.Warning("You are using a proxy, You need to add minikube IP to the NO_PROXY. Use `export NO_PROXY=$NO_PROXY,%s`", ip) } } diff --git a/pkg/minikube/proxy/cidir.go b/pkg/minikube/proxy/cidir.go deleted file mode 100644 index 8943940513d7..000000000000 --- a/pkg/minikube/proxy/cidir.go +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors All rights reserved. - -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 proxy - -import "net" - -// isInBlock checks if ip is a CIDIR block -func isInBlock(ip string, block string) (bool, error) { - _, b, err := net.ParseCIDR(block) - if err != nil { - return false, err - } - i := net.ParseIP(ip) - if b.Contains(i) { - return true, nil - } - return false, nil -} diff --git a/pkg/minikube/proxy/cidir_test.go b/pkg/minikube/proxy/cidir_test.go deleted file mode 100644 index db60cf3bc98b..000000000000 --- a/pkg/minikube/proxy/cidir_test.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors All rights reserved. - -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 proxy - -import ( - "testing" -) - -var bTests = []struct { - ip string - block string - expectedResult bool - expectedErr error -}{ - {"", "192.168.0.1/32", false, nil}, - {"192.168.0.1", "192.168.0.1/32", true, nil}, - {"192.168.0.2", "192.168.0.1/32", false, nil}, - {"192.168.0.1", "192.168.0.1/18", true, nil}, - {"abcd", "192.168.0.1/18", false, nil}, -} - -func TestIsInBlock(t *testing.T) { - - for _, tt := range bTests { - actualR, actualErr := isInBlock(tt.ip, tt.block) - if actualR != tt.expectedResult { - t.Errorf("isInBlock(%s,%s): expected %t, actual %t", tt.ip, tt.block, tt.expectedResult, actualR) - } - if actualErr != tt.expectedErr { - t.Errorf("isInBlock(%s,%s): expected error %s, err %s", tt.ip, tt.block, tt.expectedErr, actualErr) - } - } - -} diff --git a/pkg/minikube/proxy/env.go b/pkg/minikube/proxy/env.go deleted file mode 100644 index d810e22d814e..000000000000 --- a/pkg/minikube/proxy/env.go +++ /dev/null @@ -1,20 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors All rights reserved. - -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 proxy - -// EnvVars are variables we plumb through to the underlying container runtime -var EnvVars = []string{"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY"} diff --git a/pkg/minikube/proxy/noproxy.go b/pkg/minikube/proxy/noproxy.go deleted file mode 100644 index e38b238d3cd4..000000000000 --- a/pkg/minikube/proxy/noproxy.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors All rights reserved. - -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 proxy - -import ( - "fmt" - "os" - "strings" -) - -// UpdateNoProxy is used to whitelist minikube's VM ip from going through proxy -// It updates NO_PROXY environment variable, for the current run. -func UpdateNoProxy(ip string) error { - yes, v := IsInNoProxyEnv(ip) - if yes { // skip if already whitelisted - return nil - } - return os.Setenv("NO_PROXY", fmt.Sprintf("%s,%s", v, ip)) -} - -// IsInNoProxyEnv checks if ip is set in NO_PROXY env variable -// Checks for both IP and IP ranges -func IsInNoProxyEnv(ip string) (bool, string) { - v := os.Getenv("NO_PROXY") - - if v == "" { - return false, "" - } - - // Checking for IP explicitly, i.e., 192.168.39.224 - if strings.Contains(v, ip) { - return true, v - } - - // Checks if ip included in IP ranges, i.e., 192.168.39.13/24 - noProxyBlocks := strings.Split(v, ",") - for _, b := range noProxyBlocks { - if yes, _ := isInBlock(ip, b); yes { - return true, v - } - } - - return false, v -} diff --git a/pkg/minikube/proxy/proxy.go b/pkg/minikube/proxy/proxy.go new file mode 100644 index 000000000000..3dc0737aff7f --- /dev/null +++ b/pkg/minikube/proxy/proxy.go @@ -0,0 +1,99 @@ +/* +Copyright 2019 The Kubernetes Authors All rights reserved. + +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 proxy + +import ( + "fmt" + "net" + "os" + "strings" + + "github.com/pkg/errors" +) + +// EnvVars are variables we plumb through to the underlying container runtime +var EnvVars = []string{"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY"} + +// isInBlock checks if ip is a CIDR block +func isInBlock(ip string, block string) (bool, error) { + if ip == "" { + return false, fmt.Errorf("ip is nil") + } + if ip == "" { + return false, fmt.Errorf("CIDR is nil") + } + + i := net.ParseIP(ip) + if i == nil { + return false, fmt.Errorf("parsed IP is nil") + } + _, b, err := net.ParseCIDR(block) + if err != nil { + return false, errors.Wrapf(err, "Error Parsing block %s", b) + } + + if b.Contains(i) { + return true, nil + } + return false, nil +} + +// UpdateEnv appends an ip to the environment variable +func UpdateEnv(ip string, env string) error { + if !isValidEnv(env) { + return fmt.Errorf("%s is not a valid env var name for proxy settings", env) + } + if !CheckEnv(ip, env) { + v := os.Getenv(env) + if v == "" { + return os.Setenv(env, ip) + } + return os.Setenv(env, fmt.Sprintf("%s,%s", v, ip)) + } + return nil +} + +// CheckEnv checks if ip in an environment variable +func CheckEnv(ip string, env string) bool { + v := os.Getenv(env) + if v == "" { + return false + } + // Checking for IP explicitly, i.e., 192.168.39.224 + if strings.Contains(v, ip) { + return true + } + // Checks if included in IP ranges, i.e., 192.168.39.13/24 + noProxyBlocks := strings.Split(v, ",") + for _, b := range noProxyBlocks { + if yes, _ := isInBlock(ip, b); yes { + return true + } + } + + return false +} + +// isValidEnv checks if the env for proxy settings +func isValidEnv(env string) bool { + for _, e := range EnvVars { + if e == env { + return true + } + } + return false +} diff --git a/pkg/minikube/proxy/proxy_test.go b/pkg/minikube/proxy/proxy_test.go new file mode 100644 index 000000000000..03d3d52d42a4 --- /dev/null +++ b/pkg/minikube/proxy/proxy_test.go @@ -0,0 +1,76 @@ +/* +Copyright 2019 The Kubernetes Authors All rights reserved. + +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 proxy + +import ( + "fmt" + "testing" +) + +func TestIsValidEnv(t *testing.T) { + var testCases = []struct { + env string + want bool + }{ + {"", false}, + {"HTTPS-PROXY", false}, + {"NOPROXY", false}, + } + for _, tc := range testCases { + t.Run(fmt.Sprintf("%s", tc.env), func(t *testing.T) { + got := isValidEnv(tc.env) + if got != tc.want { + t.Errorf("isValidEnv(\"%v\") got %v; want %v", tc.env, got, tc.want) + } + + }) + } + +} +func TestIsInBlock(t *testing.T) { + + var testCases = []struct { + ip string + block string + want bool + wanntAErr bool + }{ + {"", "192.168.0.1/32", false, true}, + {"192.168.0.1", "192.168.0.1/32", true, false}, + {"192.168.0.2", "192.168.0.1/32", false, false}, + {"192.168.0.1", "192.168.0.1/18", true, false}, + {"abcd", "192.168.0.1/18", false, true}, + } + for _, tc := range testCases { + t.Run(fmt.Sprintf("%s in %s", tc.ip, tc.block), func(t *testing.T) { + got, err := isInBlock(tc.ip, tc.block) + gotErr := false + if err != nil { + gotErr = true + } + if gotErr != tc.wanntAErr { + t.Errorf("isInBlock(%v,%v) got error is %v ; want error is %v", tc.ip, tc.block, gotErr, tc.wanntAErr) + } + + if got != tc.want { + t.Errorf("isInBlock(%v,%v) got %v; want %v", tc.ip, tc.block, got, tc.want) + } + + }) + } + +} diff --git a/pkg/util/kubernetes.go b/pkg/util/kubernetes.go index debe31b98cba..876fc684bf76 100644 --- a/pkg/util/kubernetes.go +++ b/pkg/util/kubernetes.go @@ -18,6 +18,7 @@ package util import ( "fmt" + "net/http" "time" "github.com/golang/glog" @@ -33,6 +34,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes" + rest "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/cmd/kubeadm/app/constants" @@ -67,6 +69,25 @@ func (s *PodStore) Stop() { close(s.stopCh) } +// setNoProxyConfig takes a k8s config and returns a config without proxy +// to avoid connectivity issues when http(s) proxy is used. +func setNoProxyConfig(cfg *rest.Config) *rest.Config { + wt := cfg.WrapTransport // Config might already have a transport wrapper + cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { + if wt != nil { + rt = wt(rt) + } + if ht, ok := rt.(*http.Transport); ok { + ht.Proxy = nil + rt = ht + } else { + glog.Errorf("Error while casting RoundTripper to *http.Transport : %v", ok) + } + return rt + } + return cfg +} + // GetClient gets the client from config func GetClient() (kubernetes.Interface, error) { loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() @@ -76,6 +97,7 @@ func GetClient() (kubernetes.Interface, error) { if err != nil { return nil, fmt.Errorf("Error creating kubeConfig: %v", err) } + config = setNoProxyConfig(config) client, err := kubernetes.NewForConfig(config) if err != nil { return nil, errors.Wrap(err, "Error creating new client from kubeConfig.ClientConfig()") From ddb95e14887ef460014e3b82db5bc24c9a3deb73 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 14 May 2019 20:22:51 -0700 Subject: [PATCH 05/25] return error if nil --- pkg/minikube/proxy/proxy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/proxy/proxy.go b/pkg/minikube/proxy/proxy.go index 3dc0737aff7f..1fec92ed044b 100644 --- a/pkg/minikube/proxy/proxy.go +++ b/pkg/minikube/proxy/proxy.go @@ -49,7 +49,7 @@ func isInBlock(ip string, block string) (bool, error) { if b.Contains(i) { return true, nil } - return false, nil + return false, errors.Wrapf(err, "Error ip not in block") } // UpdateEnv appends an ip to the environment variable From 8120cdd50542bc011628a7f43097956b15af8080 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 14 May 2019 21:45:35 -0700 Subject: [PATCH 06/25] No Proxy for Dashboard and moving logic to proxy package --- cmd/minikube/cmd/dashboard.go | 2 +- pkg/minikube/proxy/proxy.go | 21 +++++++++++++++++++++ pkg/minikube/service/service.go | 4 +++- pkg/util/kubernetes.go | 24 ++---------------------- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/cmd/minikube/cmd/dashboard.go b/cmd/minikube/cmd/dashboard.go index 7d2a9247822c..c7b57318f13d 100644 --- a/cmd/minikube/cmd/dashboard.go +++ b/cmd/minikube/cmd/dashboard.go @@ -59,7 +59,7 @@ var dashboardCmd = &cobra.Command{ if err != nil && !os.IsNotExist(err) { console.ErrLn("Error loading profile config: %v", err) } - proxy.UpdateEnv(cc.KubernetesConfig.NodeIP, "NO_PROXY") + proxy.UpdateEnv(cc.KubernetesConfig.NodeIP, "NO_PROXY") // to be used for http get calls kubectl, err := exec.LookPath("kubectl") if err != nil { diff --git a/pkg/minikube/proxy/proxy.go b/pkg/minikube/proxy/proxy.go index 1fec92ed044b..5a4388af7969 100644 --- a/pkg/minikube/proxy/proxy.go +++ b/pkg/minikube/proxy/proxy.go @@ -19,10 +19,13 @@ package proxy import ( "fmt" "net" + "net/http" "os" "strings" + "github.com/golang/glog" "github.com/pkg/errors" + "k8s.io/client-go/rest" ) // EnvVars are variables we plumb through to the underlying container runtime @@ -97,3 +100,21 @@ func isValidEnv(env string) bool { } return false } + +// SetNoProxyK8s takes a k8s config and upadates the proxy +func SetNoProxyK8s(cfg *rest.Config) *rest.Config { + wt := cfg.WrapTransport // Config might already have a transport wrapper + cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { + if wt != nil { + rt = wt(rt) + } + if ht, ok := rt.(*http.Transport); ok { + ht.Proxy = nil + rt = ht + } else { + glog.Errorf("Error while casting RoundTripper to *http.Transport : %v", ok) + } + return rt + } + return cfg +} diff --git a/pkg/minikube/service/service.go b/pkg/minikube/service/service.go index 3c44f9169639..1a6f2781625a 100644 --- a/pkg/minikube/service/service.go +++ b/pkg/minikube/service/service.go @@ -29,7 +29,7 @@ import ( "github.com/pkg/browser" "github.com/pkg/errors" "github.com/spf13/viper" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/kubernetes" @@ -40,6 +40,7 @@ import ( "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/console" "k8s.io/minikube/pkg/minikube/constants" + "k8s.io/minikube/pkg/minikube/proxy" "k8s.io/minikube/pkg/util" ) @@ -84,6 +85,7 @@ func (*K8sClientGetter) GetClientset(timeout time.Duration) (*kubernetes.Clients return nil, fmt.Errorf("Error creating kubeConfig: %v", err) } clientConfig.Timeout = timeout + clientConfig = proxy.SetNoProxyK8s(clientConfig) client, err := kubernetes.NewForConfig(clientConfig) if err != nil { return nil, errors.Wrap(err, "Error creating new client from kubeConfig.ClientConfig()") diff --git a/pkg/util/kubernetes.go b/pkg/util/kubernetes.go index 876fc684bf76..fe801b25f29c 100644 --- a/pkg/util/kubernetes.go +++ b/pkg/util/kubernetes.go @@ -18,7 +18,6 @@ package util import ( "fmt" - "net/http" "time" "github.com/golang/glog" @@ -34,10 +33,10 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes" - rest "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/cmd/kubeadm/app/constants" + "k8s.io/minikube/pkg/minikube/proxy" ) var ( @@ -69,25 +68,6 @@ func (s *PodStore) Stop() { close(s.stopCh) } -// setNoProxyConfig takes a k8s config and returns a config without proxy -// to avoid connectivity issues when http(s) proxy is used. -func setNoProxyConfig(cfg *rest.Config) *rest.Config { - wt := cfg.WrapTransport // Config might already have a transport wrapper - cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { - if wt != nil { - rt = wt(rt) - } - if ht, ok := rt.(*http.Transport); ok { - ht.Proxy = nil - rt = ht - } else { - glog.Errorf("Error while casting RoundTripper to *http.Transport : %v", ok) - } - return rt - } - return cfg -} - // GetClient gets the client from config func GetClient() (kubernetes.Interface, error) { loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() @@ -97,7 +77,7 @@ func GetClient() (kubernetes.Interface, error) { if err != nil { return nil, fmt.Errorf("Error creating kubeConfig: %v", err) } - config = setNoProxyConfig(config) + config = proxy.SetNoProxyK8s(config) client, err := kubernetes.NewForConfig(config) if err != nil { return nil, errors.Wrap(err, "Error creating new client from kubeConfig.ClientConfig()") From 830e18dc6212d9578900f2347f8e9a5e8a2eb8e4 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 14 May 2019 21:57:48 -0700 Subject: [PATCH 07/25] Updated warn message and remove duplicate warning --- cmd/minikube/cmd/start.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index f0413b18818e..20d76dfed150 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -525,6 +525,7 @@ func validateNetwork(h *host.Host) string { } optSeen := false + warnedOnce := false for _, k := range proxy.EnvVars { if v := os.Getenv(k); v != "" { if !optSeen { @@ -533,8 +534,9 @@ func validateNetwork(h *host.Host) string { } console.OutStyle("option", "%s=%s", k, v) npIsSet := proxy.CheckEnv(ip, "NO_PROXY") // Skip warning if minikube ip is already in NO_PROXY - if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !npIsSet { - console.Warning("You are using a proxy, You need to add minikube IP to the NO_PROXY. Use `export NO_PROXY=$NO_PROXY,%s`", ip) + if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !npIsSet && !warnedOnce { + console.Warning("You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP (%s). Please see https://github.com/kubernetes/minikube/blob/master/docs/http_proxy.md for more details", ip) + warnedOnce = true } } } From 6384a2294e6ec6571554f3e23ff85ae3d947a66e Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 15 May 2019 11:28:31 -0700 Subject: [PATCH 08/25] Fix naming and improve public functions singatures --- cmd/minikube/cmd/dashboard.go | 5 ++++- cmd/minikube/cmd/start.go | 6 +++--- pkg/minikube/proxy/proxy.go | 24 +++++++++++++++++------- pkg/minikube/service/service.go | 16 ++++++++-------- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/cmd/minikube/cmd/dashboard.go b/cmd/minikube/cmd/dashboard.go index c7b57318f13d..b1160d8e0936 100644 --- a/cmd/minikube/cmd/dashboard.go +++ b/cmd/minikube/cmd/dashboard.go @@ -59,7 +59,10 @@ var dashboardCmd = &cobra.Command{ if err != nil && !os.IsNotExist(err) { console.ErrLn("Error loading profile config: %v", err) } - proxy.UpdateEnv(cc.KubernetesConfig.NodeIP, "NO_PROXY") // to be used for http get calls + err = proxy.ExcludeIP(cc.KubernetesConfig.NodeIP) // to be used for http get calls + if err != nil { + glog.Errorf("Error Excluding IP from proxy: %s", err) + } kubectl, err := exec.LookPath("kubectl") if err != nil { diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 20d76dfed150..66b3c6ce0814 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -221,7 +221,7 @@ func runStart(cmd *cobra.Command, args []string) { ip := validateNetwork(host) // Makes minikube node ip to bypass http(s) proxy. since it is local traffic. - err = proxy.UpdateEnv(ip, "NO_PROXY") + err = proxy.ExcludeIP(ip) if err != nil { console.ErrStyle("Failed to set NO_PROXY Env. please Use `export NO_PROXY=$NO_PROXY,%s`.", ip) } @@ -533,8 +533,8 @@ func validateNetwork(h *host.Host) string { optSeen = true } console.OutStyle("option", "%s=%s", k, v) - npIsSet := proxy.CheckEnv(ip, "NO_PROXY") // Skip warning if minikube ip is already in NO_PROXY - if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !npIsSet && !warnedOnce { + ipExcluded := proxy.IsIPExcluded(ip) // Skip warning if minikube ip is already in NO_PROXY + if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !ipExcluded && !warnedOnce { console.Warning("You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP (%s). Please see https://github.com/kubernetes/minikube/blob/master/docs/http_proxy.md for more details", ip) warnedOnce = true } diff --git a/pkg/minikube/proxy/proxy.go b/pkg/minikube/proxy/proxy.go index 5a4388af7969..7cb9405d5de9 100644 --- a/pkg/minikube/proxy/proxy.go +++ b/pkg/minikube/proxy/proxy.go @@ -36,7 +36,7 @@ func isInBlock(ip string, block string) (bool, error) { if ip == "" { return false, fmt.Errorf("ip is nil") } - if ip == "" { + if block == "" { return false, fmt.Errorf("CIDR is nil") } @@ -55,12 +55,22 @@ func isInBlock(ip string, block string) (bool, error) { return false, errors.Wrapf(err, "Error ip not in block") } -// UpdateEnv appends an ip to the environment variable -func UpdateEnv(ip string, env string) error { +// ExcludeIP will exclude the ip from the http(s)_proxy +func ExcludeIP(ip string) error { + return updateEnv(ip, "NO_PROXY") +} + +// IsIPExcluded checks if an IP is excluded from http(s)_proxy +func IsIPExcluded(ip string) bool { + return checkEnv(ip, "NO_PROXY") +} + +// updateEnv appends an ip to the environment variable +func updateEnv(ip string, env string) error { if !isValidEnv(env) { return fmt.Errorf("%s is not a valid env var name for proxy settings", env) } - if !CheckEnv(ip, env) { + if !checkEnv(ip, env) { v := os.Getenv(env) if v == "" { return os.Setenv(env, ip) @@ -70,8 +80,8 @@ func UpdateEnv(ip string, env string) error { return nil } -// CheckEnv checks if ip in an environment variable -func CheckEnv(ip string, env string) bool { +// checkEnv checks if ip in an environment variable +func checkEnv(ip string, env string) bool { v := os.Getenv(env) if v == "" { return false @@ -112,7 +122,7 @@ func SetNoProxyK8s(cfg *rest.Config) *rest.Config { ht.Proxy = nil rt = ht } else { - glog.Errorf("Error while casting RoundTripper to *http.Transport : %v", ok) + glog.Errorf("Error while casting roundr tripper (of type %T) to *http.Transport : %v", rt, ok) } return rt } diff --git a/pkg/minikube/service/service.go b/pkg/minikube/service/service.go index 1a6f2781625a..1423d6a5eab8 100644 --- a/pkg/minikube/service/service.go +++ b/pkg/minikube/service/service.go @@ -29,7 +29,7 @@ import ( "github.com/pkg/browser" "github.com/pkg/errors" "github.com/spf13/viper" - v1 "k8s.io/api/core/v1" + core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/kubernetes" @@ -267,23 +267,23 @@ func WaitAndMaybeOpenService(api libmachine.API, namespace string, service strin } // GetServiceListByLabel returns a ServiceList by label -func GetServiceListByLabel(namespace string, key string, value string) (*v1.ServiceList, error) { +func GetServiceListByLabel(namespace string, key string, value string) (*core.ServiceList, error) { client, err := K8s.GetCoreClient() if err != nil { - return &v1.ServiceList{}, &util.RetriableError{Err: err} + return &core.ServiceList{}, &util.RetriableError{Err: err} } services := client.Services(namespace) if err != nil { - return &v1.ServiceList{}, &util.RetriableError{Err: err} + return &core.ServiceList{}, &util.RetriableError{Err: err} } return getServiceListFromServicesByLabel(services, key, value) } -func getServiceListFromServicesByLabel(services corev1.ServiceInterface, key string, value string) (*v1.ServiceList, error) { +func getServiceListFromServicesByLabel(services corev1.ServiceInterface, key string, value string) (*core.ServiceList, error) { selector := labels.SelectorFromSet(labels.Set(map[string]string{key: value})) serviceList, err := services.List(metav1.ListOptions{LabelSelector: selector.String()}) if err != nil { - return &v1.ServiceList{}, &util.RetriableError{Err: err} + return &core.ServiceList{}, &util.RetriableError{Err: err} } return serviceList, nil @@ -317,13 +317,13 @@ func CreateSecret(namespace, name string, dataValues map[string]string, labels m } // Create Secret - secretObj := &v1.Secret{ + secretObj := &core.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, Labels: labels, }, Data: data, - Type: v1.SecretTypeOpaque, + Type: core.SecretTypeOpaque, } _, err = secrets.Create(secretObj) From 6fe614efa7084d9d1ff9a2000b66dbba71564fcc Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 15 May 2019 11:34:21 -0700 Subject: [PATCH 09/25] Fix stutter between the package name and the function --- pkg/minikube/proxy/proxy.go | 4 ++-- pkg/minikube/service/service.go | 2 +- pkg/util/kubernetes.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/minikube/proxy/proxy.go b/pkg/minikube/proxy/proxy.go index 7cb9405d5de9..70b6355745f4 100644 --- a/pkg/minikube/proxy/proxy.go +++ b/pkg/minikube/proxy/proxy.go @@ -111,8 +111,8 @@ func isValidEnv(env string) bool { return false } -// SetNoProxyK8s takes a k8s config and upadates the proxy -func SetNoProxyK8s(cfg *rest.Config) *rest.Config { +// UpdateConfigTranport takes a k8s rest config and returns a config without a proxy. +func UpdateConfigTranport(cfg *rest.Config) *rest.Config { wt := cfg.WrapTransport // Config might already have a transport wrapper cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { if wt != nil { diff --git a/pkg/minikube/service/service.go b/pkg/minikube/service/service.go index 1423d6a5eab8..23d356fbf63a 100644 --- a/pkg/minikube/service/service.go +++ b/pkg/minikube/service/service.go @@ -85,7 +85,7 @@ func (*K8sClientGetter) GetClientset(timeout time.Duration) (*kubernetes.Clients return nil, fmt.Errorf("Error creating kubeConfig: %v", err) } clientConfig.Timeout = timeout - clientConfig = proxy.SetNoProxyK8s(clientConfig) + clientConfig = proxy.UpdateConfigTranport(clientConfig) client, err := kubernetes.NewForConfig(clientConfig) if err != nil { return nil, errors.Wrap(err, "Error creating new client from kubeConfig.ClientConfig()") diff --git a/pkg/util/kubernetes.go b/pkg/util/kubernetes.go index fe801b25f29c..5bf4dea64c48 100644 --- a/pkg/util/kubernetes.go +++ b/pkg/util/kubernetes.go @@ -77,7 +77,7 @@ func GetClient() (kubernetes.Interface, error) { if err != nil { return nil, fmt.Errorf("Error creating kubeConfig: %v", err) } - config = proxy.SetNoProxyK8s(config) + config = proxy.UpdateConfigTranport(config) client, err := kubernetes.NewForConfig(config) if err != nil { return nil, errors.Wrap(err, "Error creating new client from kubeConfig.ClientConfig()") From b9149b1eb03af2a01c92fbcc3e0553b7124a9e88 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 15 May 2019 11:44:31 -0700 Subject: [PATCH 10/25] Better name --- pkg/minikube/proxy/proxy.go | 4 ++-- pkg/minikube/service/service.go | 2 +- pkg/util/kubernetes.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/minikube/proxy/proxy.go b/pkg/minikube/proxy/proxy.go index 70b6355745f4..18e929d4145d 100644 --- a/pkg/minikube/proxy/proxy.go +++ b/pkg/minikube/proxy/proxy.go @@ -111,8 +111,8 @@ func isValidEnv(env string) bool { return false } -// UpdateConfigTranport takes a k8s rest config and returns a config without a proxy. -func UpdateConfigTranport(cfg *rest.Config) *rest.Config { +// UpdateTransport takes a k8s client *rest.config and returns a config without a proxy. +func UpdateTransport(cfg *rest.Config) *rest.Config { wt := cfg.WrapTransport // Config might already have a transport wrapper cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { if wt != nil { diff --git a/pkg/minikube/service/service.go b/pkg/minikube/service/service.go index 23d356fbf63a..882477d90025 100644 --- a/pkg/minikube/service/service.go +++ b/pkg/minikube/service/service.go @@ -85,7 +85,7 @@ func (*K8sClientGetter) GetClientset(timeout time.Duration) (*kubernetes.Clients return nil, fmt.Errorf("Error creating kubeConfig: %v", err) } clientConfig.Timeout = timeout - clientConfig = proxy.UpdateConfigTranport(clientConfig) + clientConfig = proxy.UpdateTransport(clientConfig) client, err := kubernetes.NewForConfig(clientConfig) if err != nil { return nil, errors.Wrap(err, "Error creating new client from kubeConfig.ClientConfig()") diff --git a/pkg/util/kubernetes.go b/pkg/util/kubernetes.go index 5bf4dea64c48..3dd216513dde 100644 --- a/pkg/util/kubernetes.go +++ b/pkg/util/kubernetes.go @@ -77,7 +77,7 @@ func GetClient() (kubernetes.Interface, error) { if err != nil { return nil, fmt.Errorf("Error creating kubeConfig: %v", err) } - config = proxy.UpdateConfigTranport(config) + config = proxy.UpdateTransport(config) client, err := kubernetes.NewForConfig(config) if err != nil { return nil, errors.Wrap(err, "Error creating new client from kubeConfig.ClientConfig()") From 10799333f1e8851c932bc8525e34ad4447dedc78 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 15 May 2019 15:00:45 -0700 Subject: [PATCH 11/25] Added integration tests for proxy --- go.mod | 2 + go.sum | 4 ++ test/integration/proxy_test.go | 98 ++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 test/integration/proxy_test.go diff --git a/go.mod b/go.mod index 7b7724ea34cb..e29964594c05 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/docker/docker v0.0.0-20180917213351-bbe08dc7f0b9 github.com/docker/go-units v0.0.0-20170127094116-9e638d38cf69 github.com/docker/machine v0.16.1 + github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f github.com/fsnotify/fsnotify v0.0.0-20160816051541-f12c6236fe7b github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 github.com/gogo/protobuf v0.0.0-20170330071051-c0656edd0d9e @@ -56,6 +57,7 @@ require ( github.com/pelletier/go-toml v0.0.0-20160822122712-0049ab3dc4c4 github.com/petar/GoLLRB v0.0.0-20130427215148-53be0d36a84c github.com/peterbourgon/diskv v2.0.1+incompatible + github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 github.com/pkg/browser v0.0.0-20160118053552-9302be274faa github.com/pkg/errors v0.8.0 github.com/pkg/profile v0.0.0-20161223203901-3a8809bd8a80 diff --git a/go.sum b/go.sum index d001caa1bab8..845140f66f4f 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ github.com/docker/go-units v0.0.0-20170127094116-9e638d38cf69 h1:N4WAsrRIb+4U1yI github.com/docker/go-units v0.0.0-20170127094116-9e638d38cf69/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/machine v0.16.1 h1:zrgroZounGVkxLmBqMyc1uT2GgapXVjIWHCfBf0udrA= github.com/docker/machine v0.16.1/go.mod h1:I8mPNDeK1uH+JTcUU7X0ZW8KiYz0jyAgNaeSJ1rCfDI= +github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs= +github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/fsnotify/fsnotify v0.0.0-20160816051541-f12c6236fe7b h1:lHoxUxMozh/yCASOoFep9dPMva62ztmxKK2VB8//Aoo= github.com/fsnotify/fsnotify v0.0.0-20160816051541-f12c6236fe7b/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 h1:ZktWZesgun21uEDrwW7iEV1zPCGQldM2atlJZ3TdvVM= @@ -105,6 +107,8 @@ github.com/pelletier/go-toml v0.0.0-20160822122712-0049ab3dc4c4/go.mod h1:5z9KED github.com/petar/GoLLRB v0.0.0-20130427215148-53be0d36a84c/go.mod h1:HUpKUBZnpzkdx0kD/+Yfuft+uD3zHGtXF/XJB14TUr4= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pkg/browser v0.0.0-20160118053552-9302be274faa h1:od00Tr1U7+cLVtc+RNFmR53spHUF98Ziu33S8UIQnt0= github.com/pkg/browser v0.0.0-20160118053552-9302be274faa/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= diff --git a/test/integration/proxy_test.go b/test/integration/proxy_test.go new file mode 100644 index 000000000000..3bb471355523 --- /dev/null +++ b/test/integration/proxy_test.go @@ -0,0 +1,98 @@ +// +build integration + +/* +Copyright 2019 The Kubernetes Authors All rights reserved. + +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 integration + +import ( + "context" + "fmt" + "os" + "strings" + "testing" + "time" + + "github.com/elazarl/goproxy" + "github.com/phayes/freeport" + "github.com/pkg/errors" + "net/http" +) + +// setUpProxy runs a local http proxy and sets the env vars for it. +func setUpProxy() error { + port, err := freeport.GetFreePort() + if err != nil { + return errors.Wrap(err, "Failed to get an open port") + } + + addr:= fmt.Sprintf("localhost:%d",port) + err = os.Setenv("NO_PROXY", "") + if err != nil { + return errors.Wrap(err, "Failed to set no proxy env") + } + err = os.Setenv("HTTP_PROXY", addr) + if err != nil { + return errors.Wrap(err, "Failed to set http proxy env") + } + + proxy := goproxy.NewProxyHttpServer() + go func() error{ // TODO: handle error @medyagh + return errors.Wrap(http.ListenAndServe(addr, proxy), "Error serving http server for proxy") + }() + return nil +} + + +func TestProxy(t *testing.T) { + err := setUpProxy() + if err != nil { + t.Fatalf("Failed to set up the test proxy: %s", err) + } + + t.Run("ConsoleWarnning", testProxyWarning) + t.Run("DashboardProxy", testDashboard) + +} + + +// testProxyWarning checks user is warned correctly about the proxy related env vars +func testProxyWarning(t *testing.T) { + mk := NewMinikubeRunner(t) + // Start a timer for all remaining commands, to display failure output before a panic. + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) + defer cancel() + startCmd := fmt.Sprintf("start %s %s %s", mk.StartArgs, mk.Args, + "--alsologtostderr --v=5") + stdout, stderr, err := mk.RunWithContext(ctx, startCmd) + if err != nil { + t.Fatalf("start: %v\nstdout: %s\nstderr: %s", err, stdout, stderr) + } + mk.EnsureRunning() + + // Pre-cleanup: this usually fails, because no instance is running. + // mk.RunWithContext(ctx, "delete") + msg := "Found network options:" + if !strings.Contains(stdout, msg) { + t.Errorf("Proxy wranning (%s) is missing from the output: %s", msg, stderr) + } + + msg = "You appear to be using a proxy" + if !strings.Contains(stderr, msg) { + t.Errorf("Proxy wranning (%s) is missing from the output: %s", msg, stderr) + } + +} From a0c6013e718913809d35bd26dd6fb3c40e228e04 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 15 May 2019 15:05:29 -0700 Subject: [PATCH 12/25] Fixed Error handling for http serve --- test/integration/proxy_test.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/integration/proxy_test.go b/test/integration/proxy_test.go index 3bb471355523..34d121d5d650 100644 --- a/test/integration/proxy_test.go +++ b/test/integration/proxy_test.go @@ -33,7 +33,7 @@ import ( ) // setUpProxy runs a local http proxy and sets the env vars for it. -func setUpProxy() error { +func setUpProxy(t *testing.T) error { port, err := freeport.GetFreePort() if err != nil { return errors.Wrap(err, "Failed to get an open port") @@ -50,19 +50,18 @@ func setUpProxy() error { } proxy := goproxy.NewProxyHttpServer() - go func() error{ // TODO: handle error @medyagh - return errors.Wrap(http.ListenAndServe(addr, proxy), "Error serving http server for proxy") + go func(){ + t.Fatalf("Failed to server a http server for proxy : %s ", http.ListenAndServe(addr, proxy)) }() return nil } func TestProxy(t *testing.T) { - err := setUpProxy() + err := setUpProxy(t) if err != nil { t.Fatalf("Failed to set up the test proxy: %s", err) } - t.Run("ConsoleWarnning", testProxyWarning) t.Run("DashboardProxy", testDashboard) From b8501ea4f4845ed0383be5971853eb67fd16e4af Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 15 May 2019 15:30:39 -0700 Subject: [PATCH 13/25] Fix formatting --- go.mod | 1 + go.sum | 3 +++ test/integration/proxy_test.go | 14 +++++++------- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index e29964594c05..bc6cc925a304 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/docker/go-units v0.0.0-20170127094116-9e638d38cf69 github.com/docker/machine v0.16.1 github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f + github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect github.com/fsnotify/fsnotify v0.0.0-20160816051541-f12c6236fe7b github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 github.com/gogo/protobuf v0.0.0-20170330071051-c0656edd0d9e diff --git a/go.sum b/go.sum index 845140f66f4f..51cf582df80a 100644 --- a/go.sum +++ b/go.sum @@ -21,6 +21,8 @@ github.com/docker/machine v0.16.1 h1:zrgroZounGVkxLmBqMyc1uT2GgapXVjIWHCfBf0udrA github.com/docker/machine v0.16.1/go.mod h1:I8mPNDeK1uH+JTcUU7X0ZW8KiYz0jyAgNaeSJ1rCfDI= github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs= github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f h1:AUj1VoZUfhPhOPHULCQQDnGhRelpFWHMLhQVWDsS0v4= +github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/fsnotify/fsnotify v0.0.0-20160816051541-f12c6236fe7b h1:lHoxUxMozh/yCASOoFep9dPMva62ztmxKK2VB8//Aoo= github.com/fsnotify/fsnotify v0.0.0-20160816051541-f12c6236fe7b/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 h1:ZktWZesgun21uEDrwW7iEV1zPCGQldM2atlJZ3TdvVM= @@ -121,6 +123,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/r2d4/external-storage v0.0.0-20171222174501-8c0e8605dc7b h1:+wokSDzl6kjfWhVQsBhFOC2t4TYfdLfRXfWorEg3KUE= github.com/r2d4/external-storage v0.0.0-20171222174501-8c0e8605dc7b/go.mod h1:/UlUhYuWiiitqIPbAxyU96i/wDlBS8sRHX2lRN+ffgs= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/russross/blackfriday v0.0.0-20151117072312-300106c228d5 h1:+6eORf9Bt4C3Wjt91epyu6wvLW+P6+AEODb6uKgO+4g= github.com/russross/blackfriday v0.0.0-20151117072312-300106c228d5/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/samalba/dockerclient v0.0.0-20160414174713-91d7393ff859 h1:XRl74t6xHKI5EVIjDI5nPlHRq0bHED9/TjQuD8/UMkE= diff --git a/test/integration/proxy_test.go b/test/integration/proxy_test.go index 34d121d5d650..37eb5f624fc8 100644 --- a/test/integration/proxy_test.go +++ b/test/integration/proxy_test.go @@ -26,10 +26,11 @@ import ( "testing" "time" + "net/http" + "github.com/elazarl/goproxy" "github.com/phayes/freeport" "github.com/pkg/errors" - "net/http" ) // setUpProxy runs a local http proxy and sets the env vars for it. @@ -39,7 +40,7 @@ func setUpProxy(t *testing.T) error { return errors.Wrap(err, "Failed to get an open port") } - addr:= fmt.Sprintf("localhost:%d",port) + addr := fmt.Sprintf("localhost:%d", port) err = os.Setenv("NO_PROXY", "") if err != nil { return errors.Wrap(err, "Failed to set no proxy env") @@ -50,13 +51,13 @@ func setUpProxy(t *testing.T) error { } proxy := goproxy.NewProxyHttpServer() - go func(){ - t.Fatalf("Failed to server a http server for proxy : %s ", http.ListenAndServe(addr, proxy)) - }() + go func() { + err := http.ListenAndServe(addr, proxy) + t.Fatalf("Failed to server a http server for proxy : %s ", err) + }() return nil } - func TestProxy(t *testing.T) { err := setUpProxy(t) if err != nil { @@ -67,7 +68,6 @@ func TestProxy(t *testing.T) { } - // testProxyWarning checks user is warned correctly about the proxy related env vars func testProxyWarning(t *testing.T) { mk := NewMinikubeRunner(t) From 08d19bf15a0b40230544721d291eaaecfd861ab0 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 15 May 2019 15:39:50 -0700 Subject: [PATCH 14/25] Improve formatting and messages --- cmd/minikube/cmd/dashboard.go | 2 +- go.mod | 3 ++- go.sum | 5 +++++ pkg/minikube/proxy/proxy.go | 2 +- test/integration/proxy_test.go | 3 +-- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cmd/minikube/cmd/dashboard.go b/cmd/minikube/cmd/dashboard.go index b1160d8e0936..6f9b6dc0906f 100644 --- a/cmd/minikube/cmd/dashboard.go +++ b/cmd/minikube/cmd/dashboard.go @@ -61,7 +61,7 @@ var dashboardCmd = &cobra.Command{ } err = proxy.ExcludeIP(cc.KubernetesConfig.NodeIP) // to be used for http get calls if err != nil { - glog.Errorf("Error Excluding IP from proxy: %s", err) + glog.Errorf("Error excluding IP from proxy: %s", err) } kubectl, err := exec.LookPath("kubectl") diff --git a/go.mod b/go.mod index bc6cc925a304..1b70dc2fd2b8 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/c4milo/gotoolkit v0.0.0-20170318115440-bcc06269efa9 github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 github.com/cpuguy83/go-md2man v1.0.4 - github.com/davecgh/go-spew v0.0.0-20170626231645-782f4967f2dc + github.com/davecgh/go-spew v1.1.0 github.com/docker/docker v0.0.0-20180917213351-bbe08dc7f0b9 github.com/docker/go-units v0.0.0-20170127094116-9e638d38cf69 github.com/docker/machine v0.16.1 @@ -75,6 +75,7 @@ require ( github.com/spf13/jwalterweatherman v0.0.0-20160311093646-33c24e77fb80 github.com/spf13/pflag v1.0.1 github.com/spf13/viper v1.0.0 + github.com/stretchr/testify v1.3.0 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20151027082146-e0fe6f683076 github.com/xeipuuv/gojsonreference v0.0.0-20150808065054-e02fc20de94c github.com/xeipuuv/gojsonschema v0.0.0-20160623135812-c539bca196be diff --git a/go.sum b/go.sum index 51cf582df80a..9d9d3ec33bc7 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,8 @@ github.com/cpuguy83/go-md2man v1.0.4 h1:OwjhDpK9YGCcI5CDf8HcdfsXqr6znFyAJfuZ27ix github.com/cpuguy83/go-md2man v1.0.4/go.mod h1:N6JayAiVKtlHSnuTCeuLSQVs75hb8q+dYQLjr7cDsKY= github.com/davecgh/go-spew v0.0.0-20170626231645-782f4967f2dc h1:0A0n6a0Y3vW5ktoWKC+ggkGXRzMJWMvqIYlFmsjwQzY= github.com/davecgh/go-spew v0.0.0-20170626231645-782f4967f2dc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/docker v0.0.0-20180917213351-bbe08dc7f0b9 h1:dArdEP6A7F7aoAph4Gs505ME7QSBjjbRdpklFV384KU= github.com/docker/docker v0.0.0-20180917213351-bbe08dc7f0b9/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-units v0.0.0-20170127094116-9e638d38cf69 h1:N4WAsrRIb+4U1yIwJO3FMrLnrr61ael894nygpViQTU= @@ -144,6 +146,9 @@ github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.0.0 h1:RUA/ghS2i64rlnn4ydTfblY8Og8QzcPtCcHvgMn+w/I= github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/xeipuuv/gojsonpointer v0.0.0-20151027082146-e0fe6f683076 h1:KM4T3G70MiR+JtqplcYkNVoNz7pDwYaBxWBXQK804So= github.com/xeipuuv/gojsonpointer v0.0.0-20151027082146-e0fe6f683076/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20150808065054-e02fc20de94c h1:XZWnr3bsDQWAZg4Ne+cPoXRPILrNlPNQfxBuwLl43is= diff --git a/pkg/minikube/proxy/proxy.go b/pkg/minikube/proxy/proxy.go index 18e929d4145d..c3ad341c34f3 100644 --- a/pkg/minikube/proxy/proxy.go +++ b/pkg/minikube/proxy/proxy.go @@ -122,7 +122,7 @@ func UpdateTransport(cfg *rest.Config) *rest.Config { ht.Proxy = nil rt = ht } else { - glog.Errorf("Error while casting roundr tripper (of type %T) to *http.Transport : %v", rt, ok) + glog.Errorf("Error while casting RoundTripper (of type %T) to *http.Transport : %v", rt, ok) } return rt } diff --git a/test/integration/proxy_test.go b/test/integration/proxy_test.go index 37eb5f624fc8..fb36b0065663 100644 --- a/test/integration/proxy_test.go +++ b/test/integration/proxy_test.go @@ -74,8 +74,7 @@ func testProxyWarning(t *testing.T) { // Start a timer for all remaining commands, to display failure output before a panic. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) defer cancel() - startCmd := fmt.Sprintf("start %s %s %s", mk.StartArgs, mk.Args, - "--alsologtostderr --v=5") + startCmd := fmt.Sprintf("start %s %s %s", mk.StartArgs, mk.Args, "--alsologtostderr --v=5") stdout, stderr, err := mk.RunWithContext(ctx, startCmd) if err != nil { t.Fatalf("start: %v\nstdout: %s\nstderr: %s", err, stdout, stderr) From 53a46251e140f1e48c5f5ae941598d4b6642bbd8 Mon Sep 17 00:00:00 2001 From: Maximilian Hess Date: Tue, 14 May 2019 10:36:14 +0200 Subject: [PATCH 15/25] Return host IP when using vmware as vm driver. Adds the missing case "vmware" to return the host IP. --- pkg/minikube/cluster/cluster.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index a8c799e5db39..e8703602fe32 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -380,6 +380,8 @@ func GetVMHostIP(host *host.Host) (net.IP, error) { return ip, nil case "xhyve", "hyperkit": return net.ParseIP("192.168.64.1"), nil + case "vmware": + return net.ParseIP("192.168.4.1"), nil default: return []byte{}, errors.New("Error, attempted to get host ip address for unsupported driver") } From 88a14890a818ec45a7c57fb0f7b180b009c8fa22 Mon Sep 17 00:00:00 2001 From: Maximilian Hess Date: Wed, 15 May 2019 11:39:06 +0200 Subject: [PATCH 16/25] Make derivation of Host IP address more generic when using vmware. --- pkg/minikube/cluster/cluster.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index e8703602fe32..d25156a3e396 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -381,7 +381,15 @@ func GetVMHostIP(host *host.Host) (net.IP, error) { case "xhyve", "hyperkit": return net.ParseIP("192.168.64.1"), nil case "vmware": - return net.ParseIP("192.168.4.1"), nil + vmIPString, err := host.Driver.GetIP() + if err != nil { + return []byte{}, errors.Wrap(err, "Error getting VM IP address") + } + vmIP := net.ParseIP(vmIPString).To4() + if vmIP == nil { + return []byte{}, errors.Wrap(err, "Error converting VM IP address to IPv4 address") + } + return net.IPv4(vmIP[0], vmIP[1], vmIP[2], byte(1)), nil default: return []byte{}, errors.New("Error, attempted to get host ip address for unsupported driver") } From a2590ecdb2c172cb73b1e24c6195bccc6fb6681a Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 15 May 2019 17:30:27 -0700 Subject: [PATCH 17/25] Adding more unit test --- pkg/minikube/proxy/proxy.go | 3 +++ pkg/minikube/proxy/proxy_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/pkg/minikube/proxy/proxy.go b/pkg/minikube/proxy/proxy.go index c3ad341c34f3..0ca19cad0104 100644 --- a/pkg/minikube/proxy/proxy.go +++ b/pkg/minikube/proxy/proxy.go @@ -67,6 +67,9 @@ func IsIPExcluded(ip string) bool { // updateEnv appends an ip to the environment variable func updateEnv(ip string, env string) error { + if ip == "" { + return fmt.Errorf("IP %s is blank. ", ip) + } if !isValidEnv(env) { return fmt.Errorf("%s is not a valid env var name for proxy settings", env) } diff --git a/pkg/minikube/proxy/proxy_test.go b/pkg/minikube/proxy/proxy_test.go index 03d3d52d42a4..95d5d6a22171 100644 --- a/pkg/minikube/proxy/proxy_test.go +++ b/pkg/minikube/proxy/proxy_test.go @@ -72,5 +72,32 @@ func TestIsInBlock(t *testing.T) { }) } +} + +func TestUpdateEnv(t *testing.T) { + var testCases = []struct { + ip string + env string + wantErr bool + }{ + {"192.168.0.13", "NO_PROXY", false}, + {"", "NO_PROXY", true}, + {"", "", true}, + {"192.168.0.13", "", true}, + {"192.168.0.13", "NPROXY", true}, + } + for _, tc := range testCases { + t.Run(fmt.Sprintf("%s in %s", tc.ip, tc.env), func(t *testing.T) { + gotErr := false + err := updateEnv(tc.ip, tc.env) + if err != nil { + gotErr = true + } + if gotErr != tc.wantErr { + t.Errorf("updateEnv(%v,%v) got error is %v ; want error is %v", tc.ip, tc.env, gotErr, tc.wantErr) + } + + }) + } } From f38efb95df9bd2e420ee6cc7f6bbc423b9a8b7c4 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 15 May 2019 17:33:10 -0700 Subject: [PATCH 18/25] Improved Style --- pkg/minikube/proxy/proxy_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/proxy/proxy_test.go b/pkg/minikube/proxy/proxy_test.go index 95d5d6a22171..0a5f78ee1ea4 100644 --- a/pkg/minikube/proxy/proxy_test.go +++ b/pkg/minikube/proxy/proxy_test.go @@ -31,7 +31,7 @@ func TestIsValidEnv(t *testing.T) { {"NOPROXY", false}, } for _, tc := range testCases { - t.Run(fmt.Sprintf("%s", tc.env), func(t *testing.T) { + t.Run(tc.env, func(t *testing.T) { got := isValidEnv(tc.env) if got != tc.want { t.Errorf("isValidEnv(\"%v\") got %v; want %v", tc.env, got, tc.want) From a1e34b01a133b08ca8b14cf1abb4b57129f1a10c Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 16 May 2019 15:26:24 -0700 Subject: [PATCH 19/25] Improve http server shutdown handling --- test/integration/proxy_test.go | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/test/integration/proxy_test.go b/test/integration/proxy_test.go index 22d86a2ed880..7657e75deb3c 100644 --- a/test/integration/proxy_test.go +++ b/test/integration/proxy_test.go @@ -34,32 +34,41 @@ import ( ) // setUpProxy runs a local http proxy and sets the env vars for it. -func setUpProxy(t *testing.T) error { +func setUpProxy(t *testing.T) (*http.Server, error) { port, err := freeport.GetFreePort() if err != nil { - return errors.Wrap(err, "Failed to get an open port") + return nil, errors.Wrap(err, "Failed to get an open port") } addr := fmt.Sprintf("localhost:%d", port) err = os.Setenv("NO_PROXY", "") if err != nil { - return errors.Wrap(err, "Failed to set no proxy env") + return nil, errors.Wrap(err, "Failed to set no proxy env") } err = os.Setenv("HTTP_PROXY", addr) if err != nil { - return errors.Wrap(err, "Failed to set http proxy env") + return nil, errors.Wrap(err, "Failed to set http proxy env") } proxy := goproxy.NewProxyHttpServer() - go func(t *testing.T) { - err := http.ListenAndServe(addr, proxy) - t.Errorf("Failed to server a http server for proxy : %s ", err) - }(t) - return nil + srv := &http.Server{Addr: addr, Handler: proxy} + go func(s *http.Server, t *testing.T) { + if err := s.ListenAndServe(); err != http.ErrServerClosed { + t.Errorf("Failed to start http server for proxy mock") + } + }(srv, t) + return srv, nil } func TestProxy(t *testing.T) { - err := setUpProxy(t) + srv, err := setUpProxy(t) + defer func(t *testing.T) { // shutting down the http proxy after tests + err := srv.Shutdown(context.TODO()) + if err != nil { + t.Errorf("Error shutting down the http proxy") + } + } (t) + if err != nil { t.Fatalf("Failed to set up the test proxy: %s", err) } From 6484548a1ffecb1581a5993650d1ff89fee0a107 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 16 May 2019 15:38:28 -0700 Subject: [PATCH 20/25] fix formatting --- test/integration/proxy_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/proxy_test.go b/test/integration/proxy_test.go index 7657e75deb3c..9657fd841f71 100644 --- a/test/integration/proxy_test.go +++ b/test/integration/proxy_test.go @@ -67,8 +67,8 @@ func TestProxy(t *testing.T) { if err != nil { t.Errorf("Error shutting down the http proxy") } - } (t) - + }(t) + if err != nil { t.Fatalf("Failed to set up the test proxy: %s", err) } From 0d58773af3a8306e01b43fb088458f68bf401494 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 16 May 2019 20:37:29 -0700 Subject: [PATCH 21/25] Clean up after unit test --- test/integration/proxy_test.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/integration/proxy_test.go b/test/integration/proxy_test.go index 9657fd841f71..2d001548f405 100644 --- a/test/integration/proxy_test.go +++ b/test/integration/proxy_test.go @@ -62,11 +62,20 @@ func setUpProxy(t *testing.T) (*http.Server, error) { func TestProxy(t *testing.T) { srv, err := setUpProxy(t) - defer func(t *testing.T) { // shutting down the http proxy after tests - err := srv.Shutdown(context.TODO()) + defer func(t *testing.T) { + err := srv.Shutdown(context.TODO()) // shutting down the http proxy after tests if err != nil { t.Errorf("Error shutting down the http proxy") } + err = os.Setenv("HTTP_PROXY", "") + if err != nil { + t.Errorf("Error reverting the HTTP_PROXY env") + } + err = os.Setenv("HTTPS_PROXY", "") + if err != nil { + t.Errorf("Error reverting the HTTPS_PROXY env") + } + }(t) if err != nil { From 42e40e3babe98e3d40b9e2ac84ce315a82be0e18 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sun, 19 May 2019 00:40:01 -0700 Subject: [PATCH 22/25] Debug --- test/integration/addons_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/addons_test.go b/test/integration/addons_test.go index 748894f2e0ba..8243d4a39967 100644 --- a/test/integration/addons_test.go +++ b/test/integration/addons_test.go @@ -73,7 +73,7 @@ func readLineWithTimeout(b *bufio.Reader, timeout time.Duration) (string, error) } func testDashboard(t *testing.T) { - t.Parallel() + // t.Parallel() minikubeRunner := NewMinikubeRunner(t) cmd, out := minikubeRunner.RunDaemon("dashboard --url") defer func() { From 871c2e67040011fe49e443dcf9354aa40d3c792c Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sun, 19 May 2019 14:07:02 -0700 Subject: [PATCH 23/25] Better clean up after tesdt proxy setup --- test/integration/addons_test.go | 2 +- test/integration/proxy_test.go | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/test/integration/addons_test.go b/test/integration/addons_test.go index 8243d4a39967..748894f2e0ba 100644 --- a/test/integration/addons_test.go +++ b/test/integration/addons_test.go @@ -73,7 +73,7 @@ func readLineWithTimeout(b *bufio.Reader, timeout time.Duration) (string, error) } func testDashboard(t *testing.T) { - // t.Parallel() + t.Parallel() minikubeRunner := NewMinikubeRunner(t) cmd, out := minikubeRunner.RunDaemon("dashboard --url") defer func() { diff --git a/test/integration/proxy_test.go b/test/integration/proxy_test.go index 2d001548f405..d6bad5dcbddb 100644 --- a/test/integration/proxy_test.go +++ b/test/integration/proxy_test.go @@ -61,26 +61,29 @@ func setUpProxy(t *testing.T) (*http.Server, error) { } func TestProxy(t *testing.T) { + origHP := os.Getenv("HTTP_PROXY") + origNP := os.Getenv("NO_PROXY") srv, err := setUpProxy(t) - defer func(t *testing.T) { - err := srv.Shutdown(context.TODO()) // shutting down the http proxy after tests + if err != nil { + t.Fatalf("Failed to set up the test proxy: %s", err) + } + + defer func(t *testing.T) { // Clean up after setting up proxy + err = os.Setenv("HTTP_PROXY", origHP) if err != nil { - t.Errorf("Error shutting down the http proxy") + t.Errorf("Error reverting the HTTP_PROXY env") } - err = os.Setenv("HTTP_PROXY", "") + err = os.Setenv("NO_PROCY", origNP) if err != nil { t.Errorf("Error reverting the HTTP_PROXY env") } - err = os.Setenv("HTTPS_PROXY", "") + + err := srv.Shutdown(context.TODO()) // shutting down the http proxy after tests if err != nil { - t.Errorf("Error reverting the HTTPS_PROXY env") + t.Errorf("Error shutting down the http proxy") } - }(t) - if err != nil { - t.Fatalf("Failed to set up the test proxy: %s", err) - } t.Run("ConsoleWarnning", testProxyWarning) t.Run("DashboardProxy", testDashboard) From c428ce5ebdcd631f1bdb5f092ed13421448fcb9e Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sun, 19 May 2019 14:10:46 -0700 Subject: [PATCH 24/25] Fix typo --- test/integration/proxy_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/proxy_test.go b/test/integration/proxy_test.go index d6bad5dcbddb..96f84c67c03f 100644 --- a/test/integration/proxy_test.go +++ b/test/integration/proxy_test.go @@ -73,9 +73,9 @@ func TestProxy(t *testing.T) { if err != nil { t.Errorf("Error reverting the HTTP_PROXY env") } - err = os.Setenv("NO_PROCY", origNP) + err = os.Setenv("NO_PROXY", origNP) if err != nil { - t.Errorf("Error reverting the HTTP_PROXY env") + t.Errorf("Error reverting the NO_PROXY env") } err := srv.Shutdown(context.TODO()) // shutting down the http proxy after tests From b6bf1dff8dc77fa2b42ea4231b91f37beb941a70 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sun, 19 May 2019 14:45:21 -0700 Subject: [PATCH 25/25] Improve test clean up --- pkg/minikube/proxy/proxy_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/minikube/proxy/proxy_test.go b/pkg/minikube/proxy/proxy_test.go index e62b4f4418e2..25dccce10da4 100644 --- a/pkg/minikube/proxy/proxy_test.go +++ b/pkg/minikube/proxy/proxy_test.go @@ -89,6 +89,7 @@ func TestUpdateEnv(t *testing.T) { } for _, tc := range testCases { t.Run(fmt.Sprintf("%s in %s", tc.ip, tc.env), func(t *testing.T) { + origVal := os.Getenv(tc.env) gotErr := false err := updateEnv(tc.ip, tc.env) if err != nil { @@ -97,6 +98,10 @@ func TestUpdateEnv(t *testing.T) { if gotErr != tc.wantErr { t.Errorf("updateEnv(%v,%v) got error is %v ; want error is %v", tc.ip, tc.env, gotErr, tc.wantErr) } + err = os.Setenv(tc.env, origVal) + if err != nil && tc.env != "" { + t.Errorf("Error reverting the env var (%s) to its original value (%s)", tc.env, origVal) + } }) }