1#[derive(Clone, Debug, Default, PartialEq)]
5pub struct StatefulSetSpec {
6 pub min_ready_seconds: Option<i32>,
8
9 pub ordinals: Option<crate::api::apps::v1::StatefulSetOrdinals>,
11
12 pub persistent_volume_claim_retention_policy: Option<crate::api::apps::v1::StatefulSetPersistentVolumeClaimRetentionPolicy>,
14
15 pub pod_management_policy: Option<std::string::String>,
17
18 pub replicas: Option<i32>,
20
21 pub revision_history_limit: Option<i32>,
23
24 pub selector: crate::apimachinery::pkg::apis::meta::v1::LabelSelector,
26
27 pub service_name: Option<std::string::String>,
29
30 pub template: crate::api::core::v1::PodTemplateSpec,
32
33 pub update_strategy: Option<crate::api::apps::v1::StatefulSetUpdateStrategy>,
35
36 pub volume_claim_templates: Option<std::vec::Vec<crate::api::core::v1::PersistentVolumeClaim>>,
38}
39
40impl crate::DeepMerge for StatefulSetSpec {
41 fn merge_from(&mut self, other: Self) {
42 crate::DeepMerge::merge_from(&mut self.min_ready_seconds, other.min_ready_seconds);
43 crate::DeepMerge::merge_from(&mut self.ordinals, other.ordinals);
44 crate::DeepMerge::merge_from(&mut self.persistent_volume_claim_retention_policy, other.persistent_volume_claim_retention_policy);
45 crate::DeepMerge::merge_from(&mut self.pod_management_policy, other.pod_management_policy);
46 crate::DeepMerge::merge_from(&mut self.replicas, other.replicas);
47 crate::DeepMerge::merge_from(&mut self.revision_history_limit, other.revision_history_limit);
48 crate::DeepMerge::merge_from(&mut self.selector, other.selector);
49 crate::DeepMerge::merge_from(&mut self.service_name, other.service_name);
50 crate::DeepMerge::merge_from(&mut self.template, other.template);
51 crate::DeepMerge::merge_from(&mut self.update_strategy, other.update_strategy);
52 crate::merge_strategies::list::atomic(&mut self.volume_claim_templates, other.volume_claim_templates);
53 }
54}
55
56impl<'de> crate::serde::Deserialize<'de> for StatefulSetSpec {
57 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: crate::serde::Deserializer<'de> {
58 #[allow(non_camel_case_types)]
59 enum Field {
60 Key_min_ready_seconds,
61 Key_ordinals,
62 Key_persistent_volume_claim_retention_policy,
63 Key_pod_management_policy,
64 Key_replicas,
65 Key_revision_history_limit,
66 Key_selector,
67 Key_service_name,
68 Key_template,
69 Key_update_strategy,
70 Key_volume_claim_templates,
71 Other,
72 }
73
74 impl<'de> crate::serde::Deserialize<'de> for Field {
75 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: crate::serde::Deserializer<'de> {
76 struct Visitor;
77
78 impl crate::serde::de::Visitor<'_> for Visitor {
79 type Value = Field;
80
81 fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
82 f.write_str("field identifier")
83 }
84
85 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: crate::serde::de::Error {
86 Ok(match v {
87 "minReadySeconds" => Field::Key_min_ready_seconds,
88 "ordinals" => Field::Key_ordinals,
89 "persistentVolumeClaimRetentionPolicy" => Field::Key_persistent_volume_claim_retention_policy,
90 "podManagementPolicy" => Field::Key_pod_management_policy,
91 "replicas" => Field::Key_replicas,
92 "revisionHistoryLimit" => Field::Key_revision_history_limit,
93 "selector" => Field::Key_selector,
94 "serviceName" => Field::Key_service_name,
95 "template" => Field::Key_template,
96 "updateStrategy" => Field::Key_update_strategy,
97 "volumeClaimTemplates" => Field::Key_volume_claim_templates,
98 _ => Field::Other,
99 })
100 }
101 }
102
103 deserializer.deserialize_identifier(Visitor)
104 }
105 }
106
107 struct Visitor;
108
109 impl<'de> crate::serde::de::Visitor<'de> for Visitor {
110 type Value = StatefulSetSpec;
111
112 fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
113 f.write_str("StatefulSetSpec")
114 }
115
116 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> where A: crate::serde::de::MapAccess<'de> {
117 let mut value_min_ready_seconds: Option<i32> = None;
118 let mut value_ordinals: Option<crate::api::apps::v1::StatefulSetOrdinals> = None;
119 let mut value_persistent_volume_claim_retention_policy: Option<crate::api::apps::v1::StatefulSetPersistentVolumeClaimRetentionPolicy> = None;
120 let mut value_pod_management_policy: Option<std::string::String> = None;
121 let mut value_replicas: Option<i32> = None;
122 let mut value_revision_history_limit: Option<i32> = None;
123 let mut value_selector: Option<crate::apimachinery::pkg::apis::meta::v1::LabelSelector> = None;
124 let mut value_service_name: Option<std::string::String> = None;
125 let mut value_template: Option<crate::api::core::v1::PodTemplateSpec> = None;
126 let mut value_update_strategy: Option<crate::api::apps::v1::StatefulSetUpdateStrategy> = None;
127 let mut value_volume_claim_templates: Option<std::vec::Vec<crate::api::core::v1::PersistentVolumeClaim>> = None;
128
129 while let Some(key) = crate::serde::de::MapAccess::next_key::<Field>(&mut map)? {
130 match key {
131 Field::Key_min_ready_seconds => value_min_ready_seconds = crate::serde::de::MapAccess::next_value(&mut map)?,
132 Field::Key_ordinals => value_ordinals = crate::serde::de::MapAccess::next_value(&mut map)?,
133 Field::Key_persistent_volume_claim_retention_policy => value_persistent_volume_claim_retention_policy = crate::serde::de::MapAccess::next_value(&mut map)?,
134 Field::Key_pod_management_policy => value_pod_management_policy = crate::serde::de::MapAccess::next_value(&mut map)?,
135 Field::Key_replicas => value_replicas = crate::serde::de::MapAccess::next_value(&mut map)?,
136 Field::Key_revision_history_limit => value_revision_history_limit = crate::serde::de::MapAccess::next_value(&mut map)?,
137 Field::Key_selector => value_selector = crate::serde::de::MapAccess::next_value(&mut map)?,
138 Field::Key_service_name => value_service_name = crate::serde::de::MapAccess::next_value(&mut map)?,
139 Field::Key_template => value_template = crate::serde::de::MapAccess::next_value(&mut map)?,
140 Field::Key_update_strategy => value_update_strategy = crate::serde::de::MapAccess::next_value(&mut map)?,
141 Field::Key_volume_claim_templates => value_volume_claim_templates = crate::serde::de::MapAccess::next_value(&mut map)?,
142 Field::Other => { let _: crate::serde::de::IgnoredAny = crate::serde::de::MapAccess::next_value(&mut map)?; },
143 }
144 }
145
146 Ok(StatefulSetSpec {
147 min_ready_seconds: value_min_ready_seconds,
148 ordinals: value_ordinals,
149 persistent_volume_claim_retention_policy: value_persistent_volume_claim_retention_policy,
150 pod_management_policy: value_pod_management_policy,
151 replicas: value_replicas,
152 revision_history_limit: value_revision_history_limit,
153 selector: value_selector.unwrap_or_default(),
154 service_name: value_service_name,
155 template: value_template.unwrap_or_default(),
156 update_strategy: value_update_strategy,
157 volume_claim_templates: value_volume_claim_templates,
158 })
159 }
160 }
161
162 deserializer.deserialize_struct(
163 "StatefulSetSpec",
164 &[
165 "minReadySeconds",
166 "ordinals",
167 "persistentVolumeClaimRetentionPolicy",
168 "podManagementPolicy",
169 "replicas",
170 "revisionHistoryLimit",
171 "selector",
172 "serviceName",
173 "template",
174 "updateStrategy",
175 "volumeClaimTemplates",
176 ],
177 Visitor,
178 )
179 }
180}
181
182impl crate::serde::Serialize for StatefulSetSpec {
183 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: crate::serde::Serializer {
184 let mut state = serializer.serialize_struct(
185 "StatefulSetSpec",
186 2 +
187 self.min_ready_seconds.as_ref().map_or(0, |_| 1) +
188 self.ordinals.as_ref().map_or(0, |_| 1) +
189 self.persistent_volume_claim_retention_policy.as_ref().map_or(0, |_| 1) +
190 self.pod_management_policy.as_ref().map_or(0, |_| 1) +
191 self.replicas.as_ref().map_or(0, |_| 1) +
192 self.revision_history_limit.as_ref().map_or(0, |_| 1) +
193 self.service_name.as_ref().map_or(0, |_| 1) +
194 self.update_strategy.as_ref().map_or(0, |_| 1) +
195 self.volume_claim_templates.as_ref().map_or(0, |_| 1),
196 )?;
197 if let Some(value) = &self.min_ready_seconds {
198 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "minReadySeconds", value)?;
199 }
200 if let Some(value) = &self.ordinals {
201 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "ordinals", value)?;
202 }
203 if let Some(value) = &self.persistent_volume_claim_retention_policy {
204 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "persistentVolumeClaimRetentionPolicy", value)?;
205 }
206 if let Some(value) = &self.pod_management_policy {
207 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "podManagementPolicy", value)?;
208 }
209 if let Some(value) = &self.replicas {
210 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "replicas", value)?;
211 }
212 if let Some(value) = &self.revision_history_limit {
213 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "revisionHistoryLimit", value)?;
214 }
215 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "selector", &self.selector)?;
216 if let Some(value) = &self.service_name {
217 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "serviceName", value)?;
218 }
219 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "template", &self.template)?;
220 if let Some(value) = &self.update_strategy {
221 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "updateStrategy", value)?;
222 }
223 if let Some(value) = &self.volume_claim_templates {
224 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "volumeClaimTemplates", value)?;
225 }
226 crate::serde::ser::SerializeStruct::end(state)
227 }
228}
229
230#[cfg(feature = "schemars")]
231impl crate::schemars::JsonSchema for StatefulSetSpec {
232 fn schema_name() -> std::string::String {
233 "io.k8s.api.apps.v1.StatefulSetSpec".into()
234 }
235
236 fn json_schema(__gen: &mut crate::schemars::gen::SchemaGenerator) -> crate::schemars::schema::Schema {
237 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
238 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
239 description: Some("A StatefulSetSpec is the specification of a StatefulSet.".into()),
240 ..Default::default()
241 })),
242 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::Object))),
243 object: Some(std::boxed::Box::new(crate::schemars::schema::ObjectValidation {
244 properties: [
245 (
246 "minReadySeconds".into(),
247 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
248 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
249 description: Some("Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)".into()),
250 ..Default::default()
251 })),
252 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::Integer))),
253 format: Some("int32".into()),
254 ..Default::default()
255 }),
256 ),
257 (
258 "ordinals".into(),
259 {
260 let mut schema_obj = __gen.subschema_for::<crate::api::apps::v1::StatefulSetOrdinals>().into_object();
261 schema_obj.metadata = Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
262 description: Some("ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested.".into()),
263 ..Default::default()
264 }));
265 crate::schemars::schema::Schema::Object(schema_obj)
266 },
267 ),
268 (
269 "persistentVolumeClaimRetentionPolicy".into(),
270 {
271 let mut schema_obj = __gen.subschema_for::<crate::api::apps::v1::StatefulSetPersistentVolumeClaimRetentionPolicy>().into_object();
272 schema_obj.metadata = Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
273 description: Some("persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down.".into()),
274 ..Default::default()
275 }));
276 crate::schemars::schema::Schema::Object(schema_obj)
277 },
278 ),
279 (
280 "podManagementPolicy".into(),
281 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
282 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
283 description: Some("podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.".into()),
284 ..Default::default()
285 })),
286 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::String))),
287 ..Default::default()
288 }),
289 ),
290 (
291 "replicas".into(),
292 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
293 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
294 description: Some("replicas is the desired number of replicas of the given Template. These are replicas in the sense that they are instantiations of the same Template, but individual replicas also have a consistent identity. If unspecified, defaults to 1.".into()),
295 ..Default::default()
296 })),
297 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::Integer))),
298 format: Some("int32".into()),
299 ..Default::default()
300 }),
301 ),
302 (
303 "revisionHistoryLimit".into(),
304 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
305 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
306 description: Some("revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.".into()),
307 ..Default::default()
308 })),
309 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::Integer))),
310 format: Some("int32".into()),
311 ..Default::default()
312 }),
313 ),
314 (
315 "selector".into(),
316 {
317 let mut schema_obj = __gen.subschema_for::<crate::apimachinery::pkg::apis::meta::v1::LabelSelector>().into_object();
318 schema_obj.metadata = Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
319 description: Some("selector is a label query over pods that should match the replica count. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors".into()),
320 ..Default::default()
321 }));
322 crate::schemars::schema::Schema::Object(schema_obj)
323 },
324 ),
325 (
326 "serviceName".into(),
327 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
328 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
329 description: Some("serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set. Pods get DNS/hostnames that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local where \"pod-specific-string\" is managed by the StatefulSet controller.".into()),
330 ..Default::default()
331 })),
332 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::String))),
333 ..Default::default()
334 }),
335 ),
336 (
337 "template".into(),
338 {
339 let mut schema_obj = __gen.subschema_for::<crate::api::core::v1::PodTemplateSpec>().into_object();
340 schema_obj.metadata = Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
341 description: Some("template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet. Each pod will be named with the format <statefulsetname>-<podindex>. For example, a pod in a StatefulSet named \"web\" with index number \"3\" would be named \"web-3\". The only allowed template.spec.restartPolicy value is \"Always\".".into()),
342 ..Default::default()
343 }));
344 crate::schemars::schema::Schema::Object(schema_obj)
345 },
346 ),
347 (
348 "updateStrategy".into(),
349 {
350 let mut schema_obj = __gen.subschema_for::<crate::api::apps::v1::StatefulSetUpdateStrategy>().into_object();
351 schema_obj.metadata = Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
352 description: Some("updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.".into()),
353 ..Default::default()
354 }));
355 crate::schemars::schema::Schema::Object(schema_obj)
356 },
357 ),
358 (
359 "volumeClaimTemplates".into(),
360 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
361 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
362 description: Some("volumeClaimTemplates is a list of claims that pods are allowed to reference. The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name.".into()),
363 ..Default::default()
364 })),
365 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::Array))),
366 array: Some(std::boxed::Box::new(crate::schemars::schema::ArrayValidation {
367 items: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(__gen.subschema_for::<crate::api::core::v1::PersistentVolumeClaim>()))),
368 ..Default::default()
369 })),
370 ..Default::default()
371 }),
372 ),
373 ].into(),
374 required: [
375 "selector".into(),
376 "template".into(),
377 ].into(),
378 ..Default::default()
379 })),
380 ..Default::default()
381 })
382 }
383}