...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package field
17
18 import (
19 v1 "k8s.io/api/core/v1"
20 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21 "k8s.io/apimachinery/pkg/fields"
22 "sigs.k8s.io/controller-runtime/pkg/client"
23
24 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
25 "github.com/chaos-mesh/chaos-mesh/pkg/selector/generic"
26 )
27
28 const Name = "field"
29
30 type fieldSelector struct {
31 fields.Selector
32 }
33
34 var _ generic.Selector = &fieldSelector{}
35
36 func (s *fieldSelector) ListOption() client.ListOption {
37 if !s.Empty() {
38 return client.MatchingFieldsSelector{Selector: s}
39 }
40 return nil
41 }
42
43 func (s *fieldSelector) ListFunc(r client.Reader) generic.ListFunc {
44
45
46 if !s.Empty() && r != nil {
47 return r.List
48 }
49 return nil
50 }
51
52 func (s *fieldSelector) Match(obj client.Object) bool {
53 var objFields fields.Set
54 switch obj := obj.(type) {
55 case *v1.Pod:
56 objFields = toPodSelectableFields(obj)
57 case *v1alpha1.PhysicalMachine:
58 objFields = toPhysicalMachineSelectableFields(obj)
59 default:
60
61 return false
62 }
63 return s.Matches(objFields)
64 }
65
66 func New(spec v1alpha1.GenericSelectorSpec, _ generic.Option) (generic.Selector, error) {
67 return &fieldSelector{
68 Selector: fields.SelectorFromSet(spec.FieldSelectors),
69 }, nil
70 }
71
72
73
74 func toPodSelectableFields(pod *v1.Pod) fields.Set {
75
76
77
78
79 podSpecificFieldsSet := make(fields.Set, 9)
80 podSpecificFieldsSet["spec.nodeName"] = pod.Spec.NodeName
81 podSpecificFieldsSet["spec.restartPolicy"] = string(pod.Spec.RestartPolicy)
82 podSpecificFieldsSet["spec.schedulerName"] = pod.Spec.SchedulerName
83 podSpecificFieldsSet["spec.serviceAccountName"] = pod.Spec.ServiceAccountName
84 podSpecificFieldsSet["status.phase"] = string(pod.Status.Phase)
85 podIP := ""
86 if len(pod.Status.PodIPs) > 0 {
87 podIP = string(pod.Status.PodIPs[0].IP)
88 }
89 podSpecificFieldsSet["status.podIP"] = podIP
90 podSpecificFieldsSet["status.nominatedNodeName"] = pod.Status.NominatedNodeName
91 return addObjectMetaFieldsSet(podSpecificFieldsSet, &pod.ObjectMeta, true)
92 }
93
94
95 func toPhysicalMachineSelectableFields(physicalMachine *v1alpha1.PhysicalMachine) fields.Set {
96 pmSpecificFieldsSet := make(fields.Set, 3)
97 pmSpecificFieldsSet["spec.address"] = physicalMachine.Spec.Address
98 return addObjectMetaFieldsSet(pmSpecificFieldsSet, &physicalMachine.ObjectMeta, true)
99 }
100
101
102 func addObjectMetaFieldsSet(source fields.Set, objectMeta *metav1.ObjectMeta, hasNamespaceField bool) fields.Set {
103 source["metadata.name"] = objectMeta.Name
104 if hasNamespaceField {
105 source["metadata.namespace"] = objectMeta.Namespace
106 }
107 return source
108 }
109