Skip to content

Commit f38ed57

Browse files
committed
feat: Improve repository selection, based on prefixes in config and full image name
Signed-off-by: Viacheslav Sychov <[email protected]>
1 parent 49825ec commit f38ed57

File tree

8 files changed

+78
-30
lines changed

8 files changed

+78
-30
lines changed

cmd/run.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/argoproj-labs/argocd-image-updater/pkg/common"
1515
"github.com/argoproj-labs/argocd-image-updater/pkg/env"
1616
"github.com/argoproj-labs/argocd-image-updater/pkg/health"
17+
"github.com/argoproj-labs/argocd-image-updater/pkg/image"
1718
"github.com/argoproj-labs/argocd-image-updater/pkg/log"
1819
"github.com/argoproj-labs/argocd-image-updater/pkg/metrics"
1920
"github.com/argoproj-labs/argocd-image-updater/pkg/registry"
@@ -343,7 +344,7 @@ func warmupImageCache(cfg *ImageUpdaterConfig) error {
343344
entries := 0
344345
eps := registry.ConfiguredEndpoints()
345346
for _, ep := range eps {
346-
r, err := registry.GetRegistryEndpoint(ep)
347+
r, err := registry.GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ep})
347348
if err == nil {
348349
entries += r.Cache.NumEntries()
349350
}

cmd/test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ argocd-image-updater test nginx --allow-tags '^1.19.\d+(\-.*)*$' --update-strate
113113
}
114114
}
115115

116-
ep, err := registry.GetRegistryEndpoint(img.RegistryURL)
116+
ep, err := registry.GetRegistryEndpoint(img)
117117
if err != nil {
118118
logCtx.Fatalf("could not get registry endpoint: %v", err)
119119
}

pkg/argocd/update.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ func UpdateApplication(updateConf *UpdateConfiguration, state *SyncIterationStat
180180

181181
imgCtx.Debugf("Considering this image for update")
182182

183-
rep, err := registry.GetRegistryEndpoint(applicationImage.RegistryURL)
183+
rep, err := registry.GetRegistryEndpoint(applicationImage)
184184
if err != nil {
185185
imgCtx.Errorf("Could not get registry endpoint from configuration: %v", err)
186186
result.NumErrors += 1

pkg/registry/client_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package registry
33
import (
44
"testing"
55

6+
"github.com/argoproj-labs/argocd-image-updater/pkg/image"
67
"github.com/argoproj-labs/argocd-image-updater/pkg/options"
78

89
"github.com/distribution/distribution/v3/manifest/schema1"
@@ -16,7 +17,7 @@ func Test_TagMetadata(t *testing.T) {
1617
History: []schema1.History{},
1718
},
1819
}
19-
ep, err := GetRegistryEndpoint("")
20+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
2021
require.NoError(t, err)
2122
client, err := NewClient(ep, "", "")
2223
require.NoError(t, err)
@@ -35,7 +36,7 @@ func Test_TagMetadata(t *testing.T) {
3536
},
3637
}
3738

38-
ep, err := GetRegistryEndpoint("")
39+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
3940
require.NoError(t, err)
4041
client, err := NewClient(ep, "", "")
4142
require.NoError(t, err)
@@ -54,7 +55,7 @@ func Test_TagMetadata(t *testing.T) {
5455
},
5556
}
5657

57-
ep, err := GetRegistryEndpoint("")
58+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
5859
require.NoError(t, err)
5960
client, err := NewClient(ep, "", "")
6061
require.NoError(t, err)
@@ -74,7 +75,7 @@ func Test_TagMetadata(t *testing.T) {
7475
},
7576
},
7677
}
77-
ep, err := GetRegistryEndpoint("")
78+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
7879
require.NoError(t, err)
7980
client, err := NewClient(ep, "", "")
8081
require.NoError(t, err)

pkg/registry/config_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"testing"
55
"time"
66

7+
"github.com/argoproj-labs/argocd-image-updater/pkg/image"
78
"github.com/argoproj-labs/argocd-image-updater/test/fixture"
89

