Skip to content

Commit

Permalink
Merge pull request #93 from dave-tucker/proxyConfig
Browse files Browse the repository at this point in the history
Allow Proxy Configuration in config.json
  • Loading branch information
cpuguy83 authored Jun 20, 2017
2 parents 5dd3073 + 35f1e30 commit 6f6ccbd
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 3 deletions.
16 changes: 14 additions & 2 deletions cli/command/container/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/promise"
Expand Down Expand Up @@ -96,14 +97,24 @@ func isLocalhost(ip string) bool {
return localhostIPRegexp.MatchString(ip)
}

func runRun(dockerCli *command.DockerCli, flags *pflag.FlagSet, opts *runOptions, copts *containerOptions) error {
func runRun(dockerCli *command.DockerCli, flags *pflag.FlagSet, ropts *runOptions, copts *containerOptions) error {
proxyConfig := dockerCli.ConfigFile().ParseProxyConfig(dockerCli.Client().DaemonHost(), copts.env.GetAll())
newEnv := []string{}
for k, v := range proxyConfig {
if v == nil {
newEnv = append(newEnv, k)
} else {
newEnv = append(newEnv, fmt.Sprintf("%s=%s", k, *v))
}
}
copts.env = *opts.NewListOptsRef(&newEnv, nil)
containerConfig, err := parse(flags, copts)
// just in case the parse does not exit
if err != nil {
reportError(dockerCli.Err(), "run", err.Error(), true)
return cli.StatusError{StatusCode: 125}
}
return runContainer(dockerCli, opts, copts, containerConfig)
return runContainer(dockerCli, ropts, copts, containerConfig)
}

// nolint: gocyclo
Expand Down Expand Up @@ -159,6 +170,7 @@ func runContainer(dockerCli *command.DockerCli, opts *runOptions, copts *contain
sigc := ForwardAllSignals(ctx, dockerCli, createResponse.ID)
defer signal.StopCatch(sigc)
}

var (
waitDisplayID chan struct{}
errCh chan error
Expand Down
2 changes: 1 addition & 1 deletion cli/command/image/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
Dockerfile: relDockerfile,
ShmSize: options.shmSize.Value(),
Ulimits: options.ulimits.GetList(),
BuildArgs: opts.ConvertKVStringsToMapWithNil(options.buildArgs.GetAll()),
BuildArgs: dockerCli.ConfigFile().ParseProxyConfig(dockerCli.Client().DaemonHost(), options.buildArgs.GetAll()),
AuthConfigs: authConfigs,
Labels: opts.ConvertKVStringsToMap(options.labels.GetAll()),
CacheFrom: options.cacheFrom,
Expand Down
43 changes: 43 additions & 0 deletions cli/config/configfile/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"path/filepath"
"strings"

"github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
)
Expand Down Expand Up @@ -41,6 +42,15 @@ type ConfigFile struct {
ConfigFormat string `json:"configFormat,omitempty"`
NodesFormat string `json:"nodesFormat,omitempty"`
PruneFilters []string `json:"pruneFilters,omitempty"`
Proxies map[string]ProxyConfig `json:"proxies,omitempty"`
}

// ProxyConfig contains proxy configuration settings
type ProxyConfig struct {
HTTPProxy string `json:"httpProxy,omitempty"`
HTTPSProxy string `json:"httpsProxy,omitempty"`
NoProxy string `json:"noProxy,omitempty"`
FTPProxy string `json:"ftpProxy,omitempty"`
}

// LegacyLoadFromReader reads the non-nested configuration data given and sets up the
Expand Down Expand Up @@ -152,6 +162,39 @@ func (configFile *ConfigFile) Save() error {
return configFile.SaveToWriter(f)
}

// ParseProxyConfig computes proxy configuration by retreiving the config for the provided host and
// then checking this against any environment variables provided to the container
func (configFile *ConfigFile) ParseProxyConfig(host string, runOpts []string) map[string]*string {
var cfgKey string

if _, ok := configFile.Proxies[host]; !ok {
cfgKey = "default"
} else {
cfgKey = host
}

config, _ := configFile.Proxies[cfgKey]
permitted := map[string]*string{
"HTTP_PROXY": &config.HTTPProxy,
"HTTPS_PROXY": &config.HTTPSProxy,
"NO_PROXY": &config.NoProxy,
"FTP_PROXY": &config.FTPProxy,
}
m := opts.ConvertKVStringsToMapWithNil(runOpts)
for k := range permitted {
if *permitted[k] == "" {
continue
}
if _, ok := m[k]; !ok {
m[k] = permitted[k]
}
if _, ok := m[strings.ToLower(k)]; !ok {
m[strings.ToLower(k)] = permitted[k]
}
}
return m
}

// encodeAuth creates a base64 encoded string to containing authorization information
func encodeAuth(authConfig *types.AuthConfig) string {
if authConfig.Username == "" && authConfig.Password == "" {
Expand Down
117 changes: 117 additions & 0 deletions cli/config/configfile/file_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package configfile

import (
"fmt"
"testing"

"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
)

func TestEncodeAuth(t *testing.T) {
Expand All @@ -25,3 +27,118 @@ func TestEncodeAuth(t *testing.T) {
t.Fatal("AuthString encoding isn't correct.")
}
}

func TestProxyConfig(t *testing.T) {
httpProxy := "http://proxy.mycorp.com:3128"
httpsProxy := "https://user:password@proxy.mycorp.com:3129"
ftpProxy := "http://ftpproxy.mycorp.com:21"
noProxy := "*.intra.mycorp.com"
defaultProxyConfig := ProxyConfig{
HTTPProxy: httpProxy,
HTTPSProxy: httpsProxy,
FTPProxy: ftpProxy,
NoProxy: noProxy,
}

cfg := ConfigFile{
Proxies: map[string]ProxyConfig{
"default": defaultProxyConfig,
},
}

proxyConfig := cfg.ParseProxyConfig("/var/run/docker.sock", []string{})
expected := map[string]*string{
"HTTP_PROXY": &httpProxy,
"http_proxy": &httpProxy,
"HTTPS_PROXY": &httpsProxy,
"https_proxy": &httpsProxy,
"FTP_PROXY": &ftpProxy,
"ftp_proxy": &ftpProxy,
"NO_PROXY": &noProxy,
"no_proxy": &noProxy,
}
assert.Equal(t, expected, proxyConfig)
}

func TestProxyConfigOverride(t *testing.T) {
httpProxy := "http://proxy.mycorp.com:3128"
overrideHTTPProxy := "http://proxy.example.com:3128"
overrideNoProxy := ""
httpsProxy := "https://user:password@proxy.mycorp.com:3129"
ftpProxy := "http://ftpproxy.mycorp.com:21"
noProxy := "*.intra.mycorp.com"
defaultProxyConfig := ProxyConfig{
HTTPProxy: httpProxy,
HTTPSProxy: httpsProxy,
FTPProxy: ftpProxy,
NoProxy: noProxy,
}

cfg := ConfigFile{
Proxies: map[string]ProxyConfig{
"default": defaultProxyConfig,
},
}

ropts := []string{
fmt.Sprintf("HTTP_PROXY=%s", overrideHTTPProxy),
"NO_PROXY=",
}
proxyConfig := cfg.ParseProxyConfig("/var/run/docker.sock", ropts)
expected := map[string]*string{
"HTTP_PROXY": &overrideHTTPProxy,
"http_proxy": &httpProxy,
"HTTPS_PROXY": &httpsProxy,
"https_proxy": &httpsProxy,
"FTP_PROXY": &ftpProxy,
"ftp_proxy": &ftpProxy,
"NO_PROXY": &overrideNoProxy,
"no_proxy": &noProxy,
}
assert.Equal(t, expected, proxyConfig)
}

func TestProxyConfigPerHost(t *testing.T) {
httpProxy := "http://proxy.mycorp.com:3128"
httpsProxy := "https://user:password@proxy.mycorp.com:3129"
ftpProxy := "http://ftpproxy.mycorp.com:21"
noProxy := "*.intra.mycorp.com"

extHTTPProxy := "http://proxy.example.com:3128"
extHTTPSProxy := "https://user:password@proxy.example.com:3129"
extFTPProxy := "http://ftpproxy.example.com:21"
extNoProxy := "*.intra.example.com"

defaultProxyConfig := ProxyConfig{
HTTPProxy: httpProxy,
HTTPSProxy: httpsProxy,
FTPProxy: ftpProxy,
NoProxy: noProxy,
}
externalProxyConfig := ProxyConfig{
HTTPProxy: extHTTPProxy,
HTTPSProxy: extHTTPSProxy,
FTPProxy: extFTPProxy,
NoProxy: extNoProxy,
}

cfg := ConfigFile{
Proxies: map[string]ProxyConfig{
"default": defaultProxyConfig,
"tcp://example.docker.com:2376": externalProxyConfig,
},
}

proxyConfig := cfg.ParseProxyConfig("tcp://example.docker.com:2376", []string{})
expected := map[string]*string{
"HTTP_PROXY": &extHTTPProxy,
"http_proxy": &extHTTPProxy,
"HTTPS_PROXY": &extHTTPSProxy,
"https_proxy": &extHTTPSProxy,
"FTP_PROXY": &extFTPProxy,
"ftp_proxy": &extFTPProxy,
"NO_PROXY": &extNoProxy,
"no_proxy": &extNoProxy,
}
assert.Equal(t, expected, proxyConfig)
}

0 comments on commit 6f6ccbd

Please sign in to comment.