2021-08-14 17:12:18 +00:00
|
|
|
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.
|
|
|
|
|
2021-08-25 15:20:31 +00:00
|
|
|
// - Note for the future -
|
|
|
|
// There is no *need* to have a 'DIPLONAT_XXX_*' prefix for all config options.
|
|
|
|
// If some config options are shared by several modules, a ConfigOptsBase could
|
|
|
|
// contain them, and parse the 'DIPLONAT_*' prefix directly.
|
2021-09-20 09:30:00 +00:00
|
|
|
// Only in runtime.rs would these options find their proper location in each
|
2021-08-25 15:20:31 +00:00
|
|
|
// module's struct.
|
|
|
|
|
|
|
|
/// Consul configuration options
|
2021-08-16 09:19:16 +00:00
|
|
|
#[derive(Clone, Default, Deserialize)]
|
2021-08-25 15:20:31 +00:00
|
|
|
pub struct ConfigOptsConsul {
|
2021-09-20 09:30:00 +00:00
|
|
|
/// 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>,
|
2021-08-14 17:12:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// ACME configuration options
|
2021-08-16 09:19:16 +00:00
|
|
|
#[derive(Clone, Default, Deserialize)]
|
2021-08-14 17:12:18 +00:00
|
|
|
pub struct ConfigOptsAcme {
|
2021-09-20 09:30:00 +00:00
|
|
|
/// Whether the ACME module is enabled [default: false]
|
|
|
|
#[serde(default)]
|
|
|
|
pub enable: bool,
|
2021-08-14 17:12:18 +00:00
|
|
|
|
2021-09-20 09:30:00 +00:00
|
|
|
/// The default domain holder's e-mail [default: None]
|
|
|
|
pub email: Option<String>,
|
2021-08-14 17:12:18 +00:00
|
|
|
}
|
|
|
|
|
2021-08-25 15:20:31 +00:00
|
|
|
/// Firewall configuration options
|
2021-08-16 09:19:16 +00:00
|
|
|
#[derive(Clone, Default, Deserialize)]
|
2021-08-25 15:20:31 +00:00
|
|
|
pub struct ConfigOptsFirewall {
|
2021-09-20 09:30:00 +00:00
|
|
|
/// Whether the firewall module is enabled [default: false]
|
|
|
|
#[serde(default)]
|
|
|
|
pub enable: bool,
|
2021-08-25 15:20:31 +00:00
|
|
|
|
2021-09-20 09:30:00 +00:00
|
|
|
/// Refresh time for firewall rules [default: 300]
|
|
|
|
pub refresh_time: Option<u16>,
|
2021-08-25 15:20:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// IGD configuration options
|
|
|
|
#[derive(Clone, Default, Deserialize)]
|
|
|
|
pub struct ConfigOptsIgd {
|
2021-09-20 09:30:00 +00:00
|
|
|
/// Whether the IGD module is enabled [default: false]
|
|
|
|
#[serde(default)]
|
|
|
|
pub enable: bool,
|
|
|
|
|
|
|
|
/// 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 rules [default: 300]
|
|
|
|
pub refresh_time: Option<u16>,
|
2021-08-14 17:12:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Model of all potential configuration options
|
|
|
|
pub struct ConfigOpts {
|
2021-09-20 09:30:00 +00:00
|
|
|
pub consul: ConfigOptsConsul,
|
|
|
|
pub acme: ConfigOptsAcme,
|
|
|
|
pub firewall: ConfigOptsFirewall,
|
|
|
|
pub igd: ConfigOptsIgd,
|
2021-08-14 17:12:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ConfigOpts {
|
2021-09-20 09:30:00 +00:00
|
|
|
pub fn from_env() -> Result<RuntimeConfig> {
|
|
|
|
let consul: ConfigOptsConsul = envy::prefixed("DIPLONAT_CONSUL_").from_env()?;
|
|
|
|
let acme: ConfigOptsAcme = envy::prefixed("DIPLONAT_ACME_").from_env()?;
|
|
|
|
let firewall: ConfigOptsFirewall = envy::prefixed("DIPLONAT_FIREWALL_").from_env()?;
|
|
|
|
let igd: ConfigOptsIgd = envy::prefixed("DIPLONAT_IGD_").from_env()?;
|
|
|
|
|
|
|
|
RuntimeConfig::new(Self {
|
|
|
|
consul,
|
|
|
|
acme,
|
|
|
|
firewall,
|
|
|
|
igd,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Currently only used in tests
|
|
|
|
#[allow(dead_code)]
|
|
|
|
pub fn from_iter<Iter: Clone>(iter: Iter) -> Result<RuntimeConfig>
|
|
|
|
where
|
|
|
|
Iter: IntoIterator<Item = (String, String)>,
|
|
|
|
{
|
|
|
|
let consul: ConfigOptsConsul = envy::prefixed("DIPLONAT_CONSUL_").from_iter(iter.clone())?;
|
|
|
|
let acme: ConfigOptsAcme = envy::prefixed("DIPLONAT_ACME_").from_iter(iter.clone())?;
|
|
|
|
let firewall: ConfigOptsFirewall =
|
|
|
|
envy::prefixed("DIPLONAT_FIREWALL_").from_iter(iter.clone())?;
|
|
|
|
let igd: ConfigOptsIgd = envy::prefixed("DIPLONAT_IGD_").from_iter(iter.clone())?;
|
|
|
|
|
|
|
|
RuntimeConfig::new(Self {
|
|
|
|
consul,
|
|
|
|
acme,
|
|
|
|
firewall,
|
|
|
|
igd,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|