mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-12 01:14:22 +00:00
Copy comments from function inputs to function outputs.
This commit is contained in:
@@ -5,11 +5,13 @@ package runtimeutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/comments"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
|
||||
@@ -44,6 +46,8 @@ type FunctionFilter struct {
|
||||
|
||||
// exit saves the error returned from Run
|
||||
exit error
|
||||
|
||||
ids map[string]*yaml.RNode
|
||||
}
|
||||
|
||||
// GetExit returns the error from Run
|
||||
@@ -138,6 +142,11 @@ func (c *FunctionFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// set ids on each input so it is possible to copy comments from inputs back to outputs
|
||||
if err := c.setIds(input); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// write the input
|
||||
err = kio.ByteWriter{
|
||||
WrappingAPIVersion: kio.ResourceListAPIVersion,
|
||||
@@ -160,6 +169,11 @@ func (c *FunctionFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// copy the comments from the inputs to the outputs
|
||||
if err := c.setComments(output); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := c.doResults(r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -178,6 +192,50 @@ 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
|
||||
c.ids = map[string]*yaml.RNode{}
|
||||
for i := range nodes {
|
||||
id++
|
||||
idStr := fmt.Sprintf("%v", id)
|
||||
err := nodes[i].PipeE(yaml.SetAnnotation(idAnnotation, idStr))
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
c.ids[idStr] = nodes[i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *FunctionFilter) setComments(nodes []*yaml.RNode) error {
|
||||
for i := range nodes {
|
||||
node := nodes[i]
|
||||
anID, err := node.Pipe(yaml.GetAnnotation(idAnnotation))
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
if anID == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var in *yaml.RNode
|
||||
var found bool
|
||||
if in, found = c.ids[anID.YNode().Value]; !found {
|
||||
continue
|
||||
}
|
||||
if err := comments.CopyComments(in, node); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
if err := node.PipeE(yaml.ClearAnnotation(idAnnotation)); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *FunctionFilter) doResults(r *kio.ByteReader) error {
|
||||
// Write the results to a file if configured to do so
|
||||
if c.ResultsFile != "" && r.Results != nil {
|
||||
|
||||
@@ -486,6 +486,7 @@ items:
|
||||
name: service-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/bar/s.yaml'
|
||||
config.k8s.io/id: '1'
|
||||
functionConfig:
|
||||
apiVersion: example.com/v1
|
||||
kind: Example
|
||||
@@ -504,6 +505,7 @@ items:
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/bar/s.yaml'
|
||||
new: annotation
|
||||
config.k8s.io/id: '1'
|
||||
functionConfig:
|
||||
apiVersion: example.com/v1
|
||||
kind: Example
|
||||
@@ -573,6 +575,7 @@ items:
|
||||
name: service-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/bar/s.yaml'
|
||||
config.k8s.io/id: '1'
|
||||
functionConfig:
|
||||
apiVersion: example.com/v1
|
||||
kind: Example
|
||||
@@ -591,6 +594,7 @@ items:
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/bar/s.yaml'
|
||||
new: annotation
|
||||
config.k8s.io/id: '1'
|
||||
functionConfig:
|
||||
apiVersion: example.com/v1
|
||||
kind: Example
|
||||
@@ -657,12 +661,14 @@ items:
|
||||
name: deployment-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'baz/bar/d.yaml'
|
||||
config.k8s.io/id: '1'
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: service-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/bar/s.yaml'
|
||||
config.k8s.io/id: '2'
|
||||
functionConfig:
|
||||
apiVersion: example.com/v1
|
||||
kind: Example
|
||||
@@ -680,6 +686,7 @@ items:
|
||||
name: deployment-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'baz/bar/d.yaml'
|
||||
config.k8s.io/id: '1'
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
@@ -687,6 +694,7 @@ items:
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/bar/s.yaml'
|
||||
new: annotation
|
||||
config.k8s.io/id: '2'
|
||||
functionConfig:
|
||||
apiVersion: example.com/v1
|
||||
kind: Example
|
||||
@@ -823,6 +831,7 @@ items:
|
||||
name: service-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/bar/s.yaml'
|
||||
config.k8s.io/id: '1'
|
||||
functionConfig:
|
||||
apiVersion: example.com/v1
|
||||
kind: Example
|
||||
@@ -840,6 +849,7 @@ items:
|
||||
name: service-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/bar/s.yaml'
|
||||
config.k8s.io/id: '1'
|
||||
new: annotation
|
||||
functionConfig:
|
||||
apiVersion: example.com/v1
|
||||
@@ -893,6 +903,107 @@ metadata:
|
||||
name: deployment-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'baz/bar/d.yaml'
|
||||
`,
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "copy_comments",
|
||||
run: testRun{
|
||||
expectedInput: `apiVersion: config.kubernetes.io/v1alpha1
|
||||
kind: ResourceList
|
||||
items:
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deployment-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/b.yaml'
|
||||
config.k8s.io/id: '1'
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: service-foo # name comment
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/a.yaml'
|
||||
config.k8s.io/id: '2'
|
||||
functionConfig:
|
||||
apiVersion: example.com/v1
|
||||
kind: Example
|
||||
metadata:
|
||||
name: foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/f.yaml'
|
||||
`,
|
||||
// delete the comment
|
||||
output: `apiVersion: config.kubernetes.io/v1alpha1
|
||||
kind: ResourceList
|
||||
items:
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deployment-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/b.yaml'
|
||||
config.k8s.io/id: '1'
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: service-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/a.yaml'
|
||||
config.k8s.io/id: '2'
|
||||
new: annotation
|
||||
functionConfig:
|
||||
apiVersion: example.com/v1
|
||||
kind: Example
|
||||
metadata:
|
||||
name: foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/f.yaml'
|
||||
`,
|
||||
},
|
||||
functionConfig: `
|
||||
apiVersion: example.com/v1
|
||||
kind: Example
|
||||
metadata:
|
||||
name: foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/f.yaml'
|
||||
`,
|
||||
input: []string{
|
||||
`
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deployment-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/b.yaml'
|
||||
`,
|
||||
`
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: service-foo # name comment
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/a.yaml'
|
||||
`},
|
||||
expectedOutput: []string{
|
||||
`
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deployment-foo
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/b.yaml'
|
||||
`, `
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: service-foo # name comment
|
||||
annotations:
|
||||
config.kubernetes.io/path: 'foo/a.yaml'
|
||||
new: annotation
|
||||
`,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
|
||||
"github.com/qri-io/starlib/util"
|
||||
"go.starlark.net/starlark"
|
||||
"sigs.k8s.io/kustomize/kyaml/comments"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio/filters"
|
||||
@@ -33,8 +32,6 @@ type Filter struct {
|
||||
Path string
|
||||
|
||||
runtimeutil.FunctionFilter
|
||||
|
||||
ids map[string]*yaml.RNode
|
||||
}
|
||||
|
||||
func (sf *Filter) String() string {
|
||||
@@ -128,23 +125,6 @@ func (sf *Filter) readResourceList(reader io.Reader) (starlark.Value, error) {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
|
||||
// set the id on each node to map inputs to outputs
|
||||
var id int
|
||||
sf.ids = map[string]*yaml.RNode{}
|
||||
items, err := rn.Pipe(yaml.Lookup("items"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
err = items.VisitElements(func(node *yaml.RNode) error {
|
||||
id++
|
||||
idStr := fmt.Sprintf("%v", id)
|
||||
sf.ids[idStr] = node
|
||||
return node.PipeE(yaml.SetAnnotation("config.k8s.io/id", idStr))
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
|
||||
// convert to a starlark value
|
||||
b, err := yaml.Marshal(rn.Document()) // convert to bytes
|
||||
if err != nil {
|
||||
@@ -182,33 +162,10 @@ func (sf *Filter) writeResourceList(value starlark.Value, writer io.Writer) erro
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
err = items.VisitElements(func(node *yaml.RNode) error {
|
||||
anID, err := node.Pipe(yaml.GetAnnotation("config.k8s.io/id"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
if anID == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var in *yaml.RNode
|
||||
var found bool
|
||||
if in, found = sf.ids[anID.YNode().Value]; !found {
|
||||
return nil
|
||||
}
|
||||
if err := node.PipeE(yaml.ClearAnnotation("config.k8s.io/id")); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
if err := comments.CopyComments(in, node); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
// starlark will serialize the resources sorting the fields alphabetically,
|
||||
// format them to have a better ordering
|
||||
fmtFltr := filters.FormatFilter{}
|
||||
if _, err := fmtFltr.Filter([]*yaml.RNode{node}); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
return nil
|
||||
_, err := filters.FormatFilter{}.Filter([]*yaml.RNode{node})
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
|
||||
Reference in New Issue
Block a user