910
"github.com/stretchr/testify/assert"
@@ -81,15 +82,15 @@ func Test_LoadRegistryConfiguration(t *testing.T) {
8182
err := LoadRegistryConfiguration("../../config/example-config.yaml", true)
8283
require.NoError(t, err)
8384
assert.Len(t, registries, 4)
84-
reg, err := GetRegistryEndpoint("gcr.io")
85+
reg, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "gcr.io"})
8586
require.NoError(t, err)
8687
assert.Equal(t, "pullsecret:foo/bar", reg.Credentials)
87-
reg, err = GetRegistryEndpoint("ghcr.io")
88+
reg, err = GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "ghcr.io"})
8889
require.NoError(t, err)
8990
assert.Equal(t, "ext:/some/script", reg.Credentials)
9091
assert.Equal(t, 5*time.Hour, reg.CredsExpire)
9192
RestoreDefaultRegistryConfiguration()
92-
reg, err = GetRegistryEndpoint("gcr.io")
93+
reg, err = GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "gcr.io"})
9394
require.NoError(t, err)
9495
assert.Equal(t, "", reg.Credentials)
9596
})

pkg/registry/endpoints.go

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"github.com/argoproj-labs/argocd-image-updater/pkg/cache"
13+
"github.com/argoproj-labs/argocd-image-updater/pkg/image"
1314
"github.com/argoproj-labs/argocd-image-updater/pkg/log"
1415

1516
"go.uber.org/ratelimit"
@@ -179,8 +180,27 @@ func inferRegistryEndpointFromPrefix(prefix string) *RegistryEndpoint {
179180
return NewRegistryEndpoint(prefix, prefix, apiURL, "", "", false, TagListSortUnsorted, 20, 0)
180181
}
181182

