diff --git a/cmd/clusterctl/client/config/imagemeta_client.go b/cmd/clusterctl/client/config/imagemeta_client.go index 23654f6f5b1d..421e78522585 100644 --- a/cmd/clusterctl/client/config/imagemeta_client.go +++ b/cmd/clusterctl/client/config/imagemeta_client.go @@ -125,6 +125,9 @@ type imageMeta struct { // repository sets the container registry to pull images from. Repository string `json:"repository,omitempty"` + // Name allows to specify a different name for the image. + Name string `json:"name,omitempty"` + // Tag allows to specify a tag for the images. Tag string `json:"tag,omitempty"` } @@ -135,6 +138,9 @@ func (i *imageMeta) Union(other *imageMeta) { if other.Repository != "" { i.Repository = other.Repository } + if other.Name != "" { + i.Name = other.Name + } if other.Tag != "" { i.Tag = other.Tag } @@ -146,6 +152,9 @@ func (i *imageMeta) ApplyToImage(image container.Image) string { if i.Repository != "" { image.Repository = strings.TrimSuffix(i.Repository, "/") } + if i.Name != "" { + image.Name = i.Name + } if i.Tag != "" { image.Tag = i.Tag } diff --git a/cmd/clusterctl/client/config/imagemeta_client_test.go b/cmd/clusterctl/client/config/imagemeta_client_test.go index 3b383a4b0fcd..7eca1e6a0da0 100644 --- a/cmd/clusterctl/client/config/imagemeta_client_test.go +++ b/cmd/clusterctl/client/config/imagemeta_client_test.go @@ -239,6 +239,56 @@ func Test_imageMetaClient_AlterImage(t *testing.T) { want: "", wantErr: true, }, + { + name: "image config for cluster-api/cluster-api-controller with name override only: only image name should be changed", + fields: fields{ + reader: test.NewFakeReader().WithImageMetaWithName("cluster-api/cluster-api-controller", "", "custom-cluster-api-controller", ""), + }, + args: args{ + component: "cluster-api", + image: "registry.k8s.io/cluster-api/cluster-api-controller:v1.8.0", + }, + want: "registry.k8s.io/cluster-api/custom-cluster-api-controller:v1.8.0", + wantErr: false, + }, + { + name: "image config for cluster-api/cluster-api-controller with repository and name override: repository and name should be changed, tag preserved", + fields: fields{ + reader: test.NewFakeReader().WithImageMetaWithName("cluster-api/cluster-api-controller", "myorg.io/mirror", "custom-cluster-api-controller", ""), + }, + args: args{ + component: "cluster-api", + image: "registry.k8s.io/cluster-api/cluster-api-controller:v1.10.6", + }, + want: "myorg.io/mirror/custom-cluster-api-controller:v1.10.6", + wantErr: false, + }, + { + name: "image config for cluster-api/cluster-api-controller with specific name override and generic repository from all: both should be applied", + fields: fields{ + reader: test.NewFakeReader(). + WithImageMeta(allImageConfig, "myorg.io/mirror", ""). + WithImageMetaWithName("cluster-api/cluster-api-controller", "", "custom-cluster-api-controller", ""), + }, + args: args{ + component: "cluster-api", + image: "registry.k8s.io/cluster-api/cluster-api-controller:v1.10.6", + }, + want: "myorg.io/mirror/custom-cluster-api-controller:v1.10.6", + wantErr: false, + }, + { + name: "image config for cluster-api/cluster-api-controller with repository, name and tag override: all fields should be changed", + fields: fields{ + reader: test.NewFakeReader().WithImageMetaWithName("cluster-api/cluster-api-controller", "myorg.io/mirror", "custom-cluster-api-controller", "v1.5.0"), + }, + args: args{ + component: "cluster-api", + image: "registry.k8s.io/cluster-api/cluster-api-controller:v1.10.6", + }, + want: "myorg.io/mirror/custom-cluster-api-controller:v1.5.0", + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/cmd/clusterctl/internal/test/fake_reader.go b/cmd/clusterctl/internal/test/fake_reader.go index d34fa6821fc2..083289739707 100644 --- a/cmd/clusterctl/internal/test/fake_reader.go +++ b/cmd/clusterctl/internal/test/fake_reader.go @@ -54,6 +54,7 @@ type configCertManager struct { // avoid circular dependencies between pkg/client/config and pkg/internal/test. type imageMeta struct { Repository string `json:"repository,omitempty"` + Name string `json:"name,omitempty"` Tag string `json:"tag,omitempty"` } @@ -120,8 +121,13 @@ func (f *FakeReader) WithCertManager(url, version, timeout string) *FakeReader { } func (f *FakeReader) WithImageMeta(component, repository, tag string) *FakeReader { + return f.WithImageMetaWithName(component, repository, "", tag) +} + +func (f *FakeReader) WithImageMetaWithName(component, repository, name, tag string) *FakeReader { f.imageMetas[component] = imageMeta{ Repository: repository, + Name: name, Tag: tag, } diff --git a/docs/book/src/clusterctl/configuration.md b/docs/book/src/clusterctl/configuration.md index 719c4b9c1fbd..3a3d5a4ff7c8 100644 --- a/docs/book/src/clusterctl/configuration.md +++ b/docs/book/src/clusterctl/configuration.md @@ -261,6 +261,33 @@ images: tag: v1.5.3 ``` +Additionally, you can override the image name itself. This is useful when images +have been mirrored with different names: + +```yaml +images: + all: + repository: myorg.io/local-repo + cluster-api: + name: mirrored-cluster-api-controller +``` + +This would transform `registry.k8s.io/cluster-api/cluster-api-controller:v1.10.6` into +`myorg.io/local-repo/mirrored-cluster-api-controller:v1.10.6`. + +Or you can specify all three fields to completely override the image: + +```yaml +images: + cluster-api: + repository: myorg.io/local-repo + name: mirrored-cluster-api-controller + tag: v1.10.6 +``` + +This would transform `registry.k8s.io/cluster-api/cluster-api-controller:v1.8.0` into +`myorg.io/local-repo/mirrored-cluster-api-controller:v1.10.6`, replacing both the image location and version. + ## Debugging/Logging 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`.