1#[derive(Clone, Debug, Default, PartialEq)]
7pub struct StorageClass {
8 pub allow_volume_expansion: Option<bool>,
10
11 pub allowed_topologies: Option<Vec<crate::api::core::v1::TopologySelectorTerm>>,
13
14 pub metadata: crate::apimachinery::pkg::apis::meta::v1::ObjectMeta,
16
17 pub mount_options: Option<Vec<String>>,
19
20 pub parameters: Option<std::collections::BTreeMap<String, String>>,
22
23 pub provisioner: String,
25
26 pub reclaim_policy: Option<String>,
28
29 pub volume_binding_mode: Option<String>,
31}
32
33impl crate::Resource for StorageClass {
34 const API_VERSION: &'static str = "storage.k8s.io/v1";
35 const GROUP: &'static str = "storage.k8s.io";
36 const KIND: &'static str = "StorageClass";
37 const VERSION: &'static str = "v1";
38 const URL_PATH_SEGMENT: &'static str = "storageclasses";
39 type Scope = crate::ClusterResourceScope;
40}
41
42impl crate::ListableResource for StorageClass {
43 const LIST_KIND: &'static str = "StorageClassList";
44}
45
46impl crate::Metadata for StorageClass {
47 type Ty = crate::apimachinery::pkg::apis::meta::v1::ObjectMeta;
48
49 fn metadata(&self) -> &<Self as crate::Metadata>::Ty {
50 &self.metadata
51 }
52
53 fn metadata_mut(&mut self) -> &mut<Self as crate::Metadata>::Ty {
54 &mut self.metadata
55 }
56}
57
58impl crate::DeepMerge for StorageClass {
59 fn merge_from(&mut self, other: Self) {
60 crate::DeepMerge::merge_from(&mut self.allow_volume_expansion, other.allow_volume_expansion);
61 crate::merge_strategies::list::atomic(&mut self.allowed_topologies, other.allowed_topologies);
62 crate::DeepMerge::merge_from(&mut self.metadata, other.metadata);
63 crate::merge_strategies::list::atomic(&mut self.mount_options, other.mount_options);
64 crate::merge_strategies::map::granular(&mut self.parameters, other.parameters, |current_item, other_item| {
65 crate::DeepMerge::merge_from(current_item, other_item);
66 });
67 crate::DeepMerge::merge_from(&mut self.provisioner, other.provisioner);
68 crate::DeepMerge::merge_from(&mut self.reclaim_policy, other.reclaim_policy);
69 crate::DeepMerge::merge_from(&mut self.volume_binding_mode, other.volume_binding_mode);
70 }
71}
72
73impl<'de> crate::serde::Deserialize<'de> for StorageClass {
74 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: crate::serde::Deserializer<'de> {
75 #[allow(non_camel_case_types)]
76 enum Field {
77 Key_api_version,
78 Key_kind,
79 Key_allow_volume_expansion,
80 Key_allowed_topologies,
81 Key_metadata,
82 Key_mount_options,
83 Key_parameters,
84 Key_provisioner,
85 Key_reclaim_policy,
86 Key_volume_binding_mode,
87 Other,
88 }
89
90 impl<'de> crate::serde::Deserialize<'de> for Field {
91 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: crate::serde::Deserializer<'de> {
92 struct Visitor;
93
94 impl crate::serde::de::Visitor<'_> for Visitor {
95 type Value = Field;
96
97 fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 f.write_str("field identifier")
99 }
100
101 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: crate::serde::de::Error {
102 Ok(match v {
103 "apiVersion" => Field::Key_api_version,
104 "kind" => Field::Key_kind,
105 "allowVolumeExpansion" => Field::Key_allow_volume_expansion,
106 "allowedTopologies" => Field::Key_allowed_topologies,
107 "metadata" => Field::Key_metadata,
108 "mountOptions" => Field::Key_mount_options,
109 "parameters" => Field::Key_parameters,
110 "provisioner" => Field::Key_provisioner,
111 "reclaimPolicy" => Field::Key_reclaim_policy,
112 "volumeBindingMode" => Field::Key_volume_binding_mode,
113 _ => Field::Other,
114 })
115 }
116 }
117
118 deserializer.deserialize_identifier(Visitor)
119 }
120 }
121
122 struct Visitor;
123
124 impl<'de> crate::serde::de::Visitor<'de> for Visitor {
125 type Value = StorageClass;
126
127 fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128 f.write_str(<Self::Value as crate::Resource>::KIND)
129 }
130
131 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> where A: crate::serde::de::MapAccess<'de> {
132 let mut value_allow_volume_expansion: Option<bool> = None;
133 let mut value_allowed_topologies: Option<Vec<crate::api::core::v1::TopologySelectorTerm>> = None;
134 let mut value_metadata: Option<crate::apimachinery::pkg::apis::meta::v1::ObjectMeta> = None;
135 let mut value_mount_options: Option<Vec<String>> = None;
136 let mut value_parameters: Option<std::collections::BTreeMap<String, String>> = None;
137 let mut value_provisioner: Option<String> = None;
138 let mut value_reclaim_policy: Option<String> = None;
139 let mut value_volume_binding_mode: Option<String> = None;
140
141 while let Some(key) = crate::serde::de::MapAccess::next_key::<Field>(&mut map)? {
142 match key {
143 Field::Key_api_version => {
144 let value_api_version: String = crate::serde::de::MapAccess::next_value(&mut map)?;
145 if value_api_version != <Self::Value as crate::Resource>::API_VERSION {
146 return Err(crate::serde::de::Error::invalid_value(crate::serde::de::Unexpected::Str(&value_api_version), &<Self::Value as crate::Resource>::API_VERSION));
147 }
148 },
149 Field::Key_kind => {
150 let value_kind: String = crate::serde::de::MapAccess::next_value(&mut map)?;
151 if value_kind != <Self::Value as crate::Resource>::KIND {
152 return Err(crate::serde::de::Error::invalid_value(crate::serde::de::Unexpected::Str(&value_kind), &<Self::Value as crate::Resource>::KIND));
153 }
154 },
155 Field::Key_allow_volume_expansion => value_allow_volume_expansion = crate::serde::de::MapAccess::next_value(&mut map)?,
156 Field::Key_allowed_topologies => value_allowed_topologies = crate::serde::de::MapAccess::next_value(&mut map)?,
157 Field::Key_metadata => value_metadata = crate::serde::de::MapAccess::next_value(&mut map)?,
158 Field::Key_mount_options => value_mount_options = crate::serde::de::MapAccess::next_value(&mut map)?,
159 Field::Key_parameters => value_parameters = crate::serde::de::MapAccess::next_value(&mut map)?,
160 Field::Key_provisioner => value_provisioner = crate::serde::de::MapAccess::next_value(&mut map)?,
161 Field::Key_reclaim_policy => value_reclaim_policy = crate::serde::de::MapAccess::next_value(&mut map)?,
162 Field::Key_volume_binding_mode => value_volume_binding_mode = crate::serde::de::MapAccess::next_value(&mut map)?,
163 Field::Other => { let _: crate::serde::de::IgnoredAny = crate::serde::de::MapAccess::next_value(&mut map)?; },
164 }
165 }
166
167 Ok(StorageClass {
168 allow_volume_expansion: value_allow_volume_expansion,
169 allowed_topologies: value_allowed_topologies,
170 metadata: value_metadata.unwrap_or_default(),
171 mount_options: value_mount_options,
172 parameters: value_parameters,
173 provisioner: value_provisioner.unwrap_or_default(),
174 reclaim_policy: value_reclaim_policy,
175 volume_binding_mode: value_volume_binding_mode,
176 })
177 }
178 }
179
180 deserializer.deserialize_struct(
181 <Self as crate::Resource>::KIND,
182 &[
183 "apiVersion",
184 "kind",
185 "allowVolumeExpansion",
186 "allowedTopologies",
187 "metadata",
188 "mountOptions",
189 "parameters",
190 "provisioner",
191 "reclaimPolicy",
192 "volumeBindingMode",
193 ],
194 Visitor,
195 )
196 }
197}
198
199impl crate::serde::Serialize for StorageClass {
200 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: crate::serde::Serializer {
201 let mut state = serializer.serialize_struct(
202 <Self as crate::Resource>::KIND,
203 4 +
204 self.allow_volume_expansion.as_ref().map_or(0, |_| 1) +
205 self.allowed_topologies.as_ref().map_or(0, |_| 1) +
206 self.mount_options.as_ref().map_or(0, |_| 1) +
207 self.parameters.as_ref().map_or(0, |_| 1) +
208 self.reclaim_policy.as_ref().map_or(0, |_| 1) +
209 self.volume_binding_mode.as_ref().map_or(0, |_| 1),
210 )?;
211 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "apiVersion", <Self as crate::Resource>::API_VERSION)?;
212 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "kind", <Self as crate::Resource>::KIND)?;
213 if let Some(value) = &self.allow_volume_expansion {
214 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "allowVolumeExpansion", value)?;
215 }
216 if let Some(value) = &self.allowed_topologies {
217 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "allowedTopologies", value)?;
218 }
219 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "metadata", &self.metadata)?;
220 if let Some(value) = &self.mount_options {
221 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "mountOptions", value)?;
222 }
223 if let Some(value) = &self.parameters {
224 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "parameters", value)?;
225 }
226 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "provisioner", &self.provisioner)?;
227 if let Some(value) = &self.reclaim_policy {
228 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "reclaimPolicy", value)?;
229 }
230 if let Some(value) = &self.volume_binding_mode {
231 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "volumeBindingMode", value)?;
232 }
233 crate::serde::ser::SerializeStruct::end(state)
234 }
235}
236
237#[cfg(feature = "schemars")]
238impl crate::schemars::JsonSchema for StorageClass {
239 fn schema_name() -> String {
240 "io.k8s.api.storage.v1.StorageClass".to_owned()
241 }
242
243 fn json_schema(__gen: &mut crate::schemars::gen::SchemaGenerator) -> crate::schemars::schema::Schema {
244 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
245 metadata: Some(Box::new(crate::schemars::schema::Metadata {
246 description: Some("StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned.\n\nStorageClasses are non-namespaced; the name of the storage class according to etcd is in ObjectMeta.Name.".to_owned()),
247 ..Default::default()
248 })),
249 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::Object))),
250 object: Some(Box::new(crate::schemars::schema::ObjectValidation {
251 properties: [
252 (
253 "allowVolumeExpansion".to_owned(),
254 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
255 metadata: Some(Box::new(crate::schemars::schema::Metadata {
256 description: Some("allowVolumeExpansion shows whether the storage class allow volume expand.".to_owned()),
257 ..Default::default()
258 })),
259 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::Boolean))),
260 ..Default::default()
261 }),
262 ),
263 (
264 "allowedTopologies".to_owned(),
265 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
266 metadata: Some(Box::new(crate::schemars::schema::Metadata {
267 description: Some("allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.".to_owned()),
268 ..Default::default()
269 })),
270 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::Array))),
271 array: Some(Box::new(crate::schemars::schema::ArrayValidation {
272 items: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(__gen.subschema_for::<crate::api::core::v1::TopologySelectorTerm>()))),
273 ..Default::default()
274 })),
275 ..Default::default()
276 }),
277 ),
278 (
279 "apiVersion".to_owned(),
280 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
281 metadata: Some(Box::new(crate::schemars::schema::Metadata {
282 description: Some("APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources".to_owned()),
283 ..Default::default()
284 })),
285 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::String))),
286 ..Default::default()
287 }),
288 ),
289 (
290 "kind".to_owned(),
291 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
292 metadata: Some(Box::new(crate::schemars::schema::Metadata {
293 description: Some("Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds".to_owned()),
294 ..Default::default()
295 })),
296 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::String))),
297 ..Default::default()
298 }),
299 ),
300 (
301 "metadata".to_owned(),
302 {
303 let mut schema_obj = __gen.subschema_for::<crate::apimachinery::pkg::apis::meta::v1::ObjectMeta>().into_object();
304 schema_obj.metadata = Some(Box::new(crate::schemars::schema::Metadata {
305 description: Some("Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata".to_owned()),
306 ..Default::default()
307 }));
308 crate::schemars::schema::Schema::Object(schema_obj)
309 },
310 ),
311 (
312 "mountOptions".to_owned(),
313 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
314 metadata: Some(Box::new(crate::schemars::schema::Metadata {
315 description: Some("mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.".to_owned()),
316 ..Default::default()
317 })),
318 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::Array))),
319 array: Some(Box::new(crate::schemars::schema::ArrayValidation {
320 items: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(
321 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
322 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::String))),
323 ..Default::default()
324 })
325 ))),
326 ..Default::default()
327 })),
328 ..Default::default()
329 }),
330 ),
331 (
332 "parameters".to_owned(),
333 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
334 metadata: Some(Box::new(crate::schemars::schema::Metadata {
335 description: Some("parameters holds the parameters for the provisioner that should create volumes of this storage class.".to_owned()),
336 ..Default::default()
337 })),
338 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::Object))),
339 object: Some(Box::new(crate::schemars::schema::ObjectValidation {
340 additional_properties: Some(Box::new(
341 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
342 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::String))),
343 ..Default::default()
344 })
345 )),
346 ..Default::default()
347 })),
348 ..Default::default()
349 }),
350 ),
351 (
352 "provisioner".to_owned(),
353 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
354 metadata: Some(Box::new(crate::schemars::schema::Metadata {
355 description: Some("provisioner indicates the type of the provisioner.".to_owned()),
356 ..Default::default()
357 })),
358 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::String))),
359 ..Default::default()
360 }),
361 ),
362 (
363 "reclaimPolicy".to_owned(),
364 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
365 metadata: Some(Box::new(crate::schemars::schema::Metadata {
366 description: Some("reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. Defaults to Delete.".to_owned()),
367 ..Default::default()
368 })),
369 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::String))),
370 ..Default::default()
371 }),
372 ),
373 (
374 "volumeBindingMode".to_owned(),
375 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
376 metadata: Some(Box::new(crate::schemars::schema::Metadata {
377 description: Some("volumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.".to_owned()),
378 ..Default::default()
379 })),
380 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(Box::new(crate::schemars::schema::InstanceType::String))),
381 ..Default::default()
382 }),
383 ),
384 ].into(),
385 required: [
386 "metadata".to_owned(),
387 "provisioner".to_owned(),
388 ].into(),
389 ..Default::default()
390 })),
391 ..Default::default()
392 })
393 }
394}