1
2
3
4
5
6
7
8
9
10
11
12
13
14 package v1alpha1
15
16 import (
17 "fmt"
18 "strconv"
19 "time"
20
21 cronv3 "github.com/robfig/cron/v3"
22
23 "k8s.io/apimachinery/pkg/util/validation/field"
24 )
25
26 const (
27
28 ValidateSchedulerError = "schedule and duration should be omitted or defined at the same time"
29
30
31 ValidatePodchaosSchedulerError = "schedule should be omitted"
32
33
34 ValidateValueParseError = "parse value field error:%s"
35 )
36
37
38 func ValidateScheduler(schedulerObject InnerSchedulerObject, spec *field.Path) field.ErrorList {
39
40 allErrs := field.ErrorList{}
41
42 schedulerField := spec.Child("scheduler")
43 durationField := spec.Child("duration")
44 duration, err := schedulerObject.GetDuration()
45 if err != nil {
46 allErrs = append(allErrs, field.Invalid(durationField, nil,
47 fmt.Sprintf("parse duration field error:%s", err)))
48 }
49
50 scheduler := schedulerObject.GetScheduler()
51
52 if duration != nil && scheduler != nil {
53 errs := validateSchedulerParams(duration, durationField, scheduler, schedulerField)
54 if len(errs) != 0 {
55 allErrs = append(allErrs, errs...)
56 }
57 } else if (duration == nil && scheduler != nil) || (duration != nil && scheduler == nil) {
58 allErrs = append(allErrs, field.Invalid(schedulerField, scheduler, ValidateSchedulerError))
59 }
60 return allErrs
61 }
62
63 func validateSchedulerParams(duration *time.Duration, durationField *field.Path, spec *SchedulerSpec, schedulerField *field.Path) field.ErrorList {
64 allErrs := field.ErrorList{}
65 if duration != nil && spec != nil {
66 cronField := schedulerField.Child("cron")
67 _, err := ParseCron(spec.Cron, cronField)
68 if len(err) != 0 {
69 allErrs = append(allErrs, err...)
70 }
71 }
72 return allErrs
73 }
74
75
76 func ParseCron(standardSpec string, cronField *field.Path) (cronv3.Schedule, field.ErrorList) {
77 allErrs := field.ErrorList{}
78 scheduler, err := cronv3.ParseStandard(standardSpec)
79 if err != nil {
80 allErrs = append(allErrs, field.Invalid(cronField, standardSpec,
81 fmt.Sprintf("parse cron field error:%s", err)))
82 }
83 return scheduler, allErrs
84 }
85
86
87 func ValidatePodMode(value string, mode PodMode, valueField *field.Path) field.ErrorList {
88 allErrs := field.ErrorList{}
89
90 switch mode {
91 case FixedPodMode:
92 num, err := strconv.Atoi(value)
93 if err != nil {
94 allErrs = append(allErrs, field.Invalid(valueField, value,
95 fmt.Sprintf(ValidateValueParseError, err)))
96 break
97 }
98
99 if num <= 0 {
100 allErrs = append(allErrs, field.Invalid(valueField, value,
101 fmt.Sprintf("value must be greater than 0 with mode:%s", FixedPodMode)))
102 }
103
104 case RandomMaxPercentPodMode, FixedPercentPodMode:
105 percentage, err := strconv.Atoi(value)
106 if err != nil {
107 allErrs = append(allErrs, field.Invalid(valueField, value,
108 fmt.Sprintf(ValidateValueParseError, err)))
109 break
110 }
111
112 if percentage <= 0 || percentage > 100 {
113 allErrs = append(allErrs, field.Invalid(valueField, value,
114 fmt.Sprintf("value of %d is invalid, Must be (0,100] with mode:%s",
115 percentage, mode)))
116 }
117 }
118
119 return allErrs
120 }
121