support krm spec v1 and legacy path, index, and id annotations

This commit is contained in:
Natasha Sarkar
2021-09-15 09:40:01 -07:00
parent 402f6ca72b
commit 67a5f6d68f
36 changed files with 1053 additions and 92 deletions

View File

@@ -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 + `'`,

View File

@@ -41,6 +41,9 @@ var BuildAnnotations = []string{
kioutil.PathAnnotation,
kioutil.IndexAnnotation,
kioutil.SeqIndentAnnotation,
kioutil.LegacyPathAnnotation,
kioutil.LegacyIndexAnnotation,
}
func (r *Resource) ResetRNode(incoming *Resource) {

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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:

View File

@@ -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}},
}
}

View File

@@ -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
}

View File

@@ -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
`

View File

@@ -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()

View File

@@ -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'
`,
},

View File

@@ -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)
}
}

View File

@@ -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'
`,
},
},

View File

@@ -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)

View File

@@ -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:

View File

@@ -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])
}

View File

@@ -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

View File

@@ -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{},

View File

@@ -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},
},

View File

@@ -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 {

View File

@@ -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"}}}
`,
},
}

View File

@@ -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])
}
}

View File

@@ -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())
}

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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())
})
}
}

View File

@@ -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

View File

@@ -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`},
}

View File

@@ -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
}
}

View File

@@ -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'
`,
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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(

View File

@@ -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"}
`},

View File

@@ -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
`)
}