...
1
2
3
4 package framework
5
6 import (
7 "sigs.k8s.io/kustomize/kyaml/errors"
8 "sigs.k8s.io/kustomize/kyaml/yaml"
9 )
10
11
12
13 type Selector struct {
14
15
16 Names []string `json:"names" yaml:"names"`
17
18
19
20 Namespaces []string `json:"namespaces" yaml:"namespaces"`
21
22
23
24 Kinds []string `json:"kinds" yaml:"kinds"`
25
26
27
28 APIVersions []string `json:"apiVersions" yaml:"apiVersions"`
29
30
31
32 Labels map[string]string `json:"labels" yaml:"labels"`
33
34
35
36 Annotations map[string]string `json:"annotations" yaml:"annotations"`
37
38
39
40 ResourceMatcher func(*yaml.RNode) bool
41
42
43
44 TemplateData interface{}
45
46
47 FailOnEmptyMatch bool
48 }
49
50
51
52 func (s *Selector) Filter(items []*yaml.RNode) ([]*yaml.RNode, error) {
53 andSel := AndSelector{TemplateData: s.TemplateData, FailOnEmptyMatch: s.FailOnEmptyMatch}
54 if s.Names != nil {
55 andSel.Matchers = append(andSel.Matchers, NameMatcher(s.Names...))
56 }
57 if s.Namespaces != nil {
58 andSel.Matchers = append(andSel.Matchers, NamespaceMatcher(s.Namespaces...))
59 }
60 if s.Kinds != nil {
61 andSel.Matchers = append(andSel.Matchers, KindMatcher(s.Kinds...))
62 }
63 if s.APIVersions != nil {
64 andSel.Matchers = append(andSel.Matchers, APIVersionMatcher(s.APIVersions...))
65 }
66 if s.Labels != nil {
67 andSel.Matchers = append(andSel.Matchers, LabelMatcher(s.Labels))
68 }
69 if s.Annotations != nil {
70 andSel.Matchers = append(andSel.Matchers, AnnotationMatcher(s.Annotations))
71 }
72 if s.ResourceMatcher != nil {
73 andSel.Matchers = append(andSel.Matchers, ResourceMatcherFunc(s.ResourceMatcher))
74 }
75 return andSel.Filter(items)
76 }
77
78
79 func MatchAll(matchers ...ResourceMatcher) *AndSelector {
80 return &AndSelector{Matchers: matchers}
81 }
82
83
84 func MatchAny(matchers ...ResourceMatcher) *OrSelector {
85 return &OrSelector{Matchers: matchers}
86 }
87
88
89
90 type OrSelector struct {
91
92 Matchers []ResourceMatcher
93
94
95 TemplateData interface{}
96
97 FailOnEmptyMatch bool
98 }
99
100
101 func (s *OrSelector) Match(item *yaml.RNode) bool {
102 for _, matcher := range s.Matchers {
103 if matcher.Match(item) {
104 return true
105 }
106 }
107 return false
108 }
109
110
111
112 func (s *OrSelector) Filter(items []*yaml.RNode) ([]*yaml.RNode, error) {
113 if err := initMatcherTemplates(s.Matchers, s.TemplateData); err != nil {
114 return nil, err
115 }
116
117 var selectedItems []*yaml.RNode
118 for i := range items {
119 for _, matcher := range s.Matchers {
120 if matcher.Match(items[i]) {
121 selectedItems = append(selectedItems, items[i])
122 break
123 }
124 }
125 }
126 if s.FailOnEmptyMatch && len(selectedItems) == 0 {
127 return nil, errors.Errorf("selector did not select any items")
128 }
129 return selectedItems, nil
130 }
131
132
133
134
135 func (s *OrSelector) DefaultTemplateData(data interface{}) {
136 if s.TemplateData == nil {
137 s.TemplateData = data
138 }
139 }
140
141 func (s *OrSelector) InitTemplates() error {
142 return initMatcherTemplates(s.Matchers, s.TemplateData)
143 }
144
145 func initMatcherTemplates(matchers []ResourceMatcher, data interface{}) error {
146 for _, matcher := range matchers {
147 if tm, ok := matcher.(ResourceTemplateMatcher); ok {
148 tm.DefaultTemplateData(data)
149 if err := tm.InitTemplates(); err != nil {
150 return err
151 }
152 }
153 }
154 return nil
155 }
156
157 var _ ResourceTemplateMatcher = &OrSelector{}
158
159
160
161 type AndSelector struct {
162
163 Matchers []ResourceMatcher
164
165
166 TemplateData interface{}
167
168 FailOnEmptyMatch bool
169 }
170
171
172 func (s *AndSelector) Match(item *yaml.RNode) bool {
173 for _, matcher := range s.Matchers {
174 if !matcher.Match(item) {
175 return false
176 }
177 }
178 return true
179 }
180
181
182
183 func (s *AndSelector) Filter(items []*yaml.RNode) ([]*yaml.RNode, error) {
184 if err := initMatcherTemplates(s.Matchers, s.TemplateData); err != nil {
185 return nil, err
186 }
187 var selectedItems []*yaml.RNode
188 for i := range items {
189 isSelected := true
190 for _, matcher := range s.Matchers {
191 if !matcher.Match(items[i]) {
192 isSelected = false
193 break
194 }
195 }
196 if isSelected {
197 selectedItems = append(selectedItems, items[i])
198 }
199 }
200 if s.FailOnEmptyMatch && len(selectedItems) == 0 {
201 return nil, errors.Errorf("selector did not select any items")
202 }
203 return selectedItems, nil
204 }
205
206
207
208
209 func (s *AndSelector) DefaultTemplateData(data interface{}) {
210 if s.TemplateData == nil {
211 s.TemplateData = data
212 }
213 }
214
215 func (s *AndSelector) InitTemplates() error {
216 return initMatcherTemplates(s.Matchers, s.TemplateData)
217 }
218
219 var _ ResourceTemplateMatcher = &AndSelector{}
220
View as plain text