mirror of https://github.com/docker/cli.git
Allow Proxy Configuration in config.json
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 <dt@docker.com>
This commit is contained in:
parent
5dd30732a2
commit
35f1e301b5
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/pkg/promise"
|
"github.com/docker/docker/pkg/promise"
|
||||||
|
@ -96,14 +97,24 @@ func isLocalhost(ip string) bool {
|
||||||
return localhostIPRegexp.MatchString(ip)
|
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)
|
containerConfig, err := parse(flags, copts)
|
||||||
// just in case the parse does not exit
|
// just in case the parse does not exit
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reportError(dockerCli.Err(), "run", err.Error(), true)
|
reportError(dockerCli.Err(), "run", err.Error(), true)
|
||||||
return cli.StatusError{StatusCode: 125}
|
return cli.StatusError{StatusCode: 125}
|
||||||
}
|
}
|
||||||
return runContainer(dockerCli, opts, copts, containerConfig)
|
return runContainer(dockerCli, ropts, copts, containerConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: gocyclo
|
// nolint: gocyclo
|
||||||
|
@ -159,6 +170,7 @@ func runContainer(dockerCli *command.DockerCli, opts *runOptions, copts *contain
|
||||||
sigc := ForwardAllSignals(ctx, dockerCli, createResponse.ID)
|
sigc := ForwardAllSignals(ctx, dockerCli, createResponse.ID)
|
||||||
defer signal.StopCatch(sigc)
|
defer signal.StopCatch(sigc)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
waitDisplayID chan struct{}
|
waitDisplayID chan struct{}
|
||||||
errCh chan error
|
errCh chan error
|
||||||
|
|
|
@ -290,7 +290,7 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
|
||||||
Dockerfile: relDockerfile,
|
Dockerfile: relDockerfile,
|
||||||
ShmSize: options.shmSize.Value(),
|
ShmSize: options.shmSize.Value(),
|
||||||
Ulimits: options.ulimits.GetList(),
|
Ulimits: options.ulimits.GetList(),
|
||||||
BuildArgs: opts.ConvertKVStringsToMapWithNil(options.buildArgs.GetAll()),
|
BuildArgs: dockerCli.ConfigFile().ParseProxyConfig(dockerCli.Client().DaemonHost(), options.buildArgs.GetAll()),
|
||||||
AuthConfigs: authConfigs,
|
AuthConfigs: authConfigs,
|
||||||
Labels: opts.ConvertKVStringsToMap(options.labels.GetAll()),
|
Labels: opts.ConvertKVStringsToMap(options.labels.GetAll()),
|
||||||
CacheFrom: options.cacheFrom,
|
CacheFrom: options.cacheFrom,
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -41,6 +42,15 @@ type ConfigFile struct {
|
||||||
ConfigFormat string `json:"configFormat,omitempty"`
|
ConfigFormat string `json:"configFormat,omitempty"`
|
||||||
NodesFormat string `json:"nodesFormat,omitempty"`
|
NodesFormat string `json:"nodesFormat,omitempty"`
|
||||||
PruneFilters []string `json:"pruneFilters,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
|
// LegacyLoadFromReader reads the non-nested configuration data given and sets up the
|
||||||
|
@ -152,6 +162,39 @@ func (configFile *ConfigFile) Save() error {
|
||||||
return configFile.SaveToWriter(f)
|
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
|
// encodeAuth creates a base64 encoded string to containing authorization information
|
||||||
func encodeAuth(authConfig *types.AuthConfig) string {
|
func encodeAuth(authConfig *types.AuthConfig) string {
|
||||||
if authConfig.Username == "" && authConfig.Password == "" {
|
if authConfig.Username == "" && authConfig.Password == "" {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package configfile
|
package configfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEncodeAuth(t *testing.T) {
|
func TestEncodeAuth(t *testing.T) {
|
||||||
|
@ -25,3 +27,118 @@ func TestEncodeAuth(t *testing.T) {
|
||||||
t.Fatal("AuthString encoding isn't correct.")
|
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)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue