Skip to content

Commit

Permalink
Allow Proxy Configuration in config.json
Browse files Browse the repository at this point in the history
This commit modifies config.json to allow for any proxies allowed in
build-args to be configured. These values will then be used
by default as build-args in docker build.

Signed-off-by: Dave Tucker <[email protected]>
  • Loading branch information
Dave Tucker authored and dave-tucker committed Jun 20, 2017
1 parent 5dd3073 commit 35f1e30
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:[email protected]: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:[email protected]: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:[email protected]:3129"
ftpProxy := "http://ftpproxy.mycorp.com:21"
noProxy := "*.intra.mycorp.com"

extHTTPProxy := "http://proxy.example.com:3128"
extHTTPSProxy := "https://user:[email protected]: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 35f1e30

Please sign in to comment.