Remove the wrappy layer.

This commit is contained in:
monopole
2021-03-10 05:38:39 -08:00
parent e4bbd04a43
commit 123a5d6e56
37 changed files with 1537 additions and 1750 deletions

View File

@@ -8,6 +8,7 @@ import (
"fmt"
"io/ioutil"
"log"
"regexp"
"strconv"
"strings"
@@ -336,6 +337,33 @@ func (rn *RNode) SetYNode(node *yaml.Node) {
*rn.value = *node
}
// GetKind returns the kind.
func (rn *RNode) GetKind() string {
node, err := rn.Pipe(FieldMatcher{Name: KindField})
if err != nil {
return ""
}
return GetValue(node)
}
// GetName returns the name.
func (rn *RNode) GetName() string {
f := rn.Field(MetadataField)
if f.IsNilOrEmpty() {
return ""
}
f = f.Value.Field(NameField)
if f.IsNilOrEmpty() {
return ""
}
return f.Value.YNode().Value
}
// SetName sets the metadata name field.
func (rn *RNode) SetName(name string) error {
return rn.SetMapField(NewScalarRNode(name), MetadataField, NameField)
}
// GetNamespace gets the metadata namespace field.
func (rn *RNode) GetNamespace() (string, error) {
meta, err := rn.GetMeta()
@@ -752,7 +780,7 @@ func (rn *RNode) GetValidatedMetadata() (ResourceMeta, error) {
return m, nil
}
// MatchesAnnotationSelector implements ifc.Kunstructured.
// MatchesAnnotationSelector returns true on a selector match to annotations.
func (rn *RNode) MatchesAnnotationSelector(selector string) (bool, error) {
s, err := labels.Parse(selector)
if err != nil {
@@ -765,7 +793,7 @@ func (rn *RNode) MatchesAnnotationSelector(selector string) (bool, error) {
return s.Matches(labels.Set(slice)), nil
}
// MatchesLabelSelector implements ifc.Kunstructured.
// MatchesLabelSelector returns true on a selector match to labels.
func (rn *RNode) MatchesLabelSelector(selector string) (bool, error) {
s, err := labels.Parse(selector)
if err != nil {
@@ -859,3 +887,123 @@ func checkKey(key string, elems []*Node) bool {
}
return count == len(elems)
}
// Deprecated: use pipes instead.
// GetSlice returns the contents of the slice field at the given path.
func (rn *RNode) GetSlice(path string) ([]interface{}, error) {
value, err := rn.GetFieldValue(path)
if err != nil {
return nil, err
}
if sliceValue, ok := value.([]interface{}); ok {
return sliceValue, nil
}
return nil, fmt.Errorf("node %s is not a slice", path)
}
// Deprecated: use pipes instead.
// GetString returns the contents of the string field at the given path.
func (rn *RNode) GetString(path string) (string, error) {
value, err := rn.GetFieldValue(path)
if err != nil {
return "", err
}
if v, ok := value.(string); ok {
return v, nil
}
return "", fmt.Errorf("node %s is not a string: %v", path, value)
}
// Deprecated: use slash paths instead.
// GetFieldValue finds period delimited fields.
// TODO: When doing kustomize var replacement, which is likely a
// a primary use of this function and the reason it returns interface{}
// rather than string, we do conversion from Nodes to Go types and back
// to nodes. We should figure out how to do replacement using raw nodes,
// assuming we keep the var feature in kustomize.
// The other end of this is: refvar.go:updateNodeValue.
func (rn *RNode) GetFieldValue(path string) (interface{}, error) {
fields := convertSliceIndex(strings.Split(path, "."))
rn, err := rn.Pipe(Lookup(fields...))
if err != nil {
return nil, err
}
if rn == nil {
return nil, NoFieldError{path}
}
yn := rn.YNode()
// If this is an alias node, resolve it
if yn.Kind == yaml.AliasNode {
yn = yn.Alias
}
// Return value as map for DocumentNode and MappingNode kinds
if yn.Kind == yaml.DocumentNode || yn.Kind == yaml.MappingNode {
var result map[string]interface{}
if err := yn.Decode(&result); err != nil {
return nil, err
}
return result, err
}
// Return value as slice for SequenceNode kind
if yn.Kind == yaml.SequenceNode {
var result []interface{}
if err := yn.Decode(&result); err != nil {
return nil, err
}
return result, nil
}
if yn.Kind != yaml.ScalarNode {
return nil, fmt.Errorf("expected ScalarNode, got Kind=%d", yn.Kind)
}
switch yn.Tag {
case NodeTagString:
return yn.Value, nil
case NodeTagInt:
return strconv.Atoi(yn.Value)
case NodeTagFloat:
return strconv.ParseFloat(yn.Value, 64)
case NodeTagBool:
return strconv.ParseBool(yn.Value)
default:
// Possibly this should be an error or log.
return yn.Value, nil
}
}
// convertSliceIndex traverses the items in `fields` and find
// if there is a slice index in the item and change it to a
// valid Lookup field path. For example, 'ports[0]' will be
// converted to 'ports' and '0'.
func convertSliceIndex(fields []string) []string {
var res []string
for _, s := range fields {
if !strings.HasSuffix(s, "]") {
res = append(res, s)
continue
}
re := regexp.MustCompile(`^(.*)\[(\d+)\]$`)
groups := re.FindStringSubmatch(s)
if len(groups) == 0 {
// no match, add to result
res = append(res, s)
continue
}
if groups[1] != "" {
res = append(res, groups[1])
}
res = append(res, groups[2])
}
return res
}
type NoFieldError struct {
Field string
}
func (e NoFieldError) Error() string {
return fmt.Sprintf("no field named '%s'", e.Field)
}