✨ Config loader
This commit is contained in:
parent
bf7004c89c
commit
5de1d13907
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![] }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user