diff --git a/Cargo.lock b/Cargo.lock index 41497e1..38b5c82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,6 +151,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "custom_error" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f8a51dd197fa6ba5b4dc98a990a43cc13693c23eb0089ebb0fcc1f04152bca6" + [[package]] name = "deranged" version = "0.3.9" @@ -221,6 +227,17 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "gimli" version = "0.28.0" @@ -424,6 +441,7 @@ name = "nfsense" version = "0.1.0" dependencies = [ "axum", + "custom_error", "ipnet", "macaddr", "serde", @@ -433,6 +451,7 @@ dependencies = [ "tower-http", "tracing", "tracing-subscriber", + "uuid", "validator", ] @@ -1025,6 +1044,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "uuid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +dependencies = [ + "getrandom", +] + [[package]] name = "validator" version = "0.15.0" diff --git a/Cargo.toml b/Cargo.toml index 8d8a709..6c776aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] axum = "0.6.20" +custom_error = "1.9.2" ipnet = { version = "2.8.0", features = ["serde"] } macaddr = { version = "1.0.1", features = ["serde"] } serde = { version = "1.0.189", features = ["derive"] } @@ -16,4 +17,5 @@ tower-cookies = "0.9.0" tower-http = "0.4.4" tracing = "0.1.40" tracing-subscriber = "0.3.17" +uuid = { version = "1.5.0", features = ["v4"] } validator = { version = "0.15", features = ["derive"] } diff --git a/src/config_manager.rs b/src/config_manager.rs index a68904a..e17ec81 100644 --- a/src/config_manager.rs +++ b/src/config_manager.rs @@ -1,12 +1,22 @@ +use serde_json::to_string; use validator::Validate; use super::definitions::config::Config; -use std::error::Error; use std::fs; use std::sync::{Arc, Mutex, MutexGuard}; +use std::{io, result::Result}; -const CURRENT_CONFIG_PATH: &str = "config.json"; -const PENDING_CONFIG_PATH: &str = "pending.json"; +use custom_error::custom_error; + +custom_error! { pub ConfigError + IoError{source: io::Error} = "io error", + SerdeError{source: serde_json::Error} = "serde json error", + ValidatonError{source: validator::ValidationErrors} = "validation failed" + +} + +pub const CURRENT_CONFIG_PATH: &str = "config.json"; +pub const PENDING_CONFIG_PATH: &str = "pending.json"; #[derive(Clone)] pub struct ConfigManager { @@ -21,7 +31,7 @@ struct SharedData { // Note, using unwarp on a mutex lock is ok since that only errors with mutex poisoning impl ConfigManager { - pub fn new() -> Result> { + pub fn new() -> Result { Ok(Self { shared_data: Arc::new(Mutex::new(SharedData { current_config: read_file_to_config(CURRENT_CONFIG_PATH)?, @@ -39,7 +49,7 @@ impl ConfigManager { self.shared_data.lock().unwrap().pending_config.clone() } - pub fn apply_pending_changes(&mut self) -> Result<(), Box> { + pub fn apply_pending_changes(&mut self) -> Result<(), ConfigError> { let mut data = self.shared_data.lock().unwrap(); // TODO run Apply functions // TODO Revert on Apply Failure and Return @@ -50,7 +60,7 @@ impl ConfigManager { Ok(()) } - pub fn discard_pending_changes(&mut self) -> Result<(), Box> { + pub fn discard_pending_changes(&mut self) -> Result<(), ConfigError> { let mut data = self.shared_data.lock().unwrap(); // TODO Remove Pending Config File @@ -58,7 +68,7 @@ impl ConfigManager { Ok(()) } - pub fn start_transaction(&mut self) -> Result> { + pub fn start_transaction(&mut self) -> Result { let data = self.shared_data.lock().unwrap(); Ok(ConfigTransaction { @@ -76,7 +86,7 @@ pub struct ConfigTransaction<'a> { } impl<'a> ConfigTransaction<'a> { - pub fn commit(mut self) -> Result<(), Box> { + pub fn commit(mut self) -> Result<(), ConfigError> { let ch = self.changes.clone(); ch.validate()?; self.shared_data.pending_config = ch.clone(); @@ -85,7 +95,7 @@ impl<'a> ConfigTransaction<'a> { } } -fn read_file_to_config(path: &str) -> Result> { +fn read_file_to_config(path: &str) -> Result { let data = fs::read_to_string(path)?; let conf: Config = serde_json::from_str(&data)?; if conf.config_version != 1 { @@ -94,7 +104,7 @@ fn read_file_to_config(path: &str) -> Result> { Ok(conf) } -fn write_config_to_file(path: &str, conf: Config) -> Result<(), Box> { +fn write_config_to_file(path: &str, conf: Config) -> Result<(), ConfigError> { let data: String = serde_json::to_string_pretty(&conf)?; fs::write(path, data)?; Ok(())