mz_orchestratord/
tls.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10use std::str::FromStr;
11
12use serde::Deserialize;
13
14use mz_cloud_resources::crd::{
15    ManagedResource, MaterializeCertSpec,
16    generated::cert_manager::certificates::{
17        Certificate, CertificatePrivateKey, CertificatePrivateKeyAlgorithm,
18        CertificatePrivateKeyEncoding, CertificatePrivateKeyRotationPolicy, CertificateSpec,
19    },
20};
21
22#[derive(Clone, Deserialize, Default)]
23#[serde(rename_all = "camelCase")]
24pub struct DefaultCertificateSpecs {
25    pub balancerd_external: Option<MaterializeCertSpec>,
26    pub console_external: Option<MaterializeCertSpec>,
27    pub internal: Option<MaterializeCertSpec>,
28}
29
30impl FromStr for DefaultCertificateSpecs {
31    type Err = serde_json::Error;
32
33    fn from_str(s: &str) -> Result<Self, Self::Err> {
34        serde_json::from_str(s)
35    }
36}
37
38pub fn create_certificate(
39    default_spec: Option<MaterializeCertSpec>,
40    resource: &impl ManagedResource,
41    mz_cert_spec: Option<MaterializeCertSpec>,
42    cert_name: String,
43    secret_name: String,
44    additional_dns_names: Option<Vec<String>>,
45    algorithm: CertificatePrivateKeyAlgorithm,
46    size: Option<i64>,
47) -> Option<Certificate> {
48    let default_spec = default_spec.unwrap_or_else(MaterializeCertSpec::default);
49    let mz_cert_spec = mz_cert_spec.unwrap_or_else(MaterializeCertSpec::default);
50    let Some(issuer_ref) = mz_cert_spec.issuer_ref.or(default_spec.issuer_ref) else {
51        return None;
52    };
53    let mut secret_template = mz_cert_spec
54        .secret_template
55        .or(default_spec.secret_template)
56        .unwrap_or_default();
57    secret_template.labels = Some(
58        secret_template
59            .labels
60            .unwrap_or_default()
61            .into_iter()
62            .chain(resource.default_labels())
63            .collect(),
64    );
65    let mut dns_names = mz_cert_spec
66        .dns_names
67        .or(default_spec.dns_names)
68        .unwrap_or_default();
69    if let Some(names) = additional_dns_names {
70        dns_names.extend(names);
71    }
72    Some(Certificate {
73        metadata: resource.managed_resource_meta(cert_name),
74        spec: CertificateSpec {
75            dns_names: Some(dns_names),
76            duration: mz_cert_spec.duration.or(default_spec.duration),
77            issuer_ref,
78            private_key: Some(CertificatePrivateKey {
79                algorithm: Some(algorithm),
80                encoding: Some(CertificatePrivateKeyEncoding::Pkcs8),
81                rotation_policy: Some(CertificatePrivateKeyRotationPolicy::Always),
82                size,
83            }),
84            renew_before: mz_cert_spec.renew_before.or(default_spec.renew_before),
85            secret_name,
86            secret_template: Some(secret_template),
87            ..Default::default()
88        },
89        status: None,
90    })
91}
92
93pub fn issuer_ref_defined(
94    defaults: &Option<MaterializeCertSpec>,
95    overrides: &Option<MaterializeCertSpec>,
96) -> bool {
97    overrides
98        .as_ref()
99        .and_then(|spec| spec.issuer_ref.as_ref())
100        .is_some()
101        || defaults
102            .as_ref()
103            .and_then(|spec| spec.issuer_ref.as_ref())
104            .is_some()
105}