k8s_openapi/v1_35/api/core/v1/
pod_certificate_projection.rs1#[derive(Clone, Debug, Default, PartialEq)]
5pub struct PodCertificateProjection {
6 pub certificate_chain_path: Option<std::string::String>,
10
11 pub credential_bundle_path: Option<std::string::String>,
19
20 pub key_path: Option<std::string::String>,
24
25 pub key_type: std::string::String,
29
30 pub max_expiration_seconds: Option<i32>,
38
39 pub signer_name: std::string::String,
41
42 pub user_annotations: Option<std::collections::BTreeMap<std::string::String, std::string::String>>,
50}
51
52impl crate::DeepMerge for PodCertificateProjection {
53 fn merge_from(&mut self, other: Self) {
54 crate::DeepMerge::merge_from(&mut self.certificate_chain_path, other.certificate_chain_path);
55 crate::DeepMerge::merge_from(&mut self.credential_bundle_path, other.credential_bundle_path);
56 crate::DeepMerge::merge_from(&mut self.key_path, other.key_path);
57 crate::DeepMerge::merge_from(&mut self.key_type, other.key_type);
58 crate::DeepMerge::merge_from(&mut self.max_expiration_seconds, other.max_expiration_seconds);
59 crate::DeepMerge::merge_from(&mut self.signer_name, other.signer_name);
60 crate::merge_strategies::map::granular(&mut self.user_annotations, other.user_annotations, |current_item, other_item| {
61 crate::DeepMerge::merge_from(current_item, other_item);
62 });
63 }
64}
65
66impl<'de> crate::serde::Deserialize<'de> for PodCertificateProjection {
67 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: crate::serde::Deserializer<'de> {
68 #[allow(non_camel_case_types)]
69 enum Field {
70 Key_certificate_chain_path,
71 Key_credential_bundle_path,
72 Key_key_path,
73 Key_key_type,
74 Key_max_expiration_seconds,
75 Key_signer_name,
76 Key_user_annotations,
77 Other,
78 }
79
80 impl<'de> crate::serde::Deserialize<'de> for Field {
81 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: crate::serde::Deserializer<'de> {
82 struct Visitor;
83
84 impl crate::serde::de::Visitor<'_> for Visitor {
85 type Value = Field;
86
87 fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
88 f.write_str("field identifier")
89 }
90
91 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: crate::serde::de::Error {
92 Ok(match v {
93 "certificateChainPath" => Field::Key_certificate_chain_path,
94 "credentialBundlePath" => Field::Key_credential_bundle_path,
95 "keyPath" => Field::Key_key_path,
96 "keyType" => Field::Key_key_type,
97 "maxExpirationSeconds" => Field::Key_max_expiration_seconds,
98 "signerName" => Field::Key_signer_name,
99 "userAnnotations" => Field::Key_user_annotations,
100 _ => Field::Other,
101 })
102 }
103 }
104
105 deserializer.deserialize_identifier(Visitor)
106 }
107 }
108
109 struct Visitor;
110
111 impl<'de> crate::serde::de::Visitor<'de> for Visitor {
112 type Value = PodCertificateProjection;
113
114 fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
115 f.write_str("PodCertificateProjection")
116 }
117
118 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> where A: crate::serde::de::MapAccess<'de> {
119 let mut value_certificate_chain_path: Option<std::string::String> = None;
120 let mut value_credential_bundle_path: Option<std::string::String> = None;
121 let mut value_key_path: Option<std::string::String> = None;
122 let mut value_key_type: Option<std::string::String> = None;
123 let mut value_max_expiration_seconds: Option<i32> = None;
124 let mut value_signer_name: Option<std::string::String> = None;
125 let mut value_user_annotations: Option<std::collections::BTreeMap<std::string::String, std::string::String>> = None;
126
127 while let Some(key) = crate::serde::de::MapAccess::next_key::<Field>(&mut map)? {
128 match key {
129 Field::Key_certificate_chain_path => value_certificate_chain_path = crate::serde::de::MapAccess::next_value(&mut map)?,
130 Field::Key_credential_bundle_path => value_credential_bundle_path = crate::serde::de::MapAccess::next_value(&mut map)?,
131 Field::Key_key_path => value_key_path = crate::serde::de::MapAccess::next_value(&mut map)?,
132 Field::Key_key_type => value_key_type = crate::serde::de::MapAccess::next_value(&mut map)?,
133 Field::Key_max_expiration_seconds => value_max_expiration_seconds = crate::serde::de::MapAccess::next_value(&mut map)?,
134 Field::Key_signer_name => value_signer_name = crate::serde::de::MapAccess::next_value(&mut map)?,
135 Field::Key_user_annotations => value_user_annotations = crate::serde::de::MapAccess::next_value(&mut map)?,
136 Field::Other => { let _: crate::serde::de::IgnoredAny = crate::serde::de::MapAccess::next_value(&mut map)?; },
137 }
138 }
139
140 Ok(PodCertificateProjection {
141 certificate_chain_path: value_certificate_chain_path,
142 credential_bundle_path: value_credential_bundle_path,
143 key_path: value_key_path,
144 key_type: value_key_type.unwrap_or_default(),
145 max_expiration_seconds: value_max_expiration_seconds,
146 signer_name: value_signer_name.unwrap_or_default(),
147 user_annotations: value_user_annotations,
148 })
149 }
150 }
151
152 deserializer.deserialize_struct(
153 "PodCertificateProjection",
154 &[
155 "certificateChainPath",
156 "credentialBundlePath",
157 "keyPath",
158 "keyType",
159 "maxExpirationSeconds",
160 "signerName",
161 "userAnnotations",
162 ],
163 Visitor,
164 )
165 }
166}
167
168impl crate::serde::Serialize for PodCertificateProjection {
169 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: crate::serde::Serializer {
170 let mut state = serializer.serialize_struct(
171 "PodCertificateProjection",
172 2 +
173 self.certificate_chain_path.as_ref().map_or(0, |_| 1) +
174 self.credential_bundle_path.as_ref().map_or(0, |_| 1) +
175 self.key_path.as_ref().map_or(0, |_| 1) +
176 self.max_expiration_seconds.as_ref().map_or(0, |_| 1) +
177 self.user_annotations.as_ref().map_or(0, |_| 1),
178 )?;
179 if let Some(value) = &self.certificate_chain_path {
180 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "certificateChainPath", value)?;
181 }
182 if let Some(value) = &self.credential_bundle_path {
183 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "credentialBundlePath", value)?;
184 }
185 if let Some(value) = &self.key_path {
186 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "keyPath", value)?;
187 }
188 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "keyType", &self.key_type)?;
189 if let Some(value) = &self.max_expiration_seconds {
190 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "maxExpirationSeconds", value)?;
191 }
192 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "signerName", &self.signer_name)?;
193 if let Some(value) = &self.user_annotations {
194 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "userAnnotations", value)?;
195 }
196 crate::serde::ser::SerializeStruct::end(state)
197 }
198}
199
200#[cfg(feature = "schemars")]
201impl crate::schemars::JsonSchema for PodCertificateProjection {
202 fn schema_name() -> std::borrow::Cow<'static, str> {
203 "io.k8s.api.core.v1.PodCertificateProjection".into()
204 }
205
206 fn json_schema(__gen: &mut crate::schemars::SchemaGenerator) -> crate::schemars::Schema {
207 crate::schemars::json_schema!({
208 "description": "PodCertificateProjection provides a private key and X.509 certificate in the pod filesystem.",
209 "type": "object",
210 "properties": {
211 "certificateChainPath": {
212 "description": "Write the certificate chain at this path in the projected volume.\n\nMost applications should use credentialBundlePath. When using keyPath and certificateChainPath, your application needs to check that the key and leaf certificate are consistent, because it is possible to read the files mid-rotation.",
213 "type": "string",
214 },
215 "credentialBundlePath": {
216 "description": "Write the credential bundle at this path in the projected volume.\n\nThe credential bundle is a single file that contains multiple PEM blocks. The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private key.\n\nThe remaining blocks are CERTIFICATE blocks, containing the issued certificate chain from the signer (leaf and any intermediates).\n\nUsing credentialBundlePath lets your Pod's application code make a single atomic read that retrieves a consistent key and certificate chain. If you project them to separate files, your application code will need to additionally check that the leaf certificate was issued to the key.",
217 "type": "string",
218 },
219 "keyPath": {
220 "description": "Write the key at this path in the projected volume.\n\nMost applications should use credentialBundlePath. When using keyPath and certificateChainPath, your application needs to check that the key and leaf certificate are consistent, because it is possible to read the files mid-rotation.",
221 "type": "string",
222 },
223 "keyType": {
224 "description": "The type of keypair Kubelet will generate for the pod.\n\nValid values are \"RSA3072\", \"RSA4096\", \"ECDSAP256\", \"ECDSAP384\", \"ECDSAP521\", and \"ED25519\".",
225 "type": "string",
226 },
227 "maxExpirationSeconds": {
228 "description": "maxExpirationSeconds is the maximum lifetime permitted for the certificate.\n\nKubelet copies this value verbatim into the PodCertificateRequests it generates for this projection.\n\nIf omitted, kube-apiserver will set it to 86400(24 hours). kube-apiserver will reject values shorter than 3600 (1 hour). The maximum allowable value is 7862400 (91 days).\n\nThe signer implementation is then free to issue a certificate with any lifetime *shorter* than MaxExpirationSeconds, but no shorter than 3600 seconds (1 hour). This constraint is enforced by kube-apiserver. `kubernetes.io` signers will never issue certificates with a lifetime longer than 24 hours.",
229 "type": "integer",
230 "format": "int32",
231 },
232 "signerName": {
233 "description": "Kubelet's generated CSRs will be addressed to this signer.",
234 "type": "string",
235 },
236 "userAnnotations": {
237 "description": "userAnnotations allow pod authors to pass additional information to the signer implementation. Kubernetes does not restrict or validate this metadata in any way.\n\nThese values are copied verbatim into the `spec.unverifiedUserAnnotations` field of the PodCertificateRequest objects that Kubelet creates.\n\nEntries are subject to the same validation as object metadata annotations, with the addition that all keys must be domain-prefixed. No restrictions are placed on values, except an overall size limitation on the entire field.\n\nSigners should document the keys and values they support. Signers should deny requests that contain keys they do not recognize.",
238 "type": "object",
239 "additionalProperties": {
240 "type": "string",
241 },
242 },
243 },
244 "required": [
245 "keyType",
246 "signerName",
247 ],
248 })
249 }
250}