Skip to content

Commit

Permalink
feat: Automatic inferring of registry from image prefix (#369)
Browse files Browse the repository at this point in the history
* feat: Infer registry from prefix

Signed-off-by: jannfis <jann@mistrust.net>

* Add missing registry testdata

Signed-off-by: jannfis <jann@mistrust.net>

* Correctly handle default registries

Signed-off-by: jannfis <jann@mistrust.net>
  • Loading branch information
jannfis committed Jan 27, 2022
1 parent 89daab6 commit 113d8e7
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 77 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ mod-vendor:
test:
go test -coverprofile coverage.out `go list ./... | egrep -v '(test|mocks|ext/)'`

test-race:
go test -race -coverprofile coverage.out `go list ./... | egrep -v '(test|mocks|ext/)'`

.PHONY: prereq
prereq:
mkdir -p dist
Expand Down
14 changes: 7 additions & 7 deletions pkg/argocd/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -839,11 +839,11 @@ func Test_UpdateApplication(t *testing.T) {
assert.Equal(t, 0, res.NumImagesUpdated)
})

t.Run("Error - unknown registry", func(t *testing.T) {
t.Run("Update from infered registry", func(t *testing.T) {
mockClientFn := func(endpoint *registry.RegistryEndpoint, username, password string) (registry.RegistryClient, error) {
regMock := regmock.RegistryClient{}
regMock.On("NewRepository", mock.Anything).Return(nil)
regMock.On("Tags", mock.Anything).Return([]string{"1.0.1"}, nil)
regMock.On("Tags", mock.Anything).Return([]string{"1.0.1", "1.0.2"}, nil)
return &regMock, nil
}

Expand All @@ -863,7 +863,7 @@ func Test_UpdateApplication(t *testing.T) {
Source: v1alpha1.ApplicationSource{
Kustomize: &v1alpha1.ApplicationSourceKustomize{
Images: v1alpha1.KustomizeImages{
"example.io/jannfis/foobar:1.0.1",
"example.io/jannfis/example:1.0.1",
},
},
},
Expand All @@ -872,13 +872,13 @@ func Test_UpdateApplication(t *testing.T) {
SourceType: v1alpha1.ApplicationSourceTypeKustomize,
Summary: v1alpha1.ApplicationSummary{
Images: []string{
"example.io/jannfis/foobar:1.0.1",
"example.io/jannfis/example:1.0.1",
},
},
},
},
Images: image.ContainerImageList{
image.NewFromIdentifier("example.io/jannfis/foobar:1.0.1"),
image.NewFromIdentifier("example.io/jannfis/example:1.0.x"),
},
}
res := UpdateApplication(&UpdateConfiguration{
Expand All @@ -888,11 +888,11 @@ func Test_UpdateApplication(t *testing.T) {
UpdateApp: appImages,
DryRun: false,
}, NewSyncIterationState())
assert.Equal(t, 1, res.NumErrors)
assert.Equal(t, 0, res.NumErrors)
assert.Equal(t, 0, res.NumSkipped)
assert.Equal(t, 1, res.NumApplicationsProcessed)
assert.Equal(t, 1, res.NumImagesConsidered)
assert.Equal(t, 0, res.NumImagesUpdated)
assert.Equal(t, 1, res.NumImagesUpdated)
})

t.Run("Test error on generic registry client failure", func(t *testing.T) {
Expand Down
38 changes: 32 additions & 6 deletions pkg/registry/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,20 @@ type RegistryConfiguration struct {
Insecure bool `yaml:"insecure,omitempty"`
DefaultNS string `yaml:"defaultns,omitempty"`
Limit int `yaml:"limit,omitempty"`
IsDefault bool `yaml:"default,omitempty"`
}

// RegistryList contains multiple RegistryConfiguration items
type RegistryList struct {
Items []RegistryConfiguration `yaml:"registries"`
}

func clearRegistries() {
registryLock.Lock()
registries = make(map[string]*RegistryEndpoint)
registryLock.Unlock()
}

// LoadRegistryConfiguration loads a YAML-formatted registry configuration from
// a given file at path.
func LoadRegistryConfiguration(path string, clear bool) error {
Expand All @@ -43,20 +50,35 @@ func LoadRegistryConfiguration(path string, clear bool) error {
}

if clear {
registryLock.Lock()
registries = make(map[string]*RegistryEndpoint)
registryLock.Unlock()
clearRegistries()
}

haveDefault := false

for _, reg := range registryList.Items {
tagSortMode := TagListSortFromString(reg.TagSortMode)
if tagSortMode != TagListSortUnsorted {
log.Warnf("Registry %s has tag sort mode set to %s, meta data retrieval will be disabled for this registry.", reg.ApiURL, tagSortMode)
}
err = AddRegistryEndpoint(reg.Prefix, reg.Name, reg.ApiURL, reg.Credentials, reg.DefaultNS, reg.Insecure, tagSortMode, reg.Limit, reg.CredsExpire)
if err != nil {
ep := NewRegistryEndpoint(reg.Prefix, reg.Name, reg.ApiURL, reg.Credentials, reg.DefaultNS, reg.Insecure, tagSortMode, reg.Limit, reg.CredsExpire)
if reg.IsDefault {
if haveDefault {
dep := GetDefaultRegistry()
if dep == nil {
panic("unexpected: default registry should be set, but is not")
}
return fmt.Errorf("cannot set registry %s as default - only one default registry allowed, currently set to %s", ep.RegistryPrefix, dep.RegistryPrefix)
}
}

if err := AddRegistryEndpoint(ep); err != nil {
return err
}

if reg.IsDefault {
SetDefaultRegistry(ep)
haveDefault = true
}
}

log.Infof("Loaded %d registry configurations from %s", len(registryList.Items), path)
Expand Down Expand Up @@ -106,8 +128,12 @@ func ParseRegistryConfiguration(yamlSource string) (RegistryList, error) {
func RestoreDefaultRegistryConfiguration() {
registryLock.Lock()
defer registryLock.Unlock()
defaultRegistry = nil
registries = make(map[string]*RegistryEndpoint)
for k, v := range defaultRegistries {
for k, v := range registryTweaks {
registries[k] = v.DeepCopy()
if v.IsDefault {
SetDefaultRegistry(registries[k])
}
}
}
20 changes: 18 additions & 2 deletions pkg/registry/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@ registries:
}

func Test_LoadRegistryConfiguration(t *testing.T) {
RestoreDefaultRegistryConfiguration()

t.Run("Load from valid location", func(t *testing.T) {
err := LoadRegistryConfiguration("../../config/example-config.yaml", false)
err := LoadRegistryConfiguration("../../config/example-config.yaml", true)
require.NoError(t, err)
assert.Len(t, registries, 5)
assert.Len(t, registries, 4)
reg, err := GetRegistryEndpoint("gcr.io")
require.NoError(t, err)
assert.Equal(t, "pullsecret:foo/bar", reg.Credentials)
Expand All @@ -91,4 +93,18 @@ func Test_LoadRegistryConfiguration(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, "", reg.Credentials)
})

t.Run("Load from invalid location", func(t *testing.T) {
err := LoadRegistryConfiguration("../../test/testdata/registry/config/does-not-exist.yaml", true)
require.Error(t, err)
require.Contains(t, err.Error(), "no such file or directory")
})

t.Run("Two defaults defined in same config", func(t *testing.T) {
err := LoadRegistryConfiguration("../../test/testdata/registry/config/two-defaults.yaml", true)
require.Error(t, err)
require.Contains(t, err.Error(), "cannot set registry")
})

RestoreDefaultRegistryConfiguration()
}
Loading

0 comments on commit 113d8e7

Please sign in to comment.