...

Source file src/sigs.k8s.io/kustomize/kyaml/kio/filters/grep.go

Documentation: sigs.k8s.io/kustomize/kyaml/kio/filters

     1  // Copyright 2019 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package filters
     5  
     6  import (
     7  	"regexp"
     8  	"strings"
     9  
    10  	"sigs.k8s.io/kustomize/kyaml/kio"
    11  	"sigs.k8s.io/kustomize/kyaml/yaml"
    12  )
    13  
    14  type GrepType int
    15  
    16  const (
    17  	Regexp GrepType = 1 << iota
    18  	GreaterThanEq
    19  	GreaterThan
    20  	LessThan
    21  	LessThanEq
    22  )
    23  
    24  // GrepFilter filters RNodes with a matching field
    25  type GrepFilter struct {
    26  	Path        []string `yaml:"path,omitempty"`
    27  	Value       string   `yaml:"value,omitempty"`
    28  	MatchType   GrepType `yaml:"matchType,omitempty"`
    29  	InvertMatch bool     `yaml:"invertMatch,omitempty"`
    30  	Compare     func(a, b string) (int, error)
    31  }
    32  
    33  var _ kio.Filter = GrepFilter{}
    34  
    35  func (f GrepFilter) Filter(input []*yaml.RNode) ([]*yaml.RNode, error) {
    36  	// compile the regular expression 1 time if we are matching using regex
    37  	var reg *regexp.Regexp
    38  	var err error
    39  	if f.MatchType == Regexp || f.MatchType == 0 {
    40  		reg, err = regexp.Compile(f.Value)
    41  		if err != nil {
    42  			return nil, err
    43  		}
    44  	}
    45  
    46  	var output kio.ResourceNodeSlice
    47  	for i := range input {
    48  		node := input[i]
    49  		val, err := node.Pipe(&yaml.PathMatcher{Path: f.Path})
    50  		if err != nil {
    51  			return nil, err
    52  		}
    53  		if val == nil || len(val.Content()) == 0 {
    54  			if f.InvertMatch {
    55  				output = append(output, input[i])
    56  			}
    57  			continue
    58  		}
    59  		found := false
    60  		err = val.VisitElements(func(elem *yaml.RNode) error {
    61  			// get the value
    62  			var str string
    63  			if f.MatchType == Regexp {
    64  				style := elem.YNode().Style
    65  				defer func() { elem.YNode().Style = style }()
    66  				elem.YNode().Style = yaml.FlowStyle
    67  				str, err = elem.String()
    68  				if err != nil {
    69  					return err
    70  				}
    71  				str = strings.TrimSpace(strings.ReplaceAll(str, `"`, ""))
    72  			} else {
    73  				// if not regexp, then it needs to parse into a quantity and comments will
    74  				// break that
    75  				str = elem.YNode().Value
    76  				if str == "" {
    77  					return nil
    78  				}
    79  			}
    80  
    81  			if f.MatchType == Regexp || f.MatchType == 0 {
    82  				if reg.MatchString(str) {
    83  					found = true
    84  				}
    85  				return nil
    86  			}
    87  
    88  			comp, err := f.Compare(str, f.Value)
    89  			if err != nil {
    90  				return err
    91  			}
    92  
    93  			if f.MatchType == GreaterThan && comp > 0 {
    94  				found = true
    95  			}
    96  			if f.MatchType == GreaterThanEq && comp >= 0 {
    97  				found = true
    98  			}
    99  			if f.MatchType == LessThan && comp < 0 {
   100  				found = true
   101  			}
   102  			if f.MatchType == LessThanEq && comp <= 0 {
   103  				found = true
   104  			}
   105  			return nil
   106  		})
   107  		if err != nil {
   108  			return nil, err
   109  		}
   110  		if found == f.InvertMatch {
   111  			continue
   112  		}
   113  
   114  		output = append(output, input[i])
   115  	}
   116  	return output, nil
   117  }
   118  

View as plain text