...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package action
17
18 import (
19 "context"
20 "reflect"
21 "strings"
22
23 "github.com/pkg/errors"
24
25 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
26 impltypes "github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/types"
27 )
28
29 var _ impltypes.ChaosImpl = (*Delegate)(nil)
30
31 type Delegate struct {
32 impl interface{}
33 }
34
35 func (i *Delegate) callAccordingToAction(action, methodName string, defaultPhase v1alpha1.Phase, args ...interface{}) (v1alpha1.Phase, error) {
36 implType := reflect.TypeOf(i.impl).Elem()
37 implVal := reflect.ValueOf(i.impl)
38
39 reflectArgs := []reflect.Value{}
40 for _, arg := range args {
41 reflectArgs = append(reflectArgs, reflect.ValueOf(arg))
42 }
43 for i := 0; i < implType.NumField(); i++ {
44 field := implType.Field(i)
45
46 actions := strings.Split(field.Tag.Get("action"), ",")
47 for i := range actions {
48 if actions[i] == action {
49 rets := implVal.Elem().FieldByIndex(field.Index).MethodByName(methodName).Call(reflectArgs)
50
51
52 err := rets[1].Interface()
53 if err == nil {
54 return rets[0].Interface().(v1alpha1.Phase), nil
55 }
56
57 return rets[0].Interface().(v1alpha1.Phase), err.(error)
58 }
59 }
60 }
61
62 return defaultPhase, errors.Errorf("unknown action %s", action)
63 }
64
65 func (i *Delegate) getAction(obj v1alpha1.InnerObject) string {
66 return reflect.ValueOf(obj).Elem().FieldByName("Spec").FieldByName("Action").String()
67 }
68
69 func (i *Delegate) Apply(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
70 return i.callAccordingToAction(i.getAction(obj), "Apply", v1alpha1.NotInjected, ctx, index, records, obj)
71 }
72
73 func (i *Delegate) Recover(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
74 return i.callAccordingToAction(i.getAction(obj), "Recover", v1alpha1.Injected, ctx, index, records, obj)
75 }
76
77 func New(impl interface{}) Delegate {
78 return Delegate{
79 impl,
80 }
81 }
82