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