✨ Config loader
This commit is contained in:
		
							
								
								
									
										55
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										55
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -216,7 +216,7 @@ dependencies = [ | ||||
|  "rust-ini", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
|  "toml", | ||||
|  "toml 0.5.11", | ||||
|  "yaml-rust", | ||||
| ] | ||||
|  | ||||
| @@ -1128,12 +1128,11 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" | ||||
|  | ||||
| [[package]] | ||||
| name = "proc-macro-crate" | ||||
| version = "2.0.1" | ||||
| version = "2.0.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" | ||||
| checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" | ||||
| dependencies = [ | ||||
|  "toml_datetime", | ||||
|  "toml_edit", | ||||
|  "toml_edit 0.20.2", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @@ -1246,11 +1245,14 @@ name = "roadsign" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "config", | ||||
|  "lazy_static", | ||||
|  "poem", | ||||
|  "poem-openapi", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
|  "tokio", | ||||
|  "toml 0.8.8", | ||||
|  "tracing", | ||||
|  "tracing-subscriber", | ||||
| ] | ||||
|  | ||||
| @@ -1352,6 +1354,15 @@ dependencies = [ | ||||
|  "serde", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "serde_spanned" | ||||
| version = "0.6.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" | ||||
| dependencies = [ | ||||
|  "serde", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "serde_urlencoded" | ||||
| version = "0.7.1" | ||||
| @@ -1629,10 +1640,25 @@ dependencies = [ | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "toml_datetime" | ||||
| version = "0.6.3" | ||||
| name = "toml" | ||||
| version = "0.8.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" | ||||
| checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" | ||||
| dependencies = [ | ||||
|  "serde", | ||||
|  "serde_spanned", | ||||
|  "toml_datetime", | ||||
|  "toml_edit 0.21.0", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "toml_datetime" | ||||
| version = "0.6.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" | ||||
| dependencies = [ | ||||
|  "serde", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "toml_edit" | ||||
| @@ -1645,6 +1671,19 @@ dependencies = [ | ||||
|  "winnow", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "toml_edit" | ||||
| version = "0.21.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" | ||||
| dependencies = [ | ||||
|  "indexmap", | ||||
|  "serde", | ||||
|  "serde_spanned", | ||||
|  "toml_datetime", | ||||
|  "winnow", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tracing" | ||||
| version = "0.1.40" | ||||
|   | ||||
| @@ -7,9 +7,12 @@ edition = "2021" | ||||
|  | ||||
| [dependencies] | ||||
| config = { version = "0.13.4", features = ["toml"] } | ||||
| lazy_static = "1.4.0" | ||||
| poem = { version = "2.0.0", features = ["tokio-metrics"] } | ||||
| poem-openapi = "4.0.0" | ||||
| serde = "1.0.195" | ||||
| serde_json = "1.0.111" | ||||
| tokio = { version = "1.35.1", features = ["rt-multi-thread", "macros", "time"] } | ||||
| toml = "0.8.8" | ||||
| tracing = "0.1.40" | ||||
| tracing-subscriber = "0.3.18" | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| regions = "./regions" | ||||
|  | ||||
| [listen] | ||||
| proxies = "0.0.0.0:80" | ||||
| proxies_tls = "0.0.0.0:443" | ||||
|   | ||||
							
								
								
									
										9
									
								
								regions/index.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								regions/index.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| id = "index" | ||||
|  | ||||
| [[locations]] | ||||
| id = "root" | ||||
| hosts = ["localhost"] | ||||
| paths = ["/"] | ||||
| [[locations.destinations]] | ||||
| id = "example" | ||||
| uri = "https://example.com" | ||||
| @@ -1 +1,12 @@ | ||||
| use std::sync::RwLock; | ||||
|  | ||||
| use config::Config; | ||||
| use lazy_static::lazy_static; | ||||
|  | ||||
| use crate::config::loader::load_settings; | ||||
|  | ||||
| pub mod loader; | ||||
|  | ||||
| lazy_static! { | ||||
|     pub static ref C: RwLock<Config> = RwLock::new(load_settings()); | ||||
| } | ||||
|   | ||||
							
								
								
									
										38
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -4,21 +4,35 @@ mod sideload; | ||||
|  | ||||
| use poem::{listener::TcpListener, Route, Server}; | ||||
| use poem_openapi::OpenApiService; | ||||
| use tracing::{error, info, Level}; | ||||
|  | ||||
| #[tokio::main] | ||||
| async fn main() -> Result<(), std::io::Error> { | ||||
|     // Load settings | ||||
|     let settings = config::loader::load_settings(); | ||||
|  | ||||
|     println!( | ||||
|         "Will listen at {:?}", | ||||
|         settings.get_array("listen.proxies").unwrap() | ||||
|     ); | ||||
|  | ||||
|     // Setting up logging | ||||
|     if std::env::var_os("RUST_LOG").is_none() { | ||||
|         std::env::set_var("RUST_LOG", "poem=debug"); | ||||
|     } | ||||
|     tracing_subscriber::fmt::init(); | ||||
|     tracing_subscriber::fmt() | ||||
|         .with_max_level(Level::DEBUG) | ||||
|         .init(); | ||||
|  | ||||
|     // Prepare all the stuff | ||||
|     let mut instance = proxies::Instance::new(); | ||||
|  | ||||
|     info!("Loading proxy regions..."); | ||||
|     match proxies::loader::scan_regions( | ||||
|         config::C | ||||
|             .read() | ||||
|             .unwrap() | ||||
|             .get_string("regions") | ||||
|             .unwrap_or("./regions".to_string()), | ||||
|     ) { | ||||
|         Err(_) => error!("Loading proxy regions... failed"), | ||||
|         Ok((regions, count)) => { | ||||
|             instance.regions = regions; | ||||
|             info!(count, "Loading proxy regions... done") | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     // Proxies | ||||
|  | ||||
| @@ -27,7 +41,9 @@ async fn main() -> Result<(), std::io::Error> { | ||||
|         .server("http://localhost:3000/cgi"); | ||||
|  | ||||
|     let sideload_server = Server::new(TcpListener::bind( | ||||
|         settings | ||||
|         config::C | ||||
|             .read() | ||||
|             .unwrap() | ||||
|             .get_string("listen.sideload") | ||||
|             .unwrap_or("0.0.0.0:81".to_string()), | ||||
|     )) | ||||
| @@ -37,3 +53,5 @@ async fn main() -> Result<(), std::io::Error> { | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,22 +1,26 @@ | ||||
| use std::{collections::HashMap, time::Duration}; | ||||
| use std::collections::HashMap; | ||||
|  | ||||
| #[derive(Debug, Clone)] | ||||
| use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||||
| pub struct Region { | ||||
|     id: String, | ||||
|     locations: Vec<Location>, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone)] | ||||
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||||
| pub struct Location { | ||||
|     id: String, | ||||
|     hosts: Vec<String>, | ||||
|     paths: Vec<String>, | ||||
|     headers: Vec<HashMap<String, String>>, | ||||
|     query_strings: Vec<HashMap<String, String>>, | ||||
|     destination: Vec<Destination>, | ||||
|     headers: Option<Vec<HashMap<String, String>>>, | ||||
|     query_strings: Option<Vec<HashMap<String, String>>>, | ||||
|     destinations: Vec<Destination>, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone)] | ||||
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||||
| pub struct Destination { | ||||
|     uri: Vec<String>, | ||||
|     timeout: Duration, | ||||
|     id: String, | ||||
|     uri: String, | ||||
|     timeout: Option<u32>, | ||||
| } | ||||
|   | ||||
							
								
								
									
										53
									
								
								src/proxies/loader.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/proxies/loader.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| use std::ffi::OsStr; | ||||
| use std::fs::{self, DirEntry}; | ||||
| use std::io; | ||||
|  | ||||
| use tracing::warn; | ||||
|  | ||||
| use crate::proxies::config; | ||||
|  | ||||
| pub fn scan_regions(basepath: String) -> io::Result<(Vec<config::Region>, u32)> { | ||||
|     let mut count: u32 = 0; | ||||
|     let mut result = vec![]; | ||||
|     for entry in fs::read_dir(basepath)? { | ||||
|         if let Ok(val) = load_region(entry.unwrap()) { | ||||
|             result.push(val); | ||||
|             count += 1; | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     Ok((result, count)) | ||||
| } | ||||
|  | ||||
| pub fn load_region(file: DirEntry) -> Result<config::Region, String> { | ||||
|     if file.path().extension().and_then(OsStr::to_str).unwrap() != "toml" { | ||||
|         return Err("File entry wasn't toml file".to_string()); | ||||
|     } | ||||
|  | ||||
|     let fp = file.path(); | ||||
|     let content = match fs::read_to_string(fp.clone()) { | ||||
|         Ok(val) => val, | ||||
|         Err(err) => { | ||||
|             warn!( | ||||
|                 err = format!("{:?}", err), | ||||
|                 filepath = fp.clone().to_str(), | ||||
|                 "An error occurred when loading region, skipped." | ||||
|             ); | ||||
|             return Err("Failed to load file".to_string()); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     let data: config::Region = match toml::from_str(&content) { | ||||
|         Ok(val) => val, | ||||
|         Err(err) => { | ||||
|             warn!( | ||||
|                 err = format!("{:?}", err), | ||||
|                 filepath = fp.clone().to_str(), | ||||
|                 "An error occurred when parsing region, skipped." | ||||
|             ); | ||||
|             return Err("Failed to parse file".to_string()); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     Ok(data) | ||||
| } | ||||
| @@ -1 +1,17 @@ | ||||
| use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| use self::config::Region; | ||||
|  | ||||
| pub mod config; | ||||
| pub mod loader; | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||||
| pub struct Instance { | ||||
|     pub regions: Vec<Region>, | ||||
| } | ||||
|  | ||||
| impl Instance { | ||||
|     pub fn new() -> Instance { | ||||
|         Instance { regions: vec![] } | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user