1
1
package credentials
2
2
3
3
import (
4
+ "bytes"
5
+ "encoding/json"
4
6
"errors"
7
+ "fmt"
5
8
"net/url"
6
9
"regexp"
7
10
"strings"
@@ -13,8 +16,9 @@ import (
13
16
)
14
17
15
18
type toolCredentialStore struct {
16
- file credentials.Store
17
- program client.ProgramFunc
19
+ file credentials.Store
20
+ program client.ProgramFunc
21
+ contexts []string
18
22
}
19
23
20
24
func (h * toolCredentialStore ) Erase (serverAddress string ) error {
@@ -43,7 +47,16 @@ func (h *toolCredentialStore) Get(serverAddress string) (types.AuthConfig, error
43
47
}
44
48
45
49
func (h * toolCredentialStore ) GetAll () (map [string ]types.AuthConfig , error ) {
46
- serverAddresses , err := client .List (h .program )
50
+ var (
51
+ serverAddresses map [string ]string
52
+ err error
53
+ )
54
+ if len (h .contexts ) == 0 {
55
+ serverAddresses , err = client .List (h .program )
56
+ } else {
57
+ serverAddresses , err = listWithContexts (h .program , h .contexts )
58
+ }
59
+
47
60
if err != nil {
48
61
return nil , err
49
62
}
@@ -94,3 +107,44 @@ func (h *toolCredentialStore) Store(authConfig types.AuthConfig) error {
94
107
Secret : authConfig .Password ,
95
108
})
96
109
}
110
+
111
+ // listWithContexts is almost an exact copy of the List function in Docker's libraries,
112
+ // the only difference being that we pass the context through as input to the program.
113
+ // This will allow some credential stores, like Postgres, to do an optimized list.
114
+ func listWithContexts (program client.ProgramFunc , contexts []string ) (map [string ]string , error ) {
115
+ cmd := program (credentials2 .ActionList )
116
+
117
+ contextsJSON , err := json .Marshal (contexts )
118
+ if err != nil {
119
+ return nil , err
120
+ }
121
+
122
+ cmd .Input (bytes .NewReader (contextsJSON ))
123
+ out , err := cmd .Output ()
124
+ if err != nil {
125
+ t := strings .TrimSpace (string (out ))
126
+
127
+ if isValidErr := isValidCredsMessage (t ); isValidErr != nil {
128
+ err = isValidErr
129
+ }
130
+
131
+ return nil , fmt .Errorf ("error listing credentials - err: %v, out: `%s`" , err , t )
132
+ }
133
+
134
+ var resp map [string ]string
135
+ if err = json .NewDecoder (bytes .NewReader (out )).Decode (& resp ); err != nil {
136
+ return nil , err
137
+ }
138
+
139
+ return resp , nil
140
+ }
141
+
142
+ func isValidCredsMessage (msg string ) error {
143
+ if credentials2 .IsCredentialsMissingServerURLMessage (msg ) {
144
+ return credentials2 .NewErrCredentialsMissingServerURL ()
145
+ }
146
+ if credentials2 .IsCredentialsMissingUsernameMessage (msg ) {
147
+ return credentials2 .NewErrCredentialsMissingUsername ()
148
+ }
149
+ return nil
150
+ }
0 commit comments