...
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package main
15
16 import (
17 "bytes"
18 "text/template"
19 )
20
21 const implImport = `
22 import (
23 "encoding/json"
24 "reflect"
25 "time"
26
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 )
29 `
30
31 const implTemplate = `
32 const Kind{{.Type}} = "{{.Type}}"
33
34 // IsDeleted returns whether this resource has been deleted
35 func (in *{{.Type}}) IsDeleted() bool {
36 return !in.DeletionTimestamp.IsZero()
37 }
38
39 // IsPaused returns whether this resource has been paused
40 func (in *{{.Type}}) IsPaused() bool {
41 if in.Annotations == nil || in.Annotations[PauseAnnotationKey] != "true" {
42 return false
43 }
44 return true
45 }
46
47 // GetDuration would return the duration for chaos
48 func (in *{{.Type}}) GetDuration() (*time.Duration, error) {
49 if in.Spec.Duration == nil {
50 return nil, nil
51 }
52 duration, err := time.ParseDuration(*in.Spec.Duration)
53 if err != nil {
54 return nil, err
55 }
56 return &duration, nil
57 }
58
59 func (in *{{.Type}}) GetNextStart() time.Time {
60 if in.Status.Scheduler.NextStart == nil {
61 return time.Time{}
62 }
63 return in.Status.Scheduler.NextStart.Time
64 }
65
66 func (in *{{.Type}}) SetNextStart(t time.Time) {
67 if t.IsZero() {
68 in.Status.Scheduler.NextStart = nil
69 return
70 }
71
72 if in.Status.Scheduler.NextStart == nil {
73 in.Status.Scheduler.NextStart = &metav1.Time{}
74 }
75 in.Status.Scheduler.NextStart.Time = t
76 }
77
78 func (in *{{.Type}}) GetNextRecover() time.Time {
79 if in.Status.Scheduler.NextRecover == nil {
80 return time.Time{}
81 }
82 return in.Status.Scheduler.NextRecover.Time
83 }
84
85 func (in *{{.Type}}) SetNextRecover(t time.Time) {
86 if t.IsZero() {
87 in.Status.Scheduler.NextRecover = nil
88 return
89 }
90
91 if in.Status.Scheduler.NextRecover == nil {
92 in.Status.Scheduler.NextRecover = &metav1.Time{}
93 }
94 in.Status.Scheduler.NextRecover.Time = t
95 }
96
97 // GetScheduler would return the scheduler for chaos
98 func (in *{{.Type}}) GetScheduler() *SchedulerSpec {
99 return in.Spec.Scheduler
100 }
101
102 // GetChaos would return the a record for chaos
103 func (in *{{.Type}}) GetChaos() *ChaosInstance {
104 instance := &ChaosInstance{
105 Name: in.Name,
106 Namespace: in.Namespace,
107 Kind: Kind{{.Type}},
108 StartTime: in.CreationTimestamp.Time,
109 Action: "",
110 Status: string(in.Status.Experiment.Phase),
111 UID: string(in.UID),
112 }
113
114 action := reflect.ValueOf(in).Elem().FieldByName("Spec").FieldByName("Action")
115 if action.IsValid() {
116 instance.Action = action.String()
117 }
118 if in.Spec.Duration != nil {
119 instance.Duration = *in.Spec.Duration
120 }
121 if in.DeletionTimestamp != nil {
122 instance.EndTime = in.DeletionTimestamp.Time
123 }
124 return instance
125 }
126
127 // GetStatus returns the status
128 func (in *{{.Type}}) GetStatus() *ChaosStatus {
129 return &in.Status.ChaosStatus
130 }
131
132 // GetSpecAndMetaString returns a string including the meta and spec field of this chaos object.
133 func (in *{{.Type}}) GetSpecAndMetaString() (string, error) {
134 spec, err := json.Marshal(in.Spec)
135 if err != nil {
136 return "", err
137 }
138
139 meta := in.ObjectMeta.DeepCopy()
140 meta.SetResourceVersion("")
141 meta.SetGeneration(0)
142
143 return string(spec) + meta.String(), nil
144 }
145
146 // +kubebuilder:object:root=true
147
148 // {{.Type}}List contains a list of {{.Type}}
149 type {{.Type}}List struct {
150 metav1.TypeMeta ` + "`" + `json:",inline"` + "`" + `
151 metav1.ListMeta ` + "`" + `json:"metadata,omitempty"` + "`" + `
152 Items []{{.Type}} ` + "`" + `json:"items"` + "`" + `
153 }
154
155 // ListChaos returns a list of chaos
156 func (in *{{.Type}}List) ListChaos() []*ChaosInstance {
157 res := make([]*ChaosInstance, 0, len(in.Items))
158 for _, item := range in.Items {
159 res = append(res, item.GetChaos())
160 }
161 return res
162 }
163 `
164
165 func generateImpl(name string) string {
166 tmpl, err := template.New("impl").Parse(implTemplate)
167 if err != nil {
168 log.Error(err, "fail to build template")
169 return ""
170 }
171
172 buf := new(bytes.Buffer)
173 err = tmpl.Execute(buf, &metadata{
174 Type: name,
175 })
176 if err != nil {
177 log.Error(err, "fail to execute template")
178 return ""
179 }
180
181 return buf.String()
182 }
183