Skip to content

Commit 7554eda

Browse files
committed
Fix issue where one bad credential helper causes none to be returned
Instead, skip bad credential helpers (and warn the user about the error) Signed-off-by: Laura Brehm <laurabrehm@hey.com>
1 parent 4a500f6 commit 7554eda

File tree

2 files changed

+58
-13
lines changed

2 files changed

+58
-13
lines changed

cli/config/configfile/file.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ func (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig,
300300
for registryHostname := range configFile.CredentialHelpers {
301301
newAuth, err := configFile.GetAuthConfig(registryHostname)
302302
if err != nil {
303-
return nil, err
303+
logrus.WithError(err).Warnf("Failed to get credentials for registry: %s", registryHostname)
304+
continue
304305
}
305306
auths[registryHostname] = newAuth
306307
}

cli/config/configfile/file_test.go

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package configfile
33
import (
44
"bytes"
55
"encoding/json"
6+
"errors"
67
"os"
78
"testing"
89

@@ -166,8 +167,9 @@ func TestConfigFile(t *testing.T) {
166167
}
167168

168169
type mockNativeStore struct {
169-
GetAllCallCount int
170-
authConfigs map[string]types.AuthConfig
170+
GetAllCallCount int
171+
authConfigs map[string]types.AuthConfig
172+
authConfigErrors map[string]error
171173
}
172174

173175
func (c *mockNativeStore) Erase(registryHostname string) error {
@@ -176,7 +178,7 @@ func (c *mockNativeStore) Erase(registryHostname string) error {
176178
}
177179

178180
func (c *mockNativeStore) Get(registryHostname string) (types.AuthConfig, error) {
179-
return c.authConfigs[registryHostname], nil
181+
return c.authConfigs[registryHostname], c.authConfigErrors[registryHostname]
180182
}
181183

182184
func (c *mockNativeStore) GetAll() (map[string]types.AuthConfig, error) {
@@ -191,8 +193,8 @@ func (c *mockNativeStore) Store(authConfig types.AuthConfig) error {
191193
// make sure it satisfies the interface
192194
var _ credentials.Store = (*mockNativeStore)(nil)
193195

194-
func NewMockNativeStore(authConfigs map[string]types.AuthConfig) credentials.Store {
195-
return &mockNativeStore{authConfigs: authConfigs}
196+
func NewMockNativeStore(authConfigs map[string]types.AuthConfig, authConfigErrors map[string]error) credentials.Store {
197+
return &mockNativeStore{authConfigs: authConfigs, authConfigErrors: authConfigErrors}
196198
}
197199

198200
func TestGetAllCredentialsFileStoreOnly(t *testing.T) {
@@ -220,7 +222,7 @@ func TestGetAllCredentialsCredsStore(t *testing.T) {
220222
Password: "pass",
221223
}
222224

223-
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: expectedAuth})
225+
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: expectedAuth}, nil)
224226

225227
tmpNewNativeStore := newNativeStore
226228
defer func() { newNativeStore = tmpNewNativeStore }()
@@ -237,6 +239,48 @@ func TestGetAllCredentialsCredsStore(t *testing.T) {
237239
assert.Check(t, is.Equal(1, testCredsStore.(*mockNativeStore).GetAllCallCount))
238240
}
239241

242+
func TestGetAllCredentialsCredStoreErrorHandling(t *testing.T) {
243+
const (
244+
workingHelperRegistryHostname = "working-helper.com"
245+
brokenHelperRegistryHostname = "broken-helper.com"
246+
)
247+
configFile := New("filename")
248+
configFile.CredentialHelpers = map[string]string{
249+
workingHelperRegistryHostname: "cred_helper",
250+
brokenHelperRegistryHostname: "broken_cred_helper",
251+
}
252+
expectedAuth := types.AuthConfig{
253+
Username: "username",
254+
Password: "pass",
255+
}
256+
// configure the mock store to throw an error
257+
// when calling the helper for this registry
258+
authErrors := map[string]error{
259+
brokenHelperRegistryHostname: errors.New("an error"),
260+
}
261+
262+
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{
263+
workingHelperRegistryHostname: expectedAuth,
264+
// configure an auth entry for the "broken" credential
265+
// helper that will throw an error
266+
brokenHelperRegistryHostname: {},
267+
}, authErrors)
268+
269+
tmpNewNativeStore := newNativeStore
270+
defer func() { newNativeStore = tmpNewNativeStore }()
271+
newNativeStore = func(configFile *ConfigFile, helperSuffix string) credentials.Store {
272+
return testCredsStore
273+
}
274+
275+
authConfigs, err := configFile.GetAllCredentials()
276+
277+
// make sure we're still returning the expected credentials
278+
// and skipping the ones throwing an error
279+
assert.NilError(t, err)
280+
assert.Check(t, is.Equal(1, len(authConfigs)))
281+
assert.Check(t, is.DeepEqual(expectedAuth, authConfigs[workingHelperRegistryHostname]))
282+
}
283+
240284
func TestGetAllCredentialsCredHelper(t *testing.T) {
241285
const (
242286
testCredHelperSuffix = "test_cred_helper"
@@ -261,7 +305,7 @@ func TestGetAllCredentialsCredHelper(t *testing.T) {
261305
// Add in an extra auth entry which doesn't appear in CredentialHelpers section of the configFile.
262306
// This verifies that only explicitly configured registries are being requested from the cred helpers.
263307
testExtraCredHelperRegistryHostname: unexpectedCredHelperAuth,
264-
})
308+
}, nil)
265309

266310
tmpNewNativeStore := newNativeStore
267311
defer func() { newNativeStore = tmpNewNativeStore }()
@@ -298,7 +342,7 @@ func TestGetAllCredentialsFileStoreAndCredHelper(t *testing.T) {
298342
configFile.CredentialHelpers = map[string]string{testCredHelperRegistryHostname: testCredHelperSuffix}
299343
configFile.AuthConfigs[testFileStoreRegistryHostname] = expectedFileStoreAuth
300344

301-
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testCredHelperRegistryHostname: expectedCredHelperAuth})
345+
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testCredHelperRegistryHostname: expectedCredHelperAuth}, nil)
302346

303347
newNativeStore = func(configFile *ConfigFile, helperSuffix string) credentials.Store {
304348
return testCredHelper
@@ -337,8 +381,8 @@ func TestGetAllCredentialsCredStoreAndCredHelper(t *testing.T) {
337381
Password: "cred_helper_pass",
338382
}
339383

340-
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testCredHelperRegistryHostname: expectedCredHelperAuth})
341-
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testCredStoreRegistryHostname: expectedCredStoreAuth})
384+
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testCredHelperRegistryHostname: expectedCredHelperAuth}, nil)
385+
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testCredStoreRegistryHostname: expectedCredStoreAuth}, nil)
342386

343387
tmpNewNativeStore := newNativeStore
344388
defer func() { newNativeStore = tmpNewNativeStore }()
@@ -380,8 +424,8 @@ func TestGetAllCredentialsCredHelperOverridesDefaultStore(t *testing.T) {
380424
Password: "cred_helper_pass",
381425
}
382426

383-
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: expectedCredHelperAuth})
384-
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: unexpectedCredStoreAuth})
427+
testCredHelper := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: expectedCredHelperAuth}, nil)
428+
testCredsStore := NewMockNativeStore(map[string]types.AuthConfig{testRegistryHostname: unexpectedCredStoreAuth}, nil)
385429

386430
tmpNewNativeStore := newNativeStore
387431
defer func() { newNativeStore = tmpNewNativeStore }()

0 commit comments

Comments
 (0)