Convert image transformer to kyaml.

This commit is contained in:
jregan
2020-07-18 06:53:12 -07:00
parent 46a6bf0bb4
commit ef924a5c9c
8 changed files with 107 additions and 49 deletions

View File

@@ -8,10 +8,10 @@ import (
"regexp"
"strings"
"sigs.k8s.io/kustomize/api/transform"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/api/filters/imagetag"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml"
)
@@ -31,18 +31,18 @@ func (p *ImageTagTransformerPlugin) Config(
func (p *ImageTagTransformerPlugin) Transform(m resmap.ResMap) error {
for _, r := range m.Resources() {
for _, path := range p.FieldSpecs {
if !r.OrgId().IsSelected(&path.Gvk) {
continue
}
err := transform.MutateField(
r.Map(), path.PathSlice(), false, p.mutateImage)
if err != nil {
return err
}
}
// Kept for backward compatibility
if err := p.findAndReplaceImage(r.Map()); err != nil && r.OrgId().Kind != `CustomResourceDefinition` {
// If you're here because someone expected any field containing
// the string "containers" or "initContainers" to get an image
// update (not just spec/template/spec/containers[], etc.) then
// a code change is needed. See api/filters/imagetag/legacy
// for the start of an implementation that won't use an
// allowlist like FsSlice, and instead walks the object looking
// for fields named containers or initContainers.
err := filtersutil.ApplyToJSON(imagetag.Filter{
ImageTag: p.ImageTag,
FsSlice: p.FieldSpecs,
}, r)
if err != nil {
return err
}
}

View File

@@ -11,11 +11,17 @@ import (
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// Filter modifies an "image tag", the value used to specify the
// name, tag, version digest etc. of (docker) container images
// used by a pod template.
type Filter struct {
// imageTag is the tag we want to apply to the inputs
// The name of the image is used as a key, and other fields
// can specify a new name, tag, etc.
ImageTag types.Image `json:"imageTag,omitempty" yaml:"imageTag,omitempty"`
// FsSlice contains the FieldSpecs to locate the namespace field
// FsSlice contains the FieldSpecs to locate an image field,
// e.g. Path: "spec/myContainers[]/image"
FsSlice types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
}
@@ -27,6 +33,12 @@ func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
}
func (f Filter) filter(node *yaml.RNode) (*yaml.RNode, error) {
// FsSlice is an allowlist, not a denyList, so to deny
// something via configuration a new config mechanism is
// needed. Until then, hardcode it.
if f.isOnDenyList(node) {
return node, nil
}
if err := node.PipeE(fsslice.Filter{
FsSlice: f.FsSlice,
SetValue: updateImageTagFn(f.ImageTag),
@@ -36,6 +48,18 @@ func (f Filter) filter(node *yaml.RNode) (*yaml.RNode, error) {
return node, nil
}
func (f Filter) isOnDenyList(node *yaml.RNode) bool {
meta, err := node.GetMeta()
if err != nil {
// A missing 'meta' field will cause problems elsewhere;
// ignore it here to keep the signature simple.
return false
}
// Ignore CRDs
// https://github.com/kubernetes-sigs/kustomize/issues/890
return meta.Kind == `CustomResourceDefinition`
}
func updateImageTagFn(imageTag types.Image) filtersutil.SetFn {
return func(node *yaml.RNode) error {
return node.PipeE(imageTagUpdater{

View File

@@ -36,7 +36,7 @@ metadata:
name: whatever
spec:
containers:
- image: theImageShouldNotChangeInACrd
- image: whatever
`,
filter: Filter{
ImageTag: types.Image{

View File

@@ -4,7 +4,15 @@
package builtinpluginconsts
const (
// imageFieldSpecs is left empty since `containers` and `initContainers`
// of *ANY* kind in *ANY* path are builtin supported in code
imagesFieldSpecs = ``
imagesFieldSpecs = `
images:
- path: spec/containers[]/image
create: true
- path: spec/initContainers[]/image
create: true
- path: spec/template/spec/containers[]/image
create: true
- path: spec/template/spec/initContainers[]/image
create: true
`
)

View File

@@ -173,6 +173,9 @@ spec:
`)
}
// The default configuration recognizes image paths starting
// with "spec", not spec2 or spec3, so the latter two specs won't
// have their image entries changed.
func TestTransfomersImageDefaultConfig(t *testing.T) {
th := kusttest_test.MakeHarness(t)
makeTransfomersImageBase(th)
@@ -212,25 +215,25 @@ spec2:
template:
spec:
containers:
- image: nginx:v2
- image: nginx:v1
name: nginx3
- image: my-nginx:previous
- image: my-nginx:latest
name: nginx4
spec3:
template:
spec:
initContainers:
- image: my-postgres:v3
- image: postgres:alpine-9
name: postgresdb
- image: my-docker@sha256:25a0d4b4
- image: docker:17-git
name: init-docker
- image: myprivaterepohostname:1234/my/image:v1.0.1
- image: myprivaterepohostname:1234/my/image:latest
name: myImage
- image: myprivaterepohostname:1234/my/image:v1.0.1
- image: myprivaterepohostname:1234/my/image
name: myImage2
- image: my-app-image:v1
name: my-app
- image: my-cool-app:latest
- image: gcr.io:8080/my-project/my-cool-app:latest
name: my-cool-app
`)
}
@@ -299,11 +302,11 @@ spec3:
th.WriteF("/app/base/config/custom.yaml", `
images:
- kind: Custom
path: spec/template/spec/myContainers/image
path: spec/template/spec/myContainers[]/image
- kind: Custom
path: spec2/template/spec/myContainers/image
path: spec2/template/spec/myContainers[]/image
- kind: Custom
path: spec3/template/spec/myInitContainers/image
path: spec3/template/spec/myInitContainers[]/image
`)
}

View File

@@ -9,10 +9,10 @@ import (
"regexp"
"strings"
"sigs.k8s.io/kustomize/api/transform"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/api/filters/imagetag"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml"
)
@@ -35,18 +35,18 @@ func (p *plugin) Config(
func (p *plugin) Transform(m resmap.ResMap) error {
for _, r := range m.Resources() {
for _, path := range p.FieldSpecs {
if !r.OrgId().IsSelected(&path.Gvk) {
continue
}
err := transform.MutateField(
r.Map(), path.PathSlice(), false, p.mutateImage)
if err != nil {
return err
}
}
// Kept for backward compatibility
if err := p.findAndReplaceImage(r.Map()); err != nil && r.OrgId().Kind != `CustomResourceDefinition` {
// If you're here because someone expected any field containing
// the string "containers" or "initContainers" to get an image
// update (not just spec/template/spec/containers[], etc.) then
// a code change is needed. See api/filters/imagetag/legacy
// for the start of an implementation that won't use an
// allowlist like FsSlice, and instead walks the object looking
// for fields named containers or initContainers.
err := filtersutil.ApplyToJSON(imagetag.Filter{
ImageTag: p.ImageTag,
FsSlice: p.FieldSpecs,
}, r)
if err != nil {
return err
}
}

View File

@@ -22,6 +22,9 @@ metadata:
imageTag:
name: nginx
newTag: v2
fieldSpecs:
- path: spec/template/spec/containers[]/image
- path: spec/template/spec/initContainers[]/image
`, `
group: apps
apiVersion: v1
@@ -89,6 +92,9 @@ metadata:
imageTag:
name: nginx
newName: busybox
fieldSpecs:
- path: spec/template/spec/containers[]/image
- path: spec/template/spec/initContainers[]/image
`, `
group: apps
apiVersion: v1
@@ -158,6 +164,9 @@ imageTag:
name: nginx
newName: busybox
newTag: v2
fieldSpecs:
- path: spec/template/spec/containers[]/image
- path: spec/template/spec/initContainers[]/image
`, `
group: apps
apiVersion: v1
@@ -226,6 +235,9 @@ metadata:
imageTag:
name: nginx
Digest: sha256:222222222222222222
fieldSpecs:
- path: spec/template/spec/containers[]/image
- path: spec/template/spec/initContainers[]/image
`, `
group: apps
apiVersion: v1
@@ -295,6 +307,9 @@ imageTag:
name: nginx
newName: busybox
Digest: sha256:222222222222222222
fieldSpecs:
- path: spec/template/spec/containers[]/image
- path: spec/template/spec/initContainers[]/image
`, `
group: apps
apiVersion: v1
@@ -363,6 +378,11 @@ metadata:
imageTag:
name: nginx
newTag: v2
fieldSpecs:
- path: spec/template/spec/containers[]/image
create: true
- path: spec/template/spec/initContainers[]/image
create: true
`, `
group: apps
apiVersion: v1
@@ -384,8 +404,8 @@ metadata:
spec:
template:
spec:
containers: null
initContainers: null
containers: []
initContainers: []
`)
}
@@ -402,6 +422,8 @@ metadata:
imageTag:
name: some.registry.io/my-image
newTag: "my-fixed-tag"
fieldSpecs:
- path: spec/template/spec/containers[]/image
`, `
group: apps
apiVersion: v1

View File

@@ -4,6 +4,7 @@ go 1.14
require (
sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/kustomize/kyaml v0.4.1
sigs.k8s.io/yaml v1.2.0
)