182-
// GetRegistryEndpoint retrieves the endpoint information for the given prefix
183-
func GetRegistryEndpoint(prefix string) (*RegistryEndpoint, error) {
183+
// find registry by prefix based on full image name
184+
func findRegistryEndpointByImage(img *image.ContainerImage) (ep *RegistryEndpoint) {
185+
log.Debugf("Try to find endpoint by image: %s/%s", img.RegistryURL, img.ImageName)
186+
registryLock.RLock()
187+
imgName := fmt.Sprintf("%s/%s", img.RegistryURL, img.ImageName)
188+
189+
for _, registry := range registries {
190+
if (ep == nil && strings.HasPrefix(imgName, registry.RegistryPrefix)) || (strings.HasPrefix(imgName, registry.RegistryPrefix) && len(registry.RegistryPrefix) > len(ep.RegistryPrefix)) {
191+
log.Debugf("Selected registry: '%s' (last selection in log - final)", registry.RegistryName)
192+
ep = registry
193+
}
194+
}
195+
196+
registryLock.RUnlock()
197+
return
198+
}
199+
200+
// GetRegistryEndpoint retrieves the endpoint information for the given image
201+
func GetRegistryEndpoint(img *image.ContainerImage) (*RegistryEndpoint, error) {
202+
prefix := img.RegistryURL
203+
184204
if prefix == "" {
185205
if defaultRegistry == nil {
186206
return nil, fmt.Errorf("no default endpoint configured")
@@ -197,7 +217,12 @@ func GetRegistryEndpoint(prefix string) (*RegistryEndpoint, error) {
197217
return registry, nil
198218
} else {
199219
var err error
200-
ep := inferRegistryEndpointFromPrefix(prefix)
220+
ep := findRegistryEndpointByImage(img)
221+
if ep != nil {
222+
return ep, err
223+
}
224+
225+
ep = inferRegistryEndpointFromPrefix(prefix)
201226
if ep != nil {
202227
err = AddRegistryEndpoint(ep)
203228
} else {
@@ -235,7 +260,7 @@ func GetDefaultRegistry() *RegistryEndpoint {
235260
// SetRegistryEndpointCredentials allows to change the credentials used for
236261
// endpoint access for existing RegistryEndpoint configuration
237262
func SetRegistryEndpointCredentials(prefix, credentials string) error {
238-
registry, err := GetRegistryEndpoint(prefix)
263+
registry, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: prefix})
239264
if err != nil {
240265
return err
241266
}

pkg/registry/endpoints_test.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"sync"
66
"testing"
77

8+
"github.com/argoproj-labs/argocd-image-updater/pkg/image"
9+
810
"github.com/stretchr/testify/assert"
911
"github.com/stretchr/testify/require"
1012
)
@@ -13,21 +15,21 @@ func Test_GetEndpoints(t *testing.T) {
1315
RestoreDefaultRegistryConfiguration()
1416

1517
t.Run("Get default endpoint", func(t *testing.T) {
16-
ep, err := GetRegistryEndpoint("")
18+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
1719
require.NoError(t, err)
1820
require.NotNil(t, ep)
1921
assert.Equal(t, "docker.io", ep.RegistryPrefix)
2022
})
2123

2224
t.Run("Get GCR endpoint", func(t *testing.T) {
23-
ep, err := GetRegistryEndpoint("gcr.io")
25+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "gcr.io"})
2426
require.NoError(t, err)
2527
require.NotNil(t, ep)
2628
assert.Equal(t, ep.RegistryPrefix, "gcr.io")
2729
})
2830

2931
t.Run("Infer endpoint", func(t *testing.T) {
30-
ep, err := GetRegistryEndpoint("foobar.com")
32+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "foobar.com"})
3133
require.NoError(t, err)
3234
require.NotNil(t, ep)
3335
assert.Equal(t, "foobar.com", ep.RegistryPrefix)
@@ -43,7 +45,7 @@ func Test_AddEndpoint(t *testing.T) {
4345
require.NoError(t, err)
4446
})
4547
t.Run("Get example.com endpoint", func(t *testing.T) {
46-
ep, err := GetRegistryEndpoint("example.com")
48+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "example.com"})
4749
require.NoError(t, err)
4850
require.NotNil(t, ep)
4951
assert.Equal(t, ep.RegistryPrefix, "example.com")
@@ -56,7 +58,7 @@ func Test_AddEndpoint(t *testing.T) {
5658
t.Run("Change existing endpoint", func(t *testing.T) {
5759
err := AddRegistryEndpoint(NewRegistryEndpoint("example.com", "Example", "https://example.com", "", "library", true, TagListSortLatestFirst, 5, 0))
5860
require.NoError(t, err)
59-
ep, err := GetRegistryEndpoint("example.com")
61+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "example.com"})
6062
require.NoError(t, err)
6163
require.NotNil(t, ep)
6264
assert.Equal(t, ep.Insecure, true)
@@ -71,7 +73,7 @@ func Test_SetEndpointCredentials(t *testing.T) {
7173
t.Run("Set credentials on default registry", func(t *testing.T) {
7274
err := SetRegistryEndpointCredentials("", "env:FOOBAR")
7375
require.NoError(t, err)
74-
ep, err := GetRegistryEndpoint("")
76+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
7577
require.NoError(t, err)
7678
require.NotNil(t, ep)
7779
assert.Equal(t, ep.Credentials, "env:FOOBAR")
@@ -80,13 +82,31 @@ func Test_SetEndpointCredentials(t *testing.T) {
8082
t.Run("Unset credentials on default registry", func(t *testing.T) {
8183
err := SetRegistryEndpointCredentials("", "")
8284
require.NoError(t, err)
83-
ep, err := GetRegistryEndpoint("")
85+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
8486
require.NoError(t, err)
8587
require.NotNil(t, ep)
8688
assert.Equal(t, ep.Credentials, "")
8789
})
8890
}
8991

92+
func Test_SelectRegistryBasedOnMaxPrefixContains(t *testing.T) {
93+
RestoreDefaultRegistryConfiguration()
94+
95+
t.Run("Set credentials on default registry", func(t *testing.T) {
96+
err := SetRegistryEndpointCredentials("foo.bar/prefix1", "env:FOOBAR_1")
97+
require.NoError(t, err)
98+
err = SetRegistryEndpointCredentials("foo.bar/prefix2", "env:FOOBAR_2")
99+
require.NoError(t, err)
100+
err = SetRegistryEndpointCredentials("foo.bar/prefix1/sub-prefix", "env:FOOBAR_SUB_1")
101+
require.NoError(t, err)
102+
103+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "foo.bar", ImageName: "prefix1/sub-prefix/image"})
104+
require.NoError(t, err)
105+
require.NotNil(t, ep)
106+
assert.Equal(t, ep.Credentials, "env:FOOBAR_SUB_1")
107+
})
108+
}
109+
90110
func Test_EndpointConcurrentAccess(t *testing.T) {
91111
RestoreDefaultRegistryConfiguration()
92112
const numRuns = 50
@@ -96,7 +116,7 @@ func Test_EndpointConcurrentAccess(t *testing.T) {
96116
wg.Add(numRuns)
97117
for i := 0; i < numRuns; i++ {
98118
go func() {
99-
ep, err := GetRegistryEndpoint("gcr.io")
119+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "gcr.io"})
100120
require.NoError(t, err)
101121
require.NotNil(t, ep)
102122
wg.Done()
@@ -114,7 +134,7 @@ func Test_EndpointConcurrentAccess(t *testing.T) {
114134
creds := fmt.Sprintf("secret:foo/secret-%d", i)
115135
err := SetRegistryEndpointCredentials("", creds)
116136
require.NoError(t, err)
117-
ep, err := GetRegistryEndpoint("")
137+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
118138
require.NoError(t, err)
119139
require.NotNil(t, ep)
120140
wg.Done()
@@ -132,7 +152,7 @@ func Test_SetDefault(t *testing.T) {
132152
assert.Equal(t, "docker.io", dep.RegistryPrefix)
133153
assert.True(t, dep.IsDefault)
134154

135-
ep, err := GetRegistryEndpoint("ghcr.io")
155+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "ghcr.io"})
136156
require.NoError(t, err)
137157
require.NotNil(t, ep)
138158
require.False(t, ep.IsDefault)
@@ -146,7 +166,7 @@ func Test_SetDefault(t *testing.T) {
146166

147167
func Test_DeepCopy(t *testing.T) {
148168
t.Run("DeepCopy endpoint object", func(t *testing.T) {
149-
ep, err := GetRegistryEndpoint("docker.pkg.github.com")
169+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "docker.pkg.github.com"})
150170
require.NoError(t, err)
151171
require.NotNil(t, ep)
152172
newEp := ep.DeepCopy()

pkg/registry/registry_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func Test_GetTags(t *testing.T) {
2323
regClient.On("NewRepository", mock.Anything).Return(nil)
2424
regClient.On("Tags", mock.Anything).Return([]string{"1.2.0", "1.2.1", "1.2.2"}, nil)
2525

26-
ep, err := GetRegistryEndpoint("")
26+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
2727
require.NoError(t, err)
2828

2929
img := image.NewFromIdentifier("foo/bar:1.2.0")
@@ -42,7 +42,7 @@ func Test_GetTags(t *testing.T) {
4242
regClient.On("NewRepository", mock.Anything).Return(nil)
4343
regClient.On("Tags", mock.Anything).Return([]string{"1.2.0", "1.2.1", "1.2.2"}, nil)
4444

45-
ep, err := GetRegistryEndpoint("")
45+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
4646
require.NoError(t, err)
4747

4848
img := image.NewFromIdentifier("foo/bar:1.2.0")
@@ -65,7 +65,7 @@ func Test_GetTags(t *testing.T) {
6565
regClient.On("NewRepository", mock.Anything).Return(nil)
6666
regClient.On("Tags", mock.Anything).Return([]string{"1.2.0", "1.2.1", "1.2.2"}, nil)
6767

68-
ep, err := GetRegistryEndpoint("")
68+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
6969
require.NoError(t, err)
7070

7171
img := image.NewFromIdentifier("foo/bar:1.2.0")
@@ -97,7 +97,7 @@ func Test_GetTags(t *testing.T) {
9797
regClient.On("ManifestForTag", mock.Anything, mock.Anything).Return(meta1, nil)
9898
regClient.On("TagMetadata", mock.Anything, mock.Anything).Return(&tag.TagInfo{}, nil)
9999

100-
ep, err := GetRegistryEndpoint("")
100+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: ""})
101101
require.NoError(t, err)
102102
ep.Cache.ClearCache()
103103

@@ -132,7 +132,7 @@ registries:
132132
// New registry configuration
133133
err = AddRegistryEndpointFromConfig(epl.Items[0])
134134
require.NoError(t, err)
135-
ep, err := GetRegistryEndpoint("ghcr.io")
135+
ep, err := GetRegistryEndpoint(&image.ContainerImage{RegistryURL: "ghcr.io"})
136136
require.NoError(t, err)
137137
require.NotEqual(t, 0, ep.CredsExpire)
138138

0 commit comments

Comments
 (0)