1#[derive(Clone, Debug, Default, PartialEq)]
5pub struct CertificateSigningRequestSpec {
6 pub expiration_seconds: Option<i32>,
19
20 pub extra: Option<std::collections::BTreeMap<std::string::String, std::vec::Vec<std::string::String>>>,
22
23 pub groups: Option<std::vec::Vec<std::string::String>>,
25
26 pub request: crate::ByteString,
28
29 pub signer_name: std::string::String,
51
52 pub uid: Option<std::string::String>,
54
55 pub usages: Option<std::vec::Vec<std::string::String>>,
70
71 pub username: Option<std::string::String>,
73}
74
75impl crate::DeepMerge for CertificateSigningRequestSpec {
76 fn merge_from(&mut self, other: Self) {
77 crate::DeepMerge::merge_from(&mut self.expiration_seconds, other.expiration_seconds);
78 crate::merge_strategies::map::granular(&mut self.extra, other.extra, |current_item, other_item| {
79 crate::merge_strategies::list::atomic(current_item, other_item);
80 });
81 crate::merge_strategies::list::atomic(&mut self.groups, other.groups);
82 crate::DeepMerge::merge_from(&mut self.request, other.request);
83 crate::DeepMerge::merge_from(&mut self.signer_name, other.signer_name);
84 crate::DeepMerge::merge_from(&mut self.uid, other.uid);
85 crate::merge_strategies::list::atomic(&mut self.usages, other.usages);
86 crate::DeepMerge::merge_from(&mut self.username, other.username);
87 }
88}
89
90impl<'de> crate::serde::Deserialize<'de> for CertificateSigningRequestSpec {
91 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: crate::serde::Deserializer<'de> {
92 #[allow(non_camel_case_types)]
93 enum Field {
94 Key_expiration_seconds,
95 Key_extra,
96 Key_groups,
97 Key_request,
98 Key_signer_name,
99 Key_uid,
100 Key_usages,
101 Key_username,
102 Other,
103 }
104
105 impl<'de> crate::serde::Deserialize<'de> for Field {
106 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: crate::serde::Deserializer<'de> {
107 struct Visitor;
108
109 impl crate::serde::de::Visitor<'_> for Visitor {
110 type Value = Field;
111
112 fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
113 f.write_str("field identifier")
114 }
115
116 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: crate::serde::de::Error {
117 Ok(match v {
118 "expirationSeconds" => Field::Key_expiration_seconds,
119 "extra" => Field::Key_extra,
120 "groups" => Field::Key_groups,
121 "request" => Field::Key_request,
122 "signerName" => Field::Key_signer_name,
123 "uid" => Field::Key_uid,
124 "usages" => Field::Key_usages,
125 "username" => Field::Key_username,
126 _ => Field::Other,
127 })
128 }
129 }
130
131 deserializer.deserialize_identifier(Visitor)
132 }
133 }
134
135 struct Visitor;
136
137 impl<'de> crate::serde::de::Visitor<'de> for Visitor {
138 type Value = CertificateSigningRequestSpec;
139
140 fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
141 f.write_str("CertificateSigningRequestSpec")
142 }
143
144 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> where A: crate::serde::de::MapAccess<'de> {
145 let mut value_expiration_seconds: Option<i32> = None;
146 let mut value_extra: Option<std::collections::BTreeMap<std::string::String, std::vec::Vec<std::string::String>>> = None;
147 let mut value_groups: Option<std::vec::Vec<std::string::String>> = None;
148 let mut value_request: Option<crate::ByteString> = None;
149 let mut value_signer_name: Option<std::string::String> = None;
150 let mut value_uid: Option<std::string::String> = None;
151 let mut value_usages: Option<std::vec::Vec<std::string::String>> = None;
152 let mut value_username: Option<std::string::String> = None;
153
154 while let Some(key) = crate::serde::de::MapAccess::next_key::<Field>(&mut map)? {
155 match key {
156 Field::Key_expiration_seconds => value_expiration_seconds = crate::serde::de::MapAccess::next_value(&mut map)?,
157 Field::Key_extra => value_extra = crate::serde::de::MapAccess::next_value(&mut map)?,
158 Field::Key_groups => value_groups = crate::serde::de::MapAccess::next_value(&mut map)?,
159 Field::Key_request => value_request = crate::serde::de::MapAccess::next_value(&mut map)?,
160 Field::Key_signer_name => value_signer_name = crate::serde::de::MapAccess::next_value(&mut map)?,
161 Field::Key_uid => value_uid = crate::serde::de::MapAccess::next_value(&mut map)?,
162 Field::Key_usages => value_usages = crate::serde::de::MapAccess::next_value(&mut map)?,
163 Field::Key_username => value_username = crate::serde::de::MapAccess::next_value(&mut map)?,
164 Field::Other => { let _: crate::serde::de::IgnoredAny = crate::serde::de::MapAccess::next_value(&mut map)?; },
165 }
166 }
167
168 Ok(CertificateSigningRequestSpec {
169 expiration_seconds: value_expiration_seconds,
170 extra: value_extra,
171 groups: value_groups,
172 request: value_request.unwrap_or_default(),
173 signer_name: value_signer_name.unwrap_or_default(),
174 uid: value_uid,
175 usages: value_usages,
176 username: value_username,
177 })
178 }
179 }
180
181 deserializer.deserialize_struct(
182 "CertificateSigningRequestSpec",
183 &[
184 "expirationSeconds",
185 "extra",
186 "groups",
187 "request",
188 "signerName",
189 "uid",
190 "usages",
191 "username",
192 ],
193 Visitor,
194 )
195 }
196}
197
198impl crate::serde::Serialize for CertificateSigningRequestSpec {
199 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: crate::serde::Serializer {
200 let mut state = serializer.serialize_struct(
201 "CertificateSigningRequestSpec",
202 2 +
203 self.expiration_seconds.as_ref().map_or(0, |_| 1) +
204 self.extra.as_ref().map_or(0, |_| 1) +
205 self.groups.as_ref().map_or(0, |_| 1) +
206 self.uid.as_ref().map_or(0, |_| 1) +
207 self.usages.as_ref().map_or(0, |_| 1) +
208 self.username.as_ref().map_or(0, |_| 1),
209 )?;
210 if let Some(value) = &self.expiration_seconds {
211 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "expirationSeconds", value)?;
212 }
213 if let Some(value) = &self.extra {
214 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "extra", value)?;
215 }
216 if let Some(value) = &self.groups {
217 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "groups", value)?;
218 }
219 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "request", &self.request)?;
220 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "signerName", &self.signer_name)?;
221 if let Some(value) = &self.uid {
222 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "uid", value)?;
223 }
224 if let Some(value) = &self.usages {
225 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "usages", value)?;
226 }
227 if let Some(value) = &self.username {
228 crate::serde::ser::SerializeStruct::serialize_field(&mut state, "username", value)?;
229 }
230 crate::serde::ser::SerializeStruct::end(state)
231 }
232}
233
234#[cfg(feature = "schemars")]
235impl crate::schemars::JsonSchema for CertificateSigningRequestSpec {
236 fn schema_name() -> std::borrow::Cow<'static, str> {
237 "io.k8s.api.certificates.v1.CertificateSigningRequestSpec".into()
238 }
239
240 fn json_schema(__gen: &mut crate::schemars::SchemaGenerator) -> crate::schemars::Schema {
241 crate::schemars::json_schema!({
242 "description": "CertificateSigningRequestSpec contains the certificate request.",
243 "type": "object",
244 "properties": {
245 "expirationSeconds": {
246 "description": "expirationSeconds is the requested duration of validity of the issued certificate. The certificate signer may issue a certificate with a different validity duration so a client must check the delta between the notBefore and and notAfter fields in the issued certificate to determine the actual duration.\n\nThe v1.22+ in-tree implementations of the well-known Kubernetes signers will honor this field as long as the requested duration is not greater than the maximum duration they will honor per the --cluster-signing-duration CLI flag to the Kubernetes controller manager.\n\nCertificate signers may not honor this field for various reasons:\n\n 1. Old signer that is unaware of the field (such as the in-tree\n implementations prior to v1.22)\n 2. Signer whose configured maximum is shorter than the requested duration\n 3. Signer whose configured minimum is longer than the requested duration\n\nThe minimum valid value for expirationSeconds is 600, i.e. 10 minutes.",
247 "type": "integer",
248 "format": "int32",
249 },
250 "extra": {
251 "description": "extra contains extra attributes of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.",
252 "type": "object",
253 "additionalProperties": {
254 "type": "array",
255 "items": {
256 "type": "string",
257 },
258 },
259 },
260 "groups": {
261 "description": "groups contains group membership of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.",
262 "type": "array",
263 "items": {
264 "type": "string",
265 },
266 },
267 "request": {
268 "description": "request contains an x509 certificate signing request encoded in a \"CERTIFICATE REQUEST\" PEM block. When serialized as JSON or YAML, the data is additionally base64-encoded.",
269 "type": "string",
270 "format": "byte",
271 },
272 "signerName": {
273 "description": "signerName indicates the requested signer, and is a qualified name.\n\nList/watch requests for CertificateSigningRequests can filter on this field using a \"spec.signerName=NAME\" fieldSelector.\n\nWell-known Kubernetes signers are:\n 1. \"kubernetes.io/kube-apiserver-client\": issues client certificates that can be used to authenticate to kube-apiserver.\n Requests for this signer are never auto-approved by kube-controller-manager, can be issued by the \"csrsigning\" controller in kube-controller-manager.\n 2. \"kubernetes.io/kube-apiserver-client-kubelet\": issues client certificates that kubelets use to authenticate to kube-apiserver.\n Requests for this signer can be auto-approved by the \"csrapproving\" controller in kube-controller-manager, and can be issued by the \"csrsigning\" controller in kube-controller-manager.\n 3. \"kubernetes.io/kubelet-serving\" issues serving certificates that kubelets use to serve TLS endpoints, which kube-apiserver can connect to securely.\n Requests for this signer are never auto-approved by kube-controller-manager, and can be issued by the \"csrsigning\" controller in kube-controller-manager.\n\nMore details are available at https://k8s.io/docs/reference/access-authn-authz/certificate-signing-requests/#kubernetes-signers\n\nCustom signerNames can also be specified. The signer defines:\n 1. Trust distribution: how trust (CA bundles) are distributed.\n 2. Permitted subjects: and behavior when a disallowed subject is requested.\n 3. Required, permitted, or forbidden x509 extensions in the request (including whether subjectAltNames are allowed, which types, restrictions on allowed values) and behavior when a disallowed extension is requested.\n 4. Required, permitted, or forbidden key usages / extended key usages.\n 5. Expiration/certificate lifetime: whether it is fixed by the signer, configurable by the admin.\n 6. Whether or not requests for CA certificates are allowed.",
274 "type": "string",
275 },
276 "uid": {
277 "description": "uid contains the uid of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.",
278 "type": "string",
279 },
280 "usages": {
281 "description": "usages specifies a set of key usages requested in the issued certificate.\n\nRequests for TLS client certificates typically request: \"digital signature\", \"key encipherment\", \"client auth\".\n\nRequests for TLS serving certificates typically request: \"key encipherment\", \"digital signature\", \"server auth\".\n\nValid values are:\n \"signing\", \"digital signature\", \"content commitment\",\n \"key encipherment\", \"key agreement\", \"data encipherment\",\n \"cert sign\", \"crl sign\", \"encipher only\", \"decipher only\", \"any\",\n \"server auth\", \"client auth\",\n \"code signing\", \"email protection\", \"s/mime\",\n \"ipsec end system\", \"ipsec tunnel\", \"ipsec user\",\n \"timestamping\", \"ocsp signing\", \"microsoft sgc\", \"netscape sgc\"",
282 "type": "array",
283 "items": {
284 "type": "string",
285 },
286 },
287 "username": {
288 "description": "username contains the name of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.",
289 "type": "string",
290 },
291 },
292 "required": [
293 "request",
294 "signerName",
295 ],
296 })
297 }
298}
299
300#[cfg(feature = "schemars08")]
301impl crate::schemars08::JsonSchema for CertificateSigningRequestSpec {
302 fn schema_name() -> std::string::String {
303 "io.k8s.api.certificates.v1.CertificateSigningRequestSpec".into()
304 }
305
306 fn json_schema(__gen: &mut crate::schemars08::gen::SchemaGenerator) -> crate::schemars08::schema::Schema {
307 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
308 metadata: Some(std::boxed::Box::new(crate::schemars08::schema::Metadata {
309 description: Some("CertificateSigningRequestSpec contains the certificate request.".into()),
310 ..Default::default()
311 })),
312 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::Object))),
313 object: Some(std::boxed::Box::new(crate::schemars08::schema::ObjectValidation {
314 properties: [
315 (
316 "expirationSeconds".into(),
317 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
318 metadata: Some(std::boxed::Box::new(crate::schemars08::schema::Metadata {
319 description: Some("expirationSeconds is the requested duration of validity of the issued certificate. The certificate signer may issue a certificate with a different validity duration so a client must check the delta between the notBefore and and notAfter fields in the issued certificate to determine the actual duration.\n\nThe v1.22+ in-tree implementations of the well-known Kubernetes signers will honor this field as long as the requested duration is not greater than the maximum duration they will honor per the --cluster-signing-duration CLI flag to the Kubernetes controller manager.\n\nCertificate signers may not honor this field for various reasons:\n\n 1. Old signer that is unaware of the field (such as the in-tree\n implementations prior to v1.22)\n 2. Signer whose configured maximum is shorter than the requested duration\n 3. Signer whose configured minimum is longer than the requested duration\n\nThe minimum valid value for expirationSeconds is 600, i.e. 10 minutes.".into()),
320 ..Default::default()
321 })),
322 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::Integer))),
323 format: Some("int32".into()),
324 ..Default::default()
325 }),
326 ),
327 (
328 "extra".into(),
329 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
330 metadata: Some(std::boxed::Box::new(crate::schemars08::schema::Metadata {
331 description: Some("extra contains extra attributes of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.".into()),
332 ..Default::default()
333 })),
334 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::Object))),
335 object: Some(std::boxed::Box::new(crate::schemars08::schema::ObjectValidation {
336 additional_properties: Some(std::boxed::Box::new(
337 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
338 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::Array))),
339 array: Some(std::boxed::Box::new(crate::schemars08::schema::ArrayValidation {
340 items: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(
341 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
342 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::String))),
343 ..Default::default()
344 })
345 ))),
346 ..Default::default()
347 })),
348 ..Default::default()
349 })
350 )),
351 ..Default::default()
352 })),
353 ..Default::default()
354 }),
355 ),
356 (
357 "groups".into(),
358 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
359 metadata: Some(std::boxed::Box::new(crate::schemars08::schema::Metadata {
360 description: Some("groups contains group membership of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.".into()),
361 ..Default::default()
362 })),
363 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::Array))),
364 array: Some(std::boxed::Box::new(crate::schemars08::schema::ArrayValidation {
365 items: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(
366 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
367 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::String))),
368 ..Default::default()
369 })
370 ))),
371 ..Default::default()
372 })),
373 ..Default::default()
374 }),
375 ),
376 (
377 "request".into(),
378 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
379 metadata: Some(std::boxed::Box::new(crate::schemars08::schema::Metadata {
380 description: Some("request contains an x509 certificate signing request encoded in a \"CERTIFICATE REQUEST\" PEM block. When serialized as JSON or YAML, the data is additionally base64-encoded.".into()),
381 ..Default::default()
382 })),
383 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::String))),
384 format: Some("byte".into()),
385 ..Default::default()
386 }),
387 ),
388 (
389 "signerName".into(),
390 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
391 metadata: Some(std::boxed::Box::new(crate::schemars08::schema::Metadata {
392 description: Some("signerName indicates the requested signer, and is a qualified name.\n\nList/watch requests for CertificateSigningRequests can filter on this field using a \"spec.signerName=NAME\" fieldSelector.\n\nWell-known Kubernetes signers are:\n 1. \"kubernetes.io/kube-apiserver-client\": issues client certificates that can be used to authenticate to kube-apiserver.\n Requests for this signer are never auto-approved by kube-controller-manager, can be issued by the \"csrsigning\" controller in kube-controller-manager.\n 2. \"kubernetes.io/kube-apiserver-client-kubelet\": issues client certificates that kubelets use to authenticate to kube-apiserver.\n Requests for this signer can be auto-approved by the \"csrapproving\" controller in kube-controller-manager, and can be issued by the \"csrsigning\" controller in kube-controller-manager.\n 3. \"kubernetes.io/kubelet-serving\" issues serving certificates that kubelets use to serve TLS endpoints, which kube-apiserver can connect to securely.\n Requests for this signer are never auto-approved by kube-controller-manager, and can be issued by the \"csrsigning\" controller in kube-controller-manager.\n\nMore details are available at https://k8s.io/docs/reference/access-authn-authz/certificate-signing-requests/#kubernetes-signers\n\nCustom signerNames can also be specified. The signer defines:\n 1. Trust distribution: how trust (CA bundles) are distributed.\n 2. Permitted subjects: and behavior when a disallowed subject is requested.\n 3. Required, permitted, or forbidden x509 extensions in the request (including whether subjectAltNames are allowed, which types, restrictions on allowed values) and behavior when a disallowed extension is requested.\n 4. Required, permitted, or forbidden key usages / extended key usages.\n 5. Expiration/certificate lifetime: whether it is fixed by the signer, configurable by the admin.\n 6. Whether or not requests for CA certificates are allowed.".into()),
393 ..Default::default()
394 })),
395 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::String))),
396 ..Default::default()
397 }),
398 ),
399 (
400 "uid".into(),
401 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
402 metadata: Some(std::boxed::Box::new(crate::schemars08::schema::Metadata {
403 description: Some("uid contains the uid of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.".into()),
404 ..Default::default()
405 })),
406 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::String))),
407 ..Default::default()
408 }),
409 ),
410 (
411 "usages".into(),
412 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
413 metadata: Some(std::boxed::Box::new(crate::schemars08::schema::Metadata {
414 description: Some("usages specifies a set of key usages requested in the issued certificate.\n\nRequests for TLS client certificates typically request: \"digital signature\", \"key encipherment\", \"client auth\".\n\nRequests for TLS serving certificates typically request: \"key encipherment\", \"digital signature\", \"server auth\".\n\nValid values are:\n \"signing\", \"digital signature\", \"content commitment\",\n \"key encipherment\", \"key agreement\", \"data encipherment\",\n \"cert sign\", \"crl sign\", \"encipher only\", \"decipher only\", \"any\",\n \"server auth\", \"client auth\",\n \"code signing\", \"email protection\", \"s/mime\",\n \"ipsec end system\", \"ipsec tunnel\", \"ipsec user\",\n \"timestamping\", \"ocsp signing\", \"microsoft sgc\", \"netscape sgc\"".into()),
415 ..Default::default()
416 })),
417 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::Array))),
418 array: Some(std::boxed::Box::new(crate::schemars08::schema::ArrayValidation {
419 items: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(
420 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
421 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::String))),
422 ..Default::default()
423 })
424 ))),
425 ..Default::default()
426 })),
427 ..Default::default()
428 }),
429 ),
430 (
431 "username".into(),
432 crate::schemars08::schema::Schema::Object(crate::schemars08::schema::SchemaObject {
433 metadata: Some(std::boxed::Box::new(crate::schemars08::schema::Metadata {
434 description: Some("username contains the name of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.".into()),
435 ..Default::default()
436 })),
437 instance_type: Some(crate::schemars08::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars08::schema::InstanceType::String))),
438 ..Default::default()
439 }),
440 ),
441 ].into(),
442 required: [
443 "request".into(),
444 "signerName".into(),
445 ].into(),
446 ..Default::default()
447 })),
448 ..Default::default()
449 })
450 }
451}