From 615735dc018c5ef12fe7e3359998b8cffaa39a5a Mon Sep 17 00:00:00 2001 From: Stuart Stock Date: Tue, 2 Oct 2018 19:11:47 -0500 Subject: Final touches and bow-tieing on configuration. Update README to reflect. --- src/config/environment.rs | 2 +- src/config/file.rs | 2 +- src/config/mod.rs | 71 ++++++++++++++++++++++++++++++----------------- 3 files changed, 47 insertions(+), 28 deletions(-) (limited to 'src/config') diff --git a/src/config/environment.rs b/src/config/environment.rs index 7ebe588..5053517 100644 --- a/src/config/environment.rs +++ b/src/config/environment.rs @@ -18,9 +18,9 @@ use std::env; use std::net::SocketAddr; use std::time::Duration; -use Error; use config::ServerConfig; use config::{DEFAULT_BATCH_SIZE, DEFAULT_STATUS_INTERVAL}; +use Error; /// /// Obtain a Roughenough server configuration ([ServerConfig](trait.ServerConfig.html)) diff --git a/src/config/file.rs b/src/config/file.rs index 8aa8ca2..e93ee99 100644 --- a/src/config/file.rs +++ b/src/config/file.rs @@ -20,9 +20,9 @@ use std::net::SocketAddr; use std::time::Duration; use yaml_rust::YamlLoader; -use Error; use config::ServerConfig; use config::{DEFAULT_BATCH_SIZE, DEFAULT_STATUS_INTERVAL}; +use Error; /// /// Read a Roughenough server configuration ([ServerConfig](trait.ServerConfig.html)) diff --git a/src/config/mod.rs b/src/config/mod.rs index 02ab941..983338c 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -28,9 +28,11 @@ use std::net::SocketAddr; use std::time::Duration; mod file; + pub use self::file::FileConfig; mod environment; + pub use self::environment::EnvironmentConfig; use Error; @@ -44,26 +46,21 @@ pub const DEFAULT_STATUS_INTERVAL: Duration = Duration::from_secs(600); /// /// Specifies parameters needed to configure a Roughenough server. /// -/// Parameters labeled "**Required**" must are always be provided and have no default value. -/// Parameters labeled "**Optional**" provide default values that can be overridden. -/// -/// * **`interface`** - [Required] IP address or interface name for listening to client requests -/// * **`port`** - [Required] UDP port to listen for requests -/// * **`seed`** - [Required] A 32-byte hexadecimal value used to generate the server's long-term -/// key pair. **This is a secret value and must be un-guessable**, -/// treat it with care. -/// * **`batch_size`** - [Optional] The maximum number of requests to process in one batch. All -/// nonces in a batch are used to build a Merkle tree, the root of which -/// is signed. -/// Defaults to [DEFAULT_BATCH_SIZE](constant.DEFAULT_BATCH_SIZE.html) -/// * **`status_interval`** - [Optional] Amount of time between each logged status update. -/// Defaults to [DEFAULT_STATUS_INTERVAL](constant.DEFAULT_STATUS_INTERVAL.html) +/// Parameters labeled "**Required**" must always be provided and have no default value +/// while those labeled "**Optional**" provide default values that can be overridden. /// -/// Implementations of this trait obtain a valid configuration from different back- -/// end sources. +/// YAML Key | Environment Variable | Necessity | Description +/// --- | --- | --- | --- +/// `interface` | `ROUGHENOUGH_INTERFACE` | Required | IP address or interface name for listening to client requests +/// `port` | `ROUGHENOUGH_PORT` | Required | UDP port to listen for requests +/// `seed` | `ROUGHENOUGH_SEED` | Required | A 32-byte hexadecimal value used to generate the server's long-term key pair. **This is a secret value and must be un-guessable**, treat it with care. +/// `batch_size` | `ROUGHENOUGH_BATCH_SIZE` | Optional | The maximum number of requests to process in one batch. All nonces in a batch are used to build a Merkle tree, the root of which is signed. Defaults to [DEFAULT_BATCH_SIZE](constant.DEFAULT_BATCH_SIZE.html) requests per batch. +/// `status_interval` | `ROUGHENOUGH_STATUS_INTERVAL` | Optional | Number of _seconds_ between each logged status update. Default value is [DEFAULT_STATUS_INTERVAL](constant.DEFAULT_STATUS_INTERVAL.html). /// -/// See: -/// * [FileConfig](struct.FileConfig.html) +/// Implementations of this trait obtain a valid configuration from different back-end +/// sources. See: +/// * [FileConfig](struct.FileConfig.html) - configure via a YAML file +/// * [EnvironmentConfig](struct.EnvironmentConfig.html) - configure via environment vars /// pub trait ServerConfig { /// [Required] IP address or interface name to listen for client requests @@ -90,6 +87,26 @@ pub trait ServerConfig { fn socket_addr(&self) -> Result; } +/// +/// Factory function to create a `ServerConfig` trait object based on the provided `arg` +/// +pub fn make_config(arg: &str) -> Result, Error> { + if arg == "ENV" { + match EnvironmentConfig::new() { + Ok(cfg) => Ok(Box::new(cfg)), + Err(e) => Err(e), + } + } else { + match FileConfig::new(arg) { + Ok(cfg) => Ok(Box::new(cfg)), + Err(e) => Err(e), + } + } +} + +/// +/// Validate configuration settings +/// pub fn is_valid_config(cfg: &Box) -> bool { let mut is_valid = true; @@ -101,13 +118,6 @@ pub fn is_valid_config(cfg: &Box) -> bool { error!("interface is missing"); is_valid = false; } - match cfg.socket_addr() { - Err(e) => { - error!("{}:{}: {:?}", cfg.interface(), cfg.port(), e); - is_valid = false; - } - _ => () - } if cfg.seed().is_empty() { error!("seed value is missing"); is_valid = false; @@ -121,6 +131,15 @@ pub fn is_valid_config(cfg: &Box) -> bool { is_valid = false; } + if is_valid { + match cfg.socket_addr() { + Err(e) => { + error!("failed to create socket {}:{} {:?}", cfg.interface(), cfg.port(), e); + is_valid = false; + } + _ => (), + } + } + is_valid } - -- cgit v1.2.3