...

Source file src/sigs.k8s.io/kustomize/api/types/selector.go

Documentation: sigs.k8s.io/kustomize/api/types

     1  // Copyright 2019 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package types
     5  
     6  import (
     7  	"fmt"
     8  	"regexp"
     9  
    10  	"sigs.k8s.io/kustomize/kyaml/resid"
    11  )
    12  
    13  // Selector specifies a set of resources.
    14  // Any resource that matches intersection of all conditions
    15  // is included in this set.
    16  type Selector struct {
    17  	// ResId refers to a GVKN/Ns of a resource.
    18  	resid.ResId `json:",inline,omitempty" yaml:",inline,omitempty"`
    19  
    20  	// AnnotationSelector is a string that follows the label selection expression
    21  	// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
    22  	// It matches with the resource annotations.
    23  	AnnotationSelector string `json:"annotationSelector,omitempty" yaml:"annotationSelector,omitempty"`
    24  
    25  	// LabelSelector is a string that follows the label selection expression
    26  	// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
    27  	// It matches with the resource labels.
    28  	LabelSelector string `json:"labelSelector,omitempty" yaml:"labelSelector,omitempty"`
    29  }
    30  
    31  func (s *Selector) Copy() Selector {
    32  	return *s
    33  }
    34  
    35  func (s *Selector) String() string {
    36  	return fmt.Sprintf(
    37  		"%s:a=%s:l=%s", s.ResId, s.AnnotationSelector, s.LabelSelector)
    38  }
    39  
    40  // SelectorRegex is a Selector with regex in GVK
    41  // Any resource that matches intersection of all conditions
    42  // is included in this set.
    43  type SelectorRegex struct {
    44  	selector       *Selector
    45  	groupRegex     *regexp.Regexp
    46  	versionRegex   *regexp.Regexp
    47  	kindRegex      *regexp.Regexp
    48  	nameRegex      *regexp.Regexp
    49  	namespaceRegex *regexp.Regexp
    50  }
    51  
    52  // NewSelectorRegex returns a pointer to a new SelectorRegex
    53  // which uses the same condition as s.
    54  func NewSelectorRegex(s *Selector) (*SelectorRegex, error) {
    55  	sr := new(SelectorRegex)
    56  	var err error
    57  	sr.selector = s
    58  	sr.groupRegex, err = regexp.Compile(anchorRegex(s.Gvk.Group))
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	sr.versionRegex, err = regexp.Compile(anchorRegex(s.Gvk.Version))
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	sr.kindRegex, err = regexp.Compile(anchorRegex(s.Gvk.Kind))
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	sr.nameRegex, err = regexp.Compile(anchorRegex(s.Name))
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  	sr.namespaceRegex, err = regexp.Compile(anchorRegex(s.Namespace))
    75  	if err != nil {
    76  		return nil, err
    77  	}
    78  	return sr, nil
    79  }
    80  
    81  func anchorRegex(pattern string) string {
    82  	if pattern == "" {
    83  		return pattern
    84  	}
    85  	return "^(?:" + pattern + ")$"
    86  }
    87  
    88  // MatchGvk return true if gvk can be matched by s.
    89  func (s *SelectorRegex) MatchGvk(gvk resid.Gvk) bool {
    90  	if len(s.selector.Gvk.Group) > 0 {
    91  		if !s.groupRegex.MatchString(gvk.Group) {
    92  			return false
    93  		}
    94  	}
    95  	if len(s.selector.Gvk.Version) > 0 {
    96  		if !s.versionRegex.MatchString(gvk.Version) {
    97  			return false
    98  		}
    99  	}
   100  	if len(s.selector.Gvk.Kind) > 0 {
   101  		if !s.kindRegex.MatchString(gvk.Kind) {
   102  			return false
   103  		}
   104  	}
   105  	return true
   106  }
   107  
   108  // MatchName returns true if the name in selector is
   109  // empty or the n can be matches by the name in selector
   110  func (s *SelectorRegex) MatchName(n string) bool {
   111  	if s.selector.Name == "" {
   112  		return true
   113  	}
   114  	return s.nameRegex.MatchString(n)
   115  }
   116  
   117  // MatchNamespace returns true if the namespace in selector is
   118  // empty or the ns can be matches by the namespace in selector
   119  func (s *SelectorRegex) MatchNamespace(ns string) bool {
   120  	if s.selector.Namespace == "" {
   121  		return true
   122  	}
   123  	return s.namespaceRegex.MatchString(ns)
   124  }
   125  

View as plain text