✨ 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",
|
"rust-ini",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"toml",
|
"toml 0.5.11",
|
||||||
"yaml-rust",
|
"yaml-rust",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1128,12 +1128,11 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "2.0.1"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a"
|
checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"toml_datetime",
|
"toml_edit 0.20.2",
|
||||||
"toml_edit",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1246,11 +1245,14 @@ name = "roadsign"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"config",
|
"config",
|
||||||
|
"lazy_static",
|
||||||
"poem",
|
"poem",
|
||||||
"poem-openapi",
|
"poem-openapi",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"toml 0.8.8",
|
||||||
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1352,6 +1354,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@ -1629,10 +1640,25 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml"
|
||||||
version = "0.6.3"
|
version = "0.8.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
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]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
@ -1645,6 +1671,19 @@ dependencies = [
|
|||||||
"winnow",
|
"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]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.40"
|
version = "0.1.40"
|
||||||
|
@ -7,9 +7,12 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
config = { version = "0.13.4", features = ["toml"] }
|
config = { version = "0.13.4", features = ["toml"] }
|
||||||
|
lazy_static = "1.4.0"
|
||||||
poem = { version = "2.0.0", features = ["tokio-metrics"] }
|
poem = { version = "2.0.0", features = ["tokio-metrics"] }
|
||||||
poem-openapi = "4.0.0"
|
poem-openapi = "4.0.0"
|
||||||
serde = "1.0.195"
|
serde = "1.0.195"
|
||||||
serde_json = "1.0.111"
|
serde_json = "1.0.111"
|
||||||
tokio = { version = "1.35.1", features = ["rt-multi-thread", "macros", "time"] }
|
tokio = { version = "1.35.1", features = ["rt-multi-thread", "macros", "time"] }
|
||||||
|
toml = "0.8.8"
|
||||||
|
tracing = "0.1.40"
|
||||||
tracing-subscriber = "0.3.18"
|
tracing-subscriber = "0.3.18"
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
regions = "./regions"
|
||||||
|
|
||||||
[listen]
|
[listen]
|
||||||
proxies = "0.0.0.0:80"
|
proxies = "0.0.0.0:80"
|
||||||
proxies_tls = "0.0.0.0:443"
|
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;
|
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::{listener::TcpListener, Route, Server};
|
||||||
use poem_openapi::OpenApiService;
|
use poem_openapi::OpenApiService;
|
||||||
|
use tracing::{error, info, Level};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), std::io::Error> {
|
async fn main() -> Result<(), std::io::Error> {
|
||||||
// Load settings
|
// Setting up logging
|
||||||
let settings = config::loader::load_settings();
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"Will listen at {:?}",
|
|
||||||
settings.get_array("listen.proxies").unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
if std::env::var_os("RUST_LOG").is_none() {
|
if std::env::var_os("RUST_LOG").is_none() {
|
||||||
std::env::set_var("RUST_LOG", "poem=debug");
|
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
|
// Proxies
|
||||||
|
|
||||||
@ -27,7 +41,9 @@ async fn main() -> Result<(), std::io::Error> {
|
|||||||
.server("http://localhost:3000/cgi");
|
.server("http://localhost:3000/cgi");
|
||||||
|
|
||||||
let sideload_server = Server::new(TcpListener::bind(
|
let sideload_server = Server::new(TcpListener::bind(
|
||||||
settings
|
config::C
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
.get_string("listen.sideload")
|
.get_string("listen.sideload")
|
||||||
.unwrap_or("0.0.0.0:81".to_string()),
|
.unwrap_or("0.0.0.0:81".to_string()),
|
||||||
))
|
))
|
||||||
@ -37,3 +53,5 @@ async fn main() -> Result<(), std::io::Error> {
|
|||||||
|
|
||||||
Ok(())
|
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 {
|
pub struct Region {
|
||||||
id: String,
|
id: String,
|
||||||
locations: Vec<Location>,
|
locations: Vec<Location>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Location {
|
pub struct Location {
|
||||||
|
id: String,
|
||||||
hosts: Vec<String>,
|
hosts: Vec<String>,
|
||||||
paths: Vec<String>,
|
paths: Vec<String>,
|
||||||
headers: Vec<HashMap<String, String>>,
|
headers: Option<Vec<HashMap<String, String>>>,
|
||||||
query_strings: Vec<HashMap<String, String>>,
|
query_strings: Option<Vec<HashMap<String, String>>>,
|
||||||
destination: Vec<Destination>,
|
destinations: Vec<Destination>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Destination {
|
pub struct Destination {
|
||||||
uri: Vec<String>,
|
id: String,
|
||||||
timeout: Duration,
|
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 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