...

Source file src/sigs.k8s.io/kustomize/kyaml/resid/resid.go

Documentation: sigs.k8s.io/kustomize/kyaml/resid

     1  // Copyright 2019 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package resid
     5  
     6  import (
     7  	"reflect"
     8  	"strings"
     9  
    10  	"sigs.k8s.io/kustomize/kyaml/yaml"
    11  )
    12  
    13  // ResId is an identifier of a k8s resource object.
    14  type ResId struct {
    15  	// Gvk of the resource.
    16  	Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
    17  
    18  	// Name of the resource.
    19  	Name string `json:"name,omitempty" yaml:"name,omitempty"`
    20  
    21  	// Namespace the resource belongs to, if it can belong to a namespace.
    22  	Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
    23  }
    24  
    25  // NewResIdWithNamespace creates new ResId
    26  // in a given namespace.
    27  func NewResIdWithNamespace(k Gvk, n, ns string) ResId {
    28  	return ResId{Gvk: k, Name: n, Namespace: ns}
    29  }
    30  
    31  // NewResId creates new ResId.
    32  func NewResId(k Gvk, n string) ResId {
    33  	return NewResIdWithNamespace(k, n, "")
    34  }
    35  
    36  // NewResIdKindOnly creates a new ResId.
    37  func NewResIdKindOnly(k string, n string) ResId {
    38  	return NewResId(FromKind(k), n)
    39  }
    40  
    41  const (
    42  	noNamespace          = "[noNs]"
    43  	noName               = "[noName]"
    44  	separator            = "/"
    45  	TotallyNotANamespace = "_non_namespaceable_"
    46  	DefaultNamespace     = "default"
    47  )
    48  
    49  // String of ResId based on GVK, name and prefix
    50  func (id ResId) String() string {
    51  	ns := id.Namespace
    52  	if ns == "" {
    53  		ns = noNamespace
    54  	}
    55  	nm := id.Name
    56  	if nm == "" {
    57  		nm = noName
    58  	}
    59  	return strings.Join(
    60  		[]string{id.Gvk.String(), strings.Join([]string{nm, ns}, fieldSep)}, separator)
    61  }
    62  
    63  func FromString(s string) ResId {
    64  	values := strings.Split(s, separator)
    65  	gvk := GvkFromString(values[0])
    66  
    67  	values = strings.Split(values[1], fieldSep)
    68  	last := len(values) - 1
    69  
    70  	ns := values[last]
    71  	if ns == noNamespace {
    72  		ns = ""
    73  	}
    74  	nm := strings.Join(values[:last], fieldSep)
    75  	if nm == noName {
    76  		nm = ""
    77  	}
    78  	return ResId{
    79  		Gvk:       gvk,
    80  		Namespace: ns,
    81  		Name:      nm,
    82  	}
    83  }
    84  
    85  // FromRNode returns the ResId for the RNode
    86  func FromRNode(rn *yaml.RNode) ResId {
    87  	group, version := ParseGroupVersion(rn.GetApiVersion())
    88  	return NewResIdWithNamespace(
    89  		Gvk{Group: group, Version: version, Kind: rn.GetKind()}, rn.GetName(), rn.GetNamespace())
    90  }
    91  
    92  // GvknEquals returns true if the other id matches
    93  // Group/Version/Kind/name.
    94  func (id ResId) GvknEquals(o ResId) bool {
    95  	return id.Name == o.Name && id.Gvk.Equals(o.Gvk)
    96  }
    97  
    98  // IsSelectedBy returns true if self is selected by the argument.
    99  func (id ResId) IsSelectedBy(selector ResId) bool {
   100  	return (selector.Name == "" || selector.Name == id.Name) &&
   101  		(selector.Namespace == "" || selector.IsNsEquals(id)) &&
   102  		id.Gvk.IsSelected(&selector.Gvk)
   103  }
   104  
   105  // Equals returns true if the other id matches
   106  // namespace/Group/Version/Kind/name.
   107  func (id ResId) Equals(o ResId) bool {
   108  	return id.IsNsEquals(o) && id.GvknEquals(o)
   109  }
   110  
   111  // IsNsEquals returns true if the id is in
   112  // the same effective namespace.
   113  func (id ResId) IsNsEquals(o ResId) bool {
   114  	return id.EffectiveNamespace() == o.EffectiveNamespace()
   115  }
   116  
   117  // IsInDefaultNs returns true if id is a namespaceable
   118  // ResId and the Namespace is either not set or set
   119  // to DefaultNamespace.
   120  func (id ResId) IsInDefaultNs() bool {
   121  	return !id.IsClusterScoped() && id.isPutativelyDefaultNs()
   122  }
   123  
   124  func (id ResId) isPutativelyDefaultNs() bool {
   125  	return id.Namespace == "" || id.Namespace == DefaultNamespace
   126  }
   127  
   128  // EffectiveNamespace returns a non-ambiguous, non-empty
   129  // namespace for use in reporting and equality tests.
   130  func (id ResId) EffectiveNamespace() string {
   131  	// The order of these checks matters.
   132  	if id.IsClusterScoped() {
   133  		return TotallyNotANamespace
   134  	}
   135  	if id.isPutativelyDefaultNs() {
   136  		return DefaultNamespace
   137  	}
   138  	return id.Namespace
   139  }
   140  
   141  // IsEmpty returns true of all of the id's fields are
   142  // empty strings
   143  func (id ResId) IsEmpty() bool {
   144  	return reflect.DeepEqual(id, ResId{})
   145  }
   146  

View as plain text