diff --git a/pkg/target/crd_test.go b/pkg/target/crd_test.go index 7bd71083c..6ffa923ba 100644 --- a/pkg/target/crd_test.go +++ b/pkg/target/crd_test.go @@ -320,3 +320,64 @@ spec: action: makehoney `) } + +func TestCrdWithContainers(t *testing.T) { + th := NewKustTestHarness(t, "/app/crd/containers") + th.writeK("/app/crd/containers", ` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - crd.yaml + +images: + - name: test/test + newName: registry.gitlab.com/test + newTag: latest +`) + th.writeF("/app/crd/containers/crd.yaml", ` +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab + shortNames: + - ct + validation: + openAPIV3Schema: + properties: + spec: + containers: + description: Containers allows injecting additional containers + `) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + names: + kind: CronTab + plural: crontabs + shortNames: + - ct + singular: crontab + scope: Namespaced + validation: + openAPIV3Schema: + properties: + spec: + containers: + description: Containers allows injecting additional containers +`) +} diff --git a/pkg/target/transformersimage_test.go b/pkg/target/transformersimage_test.go index 3f12e0cb7..450129274 100644 --- a/pkg/target/transformersimage_test.go +++ b/pkg/target/transformersimage_test.go @@ -233,11 +233,11 @@ spec3: th.writeF("/app/base/config/custom.yaml", ` images: - kind: Custom - path: spec/template/spec/myContainers + path: spec/template/spec/myContainers/image - kind: Custom - path: spec2/template/spec/myContainers + path: spec2/template/spec/myContainers/image - kind: Custom - path: spec3/template/spec/myInitContainers + path: spec3/template/spec/myInitContainers/image `) } func TestTransfomersImageCustomConfig(t *testing.T) { @@ -283,3 +283,56 @@ spec3: name: my-cool-app `) } + +func makeTransfomersImageKnativeBase(th *KustTestHarness) { + th.writeK("/app/base", ` +resources: +- knative.yaml +configurations: +- config/knative.yaml +images: +- name: solsa-echo + newTag: foo +`) + th.writeF("/app/base/knative.yaml", ` +apiVersion: serving.knative.dev/v1alpha1 +kind: Service +metadata: + name: echo +spec: + runLatest: + configuration: + revisionTemplate: + spec: + container: + image: solsa-echo +`) + th.writeF("/app/base/config/knative.yaml", ` +images: +- path: spec/runLatest/configuration/revisionTemplate/spec/container/image + apiVersion: serving.knative.dev/v1alpha1 + kind: Service +`) +} + +func TestTransfomersImageKnativeConfig(t *testing.T) { + th := NewKustTestHarness(t, "/app/base") + makeTransfomersImageKnativeBase(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: serving.knative.dev/v1alpha1 +kind: Service +metadata: + name: echo +spec: + runLatest: + configuration: + revisionTemplate: + spec: + container: + image: solsa-echo:foo +`) +} diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go index ef7f28d74..e92c78fc6 100644 --- a/pkg/transformers/image.go +++ b/pkg/transformers/image.go @@ -50,20 +50,44 @@ func (pt *imageTransformer) Transform(m resmap.ResMap) error { if !id.Gvk().IsSelected(&path.Gvk) { continue } - err := mutateField(objMap, path.PathSlice(), false, pt.updateContainers) + err := mutateField(objMap, path.PathSlice(), false, pt.mutateImage) if err != nil { return err } } - // Keep for backward compatibility - err := pt.findAndReplaceImage(objMap) - if err != nil { + // Kept for backward compatibility + if err := pt.findAndReplaceImage(objMap); err != nil && id.Gvk().Kind != `CustomResourceDefinition` { return err } } return nil } +func (pt *imageTransformer) mutateImage(in interface{}) (interface{}, error) { + image, ok := in.(string) + if !ok { + return nil, fmt.Errorf("image path is not of type string but %T", in) + } + + for _, img := range pt.images { + if !isImageMatched(image, img.Name) { + continue + } + name, tag := split(image) + if img.NewName != "" { + name = img.NewName + } + if img.NewTag != "" { + tag = ":" + img.NewTag + } + if img.Digest != "" { + tag = "@" + img.Digest + } + return name + tag, nil + } + return image, nil +} + /* findAndReplaceImage replaces the image name and tags inside one object It searches the object for container session @@ -76,8 +100,7 @@ func (pt *imageTransformer) findAndReplaceImage(obj map[string]interface{}) erro for _, path := range paths { containers, found := obj[path] if found { - _, err := pt.updateContainers(containers) - if err != nil { + if _, err := pt.updateContainers(containers); err != nil { return err } updated = true @@ -106,17 +129,11 @@ func (pt *imageTransformer) updateContainers(in interface{}) (interface{}, error if !isImageMatched(imageName, img.Name) { continue } - name, tag := split(imageName) - if img.NewName != "" { - name = img.NewName + newImage, err := pt.mutateImage(imageName) + if err != nil { + return nil, err } - if img.NewTag != "" { - tag = ":" + img.NewTag - } - if img.Digest != "" { - tag = "@" + img.Digest - } - container["image"] = name + tag + container["image"] = newImage break } }