forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
cfg.go
130 lines (115 loc) · 4.85 KB
/
cfg.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package dockercfg
import (
"os"
"os/user"
"path/filepath"
docker "github.com/fsouza/go-dockerclient"
"github.com/golang/glog"
"github.com/spf13/pflag"
kapi "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/credentialprovider"
)
const (
PushAuthType = "PUSH_DOCKERCFG_PATH"
PullAuthType = "PULL_DOCKERCFG_PATH"
PullSourceAuthType = "PULL_SOURCE_DOCKERCFG_PATH_"
)
// Helper contains all the valid config options for reading the local dockercfg file
type Helper struct {
}
// NewHelper creates a Flags object with the default values set.
func NewHelper() *Helper {
return &Helper{}
}
// InstallFlags installs the Docker flag helper into a FlagSet with the default
// options and default values from the Helper object.
func (h *Helper) InstallFlags(flags *pflag.FlagSet) {
}
// GetDockerAuth returns a valid Docker AuthConfiguration entry, and whether it was read
// from the local dockercfg file
func (h *Helper) GetDockerAuth(imageName, authType string) (docker.AuthConfiguration, bool) {
glog.V(3).Infof("Locating docker auth for image %s and type %s", imageName, authType)
var searchPaths []string
var cfg credentialprovider.DockerConfig
var err error
if pathForAuthType := os.Getenv(authType); len(pathForAuthType) > 0 {
searchPaths = []string{pathForAuthType}
} else {
searchPaths = getExtraSearchPaths()
}
glog.V(3).Infof("Getting docker auth in paths : %v", searchPaths)
cfg, err = GetDockerConfig(searchPaths)
if err != nil {
glog.Errorf("Reading docker config from %v failed: %v", searchPaths, err)
return docker.AuthConfiguration{}, false
}
keyring := credentialprovider.BasicDockerKeyring{}
keyring.Add(cfg)
authConfs, found := keyring.Lookup(imageName)
if !found || len(authConfs) == 0 {
return docker.AuthConfiguration{}, false
}
glog.V(3).Infof("Using %s user for Docker authentication for image %s", authConfs[0].Username, imageName)
return docker.AuthConfiguration{
Username: authConfs[0].Username,
Password: authConfs[0].Password,
Email: authConfs[0].Email,
ServerAddress: authConfs[0].ServerAddress,
}, true
}
// GetDockercfgFile returns the path to the dockercfg file
func GetDockercfgFile(path string) string {
var cfgPath string
if path != "" {
cfgPath = path
// There are 3 valid ways to specify docker config in a secret.
// 1) with a .dockerconfigjson key pointing to a .docker/config.json file (the key used by k8s for
// dockerconfigjson type secrets and the new docker cfg format)
// 2) with a .dockercfg key+file (the key used by k8s for dockercfg type secrets and the old docker format)
// 3) with a config.json file because you created your secret using "oc secrets new mysecret .docker/config.json"
// so you automatically got a key named config.json containing the new docker cfg format content.
// we will check to see which one was provided in that priority order.
if _, err := os.Stat(filepath.Join(path, kapi.DockerConfigJsonKey)); err == nil {
cfgPath = filepath.Join(path, kapi.DockerConfigJsonKey)
} else if _, err := os.Stat(filepath.Join(path, kapi.DockerConfigKey)); err == nil {
cfgPath = filepath.Join(path, kapi.DockerConfigKey)
} else if _, err := os.Stat(filepath.Join(path, "config.json")); err == nil {
cfgPath = filepath.Join(path, "config.json")
}
} else if os.Getenv("DOCKERCFG_PATH") != "" {
cfgPath = os.Getenv("DOCKERCFG_PATH")
} else if currentUser, err := user.Current(); err == nil {
cfgPath = filepath.Join(currentUser.HomeDir, ".docker", "config.json")
}
glog.V(5).Infof("Using Docker authentication configuration in '%s'", cfgPath)
return cfgPath
}
// GetDockerConfig return docker config info by checking given paths
func GetDockerConfig(path []string) (cfg credentialprovider.DockerConfig, err error) {
if cfg, err = credentialprovider.ReadDockerConfigJSONFile(path); err != nil {
if cfg, err = ReadDockerConfigJsonFileGeneratedFromSecret(path); err != nil {
cfg, err = credentialprovider.ReadDockercfgFile(path)
}
}
return cfg, err
}
// ReadDockerConfigJsonFileGeneratedFromSecret return DockerConfig by reading specific file named .dockerconfigjson
// generated by secret from given paths.
func ReadDockerConfigJsonFileGeneratedFromSecret(path []string) (cfg credentialprovider.DockerConfig, err error) {
for _, filePath := range path {
cfg, err = credentialprovider.ReadSpecificDockerConfigJsonFile(filepath.Join(filePath, kapi.DockerConfigJsonKey))
if err == nil {
return cfg, nil
}
}
return nil, err
}
//getExtraSearchPaths get extra paths that may contain docker-config type files.
//this invocation we do not need to handle user.Current() since upstream k8s have handled HOME path
func getExtraSearchPaths() (searchPaths []string) {
if dockerCfgPath := os.Getenv("DOCKERCFG_PATH"); dockerCfgPath != "" {
dockerCfgDir := filepath.Dir(dockerCfgPath)
searchPaths = append(searchPaths, dockerCfgDir)
}
return searchPaths
}