Skip to content

Commit 9656037

Browse files
Allow overriding image name in clusterctl config
Signed-off-by: Alexandr Demicev <[email protected]>
1 parent 376d30b commit 9656037

File tree

5 files changed

+115
-27
lines changed

5 files changed

+115
-27
lines changed

cmd/clusterctl/client/cluster/cert_manager_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ var certManagerNamespaceYaml = []byte("apiVersion: v1\n" +
6161
func Test_getManifestObjs(t *testing.T) {
6262
g := NewWithT(t)
6363

64-
defaultConfigClient, err := config.New(context.Background(), "", config.InjectReader(test.NewFakeReader().WithImageMeta(config.CertManagerImageComponent, "bar-repository.io", "")))
64+
defaultConfigClient, err := config.New(context.Background(), "", config.InjectReader(test.NewFakeReader().WithImageMeta(config.CertManagerImageComponent, "bar-repository.io", "", "")))
6565
g.Expect(err).ToNot(HaveOccurred())
6666

6767
type fields struct {
@@ -109,7 +109,7 @@ func Test_getManifestObjs(t *testing.T) {
109109
name: "successfully gets the cert-manager components for a custom release",
110110
fields: fields{
111111
configClient: func() config.Client {
112-
configClient, err := config.New(context.Background(), "", config.InjectReader(test.NewFakeReader().WithImageMeta(config.CertManagerImageComponent, "bar-repository.io", "").WithCertManager("", "v1.0.0", "")))
112+
configClient, err := config.New(context.Background(), "", config.InjectReader(test.NewFakeReader().WithImageMeta(config.CertManagerImageComponent, "bar-repository.io", "", "").WithCertManager("", "v1.0.0", "")))
113113
g.Expect(err).ToNot(HaveOccurred())
114114
return configClient
115115
}(),

cmd/clusterctl/client/config/imagemeta_client.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ type imageMeta struct {
125125
// repository sets the container registry to pull images from.
126126
Repository string `json:"repository,omitempty"`
127127

128+
// Name allows to specify a different name for the image.
129+
Name string `json:"name,omitempty"`
130+
128131
// Tag allows to specify a tag for the images.
129132
Tag string `json:"tag,omitempty"`
130133
}
@@ -135,6 +138,9 @@ func (i *imageMeta) Union(other *imageMeta) {
135138
if other.Repository != "" {
136139
i.Repository = other.Repository
137140
}
141+
if other.Name != "" {
142+
i.Name = other.Name
143+
}
138144
if other.Tag != "" {
139145
i.Tag = other.Tag
140146
}
@@ -146,6 +152,9 @@ func (i *imageMeta) ApplyToImage(image container.Image) string {
146152
if i.Repository != "" {
147153
image.Repository = strings.TrimSuffix(i.Repository, "/")
148154
}
155+
if i.Name != "" {
156+
image.Name = i.Name
157+
}
149158
if i.Tag != "" {
150159
image.Tag = i.Tag
151160
}

cmd/clusterctl/client/config/imagemeta_client_test.go

Lines changed: 74 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
5555
{
5656
name: "image config for cert-manager/cert-manager-cainjector: image for the cert-manager/cert-manager-cainjector should be changed",
5757
fields: fields{
58-
reader: test.NewFakeReader().WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "foo-tag"),
58+
reader: test.NewFakeReader().WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "", "foo-tag"),
5959
},
6060
args: args{
6161
component: CertManagerImageComponent,
@@ -67,7 +67,7 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
6767
{
6868
name: "image config for cert-manager/cert-manager-cainjector: image for the cert-manager/cert-manager-webhook should not be changed",
6969
fields: fields{
70-
reader: test.NewFakeReader().WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "foo-tag"),
70+
reader: test.NewFakeReader().WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "", "foo-tag"),
7171
},
7272
args: args{
7373
component: CertManagerImageComponent,
@@ -79,7 +79,7 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
7979
{
8080
name: "image config for cert-manager: images for the cert-manager should be changed",
8181
fields: fields{
82-
reader: test.NewFakeReader().WithImageMeta(CertManagerImageComponent, "foo-repository.io", "foo-tag"),
82+
reader: test.NewFakeReader().WithImageMeta(CertManagerImageComponent, "foo-repository.io", "", "foo-tag"),
8383
},
8484
args: args{
8585
component: CertManagerImageComponent,
@@ -92,8 +92,8 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
9292
name: "image config for cert-manager/cert-manager-cainjector and for cert-manager: images for the cert-manager/cert-manager-cainjector should be changed according to the most specific",
9393
fields: fields{
9494
reader: test.NewFakeReader().
95-
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "foo-tag").
96-
WithImageMeta(CertManagerImageComponent, "bar-repository.io", "bar-tag"),
95+
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "", "foo-tag").
96+
WithImageMeta(CertManagerImageComponent, "bar-repository.io", "", "bar-tag"),
9797
},
9898
args: args{
9999
component: CertManagerImageComponent,
@@ -106,8 +106,8 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
106106
name: "image config for cert-manager/cert-manager-cainjector and for cert-manager: images for the cert-manager/cert-manager-cainjector should be changed according to the most specific (mixed case)",
107107
fields: fields{
108108
reader: test.NewFakeReader().
109-
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "").
110-
WithImageMeta(CertManagerImageComponent, "", "bar-tag"),
109+
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "", "").
110+
WithImageMeta(CertManagerImageComponent, "", "", "bar-tag"),
111111
},
112112
args: args{
113113
component: CertManagerImageComponent,
@@ -120,8 +120,8 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
120120
name: "image config for cert-manager/cert-manager-cainjector and for cert-manager: images for the cert-manager/cert-manager-webhook should be changed according to the most generic",
121121
fields: fields{
122122
reader: test.NewFakeReader().
123-
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "foo-tag").
124-
WithImageMeta(CertManagerImageComponent, "bar-repository.io", "bar-tag"),
123+
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "", "foo-tag").
124+
WithImageMeta(CertManagerImageComponent, "bar-repository.io", "", "bar-tag"),
125125
},
126126
args: args{
127127
component: CertManagerImageComponent,
@@ -133,7 +133,7 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
133133
{
134134
name: "image config for all: images for the cert-manager should be changed",
135135
fields: fields{
136-
reader: test.NewFakeReader().WithImageMeta(allImageConfig, "foo-repository.io", "foo-tag"),
136+
reader: test.NewFakeReader().WithImageMeta(allImageConfig, "foo-repository.io", "", "foo-tag"),
137137
},
138138
args: args{
139139
component: CertManagerImageComponent,
@@ -146,8 +146,8 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
146146
name: "image config for all and for cert-manager: images for the cert-manager should be changed according to the most specific",
147147
fields: fields{
148148
reader: test.NewFakeReader().
149-
WithImageMeta(allImageConfig, "foo-repository.io", "foo-tag").
150-
WithImageMeta(CertManagerImageComponent, "bar-repository.io", "bar-tag"),
149+
WithImageMeta(allImageConfig, "foo-repository.io", "", "foo-tag").
150+
WithImageMeta(CertManagerImageComponent, "bar-repository.io", "", "bar-tag"),
151151
},
152152
args: args{
153153
component: CertManagerImageComponent,
@@ -160,8 +160,8 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
160160
name: "image config for all and for cert-manager: images for the cert-manager should be changed according to the most specific (mixed case)",
161161
fields: fields{
162162
reader: test.NewFakeReader().
163-
WithImageMeta(allImageConfig, "foo-repository.io", "").
164-
WithImageMeta(CertManagerImageComponent, "", "bar-tag"),
163+
WithImageMeta(allImageConfig, "foo-repository.io", "", "").
164+
WithImageMeta(CertManagerImageComponent, "", "", "bar-tag"),
165165
},
166166
args: args{
167167
component: CertManagerImageComponent,
@@ -174,9 +174,9 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
174174
name: "image config for cert-manager/cert-manager-cainjector, for cert-manager and for all: images for the cert-manager/cert-manager-cainjector should be changed according to the most specific",
175175
fields: fields{
176176
reader: test.NewFakeReader().
177-
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "foo-tag").
178-
WithImageMeta(CertManagerImageComponent, "bar-repository.io", "bar-tag").
179-
WithImageMeta(allImageConfig, "baz-repository.io", "baz-tag"),
177+
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "", "foo-tag").
178+
WithImageMeta(CertManagerImageComponent, "bar-repository.io", "", "bar-tag").
179+
WithImageMeta(allImageConfig, "baz-repository.io", "", "baz-tag"),
180180
},
181181
args: args{
182182
component: CertManagerImageComponent,
@@ -189,9 +189,9 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
189189
name: "image config for cert-manager/cert-manager-cainjector, for cert-manager and for all: images for the cert-manager/cert-manager-cainjector should be changed according to the most specific (mixed case)",
190190
fields: fields{
191191
reader: test.NewFakeReader().
192-
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "").
193-
WithImageMeta(CertManagerImageComponent, "", "bar-tag").
194-
WithImageMeta(allImageConfig, "baz-repository.io", "baz-tag"),
192+
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "", "").
193+
WithImageMeta(CertManagerImageComponent, "", "", "bar-tag").
194+
WithImageMeta(allImageConfig, "baz-repository.io", "", "baz-tag"),
195195
},
196196
args: args{
197197
component: CertManagerImageComponent,
@@ -204,9 +204,9 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
204204
name: "image config for cert-manager/cert-manager-cainjector, for cert-manager and for all: images for the cert-manager/cert-manager-webhook should be changed according to the most generic",
205205
fields: fields{
206206
reader: test.NewFakeReader().
207-
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "foo-tag").
208-
WithImageMeta(CertManagerImageComponent, "bar-repository.io", "").
209-
WithImageMeta(allImageConfig, "baz-repository.io", "baz-tag"),
207+
WithImageMeta(fmt.Sprintf("%s/cert-manager-cainjector", CertManagerImageComponent), "foo-repository.io", "", "foo-tag").
208+
WithImageMeta(CertManagerImageComponent, "bar-repository.io", "", "").
209+
WithImageMeta(allImageConfig, "baz-repository.io", "", "baz-tag"),
210210
},
211211
args: args{
212212
component: CertManagerImageComponent,
@@ -230,7 +230,7 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
230230
{
231231
name: "fails if wrong image name",
232232
fields: fields{
233-
reader: test.NewFakeReader().WithImageMeta(allImageConfig, "foo-Repository.io", ""),
233+
reader: test.NewFakeReader().WithImageMeta(allImageConfig, "foo-Repository.io", "", ""),
234234
},
235235
args: args{
236236
component: "any",
@@ -239,6 +239,56 @@ func Test_imageMetaClient_AlterImage(t *testing.T) {
239239
want: "",
240240
wantErr: true,
241241
},
242+
{
243+
name: "image config for cluster-api/cluster-api-controller with name override only: only image name should be changed",
244+
fields: fields{
245+
reader: test.NewFakeReader().WithImageMeta("cluster-api/cluster-api-controller", "", "custom-cluster-api-controller", ""),
246+
},
247+
args: args{
248+
component: "cluster-api",
249+
image: "registry.k8s.io/cluster-api/cluster-api-controller:v1.8.0",
250+
},
251+
want: "registry.k8s.io/cluster-api/custom-cluster-api-controller:v1.8.0",
252+
wantErr: false,
253+
},
254+
{
255+
name: "image config for cluster-api/cluster-api-controller with repository and name override: repository and name should be changed, tag preserved",
256+
fields: fields{
257+
reader: test.NewFakeReader().WithImageMeta("cluster-api/cluster-api-controller", "myorg.io/mirror", "custom-cluster-api-controller", ""),
258+
},
259+
args: args{
260+
component: "cluster-api",
261+
image: "registry.k8s.io/cluster-api/cluster-api-controller:v1.10.6",
262+
},
263+
want: "myorg.io/mirror/custom-cluster-api-controller:v1.10.6",
264+
wantErr: false,
265+
},
266+
{
267+
name: "image config for cluster-api/cluster-api-controller with specific name override and generic repository from all: both should be applied",
268+
fields: fields{
269+
reader: test.NewFakeReader().
270+
WithImageMeta(allImageConfig, "myorg.io/mirror", "", "").
271+
WithImageMeta("cluster-api/cluster-api-controller", "", "custom-cluster-api-controller", ""),
272+
},
273+
args: args{
274+
component: "cluster-api",
275+
image: "registry.k8s.io/cluster-api/cluster-api-controller:v1.10.6",
276+
},
277+
want: "myorg.io/mirror/custom-cluster-api-controller:v1.10.6",
278+
wantErr: false,
279+
},
280+
{
281+
name: "image config for cluster-api/cluster-api-controller with repository, name and tag override: all fields should be changed",
282+
fields: fields{
283+
reader: test.NewFakeReader().WithImageMeta("cluster-api/cluster-api-controller", "myorg.io/mirror", "custom-cluster-api-controller", "v1.5.0"),
284+
},
285+
args: args{
286+
component: "cluster-api",
287+
image: "registry.k8s.io/cluster-api/cluster-api-controller:v1.10.6",
288+
},
289+
want: "myorg.io/mirror/custom-cluster-api-controller:v1.5.0",
290+
wantErr: false,
291+
},
242292
}
243293
for _, tt := range tests {
244294
t.Run(tt.name, func(t *testing.T) {

cmd/clusterctl/internal/test/fake_reader.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type configCertManager struct {
5454
// avoid circular dependencies between pkg/client/config and pkg/internal/test.
5555
type imageMeta struct {
5656
Repository string `json:"repository,omitempty"`
57+
Name string `json:"name,omitempty"`
5758
Tag string `json:"tag,omitempty"`
5859
}
5960

@@ -119,9 +120,10 @@ func (f *FakeReader) WithCertManager(url, version, timeout string) *FakeReader {
119120
return f
120121
}
121122

122-
func (f *FakeReader) WithImageMeta(component, repository, tag string) *FakeReader {
123+
func (f *FakeReader) WithImageMeta(component, repository, name, tag string) *FakeReader {
123124
f.imageMetas[component] = imageMeta{
124125
Repository: repository,
126+
Name: name,
125127
Tag: tag,
126128
}
127129

docs/book/src/clusterctl/configuration.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,33 @@ images:
261261
tag: v1.5.3
262262
```
263263

264+
Additionally, you can override the image name itself. This is useful when images
265+
have been mirrored with different names:
266+
267+
```yaml
268+
images:
269+
all:
270+
repository: myorg.io/local-repo
271+
cluster-api:
272+
name: mirrored-cluster-api-controller
273+
```
274+
275+
This would transform `registry.k8s.io/cluster-api/cluster-api-controller:v1.10.6` into
276+
`myorg.io/local-repo/mirrored-cluster-api-controller:v1.10.6`.
277+
278+
Or you can specify all three fields to completely override the image:
279+
280+
```yaml
281+
images:
282+
cluster-api:
283+
repository: myorg.io/local-repo
284+
name: mirrored-cluster-api-controller
285+
tag: v1.10.6
286+
```
287+
288+
This would transform `registry.k8s.io/cluster-api/cluster-api-controller:v1.8.0` into
289+
`myorg.io/local-repo/mirrored-cluster-api-controller:v1.10.6`, replacing both the image location and version.
290+
264291
## Debugging/Logging
265292

266293
To have more verbose logs you can use the `-v` flag when running the `clusterctl` and set the level of the logging verbose with a positive integer number, ie. `-v 3`.

0 commit comments

Comments
 (0)