1use clockabilly::{
2 DateTime,
3 Utc,
4};
5use kube::CustomResource;
6use schemars::JsonSchema;
7use serde::{
8 Deserialize,
9 Serialize,
10};
11
12use crate::prometheus::PrometheusRemoteWrite;
13
14#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
15pub enum SimulationState {
16 Blocked,
17 Initializing,
18 Finished,
19 Failed,
20 Paused,
21 Retrying,
22 Running,
23}
24#[derive(Clone, Debug, Default, Deserialize, JsonSchema, Serialize)]
25#[serde(rename_all = "camelCase")]
26pub struct LifecycleParams {
27 pub image_pull_delay: Option<u32>,
28 pub image_pull_jitter: Option<u32>,
29 pub pod_startup_delay: Option<u32>,
30 pub pod_startup_jitter: Option<u32>,
31}
32
33#[derive(Clone, Debug, Default, Deserialize, JsonSchema, Serialize)]
34#[serde(rename_all = "camelCase")]
35pub struct SimulationDriverConfig {
36 pub args: Option<Vec<String>>,
37 pub image: String,
38 pub namespace: String,
39 pub port: i32,
40 pub secrets: Option<Vec<String>>,
41 pub trace_path: String,
42 #[serde(default = "default_ns_prefix")]
43 pub virtual_ns_prefix: String,
44 #[serde(default = "default_cert_issuer")]
45 pub cert_manager_issuer: String,
46}
47
48#[derive(Clone, Debug, Default, Deserialize, JsonSchema, Serialize)]
49#[serde(rename_all = "camelCase")]
50pub struct SimulationMetricsConfig {
51 pub namespace: Option<String>,
52 pub service_account: Option<String>,
53 pub prometheus_shards: Option<i32>,
54 pub pod_monitor_names: Option<Vec<String>>,
55 pub pod_monitor_namespaces: Option<Vec<String>>,
56 pub service_monitor_names: Option<Vec<String>>,
57 pub service_monitor_namespaces: Option<Vec<String>>,
58 pub remote_write_configs: Vec<PrometheusRemoteWrite>,
59}
60
61#[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
62#[serde(rename_all = "camelCase")]
63pub struct SimulationHook {
64 pub cmd: String,
65 pub args: Option<Vec<String>>,
66 pub send_sim: Option<bool>,
67 pub ignore_failure: Option<bool>,
68}
69
70#[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
71#[serde(rename_all = "camelCase")]
72pub struct SimulationHooksConfig {
73 pub pre_start_hooks: Option<Vec<SimulationHook>>,
74 pub pre_run_hooks: Option<Vec<SimulationHook>>,
75 pub post_run_hooks: Option<Vec<SimulationHook>>,
76 pub post_stop_hooks: Option<Vec<SimulationHook>>,
77}
78
79#[derive(Clone, CustomResource, Debug, Default, Deserialize, JsonSchema, Serialize)]
80#[kube(group = "simkube.io", version = "v1", kind = "Simulation")]
81#[kube(shortname = "sim", shortname = "sims")]
82#[kube(status = "SimulationStatus")]
83#[kube(
84 printcolumn = r#"{"name":"start time", "type":"string", "description":"simulation driver start time", "jsonPath":".status.startTime"}"#,
85 printcolumn = r#"{"name":"end time", "type":"string", "description":"simulation driver end time", "jsonPath":".status.endTime"}"#,
86 printcolumn = r#"{"name":"speed factor", "type":"number", "description":"multiplicative speed factor for the simulations", "jsonPath":".spec.speed"}"#,
87 printcolumn = r#"{"name":"completed", "type":"integer", "description":"number of completed simulation runs", "jsonPath":".status.completedRuns"}"#,
88 printcolumn = r#"{"name":"total", "type":"integer", "description":"total number of simulation runs", "jsonPath":".spec.repetitions"}"#,
89 printcolumn = r#"{"name":"state", "type":"string", "description":"simulation state", "jsonPath":".status.state"}"#
90)]
91#[serde(rename_all = "camelCase")]
92pub struct SimulationSpec {
93 pub driver: SimulationDriverConfig,
95
96 pub metrics: Option<SimulationMetricsConfig>,
98 pub duration: Option<String>,
99 pub repetitions: Option<i32>,
100 pub speed: Option<f64>,
101 pub reschedule_interrupted_bare_pods: Option<bool>,
102 pub paused_time: Option<DateTime<Utc>>,
103 pub hooks: Option<SimulationHooksConfig>,
104 pub lifecycle_params: LifecycleParams,
105}
106
107#[derive(Clone, Debug, Default, Deserialize, JsonSchema, Serialize)]
108#[serde(rename_all = "camelCase")]
109pub struct SimulationStatus {
110 pub observed_generation: i64,
111
112 pub state: Option<SimulationState>,
113 pub start_time: Option<DateTime<Utc>>,
114 pub end_time: Option<DateTime<Utc>>,
115 pub completed_runs: Option<u64>,
116}
117
118impl Simulation {
119 pub fn speed(&self) -> f64 {
120 self.spec.speed.unwrap_or(1.0)
121 }
122}
123
124fn default_ns_prefix() -> String {
125 "virtual".into()
126}
127
128fn default_cert_issuer() -> String {
129 "selfsigned".into()
130}