stackable_webhook/
options.rs

1//! Contains available options to configure the [WebhookServer][crate::WebhookServer].
2use std::{
3    net::{IpAddr, SocketAddr},
4    path::PathBuf,
5};
6
7use stackable_certs::PrivateKeyType;
8
9use crate::constants::DEFAULT_SOCKET_ADDRESS;
10
11/// Specifies available webhook server options.
12///
13/// The [`Default`] implementation for this struct contains the following values:
14///
15/// - The socket binds to 127.0.0.1 on port 8443 (HTTPS)
16/// - An empty list of SANs is provided to the certificate the TLS server uses.
17///
18/// ### Example with Custom HTTPS IP Address and Port
19///
20/// ```
21/// use stackable_webhook::WebhookOptions;
22///
23/// // Set IP address and port at the same time
24/// let options = WebhookOptions::builder()
25///     .bind_address([0, 0, 0, 0], 12345)
26///     .build();
27///
28/// // Set IP address only
29/// let options = WebhookOptions::builder()
30///     .bind_ip([0, 0, 0, 0])
31///     .build();
32///
33/// // Set port only
34/// let options = WebhookOptions::builder()
35///     .bind_port(12345)
36///     .build();
37/// ```
38#[derive(Debug)]
39pub struct WebhookOptions {
40    /// The default HTTPS socket address the [`TcpListener`][tokio::net::TcpListener]
41    /// binds to.
42    pub socket_addr: SocketAddr,
43
44    /// The subject alterative DNS names that should be added to the certificates generated for this
45    /// webhook.
46    pub subject_alterative_dns_names: Vec<String>,
47}
48
49impl Default for WebhookOptions {
50    fn default() -> Self {
51        Self::builder().build()
52    }
53}
54
55impl WebhookOptions {
56    /// Returns the default [`WebhookOptionsBuilder`] which allows to selectively
57    /// customize the options. See the documentation for [`WebhookOptions`] for more
58    /// information on available functions.
59    pub fn builder() -> WebhookOptionsBuilder {
60        WebhookOptionsBuilder::default()
61    }
62}
63
64/// The [`WebhookOptionsBuilder`] which allows to selectively customize the webhook
65/// server [`WebhookOptions`].
66///
67/// Usually, this struct is not constructed manually, but instead by calling
68/// [`WebhookOptions::builder()`] or [`WebhookOptionsBuilder::default()`].
69#[derive(Debug, Default)]
70pub struct WebhookOptionsBuilder {
71    socket_addr: Option<SocketAddr>,
72    subject_alterative_dns_names: Vec<String>,
73}
74
75impl WebhookOptionsBuilder {
76    /// Sets the socket address the webhook server uses to bind for HTTPS.
77    pub fn bind_address(mut self, bind_ip: impl Into<IpAddr>, bind_port: u16) -> Self {
78        self.socket_addr = Some(SocketAddr::new(bind_ip.into(), bind_port));
79        self
80    }
81
82    /// Sets the IP address of the socket address the webhook server uses to
83    /// bind for HTTPS.
84    pub fn bind_ip(mut self, bind_ip: impl Into<IpAddr>) -> Self {
85        let addr = self.socket_addr.get_or_insert(DEFAULT_SOCKET_ADDRESS);
86        addr.set_ip(bind_ip.into());
87        self
88    }
89
90    /// Sets the port of the socket address the webhook server uses to bind
91    /// for HTTPS.
92    pub fn bind_port(mut self, bind_port: u16) -> Self {
93        let addr = self.socket_addr.get_or_insert(DEFAULT_SOCKET_ADDRESS);
94        addr.set_port(bind_port);
95        self
96    }
97
98    /// Sets the subject alterative DNS names that should be added to the certificates generated for
99    /// this webhook.
100    pub fn subject_alterative_dns_names(
101        mut self,
102        subject_alterative_dns_name: Vec<String>,
103    ) -> Self {
104        self.subject_alterative_dns_names = subject_alterative_dns_name;
105        self
106    }
107
108    /// Adds the subject alterative DNS name to the list of names.
109    pub fn add_subject_alterative_dns_name(
110        mut self,
111        subject_alterative_dns_name: impl Into<String>,
112    ) -> Self {
113        self.subject_alterative_dns_names
114            .push(subject_alterative_dns_name.into());
115        self
116    }
117
118    /// Builds the final [`WebhookOptions`] by using default values for any not
119    /// explicitly set option.
120    pub fn build(self) -> WebhookOptions {
121        WebhookOptions {
122            socket_addr: self.socket_addr.unwrap_or(DEFAULT_SOCKET_ADDRESS),
123            subject_alterative_dns_names: self.subject_alterative_dns_names,
124        }
125    }
126}
127
128#[derive(Debug)]
129pub enum TlsOption {
130    AutoGenerate,
131    Mount {
132        private_key_type: PrivateKeyType,
133        private_key_path: PathBuf,
134        certificate_path: PathBuf,
135    },
136}
137
138impl Default for TlsOption {
139    fn default() -> Self {
140        Self::AutoGenerate
141    }
142}