stackable_webhook/
options.rs

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