k8s_openapi_ext/get/
pod.rs

1use super::*;
2
3pub use condition::PodConditionGetExt;
4
5mod condition;
6
7pub trait PodGetExt {
8    #[deprecated(note = "Use corev1::PodCondition::POD_SCHEDULED instead")]
9    const POD_SCHEDULED: &str = "PodScheduled";
10
11    /// The Pod has been accepted by the Kubernetes cluster, but one or more
12    /// of the containers has not been set up and made ready to run.
13    /// This includes time a Pod spends waiting to be scheduled as well as the
14    /// time spent downloading container images over the network.
15    const POD_PENDING: &str = "Pending";
16
17    /// The Pod has been bound to a node, and all of the containers have been
18    /// created. At least one container is still running, or is in the process
19    /// of starting or restarting.
20    const POD_RUNNING: &str = "Running";
21
22    /// All containers in the Pod have terminated in success, and will not
23    /// be restarted.
24    const POD_SUCCEEDED: &str = "Succeeded";
25
26    /// All containers in the Pod have terminated, and at least one container
27    /// has terminated in failure. That is, the container either exited with
28    /// non-zero status or was terminated by the system, and is not set for
29    /// automatic restarting.
30    const POD_FAILED: &str = "Failed";
31
32    /// For some reason the state of the Pod could not be obtained.
33    /// This phase typically occurs due to an error in communicating with
34    /// the node where the Pod should be running.
35    const POD_UNKNOWN: &str = "Unknown";
36
37    fn spec(&self) -> Option<&corev1::PodSpec>;
38
39    fn status(&self) -> Option<&corev1::PodStatus>;
40
41    // From spec
42    fn containers(&self) -> Option<&[corev1::Container]> {
43        self.spec().map(|spec| spec.containers.as_ref())
44    }
45
46    fn ephemeral_containers(&self) -> Option<&[corev1::EphemeralContainer]> {
47        self.spec()?.ephemeral_containers.as_deref()
48    }
49
50    fn init_containers(&self) -> Option<&[corev1::Container]> {
51        self.spec()?.init_containers.as_deref()
52    }
53
54    fn node_selector(&self) -> Option<&BTreeMap<String, String>> {
55        self.spec()?.node_selector.as_ref()
56    }
57
58    fn resource_claims(&self) -> Option<&[corev1::PodResourceClaim]> {
59        self.spec()?.resource_claims.as_deref()
60    }
61
62    fn tolerations(&self) -> Option<&[corev1::Toleration]> {
63        self.spec()?.tolerations.as_deref()
64    }
65
66    fn readiness_gates(&self) -> Option<&[corev1::PodReadinessGate]> {
67        self.spec()?.readiness_gates.as_deref()
68    }
69
70    // From status
71    fn message(&self) -> Option<&str> {
72        self.status()?.message.as_deref()
73    }
74
75    fn phase(&self) -> Option<&str> {
76        self.status()?.phase.as_deref()
77    }
78
79    fn qos_class(&self) -> Option<&str> {
80        self.status()?.qos_class.as_deref()
81    }
82
83    fn reason(&self) -> Option<&str> {
84        self.status()?.reason.as_deref()
85    }
86
87    fn resize(&self) -> Option<&str> {
88        self.status()?.resize.as_deref()
89    }
90
91    fn conditions(&self) -> Option<&[corev1::PodCondition]> {
92        self.status()?.conditions.as_deref()
93    }
94
95    fn container_statuses(&self) -> Option<&[corev1::ContainerStatus]> {
96        self.status()?.container_statuses.as_deref()
97    }
98
99    fn ephemeral_container_statuses(&self) -> Option<&[corev1::ContainerStatus]> {
100        self.status()?.ephemeral_container_statuses.as_deref()
101    }
102
103    fn init_container_statuses(&self) -> Option<&[corev1::ContainerStatus]> {
104        self.status()?.init_container_statuses.as_deref()
105    }
106
107    fn nominated_node_name(&self) -> Option<&str> {
108        self.status()?.nominated_node_name.as_deref()
109    }
110
111    fn resource_claim_statuses(&self) -> Option<&[corev1::PodResourceClaimStatus]> {
112        self.status()?.resource_claim_statuses.as_deref()
113    }
114
115    fn host_ip(&self) -> Option<&str> {
116        self.status()?.host_ip.as_deref()
117    }
118
119    fn host_ips(&self) -> Option<&[corev1::HostIP]> {
120        self.status()?.host_ips.as_deref()
121    }
122
123    fn pod_ip(&self) -> Option<&str> {
124        self.status()?.pod_ip.as_deref()
125    }
126
127    fn pod_ips(&self) -> Option<&[corev1::PodIP]> {
128        self.status()?.pod_ips.as_deref()
129    }
130
131    fn start_time(&self) -> Option<&metav1::Time> {
132        self.status()?.start_time.as_ref()
133    }
134
135    fn condition(&self, type_: &str) -> Option<&corev1::PodCondition> {
136        self.conditions()?
137            .iter()
138            .find(|condition| condition.type_ == type_)
139    }
140
141    fn is_running(&self) -> bool {
142        self.phase().is_some_and(|phase| phase == Self::POD_RUNNING)
143    }
144
145    fn is_ready(&self) -> bool {
146        let gates = self
147            .readiness_gates()
148            .unwrap_or_default()
149            .iter()
150            .all(|gate| {
151                self.condition(&gate.condition_type)
152                    .is_some_and(|condition| condition.is_true())
153            });
154
155        let ready = self
156            .condition(corev1::PodCondition::POD_READY)
157            .is_some_and(|condition| condition.is_true());
158
159        gates && ready
160    }
161
162    fn pod_scheduled_reason(&self) -> Option<&str> {
163        self.condition(corev1::PodCondition::POD_SCHEDULED)?
164            .reason()
165    }
166}
167
168impl PodGetExt for corev1::Pod {
169    fn spec(&self) -> Option<&corev1::PodSpec> {
170        self.spec.as_ref()
171    }
172
173    fn status(&self) -> Option<&corev1::PodStatus> {
174        self.status.as_ref()
175    }
176}
177
178impl PodGetExt for corev1::PodStatus {
179    fn spec(&self) -> Option<&corev1::PodSpec> {
180        None
181    }
182
183    fn status(&self) -> Option<&corev1::PodStatus> {
184        Some(self)
185    }
186}
187
188impl PodGetExt for corev1::PodTemplate {
189    fn spec(&self) -> Option<&corev1::PodSpec> {
190        self.template.as_ref()?.spec.as_ref()
191    }
192
193    fn status(&self) -> Option<&corev1::PodStatus> {
194        None
195    }
196}
197
198impl PodGetExt for corev1::PodTemplateSpec {
199    fn spec(&self) -> Option<&corev1::PodSpec> {
200        self.spec.as_ref()
201    }
202
203    fn status(&self) -> Option<&corev1::PodStatus> {
204        None
205    }
206}