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
25
26#[derive(Clone, Debug, Default, Deserialize, JsonSchema, Serialize)]
27#[serde(rename_all = "camelCase")]
28pub struct SimulationDriverConfig {
29 pub args: Option<Vec<String>>,
30 pub image: String,
31 pub namespace: String,
32 pub port: i32,
33 pub secrets: Option<Vec<String>>,
34 pub trace_path: String,
35 #[serde(default = "default_ns_prefix")]
36 pub virtual_ns_prefix: String,
37}
38
39#[derive(Clone, Debug, Default, Deserialize, JsonSchema, Serialize)]
40#[serde(rename_all = "camelCase")]
41pub struct SimulationMetricsConfig {
42 pub namespace: Option<String>,
43 pub service_account: Option<String>,
44 pub prometheus_shards: Option<i32>,
45 pub pod_monitor_names: Option<Vec<String>>,
46 pub pod_monitor_namespaces: Option<Vec<String>>,
47 pub service_monitor_names: Option<Vec<String>>,
48 pub service_monitor_namespaces: Option<Vec<String>>,
49 pub remote_write_configs: Vec<PrometheusRemoteWrite>,
50}
51
52#[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
53#[serde(rename_all = "camelCase")]
54pub struct SimulationHook {
55 pub cmd: String,
56 pub args: Option<Vec<String>>,
57 pub send_sim: Option<bool>,
58 pub ignore_failure: Option<bool>,
59}
60
61#[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
62#[serde(rename_all = "camelCase")]
63pub struct SimulationHooksConfig {
64 pub pre_start_hooks: Option<Vec<SimulationHook>>,
65 pub pre_run_hooks: Option<Vec<SimulationHook>>,
66 pub post_run_hooks: Option<Vec<SimulationHook>>,
67 pub post_stop_hooks: Option<Vec<SimulationHook>>,
68}
69
70#[derive(Clone, CustomResource, Debug, Default, Deserialize, JsonSchema, Serialize)]
71#[kube(group = "simkube.io", version = "v1", kind = "Simulation")]
72#[kube(shortname = "sim", shortname = "sims")]
73#[kube(status = "SimulationStatus")]
74#[kube(
75 printcolumn = r#"{"name":"start time", "type":"string", "description":"simulation driver start time", "jsonPath":".status.startTime"}"#,
76 printcolumn = r#"{"name":"end time", "type":"string", "description":"simulation driver end time", "jsonPath":".status.endTime"}"#,
77 printcolumn = r#"{"name":"speed factor", "type":"number", "description":"multiplicative speed factor for the simulations", "jsonPath":".spec.speed"}"#,
78 printcolumn = r#"{"name":"completed", "type":"integer", "description":"number of completed simulation runs", "jsonPath":".status.completedRuns"}"#,
79 printcolumn = r#"{"name":"total", "type":"integer", "description":"total number of simulation runs", "jsonPath":".spec.repetitions"}"#,
80 printcolumn = r#"{"name":"state", "type":"string", "description":"simulation state", "jsonPath":".status.state"}"#
81)]
82#[serde(rename_all = "camelCase")]
83pub struct SimulationSpec {
84 pub driver: SimulationDriverConfig,
86
87 pub metrics: Option<SimulationMetricsConfig>,
89 pub duration: Option<String>,
90 pub repetitions: Option<i32>,
91 pub speed: Option<f64>,
92 pub paused_time: Option<DateTime<Utc>>,
93 pub hooks: Option<SimulationHooksConfig>,
94}
95
96#[derive(Clone, Debug, Default, Deserialize, JsonSchema, Serialize)]
97#[serde(rename_all = "camelCase")]
98pub struct SimulationStatus {
99 pub observed_generation: i64,
100
101 pub state: Option<SimulationState>,
102 pub start_time: Option<DateTime<Utc>>,
103 pub end_time: Option<DateTime<Utc>>,
104 pub completed_runs: Option<u64>,
105}
106
107impl Simulation {
108 pub fn speed(&self) -> f64 {
109 self.spec.speed.unwrap_or(1.0)
110 }
111}
112
113fn default_ns_prefix() -> String {
114 "virtual".into()
115}