From 67a5f6d68f9f5f21f59b7a939bb4d66c2c779aef Mon Sep 17 00:00:00 2001 From: Natasha Sarkar Date: Wed, 15 Sep 2021 09:40:01 -0700 Subject: [PATCH] support krm spec v1 and legacy path, index, and id annotations --- api/filters/refvar/refvar_test.go | 2 + api/resource/resource.go | 3 + cmd/config/internal/commands/annotate_test.go | 48 +++ cmd/config/internal/commands/cat.go | 3 +- cmd/config/internal/commands/cmdwrap_test.go | 18 + cmd/config/internal/commands/grep_test.go | 14 + cmd/config/internal/commands/sink.go | 2 +- cmd/config/internal/commands/source_test.go | 16 +- kyaml/fn/framework/selector_test.go | 2 + kyaml/fn/runtime/container/container_test.go | 4 + kyaml/fn/runtime/exec/exec_test.go | 2 + kyaml/fn/runtime/runtimeutil/runtimeutil.go | 47 ++- .../runtime/runtimeutil/runtimeutil_test.go | 37 +- kyaml/fn/runtime/starlark/example_test.go | 12 +- kyaml/fn/runtime/starlark/starlark_test.go | 12 + kyaml/inpututil/inpututil.go | 12 +- kyaml/kio/byteio_reader.go | 1 + kyaml/kio/byteio_reader_test.go | 8 +- kyaml/kio/byteio_readwriter_test.go | 2 + kyaml/kio/byteio_writer.go | 4 + kyaml/kio/byteio_writer_test.go | 109 +++--- kyaml/kio/filters/filters.go | 11 + kyaml/kio/filters/filters_test.go | 12 + kyaml/kio/filters/merge3.go | 6 + kyaml/kio/kio.go | 211 +++++++++++ kyaml/kio/kio_test.go | 346 +++++++++++++++++- kyaml/kio/kioutil/kioutil.go | 75 +++- kyaml/kio/kioutil/kioutil_test.go | 15 + kyaml/kio/pkgio_reader.go | 1 + kyaml/kio/pkgio_reader_test.go | 52 ++- kyaml/kio/pkgio_writer.go | 1 + kyaml/kio/pkgio_writer_test.go | 20 +- kyaml/kio/tree.go | 7 +- kyaml/runfn/runfn.go | 13 +- kyaml/setters2/set_test.go | 14 + .../v1/starlarkmixer/StarlarkMixer_test.go | 3 + 36 files changed, 1053 insertions(+), 92 deletions(-) diff --git a/api/filters/refvar/refvar_test.go b/api/filters/refvar/refvar_test.go index a350b1ab8..3fd3eddf0 100644 --- a/api/filters/refvar/refvar_test.go +++ b/api/filters/refvar/refvar_test.go @@ -250,6 +250,7 @@ metadata: name: dep annotations: config.kubernetes.io/index: '0' + internal.config.kubernetes.io/index: '0' data: slice: - false @@ -276,6 +277,7 @@ metadata: name: dep annotations: config.kubernetes.io/index: '0' + internal.config.kubernetes.io/index: '0' data: 1: str : invalid map key: value='1', tag='` + yaml.NodeTagInt + `'`, diff --git a/api/resource/resource.go b/api/resource/resource.go index 3778f613a..9e1e753fb 100644 --- a/api/resource/resource.go +++ b/api/resource/resource.go @@ -41,6 +41,9 @@ var BuildAnnotations = []string{ kioutil.PathAnnotation, kioutil.IndexAnnotation, kioutil.SeqIndentAnnotation, + + kioutil.LegacyPathAnnotation, + kioutil.LegacyIndexAnnotation, } func (r *Resource) ResetRNode(incoming *Resource) { diff --git a/cmd/config/internal/commands/annotate_test.go b/cmd/config/internal/commands/annotate_test.go index f897e95f5..85ba1e62b 100644 --- a/cmd/config/internal/commands/annotate_test.go +++ b/cmd/config/internal/commands/annotate_test.go @@ -164,6 +164,8 @@ metadata: a: 'b' config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f1.yaml' spec: replicas: 1 --- @@ -175,6 +177,8 @@ metadata: a: 'b' config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f1.yaml' spec: selector: app: nginx @@ -191,6 +195,8 @@ metadata: a: 'b' config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: bar spec: replicas: 3 @@ -206,6 +212,8 @@ metadata: a: 'b' config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: foo spec: replicas: 3 @@ -222,6 +230,8 @@ metadata: c: 'd' config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f1.yaml' spec: replicas: 1 --- @@ -234,6 +244,8 @@ metadata: c: 'd' config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f1.yaml' spec: selector: app: nginx @@ -251,6 +263,8 @@ metadata: c: 'd' config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: bar spec: replicas: 3 @@ -267,6 +281,8 @@ metadata: c: 'd' config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: foo spec: replicas: 3 @@ -281,6 +297,8 @@ metadata: app: nginx2 config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f1.yaml' spec: replicas: 1 --- @@ -292,6 +310,8 @@ metadata: a: 'b' config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f1.yaml' spec: selector: app: nginx @@ -307,6 +327,8 @@ metadata: config.kubernetes.io/local-config: "true" config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: bar spec: replicas: 3 @@ -321,6 +343,8 @@ metadata: app: nginx config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: foo spec: replicas: 3 @@ -335,6 +359,8 @@ metadata: app: nginx2 config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f1.yaml' spec: replicas: 1 --- @@ -345,6 +371,8 @@ metadata: app: nginx config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f1.yaml' spec: selector: app: nginx @@ -361,6 +389,8 @@ metadata: a: 'b' config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: bar spec: replicas: 3 @@ -375,6 +405,8 @@ metadata: app: nginx config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: foo spec: replicas: 3 @@ -389,6 +421,8 @@ metadata: app: nginx2 config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f1.yaml' spec: replicas: 1 --- @@ -399,6 +433,8 @@ metadata: app: nginx config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f1.yaml' spec: selector: app: nginx @@ -414,6 +450,8 @@ metadata: config.kubernetes.io/local-config: "true" config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: bar spec: replicas: 3 @@ -429,6 +467,8 @@ metadata: a: 'b' config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: foo spec: replicas: 3 @@ -443,6 +483,8 @@ metadata: app: nginx2 config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f1.yaml' spec: replicas: 1 --- @@ -453,6 +495,8 @@ metadata: app: nginx config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f1.yaml' spec: selector: app: nginx @@ -469,6 +513,8 @@ metadata: a: 'b' config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: bar spec: replicas: 3 @@ -483,6 +529,8 @@ metadata: app: nginx config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f2.yaml' namespace: foo spec: replicas: 3 diff --git a/cmd/config/internal/commands/cat.go b/cmd/config/internal/commands/cat.go index b1ae1ecbf..62e8f3d96 100644 --- a/cmd/config/internal/commands/cat.go +++ b/cmd/config/internal/commands/cat.go @@ -17,6 +17,7 @@ import ( "sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio/filters" + "sigs.k8s.io/kustomize/kyaml/kio/kioutil" "sigs.k8s.io/kustomize/kyaml/yaml" ) @@ -182,7 +183,7 @@ func (r *CatRunner) out(w io.Writer) ([]kio.Writer, error) { // remove this annotation explicitly, the ByteWriter won't clear it by // default because it doesn't set it - clear := []string{"config.kubernetes.io/path"} + clear := []string{kioutil.LegacyPathAnnotation, kioutil.PathAnnotation} if r.KeepAnnotations { clear = nil } diff --git a/cmd/config/internal/commands/cmdwrap_test.go b/cmd/config/internal/commands/cmdwrap_test.go index fb4ead8dd..4b2e689bb 100644 --- a/cmd/config/internal/commands/cmdwrap_test.go +++ b/cmd/config/internal/commands/cmdwrap_test.go @@ -81,6 +81,8 @@ items: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'config/test_deployment.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'config/test_deployment.yaml' spec: replicas: 11 selector: @@ -112,6 +114,8 @@ items: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'config/test_service.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'config/test_service.yaml' spec: selector: name: test @@ -136,6 +140,8 @@ items: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'config/test_deployment.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'config/test_deployment.yaml' spec: replicas: 11 selector: @@ -164,6 +170,8 @@ items: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'config/test_service.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'config/test_service.yaml' spec: selector: name: test @@ -186,6 +194,8 @@ items: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'config/mysql-deployment_deployment.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'config/mysql-deployment_deployment.yaml' spec: replicas: 3 template: @@ -201,6 +211,8 @@ items: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'config/nosetters-deployment_deployment.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'config/nosetters-deployment_deployment.yaml' spec: replicas: 4 template: @@ -216,6 +228,8 @@ items: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'config/storage-deployment_deployment.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'config/storage-deployment_deployment.yaml' spec: replicas: 4 template: @@ -233,6 +247,8 @@ items: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'config/test_deployment.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'config/test_deployment.yaml' spec: replicas: 11 selector: @@ -264,6 +280,8 @@ items: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'config/test_service.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'config/test_service.yaml' spec: selector: name: test diff --git a/cmd/config/internal/commands/grep_test.go b/cmd/config/internal/commands/grep_test.go index 0c3ac5435..4667cc3e7 100644 --- a/cmd/config/internal/commands/grep_test.go +++ b/cmd/config/internal/commands/grep_test.go @@ -79,6 +79,8 @@ metadata: app: nginx2 config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f1.yaml' spec: replicas: 1 --- @@ -89,6 +91,8 @@ metadata: app: nginx config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f1.yaml' spec: selector: app: nginx @@ -146,6 +150,7 @@ metadata: annotations: app: nginx2 config.kubernetes.io/index: '0' + internal.config.kubernetes.io/index: '0' spec: replicas: 1 --- @@ -155,6 +160,7 @@ metadata: annotations: app: nginx config.kubernetes.io/index: '1' + internal.config.kubernetes.io/index: '1' spec: selector: app: nginx @@ -295,6 +301,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'deployment.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'deployment.yaml' spec: replicas: 3 template: @@ -314,6 +322,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'deployment.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'deployment.yaml' spec: replicas: 4 template: @@ -339,6 +349,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'deployment.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'deployment.yaml' spec: replicas: 3 template: @@ -364,6 +376,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'deployment.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'deployment.yaml' spec: replicas: 4 template: diff --git a/cmd/config/internal/commands/sink.go b/cmd/config/internal/commands/sink.go index 9c2c6cd13..915958212 100644 --- a/cmd/config/internal/commands/sink.go +++ b/cmd/config/internal/commands/sink.go @@ -43,7 +43,7 @@ func (r *SinkRunner) runE(c *cobra.Command, args []string) error { } else { outputs = []kio.Writer{&kio.ByteWriter{ Writer: c.OutOrStdout(), - ClearAnnotations: []string{kioutil.PathAnnotation}}, + ClearAnnotations: []string{kioutil.PathAnnotation, kioutil.LegacyPathAnnotation}}, } } diff --git a/cmd/config/internal/commands/source_test.go b/cmd/config/internal/commands/source_test.go index 1fcad88d4..dd779d7e2 100644 --- a/cmd/config/internal/commands/source_test.go +++ b/cmd/config/internal/commands/source_test.go @@ -93,6 +93,8 @@ items: app: nginx2 config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f1.yaml' spec: replicas: 1 - kind: Service @@ -102,6 +104,8 @@ items: app: nginx config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f1.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f1.yaml' spec: selector: app: nginx @@ -116,6 +120,8 @@ items: config.kubernetes.io/local-config: "true" config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'f2.yaml' spec: replicas: 3 - apiVersion: apps/v1 @@ -128,6 +134,8 @@ items: app: nginx config.kubernetes.io/index: '1' config.kubernetes.io/path: 'f2.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'f2.yaml' spec: replicas: 3 `, b.String()) { @@ -194,8 +202,8 @@ func TestSourceCommandJSON(t *testing.T) { if !assert.Equal(t, `apiVersion: config.kubernetes.io/v1alpha1 kind: ResourceList items: -- {"kind": "Deployment", "metadata": {"labels": {"app": "nginx2"}, "name": "foo", "annotations": {"app": "nginx2", config.kubernetes.io/index: '0', config.kubernetes.io/path: 'f1.json'}}, "spec": {"replicas": 1}} -- {"apiVersion": "v1", "kind": "Abstraction", "metadata": {"name": "foo", "annotations": {"config.kubernetes.io/function": "container:\n image: gcr.io/example/reconciler:v1\n", "config.kubernetes.io/local-config": "true", config.kubernetes.io/index: '0', config.kubernetes.io/path: 'f2.json'}}, "spec": {"replicas": 3}} +- {"kind": "Deployment", "metadata": {"labels": {"app": "nginx2"}, "name": "foo", "annotations": {"app": "nginx2", config.kubernetes.io/index: '0', config.kubernetes.io/path: 'f1.json', internal.config.kubernetes.io/index: '0', internal.config.kubernetes.io/path: 'f1.json'}}, "spec": {"replicas": 1}} +- {"apiVersion": "v1", "kind": "Abstraction", "metadata": {"name": "foo", "annotations": {"config.kubernetes.io/function": "container:\n image: gcr.io/example/reconciler:v1\n", "config.kubernetes.io/local-config": "true", config.kubernetes.io/index: '0', config.kubernetes.io/path: 'f2.json', internal.config.kubernetes.io/index: '0', internal.config.kubernetes.io/path: 'f2.json'}}, "spec": {"replicas": 3}} `, b.String()) { return } @@ -249,6 +257,7 @@ items: annotations: app: nginx2 config.kubernetes.io/index: '0' + internal.config.kubernetes.io/index: '0' spec: replicas: 1 - kind: Service @@ -257,6 +266,7 @@ items: annotations: app: nginx config.kubernetes.io/index: '1' + internal.config.kubernetes.io/index: '1' spec: selector: app: nginx @@ -302,7 +312,7 @@ func TestSourceCommandJSON_Stdin(t *testing.T) { if !assert.Equal(t, `apiVersion: config.kubernetes.io/v1alpha1 kind: ResourceList items: -- {"kind": "Deployment", "metadata": {"labels": {"app": "nginx2"}, "name": "foo", "annotations": {"app": "nginx2", config.kubernetes.io/index: '0'}}, "spec": {"replicas": 1}} +- {"kind": "Deployment", "metadata": {"labels": {"app": "nginx2"}, "name": "foo", "annotations": {"app": "nginx2", config.kubernetes.io/index: '0', internal.config.kubernetes.io/index: '0'}}, "spec": {"replicas": 1}} `, out.String()) { return } diff --git a/kyaml/fn/framework/selector_test.go b/kyaml/fn/framework/selector_test.go index 208a9161a..42a132ecb 100644 --- a/kyaml/fn/framework/selector_test.go +++ b/kyaml/fn/framework/selector_test.go @@ -128,6 +128,7 @@ metadata: annotations: key: foo-a config.kubernetes.io/index: '0' + internal.config.kubernetes.io/index: '0' labels: key: foo-l ` @@ -141,6 +142,7 @@ metadata: annotations: key: bar-a config.kubernetes.io/index: '1' + internal.config.kubernetes.io/index: '1' labels: key: bar-l ` diff --git a/kyaml/fn/runtime/container/container_test.go b/kyaml/fn/runtime/container/container_test.go index 53cb2b784..3774723d6 100644 --- a/kyaml/fn/runtime/container/container_test.go +++ b/kyaml/fn/runtime/container/container_test.go @@ -194,6 +194,8 @@ metadata: name: deployment-foo annotations: config.kubernetes.io/index: '0' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'statefulset_deployment-foo.yaml' config.kubernetes.io/path: 'statefulset_deployment-foo.yaml' --- apiVersion: v1 @@ -202,6 +204,8 @@ metadata: name: service-foo annotations: config.kubernetes.io/index: '1' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'service_service-foo.yaml' config.kubernetes.io/path: 'service_service-foo.yaml' `, b.String()) { t.FailNow() diff --git a/kyaml/fn/runtime/exec/exec_test.go b/kyaml/fn/runtime/exec/exec_test.go index 415c98351..1e9ff2d70 100644 --- a/kyaml/fn/runtime/exec/exec_test.go +++ b/kyaml/fn/runtime/exec/exec_test.go @@ -43,6 +43,7 @@ kind: StatefulSet metadata: name: deployment-foo annotations: + internal.config.kubernetes.io/path: 'statefulset_deployment-foo.yaml' config.kubernetes.io/path: 'statefulset_deployment-foo.yaml' `, `apiVersion: v1 @@ -50,6 +51,7 @@ kind: Service metadata: name: service-foo annotations: + internal.config.kubernetes.io/path: 'service_service-foo.yaml' config.kubernetes.io/path: 'service_service-foo.yaml' `, }, diff --git a/kyaml/fn/runtime/runtimeutil/runtimeutil.go b/kyaml/fn/runtime/runtimeutil/runtimeutil.go index f3f54606e..ae6fd93ba 100644 --- a/kyaml/fn/runtime/runtimeutil/runtimeutil.go +++ b/kyaml/fn/runtime/runtimeutil/runtimeutil.go @@ -66,9 +66,14 @@ func (c *FunctionFilter) getFunctionScope() (string, error) { if err != nil { return "", errors.Wrap(err) } - p, found := m.Annotations[kioutil.PathAnnotation] + var p string + var found bool + p, found = m.Annotations[kioutil.PathAnnotation] if !found { - return "", nil + p, found = m.Annotations[kioutil.LegacyPathAnnotation] + if !found { + return "", nil + } } functionDir := path.Clean(path.Dir(p)) @@ -101,12 +106,17 @@ func (c *FunctionFilter) scope(dir string, nodes []*yaml.RNode) ([]*yaml.RNode, if err != nil { return nil, nil, err } - p, found := m.Annotations[kioutil.PathAnnotation] + var p string + var found bool + p, found = m.Annotations[kioutil.PathAnnotation] if !found { - // this Resource isn't scoped under the function -- don't know where it came from - // consider it out of scope - saved = append(saved, nodes[i]) - continue + p, found = m.Annotations[kioutil.LegacyPathAnnotation] + if !found { + // this Resource isn't scoped under the function -- don't know where it came from + // consider it out of scope + saved = append(saved, nodes[i]) + continue + } } resourceDir := path.Clean(path.Dir(p)) @@ -193,8 +203,6 @@ func (c *FunctionFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { return append(output, saved...), nil } -const idAnnotation = "config.k8s.io/id" - func (c *FunctionFilter) setIds(nodes []*yaml.RNode) error { // set the id on each node to map inputs to outputs var id int @@ -202,7 +210,11 @@ func (c *FunctionFilter) setIds(nodes []*yaml.RNode) error { for i := range nodes { id++ idStr := fmt.Sprintf("%v", id) - err := nodes[i].PipeE(yaml.SetAnnotation(idAnnotation, idStr)) + err := nodes[i].PipeE(yaml.SetAnnotation(kioutil.IdAnnotation, idStr)) + if err != nil { + return errors.Wrap(err) + } + err = nodes[i].PipeE(yaml.SetAnnotation(kioutil.LegacyIdAnnotation, idStr)) if err != nil { return errors.Wrap(err) } @@ -214,12 +226,18 @@ func (c *FunctionFilter) setIds(nodes []*yaml.RNode) error { func (c *FunctionFilter) copyCommentsAndSyncOrder(nodes []*yaml.RNode) error { for i := range nodes { node := nodes[i] - anID, err := node.Pipe(yaml.GetAnnotation(idAnnotation)) + anID, err := node.Pipe(yaml.GetAnnotation(kioutil.IdAnnotation)) if err != nil { return errors.Wrap(err) } if anID == nil { - continue + anID, err = node.Pipe(yaml.GetAnnotation(kioutil.LegacyIdAnnotation)) + if err != nil { + return errors.Wrap(err) + } + if anID == nil { + continue + } } var in *yaml.RNode @@ -233,7 +251,10 @@ func (c *FunctionFilter) copyCommentsAndSyncOrder(nodes []*yaml.RNode) error { if err := order.SyncOrder(in, node); err != nil { return errors.Wrap(err) } - if err := node.PipeE(yaml.ClearAnnotation(idAnnotation)); err != nil { + if err := node.PipeE(yaml.ClearAnnotation(kioutil.IdAnnotation)); err != nil { + return errors.Wrap(err) + } + if err := node.PipeE(yaml.ClearAnnotation(kioutil.LegacyIdAnnotation)); err != nil { return errors.Wrap(err) } } diff --git a/kyaml/fn/runtime/runtimeutil/runtimeutil_test.go b/kyaml/fn/runtime/runtimeutil/runtimeutil_test.go index 862d9c4e8..b5bb651bc 100644 --- a/kyaml/fn/runtime/runtimeutil/runtimeutil_test.go +++ b/kyaml/fn/runtime/runtimeutil/runtimeutil_test.go @@ -82,6 +82,7 @@ kind: Deployment metadata: name: deployment-foo annotations: + internal.config.kubernetes.io/path: 'deployment_deployment-foo.yaml' config.kubernetes.io/path: 'deployment_deployment-foo.yaml' `, ` @@ -90,6 +91,7 @@ kind: Service metadata: name: service-foo annotations: + internal.config.kubernetes.io/path: 'service_service-foo.yaml' config.kubernetes.io/path: 'service_service-foo.yaml' `, }, @@ -123,6 +125,7 @@ kind: Deployment metadata: name: deployment-foo annotations: + internal.config.kubernetes.io/path: 'deployment_deployment-foo.yaml' config.kubernetes.io/path: 'deployment_deployment-foo.yaml' `, ` @@ -132,6 +135,7 @@ metadata: name: service-foo annotations: config.kubernetes.io/path: 'foo.yaml' + internal.config.kubernetes.io/path: 'foo.yaml' `, }, }, @@ -180,6 +184,7 @@ metadata: name: service-foo annotations: config.kubernetes.io/path: 'foo.yaml' + internal.config.kubernetes.io/path: 'foo.yaml' `, ` apiVersion: v1 @@ -188,6 +193,7 @@ metadata: name: configmap-foo annotations: config.kubernetes.io/path: 'foo.yaml' + internal.config.kubernetes.io/path: 'foo.yaml' `, }, }, @@ -235,6 +241,7 @@ kind: Deployment metadata: name: deployment-foo annotations: + internal.config.kubernetes.io/path: 'deployment_deployment-foo.yaml' config.kubernetes.io/path: 'deployment_deployment-foo.yaml' `, ` apiVersion: v1 @@ -242,6 +249,7 @@ kind: Service metadata: name: service-foo annotations: + internal.config.kubernetes.io/path: 'service_service-foo.yaml' config.kubernetes.io/path: 'service_service-foo.yaml' `, }, @@ -393,6 +401,7 @@ kind: Deployment metadata: name: deployment-foo annotations: + internal.config.kubernetes.io/path: 'deployment_deployment-foo.yaml' config.kubernetes.io/path: 'deployment_deployment-foo.yaml' `, ` apiVersion: v1 @@ -400,6 +409,7 @@ kind: Service metadata: name: service-foo annotations: + internal.config.kubernetes.io/path: 'service_service-foo.yaml' config.kubernetes.io/path: 'service_service-foo.yaml' `, }, @@ -486,6 +496,7 @@ items: name: service-foo annotations: config.kubernetes.io/path: 'foo/bar/s.yaml' + internal.config.kubernetes.io/id: '1' config.k8s.io/id: '1' functionConfig: apiVersion: example.com/v1 @@ -505,7 +516,7 @@ items: annotations: config.kubernetes.io/path: 'foo/bar/s.yaml' new: annotation - config.k8s.io/id: '1' + internal.config.kubernetes.io/id: '1' functionConfig: apiVersion: example.com/v1 kind: Example @@ -551,6 +562,7 @@ metadata: annotations: config.kubernetes.io/path: 'foo/bar/s.yaml' new: annotation + internal.config.kubernetes.io/path: 'foo/bar/s.yaml' `, ` apiVersion: apps/v1 kind: Deployment @@ -575,6 +587,7 @@ items: name: service-foo annotations: config.kubernetes.io/path: 'foo/bar/s.yaml' + internal.config.kubernetes.io/id: '1' config.k8s.io/id: '1' functionConfig: apiVersion: example.com/v1 @@ -594,7 +607,7 @@ items: annotations: config.kubernetes.io/path: 'foo/bar/s.yaml' new: annotation - config.k8s.io/id: '1' + internal.config.kubernetes.io/id: '1' functionConfig: apiVersion: example.com/v1 kind: Example @@ -638,6 +651,7 @@ metadata: annotations: config.kubernetes.io/path: 'foo/bar/s.yaml' new: annotation + internal.config.kubernetes.io/path: 'foo/bar/s.yaml' `, ` apiVersion: apps/v1 kind: Deployment @@ -661,6 +675,7 @@ items: name: deployment-foo annotations: config.kubernetes.io/path: 'baz/bar/d.yaml' + internal.config.kubernetes.io/id: '1' config.k8s.io/id: '1' - apiVersion: v1 kind: Service @@ -668,6 +683,7 @@ items: name: service-foo annotations: config.kubernetes.io/path: 'foo/bar/s.yaml' + internal.config.kubernetes.io/id: '2' config.k8s.io/id: '2' functionConfig: apiVersion: example.com/v1 @@ -686,7 +702,7 @@ items: name: deployment-foo annotations: config.kubernetes.io/path: 'baz/bar/d.yaml' - config.k8s.io/id: '1' + internal.config.kubernetes.io/id: '1' - apiVersion: v1 kind: Service metadata: @@ -737,6 +753,7 @@ metadata: name: deployment-foo annotations: config.kubernetes.io/path: 'baz/bar/d.yaml' + internal.config.kubernetes.io/path: 'baz/bar/d.yaml' `, ` apiVersion: v1 kind: Service @@ -745,6 +762,7 @@ metadata: annotations: config.kubernetes.io/path: 'foo/bar/s.yaml' new: annotation + internal.config.kubernetes.io/path: 'foo/bar/s.yaml' `, }, }, @@ -831,6 +849,7 @@ items: name: service-foo annotations: config.kubernetes.io/path: 'foo/bar/s.yaml' + internal.config.kubernetes.io/id: '1' config.k8s.io/id: '1' functionConfig: apiVersion: example.com/v1 @@ -849,8 +868,9 @@ items: name: service-foo annotations: config.kubernetes.io/path: 'foo/bar/s.yaml' - config.k8s.io/id: '1' + internal.config.kubernetes.io/id: '1' new: annotation + internal.config.kubernetes.io/path: 'foo/bar/s.yaml' functionConfig: apiVersion: example.com/v1 kind: Example @@ -896,6 +916,7 @@ metadata: annotations: config.kubernetes.io/path: 'foo/bar/s.yaml' new: annotation + internal.config.kubernetes.io/path: 'foo/bar/s.yaml' `, ` apiVersion: apps/v1 kind: Deployment @@ -919,6 +940,7 @@ items: name: deployment-foo annotations: config.kubernetes.io/path: 'foo/b.yaml' + internal.config.kubernetes.io/id: '1' config.k8s.io/id: '1' - apiVersion: v1 kind: Service @@ -926,6 +948,7 @@ items: name: service-foo # name comment annotations: config.kubernetes.io/path: 'foo/a.yaml' + internal.config.kubernetes.io/id: '2' config.k8s.io/id: '2' functionConfig: apiVersion: example.com/v1 @@ -945,14 +968,14 @@ items: name: deployment-foo annotations: config.kubernetes.io/path: 'foo/b.yaml' - config.k8s.io/id: '1' + internal.config.kubernetes.io/id: '1' - apiVersion: v1 kind: Service metadata: name: service-foo annotations: config.kubernetes.io/path: 'foo/a.yaml' - config.k8s.io/id: '2' + internal.config.kubernetes.io/id: '2' new: annotation functionConfig: apiVersion: example.com/v1 @@ -996,6 +1019,7 @@ metadata: name: deployment-foo annotations: config.kubernetes.io/path: 'foo/b.yaml' + internal.config.kubernetes.io/path: 'foo/b.yaml' `, ` apiVersion: v1 kind: Service @@ -1004,6 +1028,7 @@ metadata: annotations: config.kubernetes.io/path: 'foo/a.yaml' new: annotation + internal.config.kubernetes.io/path: 'foo/a.yaml' `, }, }, diff --git a/kyaml/fn/runtime/starlark/example_test.go b/kyaml/fn/runtime/starlark/example_test.go index cfb21a90e..42104e627 100644 --- a/kyaml/fn/runtime/starlark/example_test.go +++ b/kyaml/fn/runtime/starlark/example_test.go @@ -14,6 +14,7 @@ import ( "sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil" "sigs.k8s.io/kustomize/kyaml/fn/runtime/starlark" "sigs.k8s.io/kustomize/kyaml/kio" + "sigs.k8s.io/kustomize/kyaml/kio/kioutil" "sigs.k8s.io/kustomize/kyaml/yaml" ) @@ -76,6 +77,7 @@ run(ctx.resource_list["items"]) // name: deployment-1 // annotations: // foo: bar + // internal.config.kubernetes.io/path: 'deployment_deployment-1.yaml' // config.kubernetes.io/path: 'deployment_deployment-1.yaml' // spec: // template: @@ -90,6 +92,7 @@ run(ctx.resource_list["items"]) // name: deployment-2 // annotations: // foo: bar + // internal.config.kubernetes.io/path: 'deployment_deployment-2.yaml' // config.kubernetes.io/path: 'deployment_deployment-2.yaml' // spec: // template: @@ -168,6 +171,7 @@ run(ctx.resource_list["items"], ctx.resource_list["functionConfig"]["spec"]["val // name: deployment-1 // annotations: // foo: hello world + // internal.config.kubernetes.io/path: 'deployment_deployment-1.yaml' // config.kubernetes.io/path: 'deployment_deployment-1.yaml' // spec: // template: @@ -182,6 +186,7 @@ run(ctx.resource_list["items"], ctx.resource_list["functionConfig"]["spec"]["val // name: deployment-2 // annotations: // foo: hello world + // internal.config.kubernetes.io/path: 'deployment_deployment-2.yaml' // config.kubernetes.io/path: 'deployment_deployment-2.yaml' // spec: // template: @@ -257,8 +262,11 @@ run(ctx.resource_list["items"]) Inputs: []kio.Reader{&kio.LocalPackageReader{PackagePath: d}}, Filters: []kio.Filter{fltr}, Outputs: []kio.Writer{&kio.ByteWriter{ - Writer: output, - ClearAnnotations: []string{"config.kubernetes.io/path"}, + Writer: output, + ClearAnnotations: []string{ + kioutil.PathAnnotation, + kioutil.LegacyPathAnnotation, + }, }}}.Execute() if err != nil { log.Println(err) diff --git a/kyaml/fn/runtime/starlark/starlark_test.go b/kyaml/fn/runtime/starlark/starlark_test.go index d0fc57eb4..a07c016a8 100644 --- a/kyaml/fn/runtime/starlark/starlark_test.go +++ b/kyaml/fn/runtime/starlark/starlark_test.go @@ -56,6 +56,7 @@ metadata: name: nginx-deployment annotations: foo: bar + internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' spec: template: @@ -96,6 +97,7 @@ metadata: name: nginx-deployment annotations: foo: annotation-value + internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' spec: template: @@ -135,6 +137,7 @@ metadata: name: nginx-deployment annotations: foo: Deployment enables declarative updates for Pods and ReplicaSets. + internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' spec: template: @@ -177,6 +180,7 @@ metadata: name: nginx-deployment annotations: foo: bar + internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' spec: template: @@ -218,6 +222,7 @@ kind: Deployment metadata: name: nginx-deployment annotations: + internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' spec: template: @@ -272,6 +277,7 @@ metadata: name: nginx-deployment-1 annotations: foo: bar + internal.config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml' spec: template: @@ -287,6 +293,7 @@ metadata: name: nginx-deployment-2 annotations: foo: bar + internal.config.kubernetes.io/path: 'deployment_nginx-deployment-2.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment-2.yaml' spec: template: @@ -329,6 +336,7 @@ kind: Deployment metadata: name: nginx-deployment-1 annotations: + internal.config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml' spec: template: @@ -343,6 +351,7 @@ kind: Deployment metadata: name: nginx-deployment-2 annotations: + internal.config.kubernetes.io/path: 'deployment_nginx-deployment-2.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment-2.yaml' `, }, @@ -370,6 +379,7 @@ kind: Deployment metadata: name: nginx-deployment-1 annotations: + internal.config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml' `, }, @@ -409,6 +419,7 @@ metadata: name: nginx-deployment annotations: foo: hello world + internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' spec: template: @@ -462,6 +473,7 @@ metadata: name: nginx-deployment annotations: foo: hello world + internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' config.kubernetes.io/path: 'deployment_nginx-deployment.yaml' spec: template: diff --git a/kyaml/inpututil/inpututil.go b/kyaml/inpututil/inpututil.go index 41fe40772..be7d497f0 100644 --- a/kyaml/inpututil/inpututil.go +++ b/kyaml/inpututil/inpututil.go @@ -51,7 +51,15 @@ func WrapErrorWithFile(err error, meta yaml.ResourceMeta) error { if err == nil { return err } + path := meta.Annotations[kioutil.PathAnnotation] + index := meta.Annotations[kioutil.IndexAnnotation] + if path == "" { + path = meta.Annotations[kioutil.LegacyPathAnnotation] + } + if index == "" { + index = meta.Annotations[kioutil.LegacyPathAnnotation] + } return errors.WrapPrefixf(err, "%s [%s]", - meta.Annotations[kioutil.PathAnnotation], - meta.Annotations[kioutil.IndexAnnotation]) + meta.Annotations[path], + meta.Annotations[index]) } diff --git a/kyaml/kio/byteio_reader.go b/kyaml/kio/byteio_reader.go index 7513f0d64..62b26ea31 100644 --- a/kyaml/kio/byteio_reader.go +++ b/kyaml/kio/byteio_reader.go @@ -280,6 +280,7 @@ func (r *ByteReader) decode(originalYAML string, index int, decoder *yaml.Decode } if !r.OmitReaderAnnotations { r.SetAnnotations[kioutil.IndexAnnotation] = fmt.Sprintf("%d", index) + r.SetAnnotations[kioutil.LegacyIndexAnnotation] = fmt.Sprintf("%d", index) if r.PreserveSeqIndent { // derive and add the seqindent annotation diff --git a/kyaml/kio/byteio_reader_test.go b/kyaml/kio/byteio_reader_test.go index 1ae73b545..16ff86967 100644 --- a/kyaml/kio/byteio_reader_test.go +++ b/kyaml/kio/byteio_reader_test.go @@ -182,6 +182,7 @@ c: d metadata: annotations: config.kubernetes.io/index: '0' + internal.config.kubernetes.io/index: '0' `, `# second resource e: f @@ -190,11 +191,13 @@ g: metadata: annotations: config.kubernetes.io/index: '1' + internal.config.kubernetes.io/index: '1' `, `i: j metadata: annotations: config.kubernetes.io/index: '2' + internal.config.kubernetes.io/index: '2' `, }, }, @@ -260,6 +263,7 @@ c: d metadata: annotations: config.kubernetes.io/index: '0' + internal.config.kubernetes.io/index: '0' `, ` # second resource @@ -269,12 +273,14 @@ g: metadata: annotations: config.kubernetes.io/index: '1' + internal.config.kubernetes.io/index: '1' `, ` i: j metadata: annotations: config.kubernetes.io/index: '2' + internal.config.kubernetes.io/index: '2' `, }, instance: ByteReader{}, @@ -369,7 +375,7 @@ metadata: `, expectedItems: []string{ ` -{"a": "b", "c": [1, 2], metadata: {annotations: {config.kubernetes.io/index: '0'}}} +{"a": "b", "c": [1, 2], metadata: {annotations: {config.kubernetes.io/index: '0', internal.config.kubernetes.io/index: '0'}}} `, }, instance: ByteReader{}, diff --git a/kyaml/kio/byteio_readwriter_test.go b/kyaml/kio/byteio_readwriter_test.go index 9b6deada4..76ee20acf 100644 --- a/kyaml/kio/byteio_readwriter_test.go +++ b/kyaml/kio/byteio_readwriter_test.go @@ -216,6 +216,7 @@ spec: metadata: annotations: config.kubernetes.io/index: '0' + internal.config.kubernetes.io/index: '0' --- kind: Service spec: @@ -224,6 +225,7 @@ spec: metadata: annotations: config.kubernetes.io/index: '1' + internal.config.kubernetes.io/index: '1' `, instance: kio.ByteReadWriter{KeepReaderAnnotations: true}, }, diff --git a/kyaml/kio/byteio_writer.go b/kyaml/kio/byteio_writer.go index 33e5a8999..87a3cd2e7 100644 --- a/kyaml/kio/byteio_writer.go +++ b/kyaml/kio/byteio_writer.go @@ -75,6 +75,10 @@ func (w ByteWriter) Write(inputNodes []*yaml.RNode) error { if err != nil { return errors.Wrap(err) } + _, err = nodes[i].Pipe(yaml.ClearAnnotation(kioutil.LegacyIndexAnnotation)) + if err != nil { + return errors.Wrap(err) + } _, err = nodes[i].Pipe(yaml.ClearAnnotation(kioutil.SeqIndentAnnotation)) if err != nil { diff --git a/kyaml/kio/byteio_writer_test.go b/kyaml/kio/byteio_writer_test.go index 241a9c31d..ce3c37321 100644 --- a/kyaml/kio/byteio_writer_test.go +++ b/kyaml/kio/byteio_writer_test.go @@ -222,8 +222,8 @@ spec: `a: b #first metadata: annotations: - config.kubernetes.io/index: 0 - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/index: 0 + internal.config.kubernetes.io/path: "a/b/a_test.yaml" `, `e: f g: @@ -232,28 +232,32 @@ g: - j metadata: annotations: - config.kubernetes.io/index: 0 - config.kubernetes.io/path: "a/b/b_test.yaml" + internal.config.kubernetes.io/index: 0 + internal.config.kubernetes.io/path: "a/b/b_test.yaml" `, `c: d # second metadata: annotations: - config.kubernetes.io/index: 1 - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/index: 1 + internal.config.kubernetes.io/path: "a/b/a_test.yaml" `, }, expectedOutput: `a: b #first metadata: annotations: - config.kubernetes.io/index: 0 - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/index: 0 + internal.config.kubernetes.io/path: "a/b/a_test.yaml" + config.kubernetes.io/path: 'a/b/a_test.yaml' + config.kubernetes.io/index: '0' --- c: d # second metadata: annotations: - config.kubernetes.io/index: 1 - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/index: 1 + internal.config.kubernetes.io/path: "a/b/a_test.yaml" + config.kubernetes.io/path: 'a/b/a_test.yaml' + config.kubernetes.io/index: '1' --- e: f g: @@ -262,8 +266,10 @@ g: - j metadata: annotations: - config.kubernetes.io/index: 0 - config.kubernetes.io/path: "a/b/b_test.yaml" + internal.config.kubernetes.io/index: 0 + internal.config.kubernetes.io/path: "a/b/b_test.yaml" + config.kubernetes.io/path: 'a/b/b_test.yaml' + config.kubernetes.io/index: '0' `, }, @@ -277,13 +283,13 @@ metadata: `a: b #first metadata: annotations: - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/path: "a/b/a_test.yaml" `, `c: d # second metadata: annotations: - config.kubernetes.io/index: 1 - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/index: 1 + internal.config.kubernetes.io/path: "a/b/a_test.yaml" `, `e: f g: @@ -293,21 +299,23 @@ g: `, }, - expectedOutput: `e: f -g: - h: - - i # has a list - - j ---- -a: b #first + expectedOutput: `a: b #first metadata: annotations: - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/path: "a/b/a_test.yaml" + config.kubernetes.io/path: 'a/b/a_test.yaml' --- c: d # second metadata: annotations: - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/path: "a/b/a_test.yaml" + config.kubernetes.io/path: 'a/b/a_test.yaml' +--- +e: f +g: + h: + - i # has a list + - j `, }, @@ -321,8 +329,8 @@ metadata: `a: b #first metadata: annotations: - config.kubernetes.io/index: 0 - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/index: 0 + internal.config.kubernetes.io/path: "a/b/a_test.yaml" internal.config.kubernetes.io/index: "compact" `, `e: f @@ -332,15 +340,15 @@ g: - j metadata: annotations: - config.kubernetes.io/index: 0 - config.kubernetes.io/path: "a/b/b_test.yaml" + internal.config.kubernetes.io/index: 0 + internal.config.kubernetes.io/path: "a/b/b_test.yaml" internal.config.kubernetes.io/seqindent: "wide" `, `c: d # second metadata: annotations: - config.kubernetes.io/index: 1 - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/index: 1 + internal.config.kubernetes.io/path: "a/b/a_test.yaml" internal.config.kubernetes.io/seqindent: "compact" `, }, @@ -348,8 +356,8 @@ metadata: expectedOutput: `a: b #first metadata: annotations: - config.kubernetes.io/index: 0 - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/index: 0 + internal.config.kubernetes.io/path: "a/b/a_test.yaml" internal.config.kubernetes.io/index: "compact" --- e: f @@ -359,15 +367,15 @@ g: - j metadata: annotations: - config.kubernetes.io/index: 0 - config.kubernetes.io/path: "a/b/b_test.yaml" + internal.config.kubernetes.io/index: 0 + internal.config.kubernetes.io/path: "a/b/b_test.yaml" internal.config.kubernetes.io/seqindent: "wide" --- c: d # second metadata: annotations: - config.kubernetes.io/index: 1 - config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/index: 1 + internal.config.kubernetes.io/path: "a/b/a_test.yaml" internal.config.kubernetes.io/seqindent: "compact" `, }, @@ -382,7 +390,7 @@ metadata: "a": "a long string that would certainly see a newline introduced by the YAML marshaller abcd123", metadata: { annotations: { - config.kubernetes.io/path: test.json + internal.config.kubernetes.io/path: test.json } } }`, @@ -392,7 +400,8 @@ metadata: "a": "a long string that would certainly see a newline introduced by the YAML marshaller abcd123", "metadata": { "annotations": { - "config.kubernetes.io/path": "test.json" + "config.kubernetes.io/path": "test.json", + "internal.config.kubernetes.io/path": "test.json" } } }`, @@ -409,8 +418,8 @@ metadata: metadata: { annotations: { "internal.config.kubernetes.io/seqindent": "compact", - "config.kubernetes.io/index": "0", - "config.kubernetes.io/path": "test.json" + "internal.config.kubernetes.io/index": "0", + "internal.config.kubernetes.io/path": "test.json" } } }`, @@ -420,7 +429,8 @@ metadata: "a": "a long string that would certainly see a newline introduced by the YAML marshaller abcd123", "metadata": { "annotations": { - "config.kubernetes.io/path": "test.json" + "config.kubernetes.io/path": "test.json", + "internal.config.kubernetes.io/path": "test.json" } } }`, @@ -432,14 +442,15 @@ metadata: { name: "encode_unformatted_valid_json", items: []string{ - `{ "a": "b", metadata: { annotations: { config.kubernetes.io/path: test.json } } }`, + `{ "a": "b", metadata: { annotations: { internal.config.kubernetes.io/path: test.json } } }`, }, expectedOutput: `{ "a": "b", "metadata": { "annotations": { - "config.kubernetes.io/path": "test.json" + "config.kubernetes.io/path": "test.json", + "internal.config.kubernetes.io/path": "test.json" } } }`, @@ -460,7 +471,7 @@ metadata: "a": "b", "metadata": { "annotations": { - "config.kubernetes.io/path": "test.json" + "internal.config.kubernetes.io/path": "test.json" } } }`, @@ -469,7 +480,7 @@ metadata: expectedOutput: `apiVersion: config.kubernetes.io/v1alpha1 kind: ResourceList items: -- {"a": "b", "metadata": {"annotations": {"config.kubernetes.io/path": "test.json"}}} +- {"a": "b", "metadata": {"annotations": {"internal.config.kubernetes.io/path": "test.json"}}} `, }, @@ -483,7 +494,7 @@ items: "a": "b", "metadata": { "annotations": { - "config.kubernetes.io/path": "test-1.json" + "internal.config.kubernetes.io/path": "test-1.json" } } }`, @@ -491,16 +502,16 @@ items: "c": "d", "metadata": { "annotations": { - "config.kubernetes.io/path": "test-2.json" + "internal.config.kubernetes.io/path": "test-2.json" } } }`, }, expectedOutput: ` -{"a": "b", "metadata": {"annotations": {"config.kubernetes.io/path": "test-1.json"}}} +{"a": "b", "metadata": {"annotations": {"internal.config.kubernetes.io/path": "test-1.json"}}} --- -{"c": "d", "metadata": {"annotations": {"config.kubernetes.io/path": "test-2.json"}}} +{"c": "d", "metadata": {"annotations": {"internal.config.kubernetes.io/path": "test-2.json"}}} `, }, } diff --git a/kyaml/kio/filters/filters.go b/kyaml/kio/filters/filters.go index f8ceb51ca..8d7968b3c 100644 --- a/kyaml/kio/filters/filters.go +++ b/kyaml/kio/filters/filters.go @@ -165,6 +165,10 @@ func (f *FileSetter) Filter(input []*yaml.RNode) ([]*yaml.RNode, error) { resources := map[string][]*yaml.RNode{} for i := range input { + if err := kioutil.CopyLegacyAnnotations(input[i]); err != nil { + return nil, err + } + m, err := input[i].GetMeta() if err != nil { return nil, err @@ -178,6 +182,9 @@ func (f *FileSetter) Filter(input []*yaml.RNode) ([]*yaml.RNode, error) { if _, err := input[i].Pipe(yaml.SetAnnotation(kioutil.PathAnnotation, file)); err != nil { return nil, err } + if _, err := input[i].Pipe(yaml.SetAnnotation(kioutil.LegacyPathAnnotation, file)); err != nil { + return nil, err + } } resources[file] = append(resources[file], input[i]) } @@ -192,6 +199,10 @@ func (f *FileSetter) Filter(input []*yaml.RNode) ([]*yaml.RNode, error) { yaml.SetAnnotation(kioutil.IndexAnnotation, fmt.Sprintf("%d", j))); err != nil { return nil, err } + if _, err := resources[i][j].Pipe( + yaml.SetAnnotation(kioutil.LegacyIndexAnnotation, fmt.Sprintf("%d", j))); err != nil { + return nil, err + } output = append(output, resources[i][j]) } } diff --git a/kyaml/kio/filters/filters_test.go b/kyaml/kio/filters/filters_test.go index 3e24b20dc..7cf807f0c 100644 --- a/kyaml/kio/filters/filters_test.go +++ b/kyaml/kio/filters/filters_test.go @@ -53,6 +53,7 @@ metadata: name: foo1 namespace: bar annotations: + internal.config.kubernetes.io/path: 'foo1_deployment.yaml' config.kubernetes.io/path: 'foo1_deployment.yaml' --- apiVersion: v1 @@ -60,6 +61,7 @@ kind: Service metadata: name: foo1 annotations: + internal.config.kubernetes.io/path: 'foo1_service.yaml' config.kubernetes.io/path: 'foo1_service.yaml' --- apiVersion: apps/v1 @@ -67,6 +69,7 @@ kind: Deployment metadata: name: foo2 annotations: + internal.config.kubernetes.io/path: 'foo2_deployment.yaml' config.kubernetes.io/path: 'foo2_deployment.yaml' --- apiVersion: v1 @@ -75,6 +78,7 @@ metadata: name: foo2 namespace: bar annotations: + internal.config.kubernetes.io/path: 'foo2_service.yaml' config.kubernetes.io/path: 'foo2_service.yaml' `, out.String()) } @@ -97,6 +101,7 @@ kind: Service metadata: name: foo1 annotations: + internal.config.kubernetes.io/path: 'foo1__service.yaml' config.kubernetes.io/path: 'foo1__service.yaml' --- apiVersion: apps/v1 @@ -105,6 +110,7 @@ metadata: name: foo1 namespace: bar annotations: + internal.config.kubernetes.io/path: 'foo1_bar_deployment.yaml' config.kubernetes.io/path: 'foo1_bar_deployment.yaml' --- apiVersion: apps/v1 @@ -112,6 +118,7 @@ kind: Deployment metadata: name: foo2 annotations: + internal.config.kubernetes.io/path: 'foo2__deployment.yaml' config.kubernetes.io/path: 'foo2__deployment.yaml' --- apiVersion: v1 @@ -120,6 +127,7 @@ metadata: name: foo2 namespace: bar annotations: + internal.config.kubernetes.io/path: 'foo2_bar_service.yaml' config.kubernetes.io/path: 'foo2_bar_service.yaml' `, out.String()) } @@ -143,6 +151,7 @@ metadata: name: foo1 namespace: bar annotations: + internal.config.kubernetes.io/path: 'resource.yaml' config.kubernetes.io/path: 'resource.yaml' --- apiVersion: apps/v1 @@ -150,6 +159,7 @@ kind: Deployment metadata: name: foo2 annotations: + internal.config.kubernetes.io/path: 'resource.yaml' config.kubernetes.io/path: 'resource.yaml' --- apiVersion: v1 @@ -158,6 +168,7 @@ metadata: name: foo2 namespace: bar annotations: + internal.config.kubernetes.io/path: 'resource.yaml' config.kubernetes.io/path: 'resource.yaml' --- apiVersion: v1 @@ -165,6 +176,7 @@ kind: Service metadata: name: foo1 annotations: + internal.config.kubernetes.io/path: 'resource.yaml' config.kubernetes.io/path: 'resource.yaml' `, out.String()) } diff --git a/kyaml/kio/filters/merge3.go b/kyaml/kio/filters/merge3.go index 26ff86301..de8bf6f67 100644 --- a/kyaml/kio/filters/merge3.go +++ b/kyaml/kio/filters/merge3.go @@ -173,6 +173,12 @@ func (dm *DefaultGVKNNMatcher) IsSameResource(node1, node2 *yaml.RNode) bool { if node1 == nil || node2 == nil { return false } + if err := kioutil.CopyLegacyAnnotations(node1); err != nil { + return false + } + if err := kioutil.CopyLegacyAnnotations(node2); err != nil { + return false + } meta1, err := node1.GetMeta() if err != nil { diff --git a/kyaml/kio/kio.go b/kyaml/kio/kio.go index 12271aa81..7b3943839 100644 --- a/kyaml/kio/kio.go +++ b/kyaml/kio/kio.go @@ -6,7 +6,10 @@ package kio import ( + "fmt" + "sigs.k8s.io/kustomize/kyaml/errors" + "sigs.k8s.io/kustomize/kyaml/kio/kioutil" "sigs.k8s.io/kustomize/kyaml/yaml" ) @@ -113,6 +116,14 @@ func (p Pipeline) ExecuteWithCallback(callback PipelineExecuteCallbackFunc) erro // apply operations var err error for i := range p.Filters { + // Not all RNodes passed through kio.Pipeline have metadata nor should + // they all be required to. + var nodeAnnos map[string]map[string]string + nodeAnnos, err = storeInternalAnnotations(result) + if err != nil && err != yaml.ErrMissingMetadata { + return err + } + op := p.Filters[i] if callback != nil { callback(op) @@ -124,6 +135,13 @@ func (p Pipeline) ExecuteWithCallback(callback PipelineExecuteCallbackFunc) erro if len(result) == 0 && !p.ContinueOnEmptyResult || err != nil { return errors.Wrap(err) } + + // If either the internal annotations for path, index, and id OR the legacy + // annotations for path, index, and id are changed, we have to update the other. + err = reconcileInternalAnnotations(result, nodeAnnos) + if err != nil && err != yaml.ErrMissingMetadata { + return err + } } // write to the outputs @@ -147,3 +165,196 @@ func FilterAll(filter yaml.Filter) Filter { return nodes, nil }) } + +// Store the original path, index, and id annotations so that we can reconcile +// it later. This is necessary because currently both internal-prefixed annotations +// and legacy annotations are currently supported, and a change to one must be +// reflected in the other. +func storeInternalAnnotations(result []*yaml.RNode) (map[string]map[string]string, error) { + nodeAnnosMap := make(map[string]map[string]string) + + for i := range result { + if err := kioutil.CopyLegacyAnnotations(result[i]); err != nil { + return nil, err + } + meta, err := result[i].GetMeta() + if err != nil { + return nil, err + } + path := meta.Annotations[kioutil.PathAnnotation] + index := meta.Annotations[kioutil.IndexAnnotation] + id := meta.Annotations[kioutil.IdAnnotation] + + if _, ok := nodeAnnosMap[path]; !ok { + nodeAnnosMap[path] = make(map[string]string) + } + nodeAnnosMap[path][index] = id + } + return nodeAnnosMap, nil +} + +type nodeAnnotations struct { + path string + index string + id string +} + +func reconcileInternalAnnotations(result []*yaml.RNode, nodeAnnosMap map[string]map[string]string) error { + for _, node := range result { + meta, err := node.GetMeta() + if err != nil { + return err + } + // if only one annotation is set, set the other. + err = missingInternalOrLegacyAnnotations(node, meta) + if err != nil { + return err + } + // we must check to see if the function changed either the new internal annotations + // or the old legacy annotations. If one is changed, the change must be reflected + // in the other. + err = checkAnnotationsAltered(node, meta, nodeAnnosMap) + if err != nil { + return err + } + // if the annotations are still somehow out of sync, prefer the internal annotations + // and copy them to the legacy ones + err = kioutil.CopyLegacyAnnotations(node) + if err != nil { + return err + } + } + return nil +} + +func missingInternalOrLegacyAnnotations(rn *yaml.RNode, meta yaml.ResourceMeta) error { + if err := missingInternalOrLegacyAnnotation(rn, meta, kioutil.PathAnnotation, kioutil.LegacyPathAnnotation); err != nil { + return err + } + if err := missingInternalOrLegacyAnnotation(rn, meta, kioutil.IndexAnnotation, kioutil.LegacyIndexAnnotation); err != nil { + return err + } + if err := missingInternalOrLegacyAnnotation(rn, meta, kioutil.IdAnnotation, kioutil.LegacyIdAnnotation); err != nil { + return err + } + return nil +} + +func missingInternalOrLegacyAnnotation(rn *yaml.RNode, meta yaml.ResourceMeta, newKey string, legacyKey string) error { + value := meta.Annotations[newKey] + legacyValue := meta.Annotations[legacyKey] + + if value == "" && legacyValue == "" { + // do nothing + return nil + } + + if value == "" { + // new key is not set, copy from legacy key + if err := rn.PipeE(yaml.SetAnnotation(newKey, legacyValue)); err != nil { + return err + } + } else if legacyValue == "" { + // legacy key is not set, copy from new key + if err := rn.PipeE(yaml.SetAnnotation(legacyKey, value)); err != nil { + return err + } + } + return nil +} + +func checkAnnotationsAltered(rn *yaml.RNode, meta yaml.ResourceMeta, nodeAnnosMap map[string]map[string]string) error { + // get the resource's current path, index, and ids from the new annotations + internal := nodeAnnotations{ + path: meta.Annotations[kioutil.PathAnnotation], + index: meta.Annotations[kioutil.IndexAnnotation], + id: meta.Annotations[kioutil.IdAnnotation], + } + + // get the resource's current path, index, and ids from the legacy annotations + legacy := nodeAnnotations{ + path: meta.Annotations[kioutil.LegacyPathAnnotation], + index: meta.Annotations[kioutil.LegacyIndexAnnotation], + id: meta.Annotations[kioutil.LegacyIdAnnotation], + } + + if internal.path == legacy.path && + internal.index == legacy.index && + internal.id == legacy.id { + // none of the annotations differ, so no reconciliation is needed + return nil + } + + // nodeAnnosMap is a map of structure path -> index -> id that stores + // all of the resources' path/index/id annotations prior to the functions + // being run. We use that to check whether the legacy or new internal + // annotations have been changed, and make sure the change is reflected + // in the other. + + // first, check if the internal annotations are found in nodeAnnosMap + if indexIdMap, ok := nodeAnnosMap[internal.path]; ok { + if id, ok := indexIdMap[internal.index]; ok { + if id == internal.id { + // the internal annotations of the resource match the ones stored in + // nodeAnnosMap, so we should copy the legacy annotations to the + // internal ones + if err := updateAnnotations(rn, meta, + []string{ + kioutil.PathAnnotation, + kioutil.IndexAnnotation, + kioutil.IdAnnotation, + }, + []string{ + legacy.path, + legacy.index, + legacy.id, + }); err != nil { + return err + } + } + } + } + + // check the opposite, to see if the legacy annotations are in nodeAnnosMap + if indexIdMap, ok := nodeAnnosMap[legacy.path]; ok { + if id, ok := indexIdMap[legacy.index]; ok { + if id == legacy.id { + // the legacy annotations of the resource match the ones stored in + // nodeAnnosMap, so we should copy the internal annotations to the + // legacy ones + if err := updateAnnotations(rn, meta, + []string{ + kioutil.LegacyPathAnnotation, + kioutil.LegacyIndexAnnotation, + kioutil.LegacyIdAnnotation, + }, + []string{ + internal.path, + internal.index, + internal.id, + }); err != nil { + return err + } + } + } + } + return nil +} + +func updateAnnotations(rn *yaml.RNode, meta yaml.ResourceMeta, keys []string, values []string) error { + if len(keys) != len(values) { + return fmt.Errorf("keys is not same length as values") + } + for i := range keys { + _, ok := meta.Annotations[keys[i]] + if values[i] == "" && !ok { + // don't set "" if annotation is not already there + continue + } + if err := rn.PipeE(yaml.SetAnnotation(keys[i], values[i])); err != nil { + return err + } + + } + return nil +} diff --git a/kyaml/kio/kio_test.go b/kyaml/kio/kio_test.go index 0529c97d7..4c73ecd34 100644 --- a/kyaml/kio/kio_test.go +++ b/kyaml/kio/kio_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - + "sigs.k8s.io/kustomize/kyaml/kio/kioutil" "sigs.k8s.io/kustomize/kyaml/yaml" . "sigs.k8s.io/kustomize/kyaml/kio" @@ -187,3 +187,347 @@ func TestContinueOnEmptyBehavior(t *testing.T) { } } } + +func TestLegacyAnnotationReconciliation(t *testing.T) { + noopFilter1 := func(nodes []*yaml.RNode) ([]*yaml.RNode, error) { + return nodes, nil + } + noopFilter2 := func(nodes []*yaml.RNode) ([]*yaml.RNode, error) { + return nodes, nil + } + changeInternalAnnos := func(nodes []*yaml.RNode) ([]*yaml.RNode, error) { + for _, rn := range nodes { + if err := rn.PipeE(yaml.SetAnnotation(kioutil.PathAnnotation, "new")); err != nil { + return nil, err + } + if err := rn.PipeE(yaml.SetAnnotation(kioutil.IndexAnnotation, "new")); err != nil { + return nil, err + } + } + return nodes, nil + } + changeLegacyAnnos := func(nodes []*yaml.RNode) ([]*yaml.RNode, error) { + for _, rn := range nodes { + if err := rn.PipeE(yaml.SetAnnotation(kioutil.LegacyPathAnnotation, "new")); err != nil { + return nil, err + } + if err := rn.PipeE(yaml.SetAnnotation(kioutil.LegacyIndexAnnotation, "new")); err != nil { + return nil, err + } + } + return nodes, nil + } + changeLegacyId := func(nodes []*yaml.RNode) ([]*yaml.RNode, error) { + for _, rn := range nodes { + if err := rn.PipeE(yaml.SetAnnotation(kioutil.LegacyIdAnnotation, "new")); err != nil { + return nil, err + } + } + return nodes, nil + } + changeInternalId := func(nodes []*yaml.RNode) ([]*yaml.RNode, error) { + for _, rn := range nodes { + if err := rn.PipeE(yaml.SetAnnotation(kioutil.IdAnnotation, "new")); err != nil { + return nil, err + } + } + return nodes, nil + } + + noops := []Filter{ + FilterFunc(noopFilter1), + FilterFunc(noopFilter2), + } + internal := []Filter{FilterFunc(changeInternalAnnos)} + legacy := []Filter{FilterFunc(changeLegacyAnnos)} + legacyId := []Filter{FilterFunc(changeLegacyId)} + internalId := []Filter{FilterFunc(changeInternalId)} + + testCases := map[string]struct { + input string + filters []Filter + expected string + }{ + // the orchestrator should copy the legacy annotations to the new + // annotations + "legacy annotations only": { + input: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + config.kubernetes.io/path: 'configmap.yaml' + config.kubernetes.io/index: '0' +data: + grpcPort: 8080 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-to + annotations: + config.kubernetes.io/path: "configmap.yaml" + config.kubernetes.io/index: '1' +data: + grpcPort: 8081 +`, + filters: noops, + expected: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + config.kubernetes.io/path: 'configmap.yaml' + config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'configmap.yaml' + internal.config.kubernetes.io/index: '0' +data: + grpcPort: 8080 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-to + annotations: + config.kubernetes.io/path: "configmap.yaml" + config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'configmap.yaml' + internal.config.kubernetes.io/index: '1' +data: + grpcPort: 8081 +`, + }, + // the orchestrator should copy the new annotations to the + // legacy annotations + "new annotations only": { + input: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + internal.config.kubernetes.io/path: 'configmap.yaml' + internal.config.kubernetes.io/index: '0' +data: + grpcPort: 8080 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-to + annotations: + internal.config.kubernetes.io/path: "configmap.yaml" + internal.config.kubernetes.io/index: '1' +data: + grpcPort: 8081 +`, + filters: noops, + expected: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + internal.config.kubernetes.io/path: 'configmap.yaml' + internal.config.kubernetes.io/index: '0' + config.kubernetes.io/path: 'configmap.yaml' + config.kubernetes.io/index: '0' +data: + grpcPort: 8080 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-to + annotations: + internal.config.kubernetes.io/path: "configmap.yaml" + internal.config.kubernetes.io/index: '1' + config.kubernetes.io/path: 'configmap.yaml' + config.kubernetes.io/index: '1' +data: + grpcPort: 8081 +`, + }, + // the orchestrator should detect that the legacy annotations + // have been changed by the function, and should update the + // new internal annotations to reflect the same change + "change only legacy annotations": { + input: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + config.kubernetes.io/path: 'configmap.yaml' + config.kubernetes.io/index: '0' +data: + grpcPort: 8080 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-to + annotations: + config.kubernetes.io/path: "configmap.yaml" + config.kubernetes.io/index: '1' +data: + grpcPort: 8081 +`, + filters: legacy, + expected: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + config.kubernetes.io/path: 'new' + config.kubernetes.io/index: 'new' + internal.config.kubernetes.io/path: 'new' + internal.config.kubernetes.io/index: 'new' +data: + grpcPort: 8080 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-to + annotations: + config.kubernetes.io/path: "new" + config.kubernetes.io/index: 'new' + internal.config.kubernetes.io/path: 'new' + internal.config.kubernetes.io/index: 'new' +data: + grpcPort: 8081 +`, + }, + // the orchestrator should detect that the new internal annotations + // have been changed by the function, and should update the + // legacy annotations to reflect the same change + "change only internal annotations": { + input: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + config.kubernetes.io/path: 'configmap.yaml' + config.kubernetes.io/index: '0' +data: + grpcPort: 8080 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-to + annotations: + config.kubernetes.io/path: "configmap.yaml" + config.kubernetes.io/index: '1' +data: + grpcPort: 8081 +`, + filters: internal, + expected: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + config.kubernetes.io/path: 'new' + config.kubernetes.io/index: 'new' + internal.config.kubernetes.io/path: 'new' + internal.config.kubernetes.io/index: 'new' +data: + grpcPort: 8080 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-to + annotations: + config.kubernetes.io/path: "new" + config.kubernetes.io/index: 'new' + internal.config.kubernetes.io/path: 'new' + internal.config.kubernetes.io/index: 'new' +data: + grpcPort: 8081 +`, + }, + // the orchestrator should detect that the new internal id annotation + // has been changed, and copy it over to the legacy one, and also + // copy the path and index legacy annotations to the new internal + // ones + "change only internal id when original legacy set": { + input: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + config.kubernetes.io/path: 'configmap.yaml' + config.kubernetes.io/index: '0' + config.k8s.io/id: '1' +data: + grpcPort: 8080 +`, + filters: internalId, + expected: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + config.kubernetes.io/path: 'configmap.yaml' + config.kubernetes.io/index: '0' + config.k8s.io/id: 'new' + internal.config.kubernetes.io/path: 'configmap.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/id: 'new' +data: + grpcPort: 8080 +`, + }, + // the orchestrator should detect that the legacy id annotation + // has been changed, and copy it over to the internal one, and also + // copy the path and index internal annotations to the legacy + // ones + "change only legacy id when internal legacy set": { + input: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + internal.config.kubernetes.io/path: 'configmap.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/id: '1' +data: + grpcPort: 8080 +`, + filters: legacyId, + expected: `apiVersion: v1 +kind: ConfigMap +metadata: + name: ports-from + annotations: + internal.config.kubernetes.io/path: 'configmap.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/id: 'new' + config.kubernetes.io/path: 'configmap.yaml' + config.kubernetes.io/index: '0' + config.k8s.io/id: 'new' +data: + grpcPort: 8080 +`, + }, + } + + for tn, tc := range testCases { + t.Run(tn, func(t *testing.T) { + var out bytes.Buffer + input := ByteReadWriter{ + Reader: bytes.NewBufferString(tc.input), + Writer: &out, + OmitReaderAnnotations: true, + KeepReaderAnnotations: true, + } + p := Pipeline{ + Inputs: []Reader{&input}, + Filters: tc.filters, + Outputs: []Writer{&input}, + } + assert.NoError(t, p.Execute()) + assert.Equal(t, tc.expected, out.String()) + }) + } +} diff --git a/kyaml/kio/kioutil/kioutil.go b/kyaml/kio/kioutil/kioutil.go index 993cdfd84..bcd973030 100644 --- a/kyaml/kio/kioutil/kioutil.go +++ b/kyaml/kio/kioutil/kioutil.go @@ -18,16 +18,31 @@ type AnnotationKey = string const ( // IndexAnnotation records the index of a specific resource in a file or input stream. - IndexAnnotation AnnotationKey = "config.kubernetes.io/index" + IndexAnnotation AnnotationKey = "internal.config.kubernetes.io/index" // PathAnnotation records the path to the file the Resource was read from - PathAnnotation AnnotationKey = "config.kubernetes.io/path" + PathAnnotation AnnotationKey = "internal.config.kubernetes.io/path" // SeqIndentAnnotation records the sequence nodes indentation of the input resource SeqIndentAnnotation AnnotationKey = "internal.config.kubernetes.io/seqindent" + + // IdAnnotation records the id of the resource to map inputs to outputs + IdAnnotation = "internal.config.kubernetes.io/id" + + // LegacyIndexAnnotation is the deprecated annotation key for resource index + LegacyIndexAnnotation AnnotationKey = "config.kubernetes.io/index" + + // LegacyPathAnnotation is the deprecated annotation key for resource path + LegacyPathAnnotation AnnotationKey = "config.kubernetes.io/path" + + // LegacyIdAnnotation is the deprecated annotation key for resource ids + LegacyIdAnnotation = "config.k8s.io/id" ) func GetFileAnnotations(rn *yaml.RNode) (string, string, error) { + if err := CopyLegacyAnnotations(rn); err != nil { + return "", "", err + } meta, err := rn.GetMeta() if err != nil { return "", "", err @@ -37,6 +52,40 @@ func GetFileAnnotations(rn *yaml.RNode) (string, string, error) { return path, index, nil } +func CopyLegacyAnnotations(rn *yaml.RNode) error { + meta, err := rn.GetMeta() + if err != nil { + return err + } + if err := copyAnnotations(meta, rn, LegacyPathAnnotation, PathAnnotation); err != nil { + return err + } + if err := copyAnnotations(meta, rn, LegacyIndexAnnotation, IndexAnnotation); err != nil { + return err + } + if err := copyAnnotations(meta, rn, LegacyIdAnnotation, IdAnnotation); err != nil { + return err + } + return nil +} + +func copyAnnotations(meta yaml.ResourceMeta, rn *yaml.RNode, legacyKey string, newKey string) error { + newValue := meta.Annotations[newKey] + if newValue != "" { + if err := rn.PipeE(yaml.SetAnnotation(legacyKey, newValue)); err != nil { + return err + } + } else { + legacyValue := meta.Annotations[legacyKey] + if legacyValue != "" { + if err := rn.PipeE(yaml.SetAnnotation(newKey, legacyValue)); err != nil { + return err + } + } + } + return nil +} + // ErrorIfMissingAnnotation validates the provided annotations are present on the given resources func ErrorIfMissingAnnotation(nodes []*yaml.RNode, keys ...AnnotationKey) error { for _, key := range keys { @@ -67,6 +116,9 @@ func DefaultPathAndIndexAnnotation(dir string, nodes []*yaml.RNode) error { // check each node for the path annotation for i := range nodes { + if err := CopyLegacyAnnotations(nodes[i]); err != nil { + return err + } m, err := nodes[i].GetMeta() if err != nil { return err @@ -91,6 +143,9 @@ func DefaultPathAndIndexAnnotation(dir string, nodes []*yaml.RNode) error { if err := nodes[i].PipeE(yaml.SetAnnotation(PathAnnotation, path)); err != nil { return err } + if err := nodes[i].PipeE(yaml.SetAnnotation(LegacyPathAnnotation, path)); err != nil { + return err + } } // set the index annotations @@ -113,6 +168,10 @@ func DefaultPathAndIndexAnnotation(dir string, nodes []*yaml.RNode) error { yaml.SetAnnotation(IndexAnnotation, fmt.Sprintf("%d", c))); err != nil { return err } + if err := nodes[i].PipeE( + yaml.SetAnnotation(LegacyIndexAnnotation, fmt.Sprintf("%d", c))); err != nil { + return err + } } return nil } @@ -122,6 +181,9 @@ func DefaultPathAndIndexAnnotation(dir string, nodes []*yaml.RNode) error { func DefaultPathAnnotation(dir string, nodes []*yaml.RNode) error { // check each node for the path annotation for i := range nodes { + if err := CopyLegacyAnnotations(nodes[i]); err != nil { + return err + } m, err := nodes[i].GetMeta() if err != nil { return err @@ -137,6 +199,9 @@ func DefaultPathAnnotation(dir string, nodes []*yaml.RNode) error { if err := nodes[i].PipeE(yaml.SetAnnotation(PathAnnotation, path)); err != nil { return err } + if err := nodes[i].PipeE(yaml.SetAnnotation(LegacyPathAnnotation, path)); err != nil { + return err + } } return nil } @@ -185,6 +250,12 @@ func SortNodes(nodes []*yaml.RNode) error { if err != nil { return false } + if err := CopyLegacyAnnotations(nodes[i]); err != nil { + return false + } + if err := CopyLegacyAnnotations(nodes[j]); err != nil { + return false + } var iMeta, jMeta yaml.ResourceMeta if iMeta, _ = nodes[i].GetMeta(); err != nil { return false diff --git a/kyaml/kio/kioutil/kioutil_test.go b/kyaml/kio/kioutil/kioutil_test.go index 7a60a8329..6fedf21fb 100644 --- a/kyaml/kio/kioutil/kioutil_test.go +++ b/kyaml/kio/kioutil/kioutil_test.go @@ -98,6 +98,7 @@ metadata: name: a namespace: b annotations: + internal.config.kubernetes.io/path: 'foo/b/bar_a.yaml' config.kubernetes.io/path: 'foo/b/bar_a.yaml' `, `with namespace`}, { @@ -112,6 +113,7 @@ kind: Bar metadata: name: a annotations: + internal.config.kubernetes.io/path: 'foo/bar_a.yaml' config.kubernetes.io/path: 'foo/bar_a.yaml' `, `without namespace`}, @@ -129,6 +131,7 @@ metadata: name: a namespace: b annotations: + internal.config.kubernetes.io/path: 'b/bar_a.yaml' config.kubernetes.io/path: 'b/bar_a.yaml' `, `without dir`}, { @@ -139,6 +142,7 @@ metadata: name: a namespace: b annotations: + internal.config.kubernetes.io/path: 'a/b.yaml' config.kubernetes.io/path: 'a/b.yaml' `, `apiVersion: v1 @@ -147,6 +151,7 @@ metadata: name: a namespace: b annotations: + internal.config.kubernetes.io/path: 'a/b.yaml' config.kubernetes.io/path: 'a/b.yaml' `, `skip`}, } @@ -184,7 +189,9 @@ metadata: name: a namespace: b annotations: + internal.config.kubernetes.io/path: 'foo/b/bar_a.yaml' config.kubernetes.io/path: 'foo/b/bar_a.yaml' + internal.config.kubernetes.io/index: '0' config.kubernetes.io/index: '0' `, `with namespace`}, { @@ -199,7 +206,9 @@ kind: Bar metadata: name: a annotations: + internal.config.kubernetes.io/path: 'foo/bar_a.yaml' config.kubernetes.io/path: 'foo/bar_a.yaml' + internal.config.kubernetes.io/index: '0' config.kubernetes.io/index: '0' `, `without namespace`}, @@ -217,7 +226,9 @@ metadata: name: a namespace: b annotations: + internal.config.kubernetes.io/path: 'b/bar_a.yaml' config.kubernetes.io/path: 'b/bar_a.yaml' + internal.config.kubernetes.io/index: '0' config.kubernetes.io/index: '0' `, `without dir`}, { @@ -228,7 +239,9 @@ metadata: name: a namespace: b annotations: + internal.config.kubernetes.io/path: 'a/b.yaml' config.kubernetes.io/path: 'a/b.yaml' + internal.config.kubernetes.io/index: '5' config.kubernetes.io/index: '5' `, `apiVersion: v1 @@ -237,7 +250,9 @@ metadata: name: a namespace: b annotations: + internal.config.kubernetes.io/path: 'a/b.yaml' config.kubernetes.io/path: 'a/b.yaml' + internal.config.kubernetes.io/index: '5' config.kubernetes.io/index: '5' `, `skip`}, } diff --git a/kyaml/kio/pkgio_reader.go b/kyaml/kio/pkgio_reader.go index e36107787..d87752dd9 100644 --- a/kyaml/kio/pkgio_reader.go +++ b/kyaml/kio/pkgio_reader.go @@ -320,6 +320,7 @@ func (r *LocalPackageReader) initReaderAnnotations(path string, _ os.FileInfo) { } if !r.OmitReaderAnnotations { r.SetAnnotations[kioutil.PathAnnotation] = path + r.SetAnnotations[kioutil.LegacyPathAnnotation] = path } } diff --git a/kyaml/kio/pkgio_reader_test.go b/kyaml/kio/pkgio_reader_test.go index a6df5ec10..58ad083b7 100644 --- a/kyaml/kio/pkgio_reader_test.go +++ b/kyaml/kio/pkgio_reader_test.go @@ -71,12 +71,16 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'a_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'a_test.yaml' `, `c: d # second metadata: annotations: config.kubernetes.io/index: '1' config.kubernetes.io/path: 'a_test.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'a_test.yaml' `, `# second thing e: f @@ -88,18 +92,24 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'b_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'b_test.yaml' `, `a: b #third metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'c_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'c_test.yaml' `, `a: b #forth metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'd_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'd_test.yaml' `, } for i := range nodes { @@ -133,12 +143,16 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'a_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'a_test.yaml' `, `c: d # second metadata: annotations: config.kubernetes.io/index: '1' config.kubernetes.io/path: 'a_test.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'a_test.yaml' `, `# second thing e: f @@ -150,12 +164,16 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'b_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'b_test.yaml' `, `a: b #third metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'c_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'c_test.yaml' `, } for i := range nodes { @@ -191,9 +209,9 @@ func TestLocalPackageReader_Read_JSON(t *testing.T) { require.NoError(t, err) require.Len(t, nodes, 2) expected := []string{ - `{"a": "b", metadata: {annotations: {config.kubernetes.io/index: '0', config.kubernetes.io/path: 'a_test.json'}}} + `{"a": "b", metadata: {annotations: {config.kubernetes.io/index: '0', config.kubernetes.io/path: 'a_test.json', internal.config.kubernetes.io/index: '0', internal.config.kubernetes.io/path: 'a_test.json'}}} `, - `{"e": "f", "g": {"h": ["i", "j"]}, metadata: {annotations: {config.kubernetes.io/index: '0', config.kubernetes.io/path: 'b_test.json'}}} + `{"e": "f", "g": {"h": ["i", "j"]}, metadata: {annotations: {config.kubernetes.io/index: '0', config.kubernetes.io/path: 'b_test.json', internal.config.kubernetes.io/index: '0', internal.config.kubernetes.io/path: 'b_test.json'}}} `, } for i := range nodes { @@ -224,12 +242,16 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'a_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'a_test.yaml' `, `c: d # second metadata: annotations: config.kubernetes.io/index: '1' config.kubernetes.io/path: 'a_test.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'a_test.yaml' `, } for i := range nodes { @@ -297,6 +319,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'a_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'a_test.yaml' internal.config.kubernetes.io/seqindent: 'compact' `, `c: d # second @@ -304,6 +328,8 @@ metadata: annotations: config.kubernetes.io/index: '1' config.kubernetes.io/path: 'a_test.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'a_test.yaml' internal.config.kubernetes.io/seqindent: 'compact' `, `# second thing @@ -316,6 +342,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'b_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'b_test.yaml' internal.config.kubernetes.io/seqindent: 'compact' `, } @@ -347,12 +375,16 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' `, `c: d # second metadata: annotations: config.kubernetes.io/index: '1' config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' `, `# second thing e: f @@ -364,6 +396,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'a${SEP}b${SEP}b_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'a${SEP}b${SEP}b_test.yaml' `, } for i := range nodes { @@ -397,12 +431,16 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' `, `c: d # second metadata: annotations: config.kubernetes.io/index: '1' config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' `, } @@ -438,12 +476,16 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' `, `c: d # second metadata: annotations: config.kubernetes.io/index: '1' config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' `, } @@ -480,12 +522,16 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' `, `c: d # second metadata: annotations: config.kubernetes.io/index: '1' config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'a${SEP}b${SEP}a_test.yaml' `, `# second thing e: f @@ -497,6 +543,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'a${SEP}c${SEP}c_test.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'a${SEP}c${SEP}c_test.yaml' `, } diff --git a/kyaml/kio/pkgio_writer.go b/kyaml/kio/pkgio_writer.go index a31abacb2..ce6fa45a5 100644 --- a/kyaml/kio/pkgio_writer.go +++ b/kyaml/kio/pkgio_writer.go @@ -66,6 +66,7 @@ func (r LocalPackageWriter) Write(nodes []*yaml.RNode) error { if !r.KeepReaderAnnotations { r.ClearAnnotations = append(r.ClearAnnotations, kioutil.PathAnnotation) + r.ClearAnnotations = append(r.ClearAnnotations, kioutil.LegacyPathAnnotation) } // validate outputs before writing any diff --git a/kyaml/kio/pkgio_writer_test.go b/kyaml/kio/pkgio_writer_test.go index 506fa8e49..0ef664852 100644 --- a/kyaml/kio/pkgio_writer_test.go +++ b/kyaml/kio/pkgio_writer_test.go @@ -73,14 +73,18 @@ func TestLocalPackageWriter_Write_keepReaderAnnotations(t *testing.T) { require.Equal(t, `a: b #first metadata: annotations: - config.kubernetes.io/index: 0 + config.kubernetes.io/index: "0" config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/path: 'a/b/a_test.yaml' + internal.config.kubernetes.io/index: '0' --- c: d # second metadata: annotations: - config.kubernetes.io/index: 1 + config.kubernetes.io/index: "1" config.kubernetes.io/path: "a/b/a_test.yaml" + internal.config.kubernetes.io/path: 'a/b/a_test.yaml' + internal.config.kubernetes.io/index: '1' `, string(b)) b, err = fs.ReadFile(filepath.Join(d, "a", "b", "b_test.yaml")) @@ -92,8 +96,10 @@ g: - j metadata: annotations: - config.kubernetes.io/index: 0 + config.kubernetes.io/index: "0" config.kubernetes.io/path: "a/b/b_test.yaml" + internal.config.kubernetes.io/path: 'a/b/b_test.yaml' + internal.config.kubernetes.io/index: '0' `, string(b)) }) } @@ -268,7 +274,7 @@ g: metadata: annotations: config.kubernetes.io/path: a/ - config.kubernetes.io/index: 0 + config.kubernetes.io/index: "0" `) require.NoError(t, err) @@ -294,14 +300,14 @@ func getWriterInputs(t *testing.T, mockFS filesys.FileSystem) (string, *yaml.RNo node1, err := yaml.Parse(`a: b #first metadata: annotations: - config.kubernetes.io/index: 0 + config.kubernetes.io/index: "0" config.kubernetes.io/path: "a/b/a_test.yaml" `) require.NoError(t, err) node2, err := yaml.Parse(`c: d # second metadata: annotations: - config.kubernetes.io/index: 1 + config.kubernetes.io/index: "1" config.kubernetes.io/path: "a/b/a_test.yaml" `) require.NoError(t, err) @@ -312,7 +318,7 @@ g: - j metadata: annotations: - config.kubernetes.io/index: 0 + config.kubernetes.io/index: "0" config.kubernetes.io/path: "a/b/b_test.yaml" `) require.NoError(t, err) diff --git a/kyaml/kio/tree.go b/kyaml/kio/tree.go index d17293722..a14181578 100644 --- a/kyaml/kio/tree.go +++ b/kyaml/kio/tree.go @@ -32,7 +32,7 @@ var GraphStructures = []string{string(TreeStructureGraph), string(TreeStructureP // TreeWriter prints the package structured as a tree. // TODO(pwittrock): test this package better. it is lower-risk since it is only -// used for printing rather than updating or editing. +// used for printing rather than updating or editing. type TreeWriter struct { Writer io.Writer Root string @@ -49,6 +49,11 @@ type TreeWriterField struct { } func (p TreeWriter) packageStructure(nodes []*yaml.RNode) error { + for i := range nodes { + if err := kioutil.CopyLegacyAnnotations(nodes[i]); err != nil { + return err + } + } indexByPackage := p.index(nodes) // create the new tree diff --git a/kyaml/runfn/runfn.go b/kyaml/runfn/runfn.go index 217156da6..eda2c2902 100644 --- a/kyaml/runfn/runfn.go +++ b/kyaml/runfn/runfn.go @@ -343,6 +343,12 @@ func sortFns(buff *kio.PackageBuffer) error { // sort the nodes so that we traverse them depth first // functions deeper in the file system tree should be run first sort.Slice(buff.Nodes, func(i, j int) bool { + if err := kioutil.CopyLegacyAnnotations(buff.Nodes[i]); err != nil { + return false + } + if err := kioutil.CopyLegacyAnnotations(buff.Nodes[j]); err != nil { + return false + } mi, _ := buff.Nodes[i].GetMeta() pi := filepath.ToSlash(mi.Annotations[kioutil.PathAnnotation]) @@ -487,7 +493,12 @@ func (r *RunFns) ffp(spec runtimeutil.FunctionSpec, api *yaml.RNode, currentUser var p string if spec.Starlark.Path != "" { - p = filepath.ToSlash(path.Clean(m.Annotations[kioutil.PathAnnotation])) + pathAnno := m.Annotations[kioutil.PathAnnotation] + if pathAnno == "" { + pathAnno = m.Annotations[kioutil.LegacyPathAnnotation] + } + p = filepath.ToSlash(path.Clean(pathAnno)) + spec.Starlark.Path = filepath.ToSlash(path.Clean(spec.Starlark.Path)) if filepath.IsAbs(spec.Starlark.Path) || path.IsAbs(spec.Starlark.Path) { return nil, errors.Errorf( diff --git a/kyaml/setters2/set_test.go b/kyaml/setters2/set_test.go index cf69141d5..532a03e28 100644 --- a/kyaml/setters2/set_test.go +++ b/kyaml/setters2/set_test.go @@ -862,6 +862,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'cluster.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'cluster.yaml' spec: replicas: 3 # {"$ref": "#/definitions/io.k8s.cli.setters.replicas"} `, ` @@ -872,6 +874,8 @@ metadata: annotations: config.kubernetes.io/index: '1' config.kubernetes.io/path: 'cluster.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'cluster.yaml' spec: replicas: 10 `}, @@ -883,6 +887,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'cluster.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'cluster.yaml' spec: replicas: 4 # {"$ref": "#/definitions/io.k8s.cli.setters.replicas"} `, ` @@ -893,6 +899,8 @@ metadata: annotations: config.kubernetes.io/index: '1' config.kubernetes.io/path: 'cluster.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'cluster.yaml' spec: replicas: 10 `}, @@ -917,6 +925,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'cluster.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'cluster.yaml' spec: replicas: 3 # {"$ref": "#/definitions/io.k8s.cli.setters.replicas"} `, ` @@ -927,6 +937,8 @@ metadata: annotations: config.kubernetes.io/index: '1' config.kubernetes.io/path: 'another_cluster.yaml' + internal.config.kubernetes.io/index: '1' + internal.config.kubernetes.io/path: 'another_cluster.yaml' spec: replicas: 10 `}, @@ -938,6 +950,8 @@ metadata: annotations: config.kubernetes.io/index: '0' config.kubernetes.io/path: 'cluster.yaml' + internal.config.kubernetes.io/index: '0' + internal.config.kubernetes.io/path: 'cluster.yaml' spec: replicas: 4 # {"$ref": "#/definitions/io.k8s.cli.setters.replicas"} `}, diff --git a/plugin/someteam.example.com/v1/starlarkmixer/StarlarkMixer_test.go b/plugin/someteam.example.com/v1/starlarkmixer/StarlarkMixer_test.go index aa07ed1f6..a81b408c4 100644 --- a/plugin/someteam.example.com/v1/starlarkmixer/StarlarkMixer_test.go +++ b/plugin/someteam.example.com/v1/starlarkmixer/StarlarkMixer_test.go @@ -45,6 +45,7 @@ kind: ConfigMap metadata: annotations: config.kubernetes.io/path: configmap_some-cm.yaml + internal.config.kubernetes.io/path: configmap_some-cm.yaml modified-by: mixer-instance name: some-cm --- @@ -55,6 +56,7 @@ kind: ConfigMap metadata: annotations: config.kubernetes.io/path: configmap_some-cm-copy.yaml + internal.config.kubernetes.io/path: configmap_some-cm-copy.yaml name: some-cm-copy --- apiVersion: v1 @@ -62,6 +64,7 @@ kind: ConfigMap metadata: annotations: config.kubernetes.io/path: configmap_net-new.yaml + internal.config.kubernetes.io/path: configmap_net-new.yaml name: net-new `) }