...
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 podchaoslog = logf.Log.WithName("podchaos-resource")
27
28
29
30 var _ webhook.Defaulter = &PodChaos{}
31
32
33 func (in *PodChaos) Default() {
34 podchaoslog.Info("default", "name", in.Name)
35
36 in.Spec.Selector.DefaultNamespace(in.GetNamespace())
37 }
38
39
40
41 var _ ChaosValidator = &PodChaos{}
42
43
44 func (in *PodChaos) ValidateCreate() error {
45 podchaoslog.Info("validate create", "name", in.Name)
46 return in.Validate()
47 }
48
49
50 func (in *PodChaos) ValidateUpdate(old runtime.Object) error {
51 podchaoslog.Info("validate update", "name", in.Name)
52 return in.Validate()
53 }
54
55
56 func (in *PodChaos) ValidateDelete() error {
57 podchaoslog.Info("validate delete", "name", in.Name)
58
59
60 return nil
61 }
62
63
64 func (in *PodChaos) Validate() error {
65 specField := field.NewPath("spec")
66 allErrs := in.ValidateScheduler(specField)
67 allErrs = append(allErrs, in.ValidatePodMode(specField)...)
68 allErrs = append(allErrs, in.Spec.validateContainerName(specField.Child("containerName"))...)
69
70 if len(allErrs) > 0 {
71 return fmt.Errorf(allErrs.ToAggregate().Error())
72 }
73 return nil
74 }
75
76
77 func (in *PodChaos) ValidateScheduler(spec *field.Path) field.ErrorList {
78 allErrs := field.ErrorList{}
79 schedulerField := spec.Child("scheduler")
80
81 switch in.Spec.Action {
82 case PodFailureAction:
83 allErrs = append(allErrs, ValidateScheduler(in, spec)...)
84 case PodKillAction:
85
86 if in.Spec.Scheduler == nil {
87 allErrs = append(allErrs, field.Invalid(schedulerField, in.Spec.Scheduler, ValidatePodchaosSchedulerError))
88 } else {
89 _, err := ParseCron(in.Spec.Scheduler.Cron, schedulerField.Child("cron"))
90 allErrs = append(allErrs, err...)
91 }
92 case ContainerKillAction:
93
94 if in.Spec.Scheduler == nil {
95 allErrs = append(allErrs, field.Invalid(schedulerField, in.Spec.Scheduler, ValidatePodchaosSchedulerError))
96 } else {
97 _, err := ParseCron(in.Spec.Scheduler.Cron, schedulerField.Child("cron"))
98 allErrs = append(allErrs, err...)
99 }
100 default:
101 err := fmt.Errorf("podchaos[%s/%s] have unknown action type", in.Namespace, in.Name)
102 log.Error(err, "Wrong PodChaos Action type")
103
104 actionField := spec.Child("action")
105 allErrs = append(allErrs, field.Invalid(actionField, in.Spec.Action, err.Error()))
106 }
107 return allErrs
108 }
109
110
111 func (in *PodChaos) ValidatePodMode(spec *field.Path) field.ErrorList {
112 return ValidatePodMode(in.Spec.Value, in.Spec.Mode, spec.Child("value"))
113 }
114
115
116 func (in *PodChaos) GetSelectSpec() []SelectSpec {
117 return []SelectSpec{&in.Spec}
118 }
119
120
121 func (in *PodChaosSpec) validateContainerName(containerField *field.Path) field.ErrorList {
122 allErrs := field.ErrorList{}
123 if in.Action == ContainerKillAction {
124 if in.ContainerName == "" {
125 err := fmt.Errorf("the name of container should not be empty on %s action", in.Action)
126 allErrs = append(allErrs, field.Invalid(containerField, in.ContainerName, err.Error()))
127 }
128 }
129 return allErrs
130 }
131