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, /// Expiration time for IGD rules [default: 60] pub expiration_time: Option, /// Refresh time for IGD and Firewall rules [default: 300] pub refresh_time: Option, /// STUN server [default: stun.nextcloud.com:443] pub stun_server: Option, } /// 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, } /// Consul configuration options #[derive(Clone, Default, Deserialize)] pub struct ConfigOptsConsul { /// Consul's node name [default: None] pub node_name: Option, /// Consul's REST URL [default: "http://127.0.0.1:8500"] pub url: Option, /// Consul's CA certificate [default: None] pub ca_cert: Option, /// 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, /// Consul's client key [default: None] pub client_key: Option, } /// 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 { 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: Iter) -> Result where Iter: IntoIterator, { 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, }) } }