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::string::String {
237 "io.k8s.api.certificates.v1.CertificateSigningRequestSpec".into()
238 }
239
240 fn json_schema(__gen: &mut crate::schemars::gen::SchemaGenerator) -> crate::schemars::schema::Schema {
241 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
242 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
243 description: Some("CertificateSigningRequestSpec contains the certificate request.".into()),
244 ..Default::default()
245 })),
246 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::Object))),
247 object: Some(std::boxed::Box::new(crate::schemars::schema::ObjectValidation {
248 properties: [
249 (
250 "expirationSeconds".into(),
251 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
252 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
253 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()),
254 ..Default::default()
255 })),
256 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::Integer))),
257 format: Some("int32".into()),
258 ..Default::default()
259 }),
260 ),
261 (
262 "extra".into(),
263 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
264 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
265 description: Some("extra contains extra attributes of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.".into()),
266 ..Default::default()
267 })),
268 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::Object))),
269 object: Some(std::boxed::Box::new(crate::schemars::schema::ObjectValidation {
270 additional_properties: Some(std::boxed::Box::new(
271 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
272 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::Array))),
273 array: Some(std::boxed::Box::new(crate::schemars::schema::ArrayValidation {
274 items: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(
275 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
276 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::String))),
277 ..Default::default()
278 })
279 ))),
280 ..Default::default()
281 })),
282 ..Default::default()
283 })
284 )),
285 ..Default::default()
286 })),
287 ..Default::default()
288 }),
289 ),
290 (
291 "groups".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("groups contains group membership of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.".into()),
295 ..Default::default()
296 })),
297 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::Array))),
298 array: Some(std::boxed::Box::new(crate::schemars::schema::ArrayValidation {
299 items: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(
300 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
301 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::String))),
302 ..Default::default()
303 })
304 ))),
305 ..Default::default()
306 })),
307 ..Default::default()
308 }),
309 ),
310 (
311 "request".into(),
312 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
313 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
314 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()),
315 ..Default::default()
316 })),
317 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::String))),
318 format: Some("byte".into()),
319 ..Default::default()
320 }),
321 ),
322 (
323 "signerName".into(),
324 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
325 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
326 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()),
327 ..Default::default()
328 })),
329 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::String))),
330 ..Default::default()
331 }),
332 ),
333 (
334 "uid".into(),
335 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
336 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
337 description: Some("uid contains the uid of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.".into()),
338 ..Default::default()
339 })),
340 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::String))),
341 ..Default::default()
342 }),
343 ),
344 (
345 "usages".into(),
346 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
347 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
348 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()),
349 ..Default::default()
350 })),
351 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::Array))),
352 array: Some(std::boxed::Box::new(crate::schemars::schema::ArrayValidation {
353 items: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(
354 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
355 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::String))),
356 ..Default::default()
357 })
358 ))),
359 ..Default::default()
360 })),
361 ..Default::default()
362 }),
363 ),
364 (
365 "username".into(),
366 crate::schemars::schema::Schema::Object(crate::schemars::schema::SchemaObject {
367 metadata: Some(std::boxed::Box::new(crate::schemars::schema::Metadata {
368 description: Some("username contains the name of the user that created the CertificateSigningRequest. Populated by the API server on creation and immutable.".into()),
369 ..Default::default()
370 })),
371 instance_type: Some(crate::schemars::schema::SingleOrVec::Single(std::boxed::Box::new(crate::schemars::schema::InstanceType::String))),
372 ..Default::default()
373 }),
374 ),
375 ].into(),
376 required: [
377 "request".into(),
378 "signerName".into(),
379 ].into(),
380 ..Default::default()
381 })),
382 ..Default::default()
383 })
384 }
385}