Skip to main content

tests_fuzz/utils/crd/
network.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use derive_builder::Builder;
16use kube::CustomResource;
17use schemars::JsonSchema;
18use serde::{Deserialize, Serialize};
19
20use super::common::{Mode, Selector};
21
22#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Builder, JsonSchema)]
23#[serde(rename_all = "camelCase")]
24pub struct Target {
25    mode: Mode,
26    selector: Selector,
27}
28
29#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, JsonSchema)]
30#[serde(rename_all = "kebab-case")]
31pub enum Action {
32    Netem,
33    Delay,
34    Loss,
35    Corrupt,
36    Partition,
37    Bandwidth,
38}
39
40#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, JsonSchema)]
41#[serde(rename_all = "kebab-case")]
42pub enum Direction {
43    From,
44    To,
45    Both,
46}
47
48#[derive(
49    CustomResource, Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Builder, JsonSchema,
50)]
51#[kube(
52    group = "chaos-mesh.org",
53    version = "v1alpha1",
54    namespaced,
55    kind = "NetworkChaos",
56    plural = "networkchaos",
57    singular = "networkchaos",
58    derive = "PartialEq"
59)]
60#[serde(rename_all = "camelCase")]
61pub struct NetworkChaosSpec {
62    // Indicates the specific fault type. Available types include:
63    // netem, delay (network delay), loss (packet loss), duplicate (packet duplicating),
64    // corrupt (packet corrupt), partition (network partition), and bandwidth (network bandwidth limit).
65    // After you specify action field,
66    // refer to Description for action-related fields for other necessary field configuration.
67    action: Action,
68    // Used in combination with direction, making Chaos only effective for some packets.
69    #[builder(setter(into), default = "None")]
70    #[serde(skip_serializing_if = "Option::is_none")]
71    target: Option<Target>,
72    // Indicates the direction of target packets. Available value include `from` (the packets from target),
73    // `to` (the packets to target), and `both` ( the packets from or to target).
74    // This parameter makes Chaos only take effect for a specific direction of packets.
75    #[builder(setter(into), default = "None")]
76    #[serde(skip_serializing_if = "Option::is_none")]
77    direction: Option<Direction>,
78    // Specifies the mode of the experiment. The mode options include one (selecting a random Pod),
79    // all (selecting all eligible Pods), fixed (selecting a specified number of eligible Pods),
80    // fixed-percent (selecting a specified percentage of Pods from the eligible Pods),
81    // and random-max-percent (selecting the maximum percentage of Pods from the eligible Pods).
82    mode: Mode,
83    // Provides a parameter for the mode configuration, depending on mode.
84    // For example, when mode is set to fixed-percent, value specifies the percentage of Pods.
85    #[builder(setter(into), default = "None")]
86    #[serde(skip_serializing_if = "Option::is_none")]
87    value: Option<String>,
88    // Specifies the target Pod.
89    selector: Selector,
90    // Indicates the network targets except for Kubernetes, which can be IPv4 addresses or domains.
91    // This parameter only works with `direction: to`.
92    #[builder(setter(into), default = "Vec::new()")]
93    #[serde(skip_serializing_if = "Vec::is_empty", default)]
94    external_targets: Vec<String>,
95    // Specifies the affected network interface
96    #[builder(setter(into), default = "None")]
97    #[serde(skip_serializing_if = "Option::is_none")]
98    device: Option<String>,
99    #[serde(skip_serializing_if = "Option::is_none")]
100    #[builder(setter(into), default = "None")]
101    delay: Option<Delay>,
102    #[serde(skip_serializing_if = "Option::is_none")]
103    #[builder(setter(into), default = "None")]
104    loss: Option<Loss>,
105    #[serde(skip_serializing_if = "Option::is_none")]
106    #[builder(setter(into), default = "None")]
107    duplicate: Option<Duplicate>,
108    #[serde(skip_serializing_if = "Option::is_none")]
109    #[builder(setter(into), default = "None")]
110    corrupt: Option<Corrupt>,
111    #[serde(skip_serializing_if = "Option::is_none")]
112    #[builder(setter(into), default = "None")]
113    bandwidth: Option<Bandwidth>,
114    #[serde(skip_serializing_if = "Option::is_none")]
115    #[builder(setter(into), default = "None")]
116    duration: Option<String>,
117}
118
119#[derive(Debug, Default, PartialEq, Eq, Clone, Serialize, Deserialize, Builder, JsonSchema)]
120#[serde(default)]
121#[builder(default)]
122pub struct Delay {
123    #[serde(skip_serializing_if = "Option::is_none")]
124    #[builder(setter(into, strip_option))]
125    // Indicates the network latency.
126    latency: Option<String>,
127    // Indicates the correlation between the current latency and the previous one.
128    // Range of value: [0, 100]
129    #[serde(skip_serializing_if = "Option::is_none")]
130    #[builder(setter(into, strip_option))]
131    correlation: Option<String>,
132    // Indicates the range of the network latency.
133    #[serde(skip_serializing_if = "Option::is_none")]
134    #[builder(setter(into, strip_option))]
135    jitter: Option<String>,
136    // Indicates the status of network packet reordering
137    #[serde(skip_serializing_if = "Option::is_none")]
138    #[builder(setter(into, strip_option))]
139    reorder: Option<Reorder>,
140}
141
142#[derive(Debug, Default, PartialEq, Eq, Clone, Serialize, Deserialize, JsonSchema, Builder)]
143#[serde(default)]
144#[builder(default)]
145pub struct Reorder {
146    // Indicates the probability to reorder
147    #[serde(skip_serializing_if = "Option::is_none")]
148    #[builder(setter(into, strip_option))]
149    reorder: Option<String>,
150    // Indicates the correlation between this time's length of delay time
151    // and the previous time's length of delay time. Range of value: [0, 100]
152    #[serde(skip_serializing_if = "Option::is_none")]
153    #[builder(setter(into, strip_option))]
154    correlation: Option<String>,
155    // Indicates the gap before and after packet reordering.
156    #[serde(skip_serializing_if = "Option::is_none")]
157    #[builder(setter(into, strip_option))]
158    gap: Option<i32>,
159}
160
161#[derive(Debug, Default, PartialEq, Eq, Clone, Serialize, Deserialize, JsonSchema, Builder)]
162#[serde(default)]
163#[builder(default, setter(into, strip_option))]
164pub struct Loss {
165    // Indicates the probability of packet loss.
166    // Range of value: [0, 100].
167    #[serde(skip_serializing_if = "Option::is_none")]
168    loss: Option<String>,
169    // Indicates the correlation between the probability of current packet loss
170    // and the previous time's packet loss. Range of value: [0, 100].
171    #[serde(skip_serializing_if = "Option::is_none")]
172    correlation: Option<String>,
173}
174
175#[derive(Debug, Default, PartialEq, Eq, Clone, Serialize, Deserialize, JsonSchema, Builder)]
176#[serde(default)]
177#[builder(default, setter(into, strip_option))]
178pub struct Duplicate {
179    // Indicates the probability of packet duplicating.
180    // Range of value: [0, 100]
181    #[serde(skip_serializing_if = "Option::is_none")]
182    duplicate: Option<String>,
183    // Indicates the correlation between the probability of current packet duplicating
184    // and the previous time's packet duplicating. Range of value: [0, 100]
185    #[serde(skip_serializing_if = "Option::is_none")]
186    correlation: Option<String>,
187}
188
189#[derive(Debug, Default, PartialEq, Eq, Clone, Serialize, Deserialize, JsonSchema, Builder)]
190#[serde(default)]
191#[builder(default, setter(into, strip_option))]
192pub struct Corrupt {
193    // Indicates the probability of packet corruption. Range of value: [0, 100]
194    #[serde(skip_serializing_if = "Option::is_none")]
195    corrupt: Option<String>,
196    // Indicates the correlation between the probability of current packet corruption
197    // and the previous time's packet corruption. Range of value: [0, 100]
198    #[serde(skip_serializing_if = "Option::is_none")]
199    correlation: Option<String>,
200}
201
202#[derive(Debug, Default, PartialEq, Eq, Clone, Serialize, Deserialize, JsonSchema, Builder)]
203#[serde(default)]
204#[builder(default)]
205pub struct Bandwidth {
206    // Indicates the rate of bandwidth limit. e.g., 1mbps.
207    rate: String,
208    // Indicates the number of bytes waiting in queue.
209    limit: u32,
210    // Indicates the maximum number of bytes that can be sent instantaneously.
211    buffer: u32,
212    // Indicates the maximum consumption of `bucket` (usually not set)
213    #[serde(skip_serializing_if = "Option::is_none")]
214    #[builder(setter(into, strip_option))]
215    peakrate: Option<u64>,
216    // Indicates the size of peakrate bucket (usually not set).
217    #[serde(skip_serializing_if = "Option::is_none")]
218    #[builder(setter(into, strip_option))]
219    minburst: Option<u32>,
220}
221
222#[cfg(test)]
223mod tests {
224    use std::collections::BTreeMap;
225
226    use super::{Action, Direction, NetworkChaosSpecBuilder, TargetBuilder};
227    use crate::utils::crd::common::{Mode, SelectorBuilder};
228    use crate::utils::crd::network::{DelayBuilder, NetworkChaos};
229
230    #[test]
231    fn test_serde() {
232        let mut fs = BTreeMap::new();
233        fs.insert("app".into(), "datanode".into());
234        let selector = SelectorBuilder::default()
235            .namespaces(vec!["default".into()])
236            .label_selectors(fs)
237            .build()
238            .unwrap();
239        let target = TargetBuilder::default()
240            .mode(Mode::All)
241            .selector(selector.clone())
242            .build()
243            .unwrap();
244        let delay = DelayBuilder::default()
245            .latency("100ms")
246            .correlation("100")
247            .jitter("0ms")
248            .build()
249            .unwrap();
250        let spec = NetworkChaosSpecBuilder::default()
251            .action(Action::Delay)
252            .target(target)
253            .direction(Direction::Both)
254            .mode(Mode::One)
255            .selector(selector)
256            .delay(delay)
257            .duration(Some("10s".to_string()))
258            .build()
259            .unwrap();
260        let crd = NetworkChaos::new("my-delay", spec);
261        let ser = serde_yaml::to_string(&crd).unwrap();
262
263        let expected = r#"apiVersion: chaos-mesh.org/v1alpha1
264kind: NetworkChaos
265metadata:
266  name: my-delay
267spec:
268  action: delay
269  target:
270    mode: all
271    selector:
272      namespaces:
273      - default
274      labelSelectors:
275        app: datanode
276  direction: both
277  mode: one
278  selector:
279    namespaces:
280    - default
281    labelSelectors:
282      app: datanode
283  delay:
284    latency: 100ms
285    correlation: '100'
286    jitter: 0ms
287  duration: 10s
288"#;
289        assert_eq!(expected, ser);
290    }
291}