1#[derive(Clone, Debug, Default, PartialEq)]
7pub struct StorageClass {
8 pub allow_volume_expansion: Option<bool>,
10
11 pub allowed_topologies: Option<std::vec::Vec<crate::api::core::v1::TopologySelectorTerm>>,
13
14 pub metadata: crate::apimachinery::pkg::apis::meta::v1::ObjectMeta,
16
17 pub mount_options: Option<std::vec::Vec<std::string::String>>,
19
20 pub parameters: Option<std::collections::BTreeMap<std::string::String, std::string::String>>,
22
23 pub provisioner: std::string::String,
25
26 pub reclaim_policy: Option<std::string::String>,
28
29 pub volume_binding_mode: Option<std::string::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 core::fmt::Formatter<'_>) -> core::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 core::fmt::Formatter<'_>) -> core::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<std::vec::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<std::vec::Vec<std::string::String>> = None;
136 let mut value_parameters: Option<std::collections::BTreeMap<std::string::String, std::string::String>> = None;
137 let mut value_provisioner: Option<std::string::String> = None;
138 let mut value_reclaim_policy: Option<std::string::String> = None;
139 let mut value_volume_binding_mode: Option<std::string::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: std::string::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: std::string::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() -> std::borrow::Cow<'static, str> {
240 "io.k8s.api.storage.v1.StorageClass".into()
241 }
242
243 fn json_schema(__gen: &mut crate::schemars::SchemaGenerator) -> crate::schemars::Schema {
244 crate::schemars::json_schema!({
245 "description": "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.",
246 "type": "object",
247 "properties": {
248 "allowVolumeExpansion": {
249 "description": "allowVolumeExpansion shows whether the storage class allow volume expand.",
250 "type": "boolean",
251 },
252 "allowedTopologies": {
253 "description": "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.",
254 "type": "array",
255 "items": (__gen.subschema_for::<crate::api::core::v1::TopologySelectorTerm>()),
256 },
257 "apiVersion": {
258 "description": "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",
259 "type": "string",
260 },
261 "kind": {
262 "description": "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",
263 "type": "string",
264 },
265 "metadata": ({
266 let mut schema_obj = __gen.subschema_for::<crate::apimachinery::pkg::apis::meta::v1::ObjectMeta>();
267 schema_obj.ensure_object().insert("description".into(), "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata".into());
268 schema_obj
269 }),
270 "mountOptions": {
271 "description": "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.",
272 "type": "array",
273 "items": {
274 "type": "string",
275 },
276 },
277 "parameters": {
278 "description": "parameters holds the parameters for the provisioner that should create volumes of this storage class.",
279 "type": "object",
280 "additionalProperties": {
281 "type": "string",
282 },
283 },
284 "provisioner": {
285 "description": "provisioner indicates the type of the provisioner.",
286 "type": "string",
287 },
288 "reclaimPolicy": {
289 "description": "reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. Defaults to Delete.",
290 "type": "string",
291 },
292 "volumeBindingMode": {
293 "description": "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.",
294 "type": "string",
295 },
296 },
297 "required": [
298 "metadata",
299 "provisioner",
300 ],
301 })
302 }
303}