Move credential getting functions to the ConfigFile.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2017-06-21 17:20:49 -04:00 committed by Vincent Demeester
parent 33cbb70270
commit a3cbc70147
No known key found for this signature in database
GPG Key ID: 083CC6FD6EB699A3
11 changed files with 83 additions and 79 deletions

View File

@ -9,11 +9,9 @@ import (
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
cliconfig "github.com/docker/cli/cli/config" cliconfig "github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/config/credentials"
cliflags "github.com/docker/cli/cli/flags" cliflags "github.com/docker/cli/cli/flags"
dopts "github.com/docker/cli/opts" dopts "github.com/docker/cli/opts"
"github.com/docker/docker/api" "github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/docker/go-connections/sockets" "github.com/docker/go-connections/sockets"
"github.com/docker/go-connections/tlsconfig" "github.com/docker/go-connections/tlsconfig"
@ -38,7 +36,6 @@ type Cli interface {
In() *InStream In() *InStream
SetIn(in *InStream) SetIn(in *InStream)
ConfigFile() *configfile.ConfigFile ConfigFile() *configfile.ConfigFile
CredentialsStore(serverAddress string) credentials.Store
} }
// DockerCli is an instance the docker command line client. // DockerCli is an instance the docker command line client.
@ -103,55 +100,6 @@ func (cli *DockerCli) ServerInfo() ServerInfo {
return cli.server return cli.server
} }
// GetAllCredentials returns all of the credentials stored in all of the
// configured credential stores.
func (cli *DockerCli) GetAllCredentials() (map[string]types.AuthConfig, error) {
auths := make(map[string]types.AuthConfig)
for registry := range cli.configFile.CredentialHelpers {
helper := cli.CredentialsStore(registry)
newAuths, err := helper.GetAll()
if err != nil {
return nil, err
}
addAll(auths, newAuths)
}
defaultStore := cli.CredentialsStore("")
newAuths, err := defaultStore.GetAll()
if err != nil {
return nil, err
}
addAll(auths, newAuths)
return auths, nil
}
func addAll(to, from map[string]types.AuthConfig) {
for reg, ac := range from {
to[reg] = ac
}
}
// CredentialsStore returns a new credentials store based
// on the settings provided in the configuration file. Empty string returns
// the default credential store.
func (cli *DockerCli) CredentialsStore(serverAddress string) credentials.Store {
if helper := getConfiguredCredentialStore(cli.configFile, serverAddress); helper != "" {
return credentials.NewNativeStore(cli.configFile, helper)
}
return credentials.NewFileStore(cli.configFile)
}
// getConfiguredCredentialStore returns the credential helper configured for the
// given registry, the default credsStore, or the empty string if neither are
// configured.
func getConfiguredCredentialStore(c *configfile.ConfigFile, serverAddress string) string {
if c.CredentialHelpers != nil && serverAddress != "" {
if helper, exists := c.CredentialHelpers[serverAddress]; exists {
return helper
}
}
return c.CredentialsStore
}
// Initialize the dockerCli runs initialization that must happen after command // Initialize the dockerCli runs initialization that must happen after command
// line flags are parsed. // line flags are parsed.
func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error { func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error {

View File

@ -78,7 +78,7 @@ func (o buildOptions) contextFromStdin() bool {
} }
// NewBuildCommand creates a new `docker build` command // NewBuildCommand creates a new `docker build` command
func NewBuildCommand(dockerCli *command.DockerCli) *cobra.Command { func NewBuildCommand(dockerCli command.Cli) *cobra.Command {
ulimits := make(map[string]*units.Ulimit) ulimits := make(map[string]*units.Ulimit)
options := buildOptions{ options := buildOptions{
tags: opts.NewListOpts(validateTag), tags: opts.NewListOpts(validateTag),
@ -159,7 +159,7 @@ func (out *lastProgressOutput) WriteProgress(prog progress.Progress) error {
} }
// nolint: gocyclo // nolint: gocyclo
func runBuild(dockerCli *command.DockerCli, options buildOptions) error { func runBuild(dockerCli command.Cli, options buildOptions) error {
var ( var (
buildCtx io.ReadCloser buildCtx io.ReadCloser
dockerfileCtx io.ReadCloser dockerfileCtx io.ReadCloser
@ -336,7 +336,8 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
body = buildCtx body = buildCtx
} }
authConfigs, _ := dockerCli.GetAllCredentials() configFile := dockerCli.ConfigFile()
authConfigs, _ := configFile.GetAllCredentials()
buildOptions := types.ImageBuildOptions{ buildOptions := types.ImageBuildOptions{
Memory: options.memory.Value(), Memory: options.memory.Value(),
MemorySwap: options.memorySwap.Value(), MemorySwap: options.memorySwap.Value(),
@ -356,7 +357,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: dockerCli.ConfigFile().ParseProxyConfig(dockerCli.Client().DaemonHost(), options.buildArgs.GetAll()), BuildArgs: 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,

View File

@ -8,8 +8,7 @@ import (
) )
// NewImageCommand returns a cobra command for `image` subcommands // NewImageCommand returns a cobra command for `image` subcommands
// nolint: interfacer func NewImageCommand(dockerCli command.Cli) *cobra.Command {
func NewImageCommand(dockerCli *command.DockerCli) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "image", Use: "image",
Short: "Manage images", Short: "Manage images",

View File

@ -6,6 +6,7 @@ import (
"io/ioutil" "io/ioutil"
"testing" "testing"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/internal/test" "github.com/docker/cli/cli/internal/test"
"github.com/docker/docker/pkg/testutil" "github.com/docker/docker/pkg/testutil"
"github.com/docker/docker/pkg/testutil/golden" "github.com/docker/docker/pkg/testutil/golden"
@ -41,7 +42,9 @@ func TestNewPullCommandErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
cmd := NewPullCommand(test.NewFakeCli(&fakeClient{}, buf)) cli := test.NewFakeCli(&fakeClient{}, buf)
cli.SetConfigfile(configfile.NewConfigFile("filename"))
cmd := NewPullCommand(cli)
cmd.SetOutput(ioutil.Discard) cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
@ -64,7 +67,9 @@ func TestNewPullCommandSuccess(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
cmd := NewPullCommand(test.NewFakeCli(&fakeClient{}, buf)) cli := test.NewFakeCli(&fakeClient{}, buf)
cli.SetConfigfile(configfile.NewConfigFile("filename"))
cmd := NewPullCommand(cli)
cmd.SetOutput(ioutil.Discard) cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
err := cmd.Execute() err := cmd.Execute()

View File

@ -7,6 +7,7 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/internal/test" "github.com/docker/cli/cli/internal/test"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/testutil" "github.com/docker/docker/pkg/testutil"
@ -47,7 +48,9 @@ func TestNewPushCommandErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
cmd := NewPushCommand(test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc}, buf)) cli := test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc}, buf)
cli.SetConfigfile(configfile.NewConfigFile("filename"))
cmd := NewPushCommand(cli)
cmd.SetOutput(ioutil.Discard) cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
@ -66,11 +69,13 @@ func TestNewPushCommandSuccess(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
cmd := NewPushCommand(test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
imagePushFunc: func(ref string, options types.ImagePushOptions) (io.ReadCloser, error) { imagePushFunc: func(ref string, options types.ImagePushOptions) (io.ReadCloser, error) {
return ioutil.NopCloser(strings.NewReader("")), nil return ioutil.NopCloser(strings.NewReader("")), nil
}, },
}, buf)) }, buf)
cli.SetConfigfile(configfile.NewConfigFile("filename"))
cmd := NewPushCommand(cli)
cmd.SetOutput(ioutil.Discard) cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
assert.NoError(t, cmd.Execute()) assert.NoError(t, cmd.Execute())

View File

@ -70,7 +70,7 @@ func ResolveAuthConfig(ctx context.Context, cli Cli, index *registrytypes.IndexI
configKey = ElectAuthServer(ctx, cli) configKey = ElectAuthServer(ctx, cli)
} }
a, _ := cli.CredentialsStore(configKey).Get(configKey) a, _ := cli.ConfigFile().GetAuthConfig(configKey)
return a return a
} }
@ -85,7 +85,7 @@ func ConfigureAuth(cli Cli, flUser, flPassword, serverAddress string, isDefaultR
serverAddress = registry.ConvertToHostname(serverAddress) serverAddress = registry.ConvertToHostname(serverAddress)
} }
authconfig, err := cli.CredentialsStore(serverAddress).Get(serverAddress) authconfig, err := cli.ConfigFile().GetAuthConfig(serverAddress)
if err != nil { if err != nil {
return authconfig, err return authconfig, err
} }

