1 // Copyright 2021 Chaos Mesh Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 16 package generic 17 18 import ( 19 "context" 20 21 "sigs.k8s.io/controller-runtime/pkg/client" 22 ) 23 24 const InjectAnnotationKey = "chaos-mesh.org/inject" 25 26 type Option struct { 27 ClusterScoped bool 28 TargetNamespace string 29 EnableFilterNamespace bool 30 } 31 32 type ListFunc func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error 33 34 // Selector is an interface implemented by things that know how to list objects from cluster and whether this object matches the selector. 35 type Selector interface { 36 // ListFunc returns the function to list object from kubernetes cluster. 37 // If no method is specified, returns `nil` directly. (default: `List` function of `client.Client`) 38 // If needed, `List` function of `client.Reader` can be returned. Only `field selector` uses it for now. 39 // When registering the Selector, it's important to note that multiple ListFunc will be overwritten in the SelectorChain. 40 ListFunc(client.Reader) ListFunc 41 // ListOption returns the client.ListOption that modifies options for a list request. 42 // If no option is specified, returns `nil` directly. 43 // When registering a Selector, it is important to note that multiple ListOptions will all apply to 44 // the same `client.ListOptions` and will be overwritten if they have the same fields in the SelectorChain. 45 ListOption() client.ListOption 46 // Match returns whether the object matches the selector 47 Match(client.Object) bool 48 } 49 50 type SelectorChain []Selector 51 52 func (s SelectorChain) ListObjects(c client.Client, r client.Reader, 53 listObj func(listFunc ListFunc, opts client.ListOptions) error) error { 54 var options []client.ListOption 55 listFunc := c.List 56 57 for _, selector := range s { 58 if tmpOption := selector.ListOption(); tmpOption != nil { 59 options = append(options, selector.ListOption()) 60 } 61 if tmpListFunc := selector.ListFunc(r); tmpListFunc != nil { 62 listFunc = tmpListFunc 63 } 64 } 65 opts := client.ListOptions{} 66 opts.ApplyOptions(options) 67 return listObj(listFunc, opts) 68 } 69 70 func (s SelectorChain) Match(obj client.Object) bool { 71 for _, selector := range s { 72 if !selector.Match(obj) { 73 return false 74 } 75 } 76 return true 77 } 78