forked from gitlabhq/gitlab-runner
-
Notifications
You must be signed in to change notification settings - Fork 1
/
auth_config.go
132 lines (108 loc) · 3.24 KB
/
auth_config.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
131
132
package docker_helpers
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"os"
"os/user"
"path"
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/cliconfig/configfile"
"github.com/docker/docker/pkg/homedir"
)
// DefaultDockerRegistry is the name of the index
const DefaultDockerRegistry = "docker.io"
// EncodeAuthConfig constructs a token from an AuthConfig, suitable for
// authorizing against the Docker API with.
func EncodeAuthConfig(authConfig *types.AuthConfig) (string, error) {
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(authConfig); err != nil {
return "", err
}
return base64.URLEncoding.EncodeToString(buf.Bytes()), nil
}
// SplitDockerImageName breaks a reposName into an index name and remote name
func SplitDockerImageName(reposName string) (string, string) {
nameParts := strings.SplitN(reposName, "/", 2)
var indexName, remoteName string
if len(nameParts) == 1 || (!strings.Contains(nameParts[0], ".") &&
!strings.Contains(nameParts[0], ":") && nameParts[0] != "localhost") {
// This is a Docker Index repos (ex: samalba/hipache or ubuntu)
// 'docker.io'
indexName = DefaultDockerRegistry
remoteName = reposName
} else {
indexName = nameParts[0]
remoteName = nameParts[1]
}
if indexName == "index."+DefaultDockerRegistry {
indexName = DefaultDockerRegistry
}
return indexName, remoteName
}
var HomeDirectory = homedir.Get()
func ReadDockerAuthConfigsFromHomeDir(userName string) (map[string]types.AuthConfig, error) {
homeDir := HomeDirectory
if userName != "" {
u, err := user.Lookup(userName)
if err != nil {
return nil, err
}
homeDir = u.HomeDir
}
if homeDir == "" {
return nil, fmt.Errorf("Failed to get home directory")
}
p := path.Join(homeDir, ".docker", "config.json")
r, err := os.Open(p)
defer r.Close()
if err != nil {
p := path.Join(homeDir, ".dockercfg")
r, err = os.Open(p)
if err != nil && !os.IsNotExist(err) {
return nil, err
}
}
if r == nil {
return make(map[string]types.AuthConfig), nil
}
return ReadAuthConfigsFromReader(r)
}
func ReadAuthConfigsFromReader(r io.Reader) (map[string]types.AuthConfig, error) {
config := &configfile.ConfigFile{}
if err := config.LoadFromReader(r); err != nil {
return nil, err
}
return config.AuthConfigs, nil
}
// ResolveDockerAuthConfig taken from: https://github.com/docker/docker/blob/master/registry/auth.go
func ResolveDockerAuthConfig(indexName string, configs map[string]types.AuthConfig) *types.AuthConfig {
if configs == nil {
return nil
}
convertToHostname := func(url string) string {
stripped := url
if strings.HasPrefix(url, "http://") {
stripped = strings.Replace(url, "http://", "", 1)
} else if strings.HasPrefix(url, "https://") {
stripped = strings.Replace(url, "https://", "", 1)
}
nameParts := strings.SplitN(stripped, "/", 2)
if nameParts[0] == "index."+DefaultDockerRegistry {
return DefaultDockerRegistry
}
return nameParts[0]
}
// Maybe they have a legacy config file, we will iterate the keys converting
// them to the new format and testing
for registry, authConfig := range configs {
if indexName == convertToHostname(registry) {
return &authConfig
}
}
// When all else fails, return an empty auth config
return nil
}