1use chrono::{DateTime, Utc};
4use kube::CustomResource;
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7use std::collections::BTreeMap;
8
9use crate::phase::ProcessPhase;
10
11#[derive(CustomResource, Clone, Debug, Deserialize, Serialize, JsonSchema)]
16#[kube(
17 group = "tatara.pleme.io",
18 version = "v1alpha1",
19 kind = "ProcessTable",
20 plural = "processtables",
21 shortname = "pt",
22 status = "ProcessTableStatus",
23 printcolumn = r#"{"name":"Procs","type":"integer","jsonPath":".status.processCount"}"#,
24 printcolumn = r#"{"name":"Ready","type":"integer","jsonPath":".status.readyCount"}"#,
25 printcolumn = r#"{"name":"NextPID","type":"integer","jsonPath":".spec.nextSequence"}"#,
26 printcolumn = r#"{"name":"Depth","type":"integer","jsonPath":".spec.maxDepth"}"#,
27 printcolumn = r#"{"name":"Age","type":"date","jsonPath":".metadata.creationTimestamp"}"#
28)]
29#[serde(rename_all = "camelCase")]
30pub struct ProcessTableSpec {
31 #[serde(default = "default_next_seq")]
33 pub next_sequence: u32,
34
35 #[serde(default, skip_serializing_if = "Option::is_none")]
37 pub parent_pid: Option<String>,
38
39 #[serde(default, skip_serializing_if = "Option::is_none")]
41 pub dns_domain: Option<String>,
42
43 #[serde(default, skip_serializing_if = "Option::is_none")]
45 pub dns_zone_id: Option<String>,
46
47 #[serde(default)]
49 pub max_depth: u32,
50
51 #[serde(default)]
53 pub max_children: u32,
54
55 #[serde(default = "crate::serde_defaults::default_sigterm_grace_seconds")]
57 pub sigterm_timeout_seconds: u32,
58
59 #[serde(default = "crate::serde_defaults::default_zombie_timeout_seconds")]
61 pub zombie_timeout_seconds: u32,
62
63 #[serde(default = "crate::serde_defaults::default_true")]
65 pub orphan_reaping_enabled: bool,
66}
67
68fn default_next_seq() -> u32 {
69 1
70}
71
72#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema)]
73#[serde(rename_all = "camelCase")]
74pub struct ProcessTableStatus {
75 pub process_count: u32,
76 pub ready_count: u32,
77 #[serde(default)]
78 pub processes: Vec<ProcessEntry>,
79 #[serde(default, skip_serializing_if = "Option::is_none")]
80 pub last_reconciled: Option<DateTime<Utc>>,
81
82 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
91 pub claims: BTreeMap<String, ClaimRecord>,
92}
93
94#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
98#[serde(rename_all = "camelCase")]
99pub struct ClaimRecord {
100 pub holder: String,
104
105 pub pid: String,
109
110 pub granted_at: DateTime<Utc>,
113
114 pub priority: i32,
118}
119
120#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
122#[serde(rename_all = "camelCase")]
123pub struct ProcessEntry {
124 pub name: String,
125 pub namespace: String,
126 pub pid: String,
127 #[serde(default, skip_serializing_if = "Option::is_none")]
128 pub parent_pid: Option<String>,
129 pub phase: ProcessPhase,
130 pub point_type: String,
132 pub substrate: String,
134 #[serde(default, skip_serializing_if = "Option::is_none")]
135 pub content_hash: Option<String>,
136 #[serde(default, skip_serializing_if = "Option::is_none")]
137 pub attestation_root: Option<String>,
138 #[serde(default, skip_serializing_if = "Option::is_none")]
139 pub last_updated: Option<DateTime<Utc>>,
140}