mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-28 17:28:18 +00:00
Compare commits
23 Commits
cmd/config
...
release-cm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b47e34ea5e | ||
|
|
762e587471 | ||
|
|
fd5eeb1645 | ||
|
|
ff5051711f | ||
|
|
51268a5f06 | ||
|
|
9be38e815e | ||
|
|
88c318bf46 | ||
|
|
7ee75c33a9 | ||
|
|
2b328eeb36 | ||
|
|
616363ee73 | ||
|
|
0e13eadd7a | ||
|
|
0c37388135 | ||
|
|
5d1352882b | ||
|
|
c469e80cad | ||
|
|
5559601ecb | ||
|
|
01b34c8ea0 | ||
|
|
eba0ffdde2 | ||
|
|
31c59bd7f2 | ||
|
|
2da8959198 | ||
|
|
dc591f0a10 | ||
|
|
c94f164e66 | ||
|
|
fb216d8af8 | ||
|
|
ca807019f0 |
13
README.md
13
README.md
@@ -9,18 +9,15 @@ patch [kubernetes style] API objects. It's like
|
||||
[`make`], in that what it does is declared in a file,
|
||||
and it's like [`sed`], in that it emits edited text.
|
||||
|
||||
This tool is sponsored by [sig-cli] ([KEP]), and
|
||||
inspired by [DAM].
|
||||
This tool is sponsored by [sig-cli] ([KEP]).
|
||||
|
||||
- [Installation instructions](https://kubernetes-sigs.github.io/kustomize/installation)
|
||||
- [General documentation](https://kubernetes-sigs.github.io/kustomize)
|
||||
- [Examples](examples)
|
||||
|
||||
[](https://prow.k8s.io/job-history/kubernetes-jenkins/pr-logs/directory/kustomize-presubmit-master)
|
||||
[](https://goreportcard.com/report/github.com/kubernetes-sigs/kustomize)
|
||||
|
||||
Download a binary from the [release page], or see
|
||||
these [instructions](https://kubernetes-sigs.github.io/kustomize/installation/).
|
||||
|
||||
Browse the [docs](https://kubernetes-sigs.github.io/kustomize/) or jump right into the
|
||||
tested [examples](examples).
|
||||
|
||||
## kubectl integration
|
||||
|
||||
Since [v1.14][kubectl announcement] the kustomize build system has been included in kubectl.
|
||||
|
||||
@@ -112,7 +112,7 @@ func (ns Filter) roleBindingHack(obj *yaml.RNode, meta yaml.ResourceMeta) error
|
||||
// Lookup the namespace field on all elements.
|
||||
// We should change the fieldspec so this isn't necessary.
|
||||
obj, err := obj.Pipe(yaml.Lookup(subjectsField))
|
||||
if err != nil || yaml.IsEmpty(obj) {
|
||||
if err != nil || yaml.IsMissingOrNull(obj) {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ func (ns Filter) roleBindingHack(obj *yaml.RNode, meta yaml.ResourceMeta) error
|
||||
name, err := o.Pipe(
|
||||
yaml.Lookup("name"), yaml.Match("default"),
|
||||
)
|
||||
if err != nil || yaml.IsEmpty(name) {
|
||||
if err != nil || yaml.IsMissingOrNull(name) {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -66,8 +66,7 @@ func updateNodeValue(node *yaml.Node, newValue interface{}) {
|
||||
}
|
||||
|
||||
func (f Filter) setScalar(node *yaml.RNode) error {
|
||||
if node.YNode().Kind != yaml.ScalarNode || node.YNode().Tag != yaml.NodeTagString {
|
||||
// Only process string values
|
||||
if !yaml.IsYNodeString(node.YNode()) {
|
||||
return nil
|
||||
}
|
||||
v := expansion2.Expand(node.YNode().Value, f.MappingFunc)
|
||||
@@ -78,11 +77,10 @@ func (f Filter) setScalar(node *yaml.RNode) error {
|
||||
func (f Filter) setMap(node *yaml.RNode) error {
|
||||
contents := node.YNode().Content
|
||||
for i := 0; i < len(contents); i += 2 {
|
||||
if contents[i].Kind != yaml.ScalarNode || contents[i].Tag != yaml.NodeTagString {
|
||||
if !yaml.IsYNodeString(contents[i]) {
|
||||
return fmt.Errorf("invalid map key: %s, type: %s", contents[i].Value, contents[i].Tag)
|
||||
}
|
||||
if contents[i+1].Kind != yaml.ScalarNode || contents[i+1].Tag != yaml.NodeTagString {
|
||||
// value is not a string
|
||||
if !yaml.IsYNodeString(contents[i+1]) {
|
||||
continue
|
||||
}
|
||||
newValue := expansion2.Expand(contents[i+1].Value, f.MappingFunc)
|
||||
@@ -93,8 +91,7 @@ func (f Filter) setMap(node *yaml.RNode) error {
|
||||
|
||||
func (f Filter) setSeq(node *yaml.RNode) error {
|
||||
for _, item := range node.YNode().Content {
|
||||
if item.Kind != yaml.ScalarNode || item.Tag != yaml.NodeTagString {
|
||||
// value is not a string
|
||||
if !yaml.IsYNodeString(item) {
|
||||
return fmt.Errorf("invalid value type expect a string")
|
||||
}
|
||||
newValue := expansion2.Expand(item.Value, f.MappingFunc)
|
||||
|
||||
@@ -14,6 +14,6 @@ require (
|
||||
k8s.io/cli-runtime v0.17.3
|
||||
k8s.io/client-go v0.17.3
|
||||
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd
|
||||
sigs.k8s.io/cli-utils v0.17.0
|
||||
sigs.k8s.io/kustomize/kyaml v0.5.0
|
||||
sigs.k8s.io/cli-utils v0.18.0
|
||||
sigs.k8s.io/kustomize/kyaml v0.6.0
|
||||
)
|
||||
|
||||
@@ -619,6 +619,8 @@ modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs
|
||||
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
|
||||
sigs.k8s.io/cli-utils v0.17.0 h1:iQ0nhgU8DZiRphHTErI1IHcHYp2fZaULrrFN4NF3dCc=
|
||||
sigs.k8s.io/cli-utils v0.17.0/go.mod h1:9Jqm9K2W6ShhCxsEuaz6HSRKKOXigPUx3ZfypGgxBLY=
|
||||
sigs.k8s.io/cli-utils v0.18.0 h1:PPFUhhwKsdMiYYm1DY9lZursNWSAEj8FYgMCZKVvOkQ=
|
||||
sigs.k8s.io/cli-utils v0.18.0/go.mod h1:B7KdqkSkHNIUn3cFbaR4aKUZMKtr+Benboi1w/HW/Fg=
|
||||
sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
|
||||
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
||||
@@ -626,6 +628,8 @@ sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5
|
||||
sigs.k8s.io/kustomize/kyaml v0.4.0/go.mod h1:XJL84E6sOFeNrQ7CADiemc1B0EjIxHo3OhW4o1aJYNw=
|
||||
sigs.k8s.io/kustomize/kyaml v0.5.0 h1:xufpSxgpugQxtd0aN1ZsWnr3Kj0fpAi7GN4dnEs4oPg=
|
||||
sigs.k8s.io/kustomize/kyaml v0.5.0/go.mod h1:bEzbO5pN9OvlEeCLvFHo8Pu7SA26Herc2m60UeWZBdI=
|
||||
sigs.k8s.io/kustomize/kyaml v0.6.0 h1:Z/9TxsiG21sbcd6JD4IeM6BVZ2+04001KKzbxCf+qeY=
|
||||
sigs.k8s.io/kustomize/kyaml v0.6.0/go.mod h1:bEzbO5pN9OvlEeCLvFHo8Pu7SA26Herc2m60UeWZBdI=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
|
||||
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
|
||||
|
||||
@@ -177,13 +177,13 @@ func (r *XArgsRunner) runE(c *cobra.Command, _ []string) error {
|
||||
}
|
||||
|
||||
if r.WrapKind != "" {
|
||||
if kind := rw.FunctionConfig.Field("kind"); !yaml.IsFieldEmpty(kind) {
|
||||
if kind := rw.FunctionConfig.Field("kind"); !kind.IsNilOrEmpty() {
|
||||
kind.Value.YNode().Value = r.WrapKind
|
||||
}
|
||||
rw.WrappingKind = r.WrapKind
|
||||
}
|
||||
if r.WrapVersion != "" {
|
||||
if version := rw.FunctionConfig.Field("apiVersion"); !yaml.IsFieldEmpty(version) {
|
||||
if version := rw.FunctionConfig.Field("apiVersion"); !version.IsNilOrEmpty() {
|
||||
version.Value.YNode().Value = r.WrapVersion
|
||||
}
|
||||
rw.WrappingAPIVersion = r.WrapVersion
|
||||
|
||||
@@ -8,13 +8,14 @@ require (
|
||||
github.com/spf13/pflag v1.0.5
|
||||
k8s.io/client-go v0.17.3
|
||||
sigs.k8s.io/kustomize/api v0.5.1
|
||||
sigs.k8s.io/kustomize/cmd/config v0.4.2
|
||||
sigs.k8s.io/kustomize/cmd/config v0.5.0
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
||||
replace (
|
||||
sigs.k8s.io/kustomize/api v0.5.1 => ../api
|
||||
sigs.k8s.io/kustomize/cmd/config v0.4.2 => ../cmd/config
|
||||
sigs.k8s.io/kustomize/cmd/config v0.5.0 => ../cmd/config
|
||||
sigs.k8s.io/kustomize/kyaml => ../kyaml
|
||||
)
|
||||
|
||||
exclude (
|
||||
|
||||
@@ -138,7 +138,7 @@ func getFunctionSpecFromAnnotation(n *yaml.RNode, meta yaml.ResourceMeta) *Funct
|
||||
}
|
||||
}
|
||||
n, err := n.Pipe(yaml.Lookup("metadata", "configFn"))
|
||||
if err != nil || yaml.IsEmpty(n) {
|
||||
if err != nil || yaml.IsMissingOrNull(n) {
|
||||
return nil
|
||||
}
|
||||
s, err := n.String()
|
||||
|
||||
@@ -238,10 +238,10 @@ func ownerToString(node *yaml.RNode) (string, error) {
|
||||
owner := elements[0]
|
||||
var kind, name string
|
||||
|
||||
if value := owner.Field("kind"); !yaml.IsFieldEmpty(value) {
|
||||
if value := owner.Field("kind"); !value.IsNilOrEmpty() {
|
||||
kind = value.Value.YNode().Value
|
||||
}
|
||||
if value := owner.Field("name"); !yaml.IsFieldEmpty(value) {
|
||||
if value := owner.Field("name"); !value.IsNilOrEmpty() {
|
||||
name = value.Value.YNode().Value
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ type ResourceSchema struct {
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the ResourceSchema is empty
|
||||
func (rs *ResourceSchema) IsEmpty() bool {
|
||||
func (rs *ResourceSchema) IsMissingOrNull() bool {
|
||||
if rs == nil || rs.Schema == nil {
|
||||
return true
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func AddSchemaFromFileUsingField(path, field string) error {
|
||||
if field != "" {
|
||||
// get the field containing the openAPI
|
||||
m := y.Field(field)
|
||||
if yaml.IsFieldEmpty(m) {
|
||||
if m.IsNilOrEmpty() {
|
||||
// doesn't contain openAPI definitions
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func (l *List) listSetters(object *yaml.RNode, resourcePath string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if yaml.IsEmpty(def) {
|
||||
if yaml.IsMissingOrNull(def) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func (l *List) listSetters(object *yaml.RNode, resourcePath string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if yaml.IsEmpty(setterNode) {
|
||||
if yaml.IsMissingOrNull(setterNode) {
|
||||
// has the setter prefix, but missing the setter extension
|
||||
return errors.Errorf("missing x-k8s-cli.setter for %s", key)
|
||||
}
|
||||
@@ -126,7 +126,7 @@ func (l *List) listSubst(object *yaml.RNode) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if yaml.IsEmpty(def) {
|
||||
if yaml.IsMissingOrNull(def) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ func (l *List) listSubst(object *yaml.RNode) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if yaml.IsEmpty(substNode) {
|
||||
if yaml.IsMissingOrNull(substNode) {
|
||||
// has the substitution prefix, but missing the setter extension
|
||||
return errors.Errorf("missing x-k8s-cli.substitution for %s", key)
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ func getSchema(r *yaml.RNode, s *openapi.ResourceSchema, field string) *openapi.
|
||||
return s
|
||||
}
|
||||
|
||||
if yaml.IsEmpty(r) {
|
||||
if yaml.IsMissingOrNull(r) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ func (e ElementSetter) Filter(rn *RNode) (*RNode, error) {
|
||||
newNode := NewRNode(elem)
|
||||
|
||||
// empty elements are not valid -- they at least need an associative key
|
||||
if IsEmpty(newNode) || IsEmptyMap(newNode) {
|
||||
if IsMissingOrNull(newNode) || IsEmptyMap(newNode) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -482,7 +482,7 @@ func (s FieldSetter) Filter(rn *RNode) (*RNode, error) {
|
||||
}
|
||||
|
||||
// Clear the field if it is empty, or explicitly null
|
||||
if s.Value == nil || IsNull(s.Value) {
|
||||
if s.Value == nil || s.Value.IsTaggedNull() {
|
||||
return rn.Pipe(Clear(s.Name))
|
||||
}
|
||||
|
||||
@@ -549,7 +549,7 @@ func IsFoundOrError(rn *RNode, err error) bool {
|
||||
|
||||
func ErrorIfAnyInvalidAndNonNull(kind yaml.Kind, rn ...*RNode) error {
|
||||
for i := range rn {
|
||||
if IsEmpty(rn[i]) {
|
||||
if IsMissingOrNull(rn[i]) {
|
||||
continue
|
||||
}
|
||||
if err := ErrorIfInvalid(rn[i], kind); err != nil {
|
||||
@@ -568,7 +568,7 @@ var nodeTypeIndex = map[yaml.Kind]string{
|
||||
}
|
||||
|
||||
func ErrorIfInvalid(rn *RNode, kind yaml.Kind) error {
|
||||
if rn == nil || rn.YNode() == nil || IsNull(rn) {
|
||||
if IsMissingOrNull(rn) {
|
||||
// node has no type, pass validation
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -52,11 +52,11 @@ func (m Merger) VisitMap(nodes walk.Sources, s *openapi.ResourceSchema) (*yaml.R
|
||||
if err := m.SetStyle(nodes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if yaml.IsEmpty(nodes.Dest()) {
|
||||
if yaml.IsMissingOrNull(nodes.Dest()) {
|
||||
// Add
|
||||
return nodes.Origin(), nil
|
||||
}
|
||||
if yaml.IsNull(nodes.Origin()) {
|
||||
if nodes.Origin().IsTaggedNull() {
|
||||
// clear the value
|
||||
return walk.ClearNode, nil
|
||||
}
|
||||
@@ -108,11 +108,11 @@ func (m Merger) VisitList(nodes walk.Sources, s *openapi.ResourceSchema, kind wa
|
||||
}
|
||||
|
||||
// Add
|
||||
if yaml.IsEmpty(nodes.Dest()) {
|
||||
if yaml.IsMissingOrNull(nodes.Dest()) {
|
||||
return nodes.Origin(), nil
|
||||
}
|
||||
// Clear
|
||||
if yaml.IsNull(nodes.Origin()) {
|
||||
if nodes.Origin().IsTaggedNull() {
|
||||
return walk.ClearNode, nil
|
||||
}
|
||||
// Recursively Merge dest
|
||||
|
||||
@@ -20,7 +20,7 @@ const (
|
||||
type Visitor struct{}
|
||||
|
||||
func (m Visitor) VisitMap(nodes walk.Sources, s *openapi.ResourceSchema) (*yaml.RNode, error) {
|
||||
if yaml.IsNull(nodes.Updated()) || yaml.IsNull(nodes.Dest()) {
|
||||
if nodes.Updated().IsTaggedNull() || nodes.Dest().IsTaggedNull() {
|
||||
// explicitly cleared from either dest or update
|
||||
return walk.ClearNode, nil
|
||||
}
|
||||
@@ -39,11 +39,11 @@ func (m Visitor) VisitMap(nodes walk.Sources, s *openapi.ResourceSchema) (*yaml.
|
||||
}
|
||||
|
||||
func (m Visitor) visitAList(nodes walk.Sources, _ *openapi.ResourceSchema) (*yaml.RNode, error) {
|
||||
if yaml.IsEmpty(nodes.Updated()) && !yaml.IsEmpty(nodes.Origin()) {
|
||||
if yaml.IsMissingOrNull(nodes.Updated()) && !yaml.IsMissingOrNull(nodes.Origin()) {
|
||||
// implicitly cleared from update -- element was deleted
|
||||
return walk.ClearNode, nil
|
||||
}
|
||||
if yaml.IsEmpty(nodes.Dest()) {
|
||||
if yaml.IsMissingOrNull(nodes.Dest()) {
|
||||
// not cleared, but missing from the dest
|
||||
// initialize a new value that can be recursively merged
|
||||
return yaml.NewRNode(&yaml.Node{Kind: yaml.SequenceNode}), nil
|
||||
@@ -54,15 +54,15 @@ func (m Visitor) visitAList(nodes walk.Sources, _ *openapi.ResourceSchema) (*yam
|
||||
}
|
||||
|
||||
func (m Visitor) VisitScalar(nodes walk.Sources, s *openapi.ResourceSchema) (*yaml.RNode, error) {
|
||||
if yaml.IsNull(nodes.Updated()) || yaml.IsNull(nodes.Dest()) {
|
||||
if nodes.Updated().IsTaggedNull() || nodes.Dest().IsTaggedNull() {
|
||||
// explicitly cleared from either dest or update
|
||||
return nil, nil
|
||||
}
|
||||
if yaml.IsEmpty(nodes.Updated()) != yaml.IsEmpty(nodes.Origin()) {
|
||||
if yaml.IsMissingOrNull(nodes.Updated()) != yaml.IsMissingOrNull(nodes.Origin()) {
|
||||
// value added or removed in update
|
||||
return nodes.Updated(), nil
|
||||
}
|
||||
if yaml.IsEmpty(nodes.Updated()) && yaml.IsEmpty(nodes.Origin()) {
|
||||
if yaml.IsMissingOrNull(nodes.Updated()) && yaml.IsMissingOrNull(nodes.Origin()) {
|
||||
// value added or removed in update
|
||||
return nodes.Dest(), nil
|
||||
}
|
||||
@@ -91,16 +91,16 @@ func (m Visitor) VisitScalar(nodes walk.Sources, s *openapi.ResourceSchema) (*ya
|
||||
}
|
||||
|
||||
func (m Visitor) visitNAList(nodes walk.Sources) (*yaml.RNode, error) {
|
||||
if yaml.IsNull(nodes.Updated()) || yaml.IsNull(nodes.Dest()) {
|
||||
if nodes.Updated().IsTaggedNull() || nodes.Dest().IsTaggedNull() {
|
||||
// explicitly cleared from either dest or update
|
||||
return walk.ClearNode, nil
|
||||
}
|
||||
|
||||
if yaml.IsEmpty(nodes.Updated()) != yaml.IsEmpty(nodes.Origin()) {
|
||||
if yaml.IsMissingOrNull(nodes.Updated()) != yaml.IsMissingOrNull(nodes.Origin()) {
|
||||
// value added or removed in update
|
||||
return nodes.Updated(), nil
|
||||
}
|
||||
if yaml.IsEmpty(nodes.Updated()) && yaml.IsEmpty(nodes.Origin()) {
|
||||
if yaml.IsMissingOrNull(nodes.Updated()) && yaml.IsMissingOrNull(nodes.Origin()) {
|
||||
// value not present in source or dest
|
||||
return nodes.Dest(), nil
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ func IsAssociative(schema *openapi.ResourceSchema, nodes []*yaml.RNode, infer bo
|
||||
}
|
||||
for i := range nodes {
|
||||
node := nodes[i]
|
||||
if yaml.IsEmpty(node) {
|
||||
if yaml.IsMissingOrNull(node) {
|
||||
continue
|
||||
}
|
||||
if node.IsAssociative() {
|
||||
|
||||
@@ -33,48 +33,32 @@ func MakeNullNode() *RNode {
|
||||
return NewRNode(&Node{Tag: NodeTagNull})
|
||||
}
|
||||
|
||||
// IsMissingOrNull returns true if the RNode is nil or contains and explicitly null value.
|
||||
// IsMissingOrNull is true if the RNode is nil or explicitly tagged null.
|
||||
// TODO: make this a method on RNode.
|
||||
func IsMissingOrNull(node *RNode) bool {
|
||||
return IsNil(node) || node.YNode().Tag == NodeTagNull
|
||||
return node.IsNil() || node.YNode().Tag == NodeTagNull
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the RNode is MissingOrNull
|
||||
func IsEmpty(node *RNode) bool {
|
||||
return IsMissingOrNull(node)
|
||||
}
|
||||
|
||||
// IsEmptyMap returns true if the RNode is an empty node or an empty map
|
||||
// IsEmptyMap returns true if the RNode is an empty node or an empty map.
|
||||
// TODO: make this a method on RNode.
|
||||
func IsEmptyMap(node *RNode) bool {
|
||||
if IsEmpty(node) {
|
||||
return true
|
||||
}
|
||||
return IsYNodeEmptyMap(node.YNode())
|
||||
return IsMissingOrNull(node) || IsYNodeEmptyMap(node.YNode())
|
||||
}
|
||||
|
||||
// IsNil return true if the node is nil, or its underlying YNode is nil.
|
||||
func IsNil(node *RNode) bool {
|
||||
return node == nil || node.YNode() == nil
|
||||
}
|
||||
|
||||
func IsNull(node *RNode) bool {
|
||||
return !IsNil(node) && node.YNode().Tag == NodeTagNull
|
||||
}
|
||||
|
||||
func IsFieldEmpty(node *MapNode) bool {
|
||||
if node == nil || node.Value == nil || node.Value.YNode() == nil ||
|
||||
node.Value.YNode().Tag == NodeTagNull {
|
||||
return true
|
||||
}
|
||||
return IsYNodeEmptyMap(node.Value.YNode()) ||
|
||||
IsYNodeEmptySeq(node.Value.YNode())
|
||||
// IsYNodeTaggedNull returns true if the node is explicitly tagged Null.
|
||||
func IsYNodeTaggedNull(n *yaml.Node) bool {
|
||||
return n != nil && n.Tag == NodeTagNull
|
||||
}
|
||||
|
||||
// IsYNodeEmptyMap is true if the Node is a non-nil empty map.
|
||||
func IsYNodeEmptyMap(n *yaml.Node) bool {
|
||||
return n.Kind == yaml.MappingNode && len(n.Content) == 0
|
||||
return n != nil && n.Kind == yaml.MappingNode && len(n.Content) == 0
|
||||
}
|
||||
|
||||
|
||||
// IsYNodeEmptyMap is true if the Node is a non-nil empty sequence.
|
||||
func IsYNodeEmptySeq(n *yaml.Node) bool {
|
||||
return n.Kind == yaml.SequenceNode && len(n.Content) == 0
|
||||
return n != nil && n.Kind == yaml.SequenceNode && len(n.Content) == 0
|
||||
}
|
||||
|
||||
// IsYNodeEmptyDoc is true if the node is a Document with no content.
|
||||
@@ -89,17 +73,12 @@ func IsYNodeString(n *yaml.Node) bool {
|
||||
|
||||
// GetValue returns underlying yaml.Node Value field
|
||||
func GetValue(node *RNode) string {
|
||||
if IsEmpty(node) {
|
||||
if IsMissingOrNull(node) {
|
||||
return ""
|
||||
}
|
||||
return node.YNode().Value
|
||||
}
|
||||
|
||||
func IsFieldNull(node *MapNode) bool {
|
||||
return node != nil && node.Value != nil && node.Value.YNode() != nil &&
|
||||
node.Value.YNode().Tag == NodeTagNull
|
||||
}
|
||||
|
||||
// Parser parses values into configuration.
|
||||
type Parser struct {
|
||||
Kind string `yaml:"kind,omitempty"`
|
||||
@@ -275,6 +254,12 @@ type MapNode struct {
|
||||
Value *RNode
|
||||
}
|
||||
|
||||
// IsNilOrEmpty returns true if the MapNode is nil,
|
||||
// has no value, or has a value that appears empty.
|
||||
func (mn *MapNode) IsNilOrEmpty() bool {
|
||||
return mn == nil || mn.Value.IsNilOrEmpty()
|
||||
}
|
||||
|
||||
type MapNodeSlice []*MapNode
|
||||
|
||||
func (m MapNodeSlice) Keys() []*RNode {
|
||||
@@ -379,9 +364,28 @@ const (
|
||||
LabelsField = "labels"
|
||||
)
|
||||
|
||||
// IsNil is true if the node is nil, or its underlying YNode is nil.
|
||||
func (rn *RNode) IsNil() bool {
|
||||
return rn == nil || rn.YNode() == nil
|
||||
}
|
||||
|
||||
// IsTaggedNull is true if a non-nil node is explicitly tagged Null.
|
||||
func (rn *RNode) IsTaggedNull() bool {
|
||||
return !rn.IsNil() && IsYNodeTaggedNull(rn.YNode())
|
||||
}
|
||||
|
||||
// IsNilOrEmpty is true if the node is nil,
|
||||
// has no YNode, or has YNode that appears empty.
|
||||
func (rn *RNode) IsNilOrEmpty() bool {
|
||||
return rn.IsNil() ||
|
||||
IsYNodeTaggedNull(rn.YNode()) ||
|
||||
IsYNodeEmptyMap(rn.YNode()) ||
|
||||
IsYNodeEmptySeq(rn.YNode())
|
||||
}
|
||||
|
||||
// GetMeta returns the ResourceMeta for an RNode
|
||||
func (rn *RNode) GetMeta() (ResourceMeta, error) {
|
||||
if IsEmpty(rn) {
|
||||
if IsMissingOrNull(rn) {
|
||||
return ResourceMeta{}, nil
|
||||
}
|
||||
missingMeta := true
|
||||
@@ -396,17 +400,17 @@ func (rn *RNode) GetMeta() (ResourceMeta, error) {
|
||||
m := ResourceMeta{}
|
||||
|
||||
// TODO: consider optimizing this parsing
|
||||
if f := n.Field(APIVersionField); !IsFieldEmpty(f) {
|
||||
if f := n.Field(APIVersionField); !f.IsNilOrEmpty() {
|
||||
m.APIVersion = GetValue(f.Value)
|
||||
missingMeta = false
|
||||
}
|
||||
if f := n.Field(KindField); !IsFieldEmpty(f) {
|
||||
if f := n.Field(KindField); !f.IsNilOrEmpty() {
|
||||
m.Kind = GetValue(f.Value)
|
||||
missingMeta = false
|
||||
}
|
||||
|
||||
mf := n.Field(MetadataField)
|
||||
if IsFieldEmpty(mf) {
|
||||
if mf.IsNilOrEmpty() {
|
||||
if missingMeta {
|
||||
return m, ErrMissingMetadata
|
||||
}
|
||||
@@ -414,16 +418,16 @@ func (rn *RNode) GetMeta() (ResourceMeta, error) {
|
||||
}
|
||||
meta := mf.Value
|
||||
|
||||
if f := meta.Field(NameField); !IsFieldEmpty(f) {
|
||||
if f := meta.Field(NameField); !f.IsNilOrEmpty() {
|
||||
m.Name = f.Value.YNode().Value
|
||||
missingMeta = false
|
||||
}
|
||||
if f := meta.Field(NamespaceField); !IsFieldEmpty(f) {
|
||||
if f := meta.Field(NamespaceField); !f.IsNilOrEmpty() {
|
||||
m.Namespace = GetValue(f.Value)
|
||||
missingMeta = false
|
||||
}
|
||||
|
||||
if f := meta.Field(LabelsField); !IsFieldEmpty(f) {
|
||||
if f := meta.Field(LabelsField); !f.IsNilOrEmpty() {
|
||||
m.Labels = map[string]string{}
|
||||
_ = f.Value.VisitFields(func(node *MapNode) error {
|
||||
m.Labels[GetValue(node.Key)] = GetValue(node.Value)
|
||||
@@ -431,7 +435,7 @@ func (rn *RNode) GetMeta() (ResourceMeta, error) {
|
||||
})
|
||||
missingMeta = false
|
||||
}
|
||||
if f := meta.Field(AnnotationsField); !IsFieldEmpty(f) {
|
||||
if f := meta.Field(AnnotationsField); !f.IsNilOrEmpty() {
|
||||
m.Annotations = map[string]string{}
|
||||
_ = f.Value.VisitFields(func(node *MapNode) error {
|
||||
m.Annotations[GetValue(node.Key)] = GetValue(node.Value)
|
||||
@@ -650,7 +654,7 @@ func (rn *RNode) ElementValues(key string) ([]string, error) {
|
||||
var elements []string
|
||||
for i := 0; i < len(rn.Content()); i++ {
|
||||
field := NewRNode(rn.Content()[i]).Field(key)
|
||||
if !IsFieldEmpty(field) {
|
||||
if !field.IsNilOrEmpty() {
|
||||
elements = append(elements, field.Value.YNode().Value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +167,61 @@ type: string
|
||||
assert.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
func TestIsYNodeTaggedNull(t *testing.T) {
|
||||
if IsYNodeTaggedNull(nil) {
|
||||
t.Fatalf("nil cannot be tagged null")
|
||||
}
|
||||
if IsYNodeTaggedNull(&Node{}) {
|
||||
t.Fatalf("untagged node is not tagged")
|
||||
}
|
||||
if IsYNodeTaggedNull(&Node{Tag: NodeTagFloat}) {
|
||||
t.Fatalf("float tagged node is not tagged")
|
||||
}
|
||||
if !IsYNodeTaggedNull(&Node{Tag: NodeTagNull}) {
|
||||
t.Fatalf("tagged node is tagged")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsYNodeEmptyMap(t *testing.T) {
|
||||
if IsYNodeEmptyMap(nil) {
|
||||
t.Fatalf("nil cannot be a map")
|
||||
}
|
||||
if IsYNodeEmptyMap(&Node{}) {
|
||||
t.Fatalf("raw node is not a map")
|
||||
}
|
||||
if IsYNodeEmptyMap(&Node{Kind: SequenceNode}) {
|
||||
t.Fatalf("seq node is not a map")
|
||||
}
|
||||
n := &Node{Kind: MappingNode}
|
||||
if !IsYNodeEmptyMap(n) {
|
||||
t.Fatalf("empty mapping node is an empty mapping node")
|
||||
}
|
||||
n.Content = append(n.Content, &Node{Kind: SequenceNode})
|
||||
if IsYNodeEmptyMap(n) {
|
||||
t.Fatalf("a node with content isn't empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsYNodeEmptySeq(t *testing.T) {
|
||||
if IsYNodeEmptySeq(nil) {
|
||||
t.Fatalf("nil cannot be a map")
|
||||
}
|
||||
if IsYNodeEmptySeq(&Node{}) {
|
||||
t.Fatalf("raw node is not a map")
|
||||
}
|
||||
if IsYNodeEmptySeq(&Node{Kind: MappingNode}) {
|
||||
t.Fatalf("map node is not a sequence")
|
||||
}
|
||||
n := &Node{Kind: SequenceNode}
|
||||
if !IsYNodeEmptySeq(n) {
|
||||
t.Fatalf("empty sequence node is an empty sequence node")
|
||||
}
|
||||
n.Content = append(n.Content, &Node{Kind: MappingNode})
|
||||
if IsYNodeEmptySeq(n) {
|
||||
t.Fatalf("a node with content isn't empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsMissingOrNull(t *testing.T) {
|
||||
if !IsMissingOrNull(nil) {
|
||||
t.Fatalf("input: nil")
|
||||
@@ -183,42 +238,26 @@ func TestIsMissingOrNull(t *testing.T) {
|
||||
if !IsMissingOrNull(MakeNullNode()) {
|
||||
t.Fatalf("input: with NullNodeTag")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsEmpty(t *testing.T) {
|
||||
if !IsEmpty(nil) {
|
||||
t.Fatalf("input: nil")
|
||||
}
|
||||
|
||||
// missing value or null value
|
||||
if !IsEmpty(NewRNode(nil)) {
|
||||
t.Fatalf("input: nil value")
|
||||
}
|
||||
// not array or map
|
||||
if IsEmpty(NewScalarRNode("foo")) {
|
||||
t.Fatalf("input: not array or map")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsEmpty_Arrays(t *testing.T) {
|
||||
node := NewListRNode()
|
||||
// empty array. empty array is not expected as empty
|
||||
if IsEmpty(node) {
|
||||
if IsMissingOrNull(NewListRNode()) {
|
||||
t.Fatalf("input: empty array")
|
||||
}
|
||||
|
||||
// array with 1 item
|
||||
node = NewListRNode("foo")
|
||||
if IsEmpty(node) {
|
||||
node := NewListRNode("foo")
|
||||
if IsMissingOrNull(node) {
|
||||
t.Fatalf("input: array with 1 item")
|
||||
}
|
||||
|
||||
// delete the item in array
|
||||
node.value.Content = nil
|
||||
if IsEmpty(node) {
|
||||
if IsMissingOrNull(node) {
|
||||
t.Fatalf("input: empty array")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsEmpty_Maps(t *testing.T) {
|
||||
func TestIsEmptyMap(t *testing.T) {
|
||||
node := NewMapRNode(nil)
|
||||
// empty map
|
||||
if !IsEmptyMap(node) {
|
||||
@@ -237,3 +276,126 @@ func TestIsEmpty_Maps(t *testing.T) {
|
||||
t.Fatalf("input: empty map")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsNil(t *testing.T) {
|
||||
var rn *RNode
|
||||
|
||||
if !rn.IsNil() {
|
||||
t.Fatalf("uninitialized RNode should be nil")
|
||||
}
|
||||
|
||||
if !NewRNode(nil).IsNil() {
|
||||
t.Fatalf("missing value YNode should be nil")
|
||||
}
|
||||
|
||||
if MakeNullNode().IsNil() {
|
||||
t.Fatalf("value tagged null is not nil")
|
||||
}
|
||||
|
||||
if NewMapRNode(nil).IsNil() {
|
||||
t.Fatalf("empty map not nil")
|
||||
}
|
||||
|
||||
if NewListRNode().IsNil() {
|
||||
t.Fatalf("empty list not nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsTaggedNull(t *testing.T) {
|
||||
var rn *RNode
|
||||
|
||||
if rn.IsTaggedNull() {
|
||||
t.Fatalf("nil RNode cannot be tagged")
|
||||
}
|
||||
|
||||
if NewRNode(nil).IsTaggedNull() {
|
||||
t.Fatalf("bare RNode should not be tagged")
|
||||
}
|
||||
|
||||
if !MakeNullNode().IsTaggedNull() {
|
||||
t.Fatalf("a null node is tagged null by definition")
|
||||
}
|
||||
|
||||
if NewMapRNode(nil).IsTaggedNull() {
|
||||
t.Fatalf("empty map should not be tagged null")
|
||||
}
|
||||
|
||||
if NewListRNode().IsTaggedNull() {
|
||||
t.Fatalf("empty list should not be tagged null")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRNodeIsNilOrEmpty(t *testing.T) {
|
||||
var rn *RNode
|
||||
|
||||
if !rn.IsNilOrEmpty() {
|
||||
t.Fatalf("uninitialized RNode should be empty")
|
||||
}
|
||||
|
||||
if !NewRNode(nil).IsNilOrEmpty() {
|
||||
t.Fatalf("missing value YNode should be empty")
|
||||
}
|
||||
|
||||
if !MakeNullNode().IsNilOrEmpty() {
|
||||
t.Fatalf("value tagged null should be empty")
|
||||
}
|
||||
|
||||
if !NewMapRNode(nil).IsNilOrEmpty() {
|
||||
t.Fatalf("empty map should be empty")
|
||||
}
|
||||
|
||||
if NewMapRNode(&map[string]string{"foo": "bar"}).IsNilOrEmpty() {
|
||||
t.Fatalf("non-empty map should not be empty")
|
||||
}
|
||||
|
||||
if !NewListRNode().IsNilOrEmpty() {
|
||||
t.Fatalf("empty list should be empty")
|
||||
}
|
||||
|
||||
if NewListRNode("foo").IsNilOrEmpty() {
|
||||
t.Fatalf("non-empty list should not be empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapNodeIsNilOrEmpty(t *testing.T) {
|
||||
var mn *MapNode
|
||||
|
||||
if !mn.IsNilOrEmpty() {
|
||||
t.Fatalf("nil should be empty")
|
||||
}
|
||||
|
||||
mn = &MapNode{Key: MakeNullNode()}
|
||||
if !mn.IsNilOrEmpty() {
|
||||
t.Fatalf("missing value should be empty")
|
||||
}
|
||||
|
||||
mn.Value = NewRNode(nil)
|
||||
if !mn.IsNilOrEmpty() {
|
||||
t.Fatalf("missing value YNode should be empty")
|
||||
}
|
||||
|
||||
mn.Value = MakeNullNode()
|
||||
if !mn.IsNilOrEmpty() {
|
||||
t.Fatalf("value tagged null should be empty")
|
||||
}
|
||||
|
||||
mn.Value = NewMapRNode(nil)
|
||||
if !mn.IsNilOrEmpty() {
|
||||
t.Fatalf("empty map should be empty")
|
||||
}
|
||||
|
||||
mn.Value = NewMapRNode(&map[string]string{"foo": "bar"})
|
||||
if mn.IsNilOrEmpty() {
|
||||
t.Fatalf("non-empty map should not be empty")
|
||||
}
|
||||
|
||||
mn.Value = NewListRNode()
|
||||
if !mn.IsNilOrEmpty() {
|
||||
t.Fatalf("empty list should be empty")
|
||||
}
|
||||
|
||||
mn.Value = NewListRNode("foo")
|
||||
if mn.IsNilOrEmpty() {
|
||||
t.Fatalf("non-empty list should not be empty")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func (l *Walker) walkAssociativeSequence() (*yaml.RNode, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if yaml.IsEmpty(val) || yaml.IsEmptyMap(val) {
|
||||
if yaml.IsMissingOrNull(val) || yaml.IsEmptyMap(val) {
|
||||
_, err = dest.Pipe(yaml.ElementSetter{Key: key, Value: value})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -74,7 +74,7 @@ func (l *Walker) walkAssociativeSequence() (*yaml.RNode, error) {
|
||||
}
|
||||
}
|
||||
// field is empty
|
||||
if yaml.IsEmpty(dest) {
|
||||
if yaml.IsMissingOrNull(dest) {
|
||||
return nil, nil
|
||||
}
|
||||
return dest, nil
|
||||
@@ -97,7 +97,7 @@ func (l *Walker) walkAssociativeSequence() (*yaml.RNode, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if yaml.IsEmpty(val) {
|
||||
if yaml.IsMissingOrNull(val) {
|
||||
_, err = dest.Pipe(yaml.ElementSetter{Key: key, Value: value})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -121,7 +121,7 @@ func (l *Walker) walkAssociativeSequence() (*yaml.RNode, error) {
|
||||
}
|
||||
|
||||
// field is empty
|
||||
if yaml.IsEmpty(dest) {
|
||||
if yaml.IsMissingOrNull(dest) {
|
||||
return nil, nil
|
||||
}
|
||||
return dest, nil
|
||||
|
||||
@@ -39,7 +39,7 @@ func (l Walker) walkMap() (*yaml.RNode, error) {
|
||||
continue
|
||||
}
|
||||
field := l.Sources[i].Field(key)
|
||||
if field == nil || yaml.IsEmpty(field.Key) {
|
||||
if field == nil || yaml.IsMissingOrNull(field.Key) {
|
||||
keys = append(keys, nil)
|
||||
continue
|
||||
}
|
||||
@@ -148,7 +148,7 @@ func (l Walker) fieldValue(fieldName string) ([]*yaml.RNode, *openapi.ResourceSc
|
||||
field := l.Sources[i].Field(fieldName)
|
||||
f, s := l.valueIfPresent(field)
|
||||
fields = append(fields, f)
|
||||
if sch == nil && !s.IsEmpty() {
|
||||
if sch == nil && !s.IsMissingOrNull() {
|
||||
sch = s
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ type Walker struct {
|
||||
|
||||
func (l Walker) Kind() yaml.Kind {
|
||||
for _, s := range l.Sources {
|
||||
if !yaml.IsEmpty(s) {
|
||||
if !yaml.IsMissingOrNull(s) {
|
||||
return s.YNode().Kind
|
||||
}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ func (l Walker) Walk() (*yaml.RNode, error) {
|
||||
func (l Walker) GetSchema() *openapi.ResourceSchema {
|
||||
for i := range l.Sources {
|
||||
r := l.Sources[i]
|
||||
if yaml.IsEmpty(r) {
|
||||
if yaml.IsMissingOrNull(r) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ func (l Walker) GetSchema() *openapi.ResourceSchema {
|
||||
}
|
||||
for i := range l.Sources {
|
||||
r := l.Sources[i]
|
||||
if yaml.IsEmpty(r) {
|
||||
if yaml.IsMissingOrNull(r) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ can only be placed in particular fields of
|
||||
particular objects as specified by kustomize's
|
||||
configuration data.
|
||||
|
||||
The default config data for vars is at [/api/konfig/builtinpluginconsts/varreference.go](/konfig/builtinpluginconsts/varreference.go)
|
||||
The default config data for vars is at [/api/konfig/builtinpluginconsts/varreference.go](https://github.com/kubernetes-sigs/kustomize/blob/master/api/konfig/builtinpluginconsts/varreference.go)
|
||||
Long story short, the default targets are all
|
||||
container command args and env value fields.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user