Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Plumb HTTP proxy configuration from host into VM environment #3835

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/minikube/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ func startHost(api libmachine.API, mc cfg.MachineConfig) (*host.Host, bool) {
}

// validateNetwork tries to catch network problems as soon as possible
func validateNetwork(h *host.Host) string {
func validateNetwork(h *host.Host, k8s cfg.KubernetesConfig) string {
ip, err := h.Driver.GetIP()
if err != nil {
exit.WithError("Unable to get VM IP address", err)
Expand Down
32 changes: 32 additions & 0 deletions pkg/minikube/bootstrapper/kubeadm/kubeadm.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/cruntime"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/proxy"
"k8s.io/minikube/pkg/util"
)

Expand Down Expand Up @@ -503,7 +504,38 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error {
var files []assets.CopyableFile
files = copyConfig(cfg, files, kubeadmCfg, kubeletCfg)

<<<<<<< HEAD
if proxy.Detected() {
content := proxy.EnvContent(cfg)
glog.Infof("Detected proxy, will update /etc/environment with:\n%s", content)
// Only mutate /etc/environment if the runner is executing on a remote VM
if _, local := k.c.(*bootstrapper.ExecRunner); !local {
files = append(files, assets.NewMemoryAssetTarget(content, "/etc/environment", "0444"))
}
}

var g errgroup.Group
for _, bin := range []string{"kubelet", "kubeadm"} {
bin := bin
g.Go(func() error {
path, err := maybeDownloadAndCache(bin, cfg.KubernetesVersion)
if err != nil {
return errors.Wrapf(err, "downloading %s", bin)
}
f, err := assets.NewFileAsset(path, "/usr/bin", bin, "0641")
if err != nil {
return errors.Wrap(err, "new file asset")
}
if err := k.c.Copy(f); err != nil {
return errors.Wrapf(err, "copy")
}
return nil
})
}
if err := g.Wait(); err != nil {
=======
if err := downloadBinaries(cfg, k.c); err != nil {
>>>>>>> master
return errors.Wrap(err, "downloading binaries")
}

Expand Down
132 changes: 132 additions & 0 deletions pkg/minikube/proxy/proxy.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,134 @@
<<<<<<< HEAD
// Package proxy contains helpers for interacting with HTTP proxies
package proxy

import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"sort"
"strings"

"github.com/golang/glog"
ggp "github.com/rapid7/go-get-proxied/proxy"
"k8s.io/minikube/pkg/minikube/config"
)

const bypass = "bypass"
const http = "http"
const https = "https"

// envVars is a map of environment proxy to protocol
var envVars = map[string][]string{
"http_proxy": []string{http},
"https_proxy": []string{https},
"HTTP_PROXY": []string{http},
"HTTPS_PROXY": []string{https},
"ALL_PROXY": []string{http, https},
"NO_PROXY": []string{bypass},
}

// envVarPriority describes our environment priority order: first wins
var envVarPriority = []string{"HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy", "ALL_PROXY", "NO_PROXY"}

// Detected returns whether or not a proxy configuration was detected
func Detected() bool {
e := Environment()
if e[http] != "" || e[https] != "" {
return true
}
return false
}

// proxyString converts a ggp.Proxy object into a well-formed string
func proxyString(p ggp.Proxy) string {
url := p.URL()
if url.Scheme == "" {
url.Scheme = "http"
}
return url.String()
}

// Environment returns values discovered from the environment
func Environment() map[string]string {
env := map[string]string{}

for _, ev := range envVarPriority {
v := os.Getenv(ev)
if v == "" {
continue
}
for _, proto := range envVars[ev] {
if env[proto] == "" {
env[proto] = v
}
}
}

glog.Infof("Disabling log output because of ggp ... don't hate me.")
log.SetOutput(ioutil.Discard)

// If env is unset, include values detected from the operating system
if env[https] == "" {
p := ggp.NewProvider("").GetHTTPSProxy("https://k8s.gcr.io/")
if p != nil {
env[https] = proxyString(p)
}
}
if env[http] == "" {
p := ggp.NewProvider("").GetHTTPProxy("http://storage.googleapis.com/")
if p != nil {
env[http] = proxyString(p)
}
}
return env
}

// Recommended returns recommended values for use within a VM
func Recommended(k8s config.KubernetesConfig) map[string]string {
env := map[string]string{}

for proto, value := range Environment() {
if proto != bypass {
env[fmt.Sprintf("%s_PROXY", strings.ToUpper(proto))] = value
}
}
env["NO_PROXY"] = NoProxy(k8s)
return env
}

// NoProxy returns a recommended value for NO_PROXY
func NoProxy(k8s config.KubernetesConfig) string {
current := Environment()[bypass]
var vals []string
if current != "" {
vals = strings.Split(current, ",")
}
seen := map[string]bool{}
for _, v := range vals {
seen[v] = true
}

for _, optVal := range []string{k8s.NodeIP, k8s.ServiceCIDR, "127.0.0.1"} {
if optVal != "" && !seen[optVal] {
vals = append(vals, optVal)
}
}

sort.Strings(vals)
return strings.Join(vals, ",")
}

// EnvContent returns content appropriate for /etc/environment
func EnvContent(k8s config.KubernetesConfig) []byte {
var b bytes.Buffer
for k, v := range Recommended(k8s) {
b.WriteString(fmt.Sprintf("%s=%s\n", k, v))
}
return b.Bytes()
=======
/*
Copyright 2019 The Kubernetes Authors All rights reserved.

Expand Down Expand Up @@ -130,4 +261,5 @@ func UpdateTransport(cfg *rest.Config) *rest.Config {
return rt
}
return cfg
>>>>>>> master
}
56 changes: 56 additions & 0 deletions pkg/minikube/proxy/proxy_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,58 @@
<<<<<<< HEAD
package proxy

import (
"os"
"testing"

"github.com/google/go-cmp/cmp"
"k8s.io/minikube/pkg/minikube/config"
)

func TestEnvironment(t *testing.T) {
want := "moo"
os.Setenv("NO_PROXY", want)
got := Environment()["bypass"]
if got != want {
t.Errorf("got %q, want %q", got, want)
}
}
func TestRecommended(t *testing.T) {
c := config.KubernetesConfig{NodeIP: "1.2.3.4"}
os.Setenv("ALL_PROXY", "moo")
got := Recommended(c)
want := map[string]string{
"HTTP_PROXY": "moo",
"HTTPS_PROXY": "moo",
"NO_PROXY": "1.2.3.4,127.0.0.1,moo",
}

if diff := cmp.Diff(got, want); diff != "" {
t.Errorf("unexpected diff: %s", diff)

}
}
func TestNoProxyWithValue(t *testing.T) {
var tests = []struct {
env string
want string
}{
{"", "1.2.3.4/8,127.0.0.1"},
{"127.0.0.1", "1.2.3.4/8,127.0.0.1"},
{"x.y.com", "1.2.3.4/8,127.0.0.1,x.y.com"},
}
c := config.KubernetesConfig{ServiceCIDR: "1.2.3.4/8"}

for _, tc := range tests {
t.Run(tc.env, func(t *testing.T) {
os.Setenv("NO_PROXY", tc.env)
got := NoProxy(c)
if got != tc.want {
t.Errorf("got %q, want %q", got, tc.want)
}
})
}
=======
/*
Copyright 2019 The Kubernetes Authors All rights reserved.

Expand Down Expand Up @@ -148,4 +203,5 @@ func TestCheckEnv(t *testing.T) {
})
}

>>>>>>> master
}
29 changes: 29 additions & 0 deletions vendor/github.com/rapid7/go-get-proxied/LICENSE.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions vendor/github.com/rapid7/go-get-proxied/proxy/doc.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading