Skip to main content

k8s_openapi_ext/ext/
statefulset.rs

1use super::*;
2
3pub trait StatefulSetExt: super::ResourceBuilder {
4    /// Create a new StatefulSet with the given name.
5    ///
6    /// # Examples
7    ///
8    /// ```
9    /// use k8s_openapi_ext::appsv1;
10    /// use k8s_openapi_ext::StatefulSetExt;
11    ///
12    /// let statefulset = appsv1::StatefulSet::new("my-statefulset");
13    /// assert_eq!(statefulset.metadata.name, Some("my-statefulset".to_string()));
14    /// ```
15    fn new(name: impl ToString) -> Self;
16
17    /// Create a new StatefulSet with the given name and labels.
18    ///
19    /// # Examples
20    ///
21    /// ```
22    /// use k8s_openapi_ext::appsv1;
23    /// use k8s_openapi_ext::StatefulSetExt;
24    ///
25    /// let statefulset = appsv1::StatefulSet::with_labels(
26    ///     "my-statefulset",
27    ///     [("app", "my-app"), ("version", "v1")]
28    /// );
29    /// ```
30    fn with_labels(
31        name: impl ToString,
32        labels: impl IntoIterator<Item = (impl ToString, impl ToString)>,
33    ) -> Self;
34
35    /// Set the spec for the StatefulSet.
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// use k8s_openapi_ext::appsv1;
41    /// use k8s_openapi_ext::StatefulSetExt;
42    ///
43    /// let spec = appsv1::StatefulSetSpec::default();
44    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
45    ///     .spec(spec);
46    /// ```
47    fn spec(self, spec: appsv1::StatefulSetSpec) -> Self;
48
49    /// Set the number of replicas for the StatefulSet.
50    ///
51    /// # Examples
52    ///
53    /// ```
54    /// use k8s_openapi_ext::appsv1;
55    /// use k8s_openapi_ext::StatefulSetExt;
56    ///
57    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
58    ///     .replicas(3);
59    /// ```
60    fn replicas(self, replicas: i32) -> Self;
61
62    /// Set the minimum ready seconds for the StatefulSet.
63    ///
64    /// Minimum number of seconds for which a newly created pod should be ready
65    /// without any of its container crashing, for it to be considered available.
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// use k8s_openapi_ext::appsv1;
71    /// use k8s_openapi_ext::StatefulSetExt;
72    ///
73    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
74    ///     .min_ready_seconds(30);
75    /// ```
76    fn min_ready_seconds(self, seconds: i32) -> Self;
77
78    /// Set the selector for the StatefulSet.
79    ///
80    /// # Examples
81    ///
82    /// ```
83    /// use k8s_openapi_ext::appsv1;
84    /// use k8s_openapi_ext::metav1;
85    /// use k8s_openapi_ext::StatefulSetExt;
86    ///
87    /// let selector = metav1::LabelSelector::default();
88    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
89    ///     .selector(selector);
90    /// ```
91    fn selector(self, selector: metav1::LabelSelector) -> Self;
92
93    /// Set the matchLabels for the StatefulSet's selector.
94    ///
95    /// # Examples
96    ///
97    /// ```
98    /// use k8s_openapi_ext::appsv1;
99    /// use k8s_openapi_ext::StatefulSetExt;
100    ///
101    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
102    ///     .match_labels([("app", "my-app"), ("version", "v1")]);
103    /// ```
104    fn match_labels(
105        self,
106        match_labels: impl IntoIterator<Item = (impl ToString, impl ToString)>,
107    ) -> Self;
108
109    /// Set the service name for the StatefulSet.
110    ///
111    /// The service name is used to govern the StatefulSet and must be the name
112    /// of an existing headless service.
113    ///
114    /// # Examples
115    ///
116    /// ```
117    /// use k8s_openapi_ext::appsv1;
118    /// use k8s_openapi_ext::StatefulSetExt;
119    ///
120    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
121    ///     .service_name("my-headless-service");
122    /// ```
123    fn service_name(self, service_name: impl ToString) -> Self;
124
125    /// Set the revision history limit for the StatefulSet.
126    ///
127    /// The number of old ReplicaSets to retain to allow rollback.
128    /// This is a pointer to distinguish between explicit zero and not specified.
129    ///
130    /// # Examples
131    ///
132    /// ```
133    /// use k8s_openapi_ext::appsv1;
134    /// use k8s_openapi_ext::StatefulSetExt;
135    ///
136    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
137    ///     .revision_history_limit(5);
138    /// ```
139    fn revision_history_limit(self, limit: i32) -> Self;
140
141    /// Set the pod template spec for the StatefulSet.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use k8s_openapi_ext::appsv1;
147    /// use k8s_openapi_ext::corev1;
148    /// use k8s_openapi_ext::StatefulSetExt;
149    ///
150    /// let template = corev1::PodTemplateSpec::default();
151    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
152    ///     .template(template);
153    /// ```
154    fn template(self, template: corev1::PodTemplateSpec) -> Self;
155
156    /// Set the starting ordinal for the StatefulSet.
157    ///
158    /// Controls the starting ordinal number for the StatefulSet pods.
159    /// By default, pods start from ordinal 0.
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// use k8s_openapi_ext::appsv1;
165    /// use k8s_openapi_ext::StatefulSetExt;
166    ///
167    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
168    ///     .ordinals(1); // Pods will start from ordinal 1
169    /// ```
170    fn ordinals(self, ordinals: i32) -> Self;
171
172    /// Set the update strategy for the StatefulSet.
173    ///
174    /// Update strategy indicates the StatefulSetUpdateStrategy that will be
175    /// employed to update pods when a revision is made to the template.
176    ///
177    /// # Examples
178    ///
179    /// ```
180    /// use k8s_openapi_ext::appsv1;
181    /// use k8s_openapi_ext::StatefulSetExt;
182    ///
183    /// let strategy = appsv1::StatefulSetUpdateStrategy::default();
184    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
185    ///     .update_strategy(strategy);
186    /// ```
187    fn update_strategy(self, strategy: appsv1::StatefulSetUpdateStrategy) -> Self;
188
189    /// Set the pod management policy for the StatefulSet.
190    ///
191    /// Pod management policy controls how pods are created during initial scale up,
192    /// replacement, or scale down operations.
193    ///
194    /// # Examples
195    ///
196    /// ```
197    /// use k8s_openapi_ext::appsv1;
198    /// use k8s_openapi_ext::StatefulSetExt;
199    ///
200    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
201    ///     .pod_management_policy("Parallel");
202    /// ```
203    fn pod_management_policy(self, policy: impl ToString) -> Self;
204
205    /// Set the pod management policy to "OrderedReady" (default).
206    ///
207    /// In OrderedReady mode, pods are created, scaled, and deleted in order.
208    /// Each pod must be Ready before the next one is created or deleted.
209    ///
210    /// # Examples
211    ///
212    /// ```
213    /// use k8s_openapi_ext::appsv1;
214    /// use k8s_openapi_ext::StatefulSetExt;
215    ///
216    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
217    ///     .ordered_ready();
218    /// ```
219    fn ordered_ready(self) -> Self;
220
221    /// Set the pod management policy to "Parallel".
222    ///
223    /// In Parallel mode, pods are created and deleted in parallel,
224    /// similar to Deployment behavior. Pods can start simultaneously
225    /// without waiting for others to be Ready.
226    ///
227    /// # Examples
228    ///
229    /// ```
230    /// use k8s_openapi_ext::appsv1;
231    /// use k8s_openapi_ext::StatefulSetExt;
232    ///
233    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
234    ///     .parallel();
235    /// ```
236    fn parallel(self) -> Self;
237
238    /// Set the volume claim templates for the StatefulSet.
239    ///
240    /// VolumeClaimTemplates is a list of claims that pods are allowed to reference.
241    /// The StatefulSet controller is responsible for mapping network identities to
242    /// claims in a way that maintains the identity of a pod.
243    ///
244    /// # Examples
245    ///
246    /// ```
247    /// use k8s_openapi_ext::appsv1;
248    /// use k8s_openapi_ext::corev1;
249    /// use k8s_openapi_ext::StatefulSetExt;
250    ///
251    /// let claim = corev1::PersistentVolumeClaim::default();
252    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
253    ///     .volume_claim_templates([claim]);
254    /// ```
255    fn volume_claim_templates(
256        self,
257        templates: impl IntoIterator<Item = corev1::PersistentVolumeClaim>,
258    ) -> Self;
259
260    /// Set the persistent volume claim retention policy for the StatefulSet.
261    ///
262    /// PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs
263    /// created from the StatefulSet VolumeClaimTemplates.
264    ///
265    /// # Examples
266    ///
267    /// ```
268    /// use k8s_openapi_ext::appsv1;
269    /// use k8s_openapi_ext::StatefulSetExt;
270    ///
271    /// let policy = appsv1::StatefulSetPersistentVolumeClaimRetentionPolicy::default();
272    /// let statefulset = appsv1::StatefulSet::new("my-statefulset")
273    ///     .persistent_volume_claim_retention_policy(policy);
274    /// ```
275    fn persistent_volume_claim_retention_policy(
276        self,
277        policy: appsv1::StatefulSetPersistentVolumeClaimRetentionPolicy,
278    ) -> Self;
279}
280
281impl StatefulSetExt for appsv1::StatefulSet {
282    fn new(name: impl ToString) -> Self {
283        let metadata = metadata(name);
284        Self {
285            metadata,
286            // spec: todo!(),
287            // status: todo!(),
288            ..default()
289        }
290    }
291
292    fn with_labels(
293        name: impl ToString,
294        labels: impl IntoIterator<Item = (impl ToString, impl ToString)>,
295    ) -> Self {
296        Self::new(name).labels(labels)
297    }
298
299    fn spec(self, spec: appsv1::StatefulSetSpec) -> Self {
300        Self {
301            spec: Some(spec),
302            ..self
303        }
304    }
305
306    fn replicas(mut self, replicas: i32) -> Self {
307        self.spec_mut().replicas.replace(replicas);
308        self
309    }
310
311    fn min_ready_seconds(mut self, seconds: i32) -> Self {
312        self.spec_mut().min_ready_seconds.replace(seconds);
313        self
314    }
315
316    fn selector(mut self, selector: metav1::LabelSelector) -> Self {
317        self.spec_mut().selector = selector;
318        self
319    }
320
321    fn match_labels(
322        mut self,
323        match_labels: impl IntoIterator<Item = (impl ToString, impl ToString)>,
324    ) -> Self {
325        self.spec_mut().selector = metav1::LabelSelector::match_labels(match_labels);
326        self
327    }
328
329    fn service_name(mut self, service_name: impl ToString) -> Self {
330        let service_name = service_name.to_string();
331        self.spec_mut().service_name.replace(service_name);
332        self
333    }
334
335    fn revision_history_limit(mut self, limit: i32) -> Self {
336        self.spec_mut().revision_history_limit.replace(limit);
337        self
338    }
339
340    fn template(mut self, template: corev1::PodTemplateSpec) -> Self {
341        self.spec_mut().template = template;
342        self
343    }
344
345    fn ordinals(mut self, start: i32) -> Self {
346        self.spec_mut().ordinals = Some(appsv1::StatefulSetOrdinals { start: Some(start) });
347        self
348    }
349
350    fn update_strategy(mut self, strategy: appsv1::StatefulSetUpdateStrategy) -> Self {
351        self.spec_mut().update_strategy.replace(strategy);
352        self
353    }
354
355    fn pod_management_policy(mut self, policy: impl ToString) -> Self {
356        let policy = policy.to_string();
357        self.spec_mut().pod_management_policy.replace(policy);
358        self
359    }
360
361    fn ordered_ready(self) -> Self {
362        self.pod_management_policy("OrderedReady")
363    }
364
365    fn parallel(self) -> Self {
366        self.pod_management_policy("Parallel")
367    }
368
369    fn volume_claim_templates(
370        mut self,
371        templates: impl IntoIterator<Item = corev1::PersistentVolumeClaim>,
372    ) -> Self {
373        let templates = templates.into_iter().collect();
374        self.spec_mut().volume_claim_templates.replace(templates);
375        self
376    }
377
378    fn persistent_volume_claim_retention_policy(
379        mut self,
380        policy: appsv1::StatefulSetPersistentVolumeClaimRetentionPolicy,
381    ) -> Self {
382        self.spec_mut()
383            .persistent_volume_claim_retention_policy
384            .replace(policy);
385        self
386    }
387}
388
389impl HasSpec for appsv1::StatefulSet {
390    type Spec = appsv1::StatefulSetSpec;
391
392    fn spec_mut(&mut self) -> &mut Self::Spec {
393        self.spec.get_or_insert_default()
394    }
395}