...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package v1alpha1
17
18 import (
19 "errors"
20 "fmt"
21 "reflect"
22 "strconv"
23 "strings"
24
25 "k8s.io/apimachinery/pkg/util/validation/field"
26
27 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1/genericwebhook"
28 )
29
30 const (
31
32 DefaultJitter = "0ms"
33
34
35 DefaultCorrelation = "0"
36 )
37
38 func (in *Direction) Default(root interface{}, field *reflect.StructField) {
39 if *in == "" {
40 *in = To
41 }
42 }
43
44 type Rate string
45
46
47 func (in *Rate) Validate(root interface{}, path *field.Path) field.ErrorList {
48 allErrs := field.ErrorList{}
49
50 _, err := ConvertUnitToBytes(string(*in))
51
52 if err != nil {
53 allErrs = append(allErrs,
54 field.Invalid(path, in,
55 fmt.Sprintf("parse rate field error:%s", err)))
56 }
57 return allErrs
58 }
59
60 func ConvertUnitToBytes(nu string) (uint64, error) {
61
62 s := strings.ToLower(strings.TrimSpace(nu))
63
64 for i, u := range []string{"tbps", "gbps", "mbps", "kbps", "bps"} {
65 if strings.HasSuffix(s, u) {
66 ts := strings.TrimSuffix(s, u)
67 s := strings.TrimSpace(ts)
68
69 n, err := strconv.ParseUint(s, 10, 64)
70
71 if err != nil {
72 return 0, err
73 }
74
75
76 for j := 4 - i; j > 0; j-- {
77 n = n * 1024
78 }
79
80 return n, nil
81 }
82 }
83
84 return 0, errors.New("invalid unit")
85 }
86
87
88 func (in *NetworkChaosSpec) Validate(root interface{}, path *field.Path) field.ErrorList {
89 allErrs := field.ErrorList{}
90
91 if in.Action == PartitionAction {
92 return nil
93 }
94
95 if (in.Direction == From || in.Direction == Both) &&
96 in.ExternalTargets != nil && in.Action != PartitionAction {
97 allErrs = append(allErrs,
98 field.Invalid(path.Child("direction"), in.Direction,
99 "external targets cannot be used with `from` and `both` direction in netem action yet"))
100 }
101
102 if (in.Direction == From || in.Direction == Both) && in.Target == nil {
103 if in.Action != PartitionAction {
104 allErrs = append(allErrs,
105 field.Invalid(path.Child("direction"), in.Direction,
106 "`from` and `both` direction cannot be used when targets is empty in netem action"))
107 } else if in.ExternalTargets == nil {
108 allErrs = append(allErrs,
109 field.Invalid(path.Child("direction"), in.Direction,
110 "`from` and `both` direction cannot be used when targets and external targets are both empty"))
111 }
112 }
113
114
115 return allErrs
116 }
117
118 func init() {
119 genericwebhook.Register("Rate", reflect.PtrTo(reflect.TypeOf(Rate(""))))
120 }
121