...
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package v1alpha1
15
16 import (
17 "fmt"
18
19 "k8s.io/apimachinery/pkg/runtime"
20 "k8s.io/apimachinery/pkg/util/validation/field"
21 logf "sigs.k8s.io/controller-runtime/pkg/log"
22 "sigs.k8s.io/controller-runtime/pkg/webhook"
23 )
24
25
26 var awschaoslog = logf.Log.WithName("awschaos-resource")
27
28
29
30 var _ webhook.Defaulter = &AwsChaos{}
31
32
33 func (in *AwsChaos) Default() {
34 awschaoslog.Info("default", "name", in.Name)
35 }
36
37
38
39 var _ ChaosValidator = &AwsChaos{}
40
41
42 func (in *AwsChaos) ValidateCreate() error {
43 awschaoslog.Info("validate create", "name", in.Name)
44 return in.Validate()
45 }
46
47
48 func (in *AwsChaos) ValidateUpdate(old runtime.Object) error {
49 awschaoslog.Info("validate update", "name", in.Name)
50 return in.Validate()
51 }
52
53
54 func (in *AwsChaos) ValidateDelete() error {
55 awschaoslog.Info("validate delete", "name", in.Name)
56
57
58 return nil
59 }
60
61
62 func (in *AwsChaos) Validate() error {
63 specField := field.NewPath("spec")
64 allErrs := in.ValidateScheduler(specField)
65 allErrs = append(allErrs, in.ValidatePodMode(specField)...)
66 allErrs = append(allErrs, in.Spec.validateEbsVolume(specField.Child("volumeID"))...)
67 allErrs = append(allErrs, in.Spec.validateDeviceName(specField.Child("deviceName"))...)
68
69 if len(allErrs) > 0 {
70 return fmt.Errorf(allErrs.ToAggregate().Error())
71 }
72 return nil
73 }
74
75
76 func (in *AwsChaos) ValidateScheduler(spec *field.Path) field.ErrorList {
77 allErrs := field.ErrorList{}
78 schedulerField := spec.Child("scheduler")
79
80 switch in.Spec.Action {
81 case Ec2Stop, DetachVolume:
82 allErrs = append(allErrs, ValidateScheduler(in, spec)...)
83 case Ec2Restart:
84
85 if in.Spec.Scheduler != nil {
86 _, err := ParseCron(in.Spec.Scheduler.Cron, schedulerField.Child("cron"))
87 allErrs = append(allErrs, err...)
88 }
89 default:
90 err := fmt.Errorf("awschaos[%s/%s] have unknown action type", in.Namespace, in.Name)
91 log.Error(err, "Wrong AwsChaos Action type")
92
93 actionField := spec.Child("action")
94 allErrs = append(allErrs, field.Invalid(actionField, in.Spec.Action, err.Error()))
95 }
96 return allErrs
97 }
98
99
100 func (in *AwsChaos) ValidatePodMode(spec *field.Path) field.ErrorList {
101
102 return nil
103 }
104
105
106 func (in *AwsChaos) GetSelectSpec() []SelectSpec {
107 return nil
108 }
109
110
111 func (in *AwsChaosSpec) validateEbsVolume(containerField *field.Path) field.ErrorList {
112 allErrs := field.ErrorList{}
113 if in.Action == DetachVolume {
114 if in.EbsVolume == nil {
115 err := fmt.Errorf("the ID of EBS volume should not be empty on %s action", in.Action)
116 allErrs = append(allErrs, field.Invalid(containerField, in.EbsVolume, err.Error()))
117 }
118 }
119 return allErrs
120 }
121
122
123 func (in *AwsChaosSpec) validateDeviceName(containerField *field.Path) field.ErrorList {
124 allErrs := field.ErrorList{}
125 if in.Action == DetachVolume {
126 if in.DeviceName == nil {
127 err := fmt.Errorf("the name of device should not be empty on %s action", in.Action)
128 allErrs = append(allErrs, field.Invalid(containerField, in.DeviceName, err.Error()))
129 }
130 }
131 return allErrs
132 }
133