...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package selector
17
18 import (
19 "context"
20 "reflect"
21
22 "github.com/pkg/errors"
23 "go.uber.org/fx"
24
25 "github.com/chaos-mesh/chaos-mesh/pkg/selector/aws"
26 "github.com/chaos-mesh/chaos-mesh/pkg/selector/azure"
27 "github.com/chaos-mesh/chaos-mesh/pkg/selector/container"
28 "github.com/chaos-mesh/chaos-mesh/pkg/selector/gcp"
29 "github.com/chaos-mesh/chaos-mesh/pkg/selector/nodevolumepath"
30 "github.com/chaos-mesh/chaos-mesh/pkg/selector/physicalmachine"
31 "github.com/chaos-mesh/chaos-mesh/pkg/selector/pod"
32 )
33
34 type Selector struct {
35 selectorMap map[reflect.Type]interface{}
36 }
37
38 type Target interface {
39 Id() string
40 }
41
42 func (s *Selector) Select(ctx context.Context, spec interface{}) ([]Target, error) {
43 if spec == nil {
44 return []Target{}, nil
45 }
46
47 var targets []Target
48 impl, ok := s.selectorMap[reflect.TypeOf(spec)]
49 if ok {
50 vals := reflect.ValueOf(impl).MethodByName("Select").Call([]reflect.Value{reflect.ValueOf(ctx), reflect.ValueOf(spec)})
51 ret := vals[0]
52
53 for i := 0; i < ret.Len(); i++ {
54 targets = append(targets, ret.Index(i).Interface().(Target))
55 }
56
57 err := vals[1].Interface()
58 if err == nil {
59 return targets, nil
60 }
61
62 return targets, err.(error)
63 }
64
65 return nil, errors.Errorf("specification type not found: %s", reflect.TypeOf(spec))
66 }
67
68 type SelectorParams struct {
69 fx.In
70
71 PodSelector *pod.SelectImpl
72 ContainerSelector *container.SelectImpl
73 AWSSelector *aws.SelectImpl
74 AzureSelector *azure.SelectImpl
75 GCPSelector *gcp.SelectImpl
76 PhysicalMachineSelector *physicalmachine.SelectImpl
77 NodeVolumePath *nodevolumepath.SelectImpl
78 }
79
80 func New(p SelectorParams) *Selector {
81 selectorMap := make(map[reflect.Type]interface{})
82
83 val := reflect.ValueOf(p)
84 for i := 0; i < val.NumField(); i++ {
85 method := val.Field(i).MethodByName("Select")
86 if method.IsValid() && method.Type().NumIn() > 1 {
87 typ := method.Type().In(1)
88 selectorMap[typ] = val.Field(i).Interface()
89 }
90 }
91
92 return &Selector{
93 selectorMap,
94 }
95 }
96
97 var Module = fx.Provide(
98 New,
99
100 pod.New,
101 container.New,
102 aws.New,
103 azure.New,
104 gcp.New,
105 physicalmachine.New,
106 nodevolumepath.New,
107 )
108