aboutsummaryrefslogblamecommitdiff
path: root/src/config/options.rs
blob: 54e948d7d645c3535cfc7c4751e01f326fff721f (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                              








                                                                               
                                      




                                                                


                              
                                      
                           
                                                               




                                                              

                                                          

 
                                  
                                      





















                                                                   


                                                
                       
                                     


                                         



                                                    

                                                                                              

                                                                                                    

                                         



                                 


                  

                                       

                                                                          

                                                                                                           

                                                                                                                 

                                         



                                 


                  
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.

// - 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.
// Only in runtime.rs would these options find their proper location in each 
// module's struct.


/// 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>,
}

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

	/// The default domain holder's e-mail [default: None]
	pub email: Option<String>,
	/// Refresh time for firewall rules [default: 300]
	pub refresh_time: Option<u16>,
}

/// Firewall configuration options
#[derive(Clone, Default, Deserialize)]
pub struct ConfigOptsFirewall {
	/// Whether the firewall module is enabled [default: false]
	#[serde(default)]
	pub enable: bool,

	/// Refresh time for firewall rules [default: 300]
	pub refresh_time: Option<u16>,
}

/// IGD configuration options
#[derive(Clone, Default, Deserialize)]
pub struct ConfigOptsIgd {
	/// 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>,
}

/// Model of all potential configuration options
pub struct ConfigOpts {
	pub consul: ConfigOptsConsul,
	pub acme: ConfigOptsAcme,
	pub firewall: ConfigOptsFirewall,
	pub igd: ConfigOptsIgd,
}

impl ConfigOpts {
	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,
		})
	}
}