aboutsummaryrefslogtreecommitdiff
path: root/src/config/options.rs
blob: 100c23cbcc6042d9de9d800b3afb3d9c0a797b26 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use anyhow::Result;
use serde::Deserialize;

use crate::config::RuntimeConfig;

// This code is inspired by the Trunk crate (https://github.com/thedodd/trunk)

// This file parses the options that can be declared in the environment.
// runtime.rs applies business logic and builds RuntimeConfig structs.

/// Base configuration options
#[derive(Clone, Default, Deserialize)]
pub struct ConfigOptsBase {
    /// This node's private IP address [default: None]
    pub private_ip: Option<String>,
    /// Expiration time for IGD rules [default: 60]
    pub expiration_time: Option<u16>,
    /// Refresh time for IGD and Firewall rules [default: 300]
    pub refresh_time: Option<u16>,
    /// STUN server [default: stun.nextcloud.com:443]
    pub stun_server: Option<String>,
}

/// ACME configuration options
#[derive(Clone, Default, Deserialize)]
pub struct ConfigOptsAcme {
    /// Whether ACME is enabled [default: false]
    #[serde(default)]
    pub enable: bool,

    /// The default domain holder's e-mail [default: None]
    pub email: Option<String>,
}

/// Consul configuration options
#[derive(Clone, Default, Deserialize)]
pub struct ConfigOptsConsul {
    /// Consul's node name [default: None]
    pub node_name: Option<String>,
    /// Consul's REST URL [default: "http://127.0.0.1:8500"]
    pub url: Option<String>,
    /// Consul's CA certificate [default: None]
    pub ca_cert: Option<String>,
    /// Skip TLS verification for Consul server [default: false]
    #[serde(default)]
    pub tls_skip_verify: bool,
    /// Consul's client certificate [default: None]
    pub client_cert: Option<String>,
    /// Consul's client key [default: None]
    pub client_key: Option<String>,
}

/// Model of all potential configuration options
pub struct ConfigOpts {
    pub base: ConfigOptsBase,
    pub acme: ConfigOptsAcme,
    pub consul: ConfigOptsConsul,
}

impl ConfigOpts {
    pub fn from_env() -> Result<RuntimeConfig> {
        let base: ConfigOptsBase = envy::prefixed("DIPLONAT_").from_env()?;
        let consul: ConfigOptsConsul = envy::prefixed("DIPLONAT_CONSUL_").from_env()?;
        let acme: ConfigOptsAcme = envy::prefixed("DIPLONAT_ACME_").from_env()?;

        RuntimeConfig::new(Self {
            base: base,
            consul: consul,
            acme: acme,
        })
    }

    // Currently only used in tests
    #[cfg(test)]
    pub fn from_iter<Iter: Clone>(iter: Iter) -> Result<RuntimeConfig>
    where
        Iter: IntoIterator<Item = (String, String)>,
    {
        let base: ConfigOptsBase = envy::prefixed("DIPLONAT_").from_iter(iter.clone())?;
        let consul: ConfigOptsConsul =
            envy::prefixed("DIPLONAT_CONSUL_").from_iter(iter.clone())?;
        let acme: ConfigOptsAcme = envy::prefixed("DIPLONAT_ACME_").from_iter(iter.clone())?;

        RuntimeConfig::new(Self {
            base: base,
            consul: consul,
            acme: acme,
        })
    }
}