View File

@ -71,7 +71,7 @@ func runLogin(dockerCli command.Cli, opts loginOptions) error {
authConfig.Password = "" authConfig.Password = ""
authConfig.IdentityToken = response.IdentityToken authConfig.IdentityToken = response.IdentityToken
} }
if err := dockerCli.CredentialsStore(serverAddress).Store(authConfig); err != nil { if err := dockerCli.ConfigFile().GetCredentialsStore(serverAddress).Store(authConfig); err != nil {
return errors.Errorf("Error saving credentials: %v", err) return errors.Errorf("Error saving credentials: %v", err)
} }

View File

@ -68,7 +68,7 @@ func runLogout(dockerCli command.Cli, serverAddress string) error {
fmt.Fprintf(dockerCli.Out(), "Removing login credentials for %s\n", hostnameAddress) fmt.Fprintf(dockerCli.Out(), "Removing login credentials for %s\n", hostnameAddress)
for _, r := range regsToLogout { for _, r := range regsToLogout {
if err := dockerCli.CredentialsStore(r).Erase(r); err != nil { if err := dockerCli.ConfigFile().GetCredentialsStore(r).Erase(r); err != nil {
fmt.Fprintf(dockerCli.Err(), "WARNING: could not erase credentials: %v\n", err) fmt.Fprintf(dockerCli.Err(), "WARNING: could not erase credentials: %v\n", err)
} }
} }

View File

@ -114,10 +114,10 @@ func Load(configDir string) (*configfile.ConfigFile, error) {
// LoadDefaultConfigFile attempts to load the default config file and returns // LoadDefaultConfigFile attempts to load the default config file and returns
// an initialized ConfigFile struct if none is found. // an initialized ConfigFile struct if none is found.
func LoadDefaultConfigFile(err io.Writer) *configfile.ConfigFile { func LoadDefaultConfigFile(stderr io.Writer) *configfile.ConfigFile {
configFile, e := Load(Dir()) configFile, err := Load(Dir())
if e != nil { if err != nil {
fmt.Fprintf(err, "WARNING: Error loading config file:%v\n", e) fmt.Fprintf(stderr, "WARNING: Error loading config file: %v\n", err)
} }
if !configFile.ContainsAuth() { if !configFile.ContainsAuth() {
configFile.CredentialsStore = credentials.DetectDefaultStore(configFile.CredentialsStore) configFile.CredentialsStore = credentials.DetectDefaultStore(configFile.CredentialsStore)

View File

@ -9,6 +9,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/docker/cli/cli/config/credentials"
"github.com/docker/cli/opts" "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"
@ -245,3 +246,56 @@ func decodeAuth(authStr string) (string, string, error) {
password := strings.Trim(arr[1], "\x00") password := strings.Trim(arr[1], "\x00")
return arr[0], password, nil return arr[0], password, nil
} }
// GetCredentialsStore returns a new credentials store from the settings in the
// configuration file
func (configFile *ConfigFile) GetCredentialsStore(serverAddress string) credentials.Store {
if helper := getConfiguredCredentialStore(configFile, serverAddress); helper != "" {
return credentials.NewNativeStore(configFile, helper)
}
return credentials.NewFileStore(configFile)
}
// GetAuthConfig for a repository from the credential store
func (configFile *ConfigFile) GetAuthConfig(serverAddress string) (types.AuthConfig, error) {
return configFile.GetCredentialsStore(serverAddress).Get(serverAddress)
}
// getConfiguredCredentialStore returns the credential helper configured for the
// given registry, the default credsStore, or the empty string if neither are
// configured.
func getConfiguredCredentialStore(c *ConfigFile, serverAddress string) string {
if c.CredentialHelpers != nil && serverAddress != "" {
if helper, exists := c.CredentialHelpers[serverAddress]; exists {
return helper
}
}
return c.CredentialsStore
}
// GetAllCredentials returns all of the credentials stored in all of the
// configured credential stores.
func (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig, error) {
auths := make(map[string]types.AuthConfig)
addAll := func(from map[string]types.AuthConfig) {
for reg, ac := range from {
auths[reg] = ac
}
}
for registry := range configFile.CredentialHelpers {
helper := configFile.GetCredentialsStore(registry)
newAuths, err := helper.GetAll()
if err != nil {
return nil, err
}
addAll(newAuths)
}
defaultStore := configFile.GetCredentialsStore("")
newAuths, err := defaultStore.GetAll()
if err != nil {
return nil, err
}
addAll(newAuths)
return auths, nil
}

View File

@ -71,11 +71,3 @@ func (c *FakeCli) In() *command.InStream {
func (c *FakeCli) ConfigFile() *configfile.ConfigFile { func (c *FakeCli) ConfigFile() *configfile.ConfigFile {
return c.configfile return c.configfile
} }
// CredentialsStore returns the fake store the cli will use
func (c *FakeCli) CredentialsStore(serverAddress string) credentials.Store {
if c.store == nil {
c.store = NewFakeStore()
}
return c.store
}