Merge pull request #4229 from medyagh/no_proxy_for_self
Allow minikube to function with misconfigured NO_PROXY valuepull/4299/head^2
commit
9d09ff069b
|
|
@ -21,6 +21,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"time"
|
||||
|
|
@ -32,9 +33,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 +55,19 @@ 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()
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
console.ErrLn("Error loading profile config: %v", err)
|
||||
}
|
||||
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 {
|
||||
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 +128,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")
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
@ -225,6 +223,11 @@ 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.
|
||||
err = proxy.ExcludeIP(ip)
|
||||
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 {
|
||||
|
|
@ -394,7 +397,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))
|
||||
}
|
||||
|
|
@ -533,13 +536,19 @@ func validateNetwork(h *host.Host) string {
|
|||
}
|
||||
|
||||
optSeen := false
|
||||
for _, k := range proxyVars {
|
||||
warnedOnce := false
|
||||
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)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
3
go.mod
3
go.mod
|
|
@ -14,6 +14,8 @@ require (
|
|||
github.com/docker/docker v1.13.1 // indirect
|
||||
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/fatih/color v1.7.0 // indirect
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 // indirect
|
||||
github.com/gogo/protobuf v0.0.0-20170330071051-c0656edd0d9e // indirect
|
||||
|
|
@ -60,6 +62,7 @@ require (
|
|||
github.com/pelletier/go-buffruneio v0.1.0 // indirect
|
||||
github.com/pelletier/go-toml v0.0.0-20160822122712-0049ab3dc4c4 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
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
|
||||
|
|
|
|||
12
go.sum
12
go.sum
|
|
@ -15,6 +15,8 @@ github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 h1:tuij
|
|||
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21/go.mod h1:po7NpZ/QiTKzBKyrsEAxwnTamCoh8uDk/egRpQ7siIc=
|
||||
github.com/cpuguy83/go-md2man v1.0.4 h1:OwjhDpK9YGCcI5CDf8HcdfsXqr6znFyAJfuZ27ixJsc=
|
||||
github.com/cpuguy83/go-md2man v1.0.4/go.mod h1:N6JayAiVKtlHSnuTCeuLSQVs75hb8q+dYQLjr7cDsKY=
|
||||
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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
|
@ -24,6 +26,10 @@ 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/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/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
|
|
@ -130,6 +136,8 @@ github.com/pelletier/go-toml v0.0.0-20160822122712-0049ab3dc4c4 h1:tMVXZ04h5CqgT
|
|||
github.com/pelletier/go-toml v0.0.0-20160822122712-0049ab3dc4c4/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
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=
|
||||
|
|
@ -142,6 +150,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=
|
||||
|
|
@ -163,10 +172,13 @@ github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
|||
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/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
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=
|
||||
|
|
|
|||
|
|
@ -152,6 +152,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}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
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"
|
||||
"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
|
||||
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 block == "" {
|
||||
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, errors.Wrapf(err, "Error ip not in block")
|
||||
}
|
||||
|
||||
// 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 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)
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// 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 {
|
||||
rt = wt(rt)
|
||||
}
|
||||
if ht, ok := rt.(*http.Transport); ok {
|
||||
ht.Proxy = nil
|
||||
rt = ht
|
||||
} else {
|
||||
glog.Errorf("Error while casting RoundTripper (of type %T) to *http.Transport : %v", rt, ok)
|
||||
}
|
||||
return rt
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
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"
|
||||
"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(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)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
origVal := os.Getenv(tc.env)
|
||||
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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCheckEnv(t *testing.T) {
|
||||
var testCases = []struct {
|
||||
ip string
|
||||
envName string
|
||||
want bool
|
||||
mockEnvValue string
|
||||
}{
|
||||
{"", "NO_PROXY", false, ""},
|
||||
{"192.168.0.13", "NO_PROXY", false, ""},
|
||||
{"192.168.0.13", "NO_PROXY", false, ","},
|
||||
{"192.168.0.13", "NO_PROXY", true, "192.168.0.13"},
|
||||
{"192.168.0.13", "NO_PROXY", true, ",192.168.0.13"},
|
||||
{"192.168.0.13", "NO_PROXY", true, "10.10.0.13,192.168.0.13"},
|
||||
{"192.168.0.13", "NO_PROXY", true, "192.168.0.13/22"},
|
||||
{"192.168.0.13", "NO_PROXY", true, "10.10.0.13,192.168.0.13"},
|
||||
{"192.168.0.13", "NO_PROXY", false, "10.10.0.13/22"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("%s in %s", tc.ip, tc.envName), func(t *testing.T) {
|
||||
originalEnv := os.Getenv(tc.envName)
|
||||
defer func() { // revert to pre-test env var
|
||||
err := os.Setenv(tc.envName, originalEnv)
|
||||
if err != nil {
|
||||
t.Fatalf("Error reverting env (%s) to its original value (%s) var after test ", tc.envName, originalEnv)
|
||||
}
|
||||
}()
|
||||
|
||||
// defer os.Setenv(tc.envName, originalEnv)
|
||||
err := os.Setenv(tc.envName, tc.mockEnvValue) // setting up the test case
|
||||
if err != nil {
|
||||
t.Error("Error setting env var for taste case")
|
||||
}
|
||||
got := checkEnv(tc.ip, tc.envName)
|
||||
if got != tc.want {
|
||||
t.Errorf("CheckEnv(%v,%v) got %v ; want is %v", tc.ip, tc.envName, got, tc.want)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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("kubeConfig: %v", err)
|
||||
}
|
||||
clientConfig.Timeout = timeout
|
||||
clientConfig = proxy.UpdateTransport(clientConfig)
|
||||
client, err := kubernetes.NewForConfig(clientConfig)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "client from config")
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import (
|
|||
"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 (
|
||||
|
|
@ -76,6 +77,7 @@ func GetClient() (kubernetes.Interface, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating kubeConfig: %v", err)
|
||||
}
|
||||
config = proxy.UpdateTransport(config)
|
||||
client, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error creating new client from kubeConfig.ClientConfig()")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
// +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"
|
||||
|
||||
"net/http"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
"github.com/phayes/freeport"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// setUpProxy runs a local http proxy and sets the env vars for it.
|
||||
func setUpProxy(t *testing.T) (*http.Server, error) {
|
||||
port, err := freeport.GetFreePort()
|
||||
if err != nil {
|
||||
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 nil, errors.Wrap(err, "Failed to set no proxy env")
|
||||
}
|
||||
err = os.Setenv("HTTP_PROXY", addr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to set http proxy env")
|
||||
}
|
||||
|
||||
proxy := goproxy.NewProxyHttpServer()
|
||||
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) {
|
||||
origHP := os.Getenv("HTTP_PROXY")
|
||||
origNP := os.Getenv("NO_PROXY")
|
||||
srv, err := setUpProxy(t)
|
||||
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 reverting the HTTP_PROXY env")
|
||||
}
|
||||
err = os.Setenv("NO_PROXY", origNP)
|
||||
if err != nil {
|
||||
t.Errorf("Error reverting the NO_PROXY env")
|
||||
}
|
||||
|
||||
err := srv.Shutdown(context.TODO()) // shutting down the http proxy after tests
|
||||
if err != nil {
|
||||
t.Errorf("Error shutting down the http proxy")
|
||||
}
|
||||
}(t)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue