Improve error handling in kyaml libraries

This commit is contained in:
Phillip Wittrock
2019-11-12 08:16:29 -08:00
parent 1bbd8b2c43
commit b473faccca
23 changed files with 483 additions and 96 deletions

View File

@@ -10,6 +10,7 @@ import (
"sort"
"strings"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -53,7 +54,7 @@ func (rw *ByteReadWriter) Read() ([]*yaml.RNode, error) {
rw.FunctionConfig = b.FunctionConfig
rw.WrappingApiVersion = b.WrappingApiVersion
rw.WrappingKind = b.WrappingKind
return val, err
return val, errors.Wrap(err)
}
func (rw *ByteReadWriter) Write(nodes []*yaml.RNode) error {
@@ -84,8 +85,16 @@ type ByteReader struct {
FunctionConfig *yaml.RNode
// DisableUnwrapping prevents Resources in Lists and ResourceLists from being unwrapped
DisableUnwrapping bool
// WrappingApiVersion is set by Read(), and is the apiVersion of the object that
// the read objects were originally wrapped in.
WrappingApiVersion string
WrappingKind string
// WrappingKind is set by Read(), and is the kind of the object that
// the read objects were originally wrapped in.
WrappingKind string
}
var _ Reader = &ByteReader{}
@@ -98,7 +107,7 @@ func (r *ByteReader) Read() ([]*yaml.RNode, error) {
input := &bytes.Buffer{}
_, err := io.Copy(input, r.Reader)
if err != nil {
return nil, err
return nil, errors.Wrap(err)
}
values := strings.Split(input.String(), "\n---\n")
@@ -110,7 +119,7 @@ func (r *ByteReader) Read() ([]*yaml.RNode, error) {
continue
}
if err != nil {
return nil, err
return nil, errors.Wrap(err)
}
if yaml.IsMissingOrNull(node) {
// empty value
@@ -118,12 +127,18 @@ func (r *ByteReader) Read() ([]*yaml.RNode, error) {
}
// ok if no metadata -- assume not an InputList
meta, _ := node.GetMeta()
meta, err := node.GetMeta()
if err != yaml.ErrMissingMetadata && err != nil {
return nil, errors.WrapPrefixf(err, "[%d]", i)
}
// the elements are wrapped in an InputList, unwrap them
// don't check apiVersion, we haven't standardized on the domain
if (meta.Kind == ResourceListKind || meta.Kind == "List") &&
if !r.DisableUnwrapping &&
len(values) == 1 && // Only unwrap if there is only 1 value
(meta.Kind == ResourceListKind || meta.Kind == "List") &&
node.Field("items") != nil {
r.WrappingKind = meta.Kind
r.WrappingApiVersion = meta.ApiVersion
@@ -166,7 +181,7 @@ func (r *ByteReader) decode(index int, decoder *yaml.Decoder) (*yaml.RNode, erro
return nil, io.EOF
}
if err != nil {
return nil, err
return nil, errors.Wrap(err)
}
if isEmptyDocument(node) {
@@ -191,7 +206,7 @@ func (r *ByteReader) decode(index int, decoder *yaml.Decoder) (*yaml.RNode, erro
for _, k := range keys {
_, err = n.Pipe(yaml.SetAnnotation(k, r.SetAnnotations[k]))
if err != nil {
return nil, err
return nil, errors.Wrap(err)
}
}
return yaml.NewRNode(node), nil

View File

@@ -6,6 +6,7 @@ package kio
import (
"io"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -46,7 +47,7 @@ var _ Writer = ByteWriter{}
func (w ByteWriter) Write(nodes []*yaml.RNode) error {
if w.Sort {
if err := kioutil.SortNodes(nodes); err != nil {
return err
return errors.Wrap(err)
}
}
@@ -58,13 +59,13 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error {
if !w.KeepReaderAnnotations {
_, err := nodes[i].Pipe(yaml.ClearAnnotation(kioutil.IndexAnnotation))
if err != nil {
return err
return errors.Wrap(err)
}
}
for _, a := range w.ClearAnnotations {
_, err := nodes[i].Pipe(yaml.ClearAnnotation(a))
if err != nil {
return err
return errors.Wrap(err)
}
}
@@ -72,11 +73,11 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error {
_, err := nodes[i].Pipe(yaml.Lookup("metadata"), yaml.FieldClearer{
Name: "annotations", IfEmpty: true})
if err != nil {
return err
return errors.Wrap(err)
}
_, err = nodes[i].Pipe(yaml.FieldClearer{Name: "metadata", IfEmpty: true})
if err != nil {
return err
return errors.Wrap(err)
}
if w.Style != 0 {
@@ -89,7 +90,7 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error {
for i := range nodes {
err := encoder.Encode(nodes[i].Document())
if err != nil {
return err
return errors.Wrap(err)
}
}
return nil
@@ -118,5 +119,5 @@ func (w ByteWriter) Write(nodes []*yaml.RNode) error {
for i := range nodes {
items.Content = append(items.Content, nodes[i].YNode())
}
return encoder.Encode(doc)
return errors.Wrap(encoder.Encode(doc))
}

View File

@@ -6,6 +6,7 @@
package kio
import (
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -85,7 +86,7 @@ func (p Pipeline) Execute() error {
for _, i := range p.Inputs {
nodes, err := i.Read()
if err != nil {
return err
return errors.Wrap(err)
}
result = append(result, nodes...)
}
@@ -100,14 +101,14 @@ func (p Pipeline) Execute() error {
op := p.Filters[i]
result, err = op.Filter(result)
if len(result) == 0 || err != nil {
return err
return errors.Wrap(err)
}
}
// write to the outputs
for _, o := range p.Outputs {
if err := o.Write(result); err != nil {
return err
return errors.Wrap(err)
}
}
return nil
@@ -119,7 +120,7 @@ func FilterAll(filter yaml.Filter) Filter {
for i := range nodes {
_, err := filter.Filter(nodes[i])
if err != nil {
return nil, err
return nil, errors.Wrap(err)
}
}
return nodes, nil

View File

@@ -8,6 +8,7 @@ import (
"sort"
"strconv"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -40,10 +41,10 @@ func ErrorIfMissingAnnotation(nodes []*yaml.RNode, keys ...AnnotationKey) error
for _, node := range nodes {
val, err := node.Pipe(yaml.GetAnnotation(key))
if err != nil {
return err
return errors.Wrap(err)
}
if val == nil {
return fmt.Errorf("missing package annotation %s", key)
return errors.Errorf("missing package annotation %s", key)
}
}
}
@@ -56,7 +57,7 @@ func Map(nodes []*yaml.RNode, fn func(*yaml.RNode) (*yaml.RNode, error)) ([]*yam
for i := range nodes {
n, err := fn(nodes[i])
if err != nil {
return nil, err
return nil, errors.Wrap(err)
}
if n != nil {
returnNodes = append(returnNodes, n)
@@ -71,11 +72,11 @@ func MapMeta(nodes []*yaml.RNode, fn func(*yaml.RNode, yaml.ResourceMeta) (*yaml
for i := range nodes {
meta, err := nodes[i].GetMeta()
if err != nil {
return nil, err
return nil, errors.Wrap(err)
}
n, err := fn(nodes[i], meta)
if err != nil {
return nil, err
return nil, errors.Wrap(err)
}
if n != nil {
returnNodes = append(returnNodes, n)
@@ -141,5 +142,5 @@ func SortNodes(nodes []*yaml.RNode) error {
// elements are equal
return false
})
return err
return errors.Wrap(err)
}

View File

@@ -8,6 +8,7 @@ import (
"os"
"path/filepath"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
"sigs.k8s.io/kustomize/kyaml/sets"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -81,13 +82,13 @@ func (r *LocalPackageReadWriter) Read() ([]*yaml.RNode, error) {
SetAnnotations: r.SetAnnotations,
}.Read()
if err != nil {
return nil, err
return nil, errors.Wrap(err)
}
// keep track of all the files
if !r.NoDeleteFiles {
r.files, err = r.getFiles(nodes)
if err != nil {
return nil, err
return nil, errors.Wrap(err)
}
}
return nodes, nil
@@ -96,7 +97,7 @@ func (r *LocalPackageReadWriter) Read() ([]*yaml.RNode, error) {
func (r *LocalPackageReadWriter) Write(nodes []*yaml.RNode) error {
newFiles, err := r.getFiles(nodes)
if err != nil {
return err
return errors.Wrap(err)
}
var clear []string
for k := range r.SetAnnotations {
@@ -108,12 +109,12 @@ func (r *LocalPackageReadWriter) Write(nodes []*yaml.RNode) error {
KeepReaderAnnotations: r.KeepReaderAnnotations,
}.Write(nodes)
if err != nil {
return err
return errors.Wrap(err)
}
deleteFiles := r.files.Difference(newFiles)
for f := range deleteFiles {
if err = os.Remove(filepath.Join(r.PackagePath, f)); err != nil {
return err
return errors.Wrap(err)
}
}
return nil
@@ -124,7 +125,7 @@ func (r *LocalPackageReadWriter) getFiles(nodes []*yaml.RNode) (sets.String, err
for _, n := range nodes {
path, _, err := kioutil.GetFileAnnotations(n)
if err != nil {
return nil, err
return nil, errors.Wrap(err)
}
val.Insert(path)
}
@@ -182,7 +183,7 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) {
err := filepath.Walk(r.PackagePath, func(
path string, info os.FileInfo, err error) error {
if err != nil {
return err
return errors.Wrap(err)
}
// is this the user specified path?
@@ -213,13 +214,13 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) {
// to another location.
path, err = filepath.Rel(pathRelativeTo, path)
if err != nil {
return err
return errors.WrapPrefixf(err, pathRelativeTo)
}
r.initReaderAnnotations(path, info)
nodes, err := r.readFile(filepath.Join(pathRelativeTo, path), info)
if err != nil {
return err
return errors.WrapPrefixf(err, filepath.Join(pathRelativeTo, path))
}
operand = append(operand, nodes...)
return nil
@@ -235,6 +236,7 @@ func (r *LocalPackageReader) readFile(path string, info os.FileInfo) ([]*yaml.RN
}
defer f.Close()
rr := &ByteReader{
DisableUnwrapping: true,
Reader: f,
OmitReaderAnnotations: r.OmitReaderAnnotations,
SetAnnotations: r.SetAnnotations,
@@ -247,7 +249,7 @@ func (r *LocalPackageReader) shouldSkipFile(info os.FileInfo) (bool, error) {
// check if the files are in scope
for _, g := range r.MatchFilesGlob {
if match, err := filepath.Match(g, info.Name()); err != nil {
return false, err
return false, errors.Wrap(err)
} else if match {
return true, nil
}
@@ -276,7 +278,7 @@ func (r *LocalPackageReader) shouldSkipDir(path string) error {
if os.IsNotExist(err) {
return nil
} else if err != nil {
return err
return errors.Wrap(err)
}
if !r.IncludeSubpackages {
return filepath.SkipDir

View File

@@ -9,6 +9,7 @@ import (
"path/filepath"
"strings"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -52,7 +53,7 @@ func (r LocalPackageWriter) Write(nodes []*yaml.RNode) error {
}
for k := range outputFiles {
if err = kioutil.SortNodes(outputFiles[k]); err != nil {
return err
return errors.Wrap(err)
}
}
@@ -66,7 +67,7 @@ func (r LocalPackageWriter) Write(nodes []*yaml.RNode) error {
outputPath := filepath.Join(r.PackagePath, path)
if st, err := os.Stat(outputPath); !os.IsNotExist(err) {
if err != nil {
return err
return errors.Wrap(err)
}
if st.IsDir() {
return fmt.Errorf("config.kubernetes.io/path cannot be a directory: %s", path)
@@ -75,7 +76,7 @@ func (r LocalPackageWriter) Write(nodes []*yaml.RNode) error {
err = os.MkdirAll(filepath.Dir(outputPath), 0700)
if err != nil {
return err
return errors.Wrap(err)
}
}
@@ -84,12 +85,12 @@ func (r LocalPackageWriter) Write(nodes []*yaml.RNode) error {
outputPath := filepath.Join(r.PackagePath, path)
err = os.MkdirAll(filepath.Dir(filepath.Join(r.PackagePath, path)), 0700)
if err != nil {
return err
return errors.Wrap(err)
}
f, err := os.OpenFile(outputPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(0600))
if err != nil {
return err
return errors.Wrap(err)
}
if err := func() error {
defer f.Close()
@@ -99,11 +100,11 @@ func (r LocalPackageWriter) Write(nodes []*yaml.RNode) error {
ClearAnnotations: r.ClearAnnotations,
}
if err = w.Write(outputFiles[path]); err != nil {
return err
return errors.Wrap(err)
}
return nil
}(); err != nil {
return err
return errors.Wrap(err)
}
}
@@ -115,10 +116,10 @@ func (r LocalPackageWriter) errorIfMissingRequiredAnnotation(nodes []*yaml.RNode
for _, s := range requiredResourcePackageAnnotations {
key, err := nodes[i].Pipe(yaml.GetAnnotation(s))
if err != nil {
return err
return errors.Wrap(err)
}
if key == nil || key.YNode() == nil || key.YNode().Value == "" {
return fmt.Errorf(
return errors.Errorf(
"resources must be annotated with %s to be written to files", s)
}
}
@@ -135,13 +136,13 @@ func (r LocalPackageWriter) indexByFilePath(nodes []*yaml.RNode) (map[string][]*
value, err := node.Pipe(yaml.GetAnnotation(kioutil.PathAnnotation))
if err != nil {
// this should never happen if errorIfMissingRequiredAnnotation was run
return nil, err
return nil, errors.Wrap(err)
}
path := value.YNode().Value
outputFiles[path] = append(outputFiles[path], node)
if filepath.IsAbs(path) {
return nil, fmt.Errorf("package paths may not be absolute paths")
return nil, errors.Errorf("package paths may not be absolute paths")
}
if strings.Contains(filepath.Clean(path), "..") {
return nil, fmt.Errorf("resource must be written under package %s: %s",