diff --git a/Cargo.lock b/Cargo.lock index 9ff45c74..1948e7a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5126,6 +5126,19 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "serde_yaml_ng" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4db627b98b36d4203a7b458cf3573730f2bb591b28871d916dfa9efabfd41f" +dependencies = [ + "indexmap 2.6.0", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "serial_test" version = "2.0.0" @@ -6521,7 +6534,7 @@ dependencies = [ "rpassword", "serde", "serde_derive", - "serde_yaml", + "serde_yaml_ng", "serial_test 3.1.1", "signal-hook", "signal-hook-async-std", @@ -6559,7 +6572,7 @@ dependencies = [ "cfg-if 1.0.0", "chrono", "clap 4.5.20", - "config 0.13.4", + "config 0.14.1", "console_error_panic_hook", "ctrlc", "eyre", @@ -6592,6 +6605,7 @@ dependencies = [ "rtnetlink", "send_wrapper 0.6.0", "serde", + "serde_yaml_ng", "serial_test 2.0.0", "simplelog", "socket2 0.5.7", diff --git a/veilid-server/Cargo.toml b/veilid-server/Cargo.toml index 8f4d3051..cbcde560 100644 --- a/veilid-server/Cargo.toml +++ b/veilid-server/Cargo.toml @@ -68,7 +68,7 @@ config = { version = "^0.14.0", default-features = false, features = ["yaml"] } cfg-if = "^1.0.0" serde = "^1.0.204" serde_derive = "^1.0.204" -serde_yaml = "^0.9.34" +serde_yaml = { package = "serde_yaml_ng", version = "^0.10.0" } json = "^0" futures-util = { version = "^0", default-features = false, features = [ "alloc", diff --git a/veilid-tools/Cargo.toml b/veilid-tools/Cargo.toml index b2e31000..2077728f 100644 --- a/veilid-tools/Cargo.toml +++ b/veilid-tools/Cargo.toml @@ -45,11 +45,12 @@ debug-locks = [] virtual-network = [] virtual-network-server = [ - "dep:ws_stream_tungstenite", "dep:async-tungstenite", "dep:clap", "dep:config", "dep:ipnet", + "dep:serde_yaml", + "dep:ws_stream_tungstenite", ] [dependencies] @@ -109,6 +110,7 @@ config = { version = "^0", default-features = false, features = [ "yaml", ], optional = true } ipnet = { version = "2", features = ["serde"], optional = true } +serde_yaml = { package = "serde_yaml_ng", version = "^0.10.0", optional = true } # Dependencies for WASM builds only [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] diff --git a/veilid-tools/src/bin/virtual_router/main.rs b/veilid-tools/src/bin/virtual_router/main.rs index f8c07517..e9077837 100644 --- a/veilid-tools/src/bin/virtual_router/main.rs +++ b/veilid-tools/src/bin/virtual_router/main.rs @@ -43,6 +43,9 @@ struct CmdlineArgs { /// Specify a configuration file to use #[arg(short = 'c', long, value_name = "FILE")] config_file: Option, + /// Instead of running the virtual router, print the configuration it would use to the console + #[arg(long)] + dump_config: bool, } fn main() -> Result<(), String> { @@ -64,6 +67,13 @@ fn main() -> Result<(), String> { let config = Config::new(args.config_file).map_err(|e| format!("Error loading config: {}", e))?; + if args.dump_config { + let cfg_yaml = serde_yaml::to_string(&config) + .map_err(|e| format!("Error serializing config: {}", e))?; + println!("{}", cfg_yaml); + return Ok(()); + } + let router_server = virtual_network::RouterServer::new(config); let _ss_tcp = if !args.no_tcp { Some( diff --git a/veilid-tools/src/virtual_network/router_server/config.rs b/veilid-tools/src/virtual_network/router_server/config.rs index 493c3c78..542a86fb 100644 --- a/veilid-tools/src/virtual_network/router_server/config.rs +++ b/veilid-tools/src/virtual_network/router_server/config.rs @@ -8,7 +8,7 @@ pub use ::config::ConfigError; const PREDEFINED_CONFIG: &str = include_str!("predefined_config.yml"); const DEFAULT_CONFIG: &str = include_str!("default_config.yml"); -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] pub enum WeightedList { Single(T), @@ -22,26 +22,26 @@ impl Default for WeightedList { pub type Probability = f32; -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] pub enum Weighted { - Weighted(T, f32), + Weighted { item: T, weight: f32 }, Unweighted(T), } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Profile { instances: Vec, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] pub enum Instance { Machine { machine: WeightedList }, Template { template: WeightedList }, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Machine { #[serde(flatten)] location: Location, @@ -55,7 +55,7 @@ pub struct Machine { bootstrap: bool, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Template { #[serde(flatten)] location: Location, @@ -65,12 +65,12 @@ pub struct Template { disable_capabilities: Vec, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Limits { machine_count: WeightedList, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] pub enum Location { Network { network: WeightedList }, @@ -79,7 +79,7 @@ pub enum Location { //////////////////////////////////////////////////////////////// -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Network { #[serde(default)] model: Option, @@ -89,20 +89,20 @@ pub struct Network { ipv6: Option, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct NetworkIpv4 { allocation: String, #[serde(default)] gateway: Option, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct NetworkIpv6 { allocation: String, #[serde(default)] gateway: Option, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct NetworkGateway { translation: Translation, upnp: bool, @@ -111,7 +111,7 @@ pub struct NetworkGateway { //////////////////////////////////////////////////////////////// -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Blueprint { #[serde(default)] model: WeightedList, @@ -121,7 +121,7 @@ pub struct Blueprint { ipv6: Option, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct BlueprintIpv4 { #[serde(default)] allocation: Option, @@ -129,7 +129,7 @@ pub struct BlueprintIpv4 { #[serde(default)] gateway: Option, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct BlueprintIpv6 { #[serde(default)] allocation: Option, @@ -138,7 +138,7 @@ pub struct BlueprintIpv6 { gateway: Option, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct BlueprintGateway { translation: WeightedList, upnp: Probability, @@ -147,7 +147,7 @@ pub struct BlueprintGateway { //////////////////////////////////////////////////////////////// -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Subnets { #[serde(default)] subnet4: Vec, @@ -155,13 +155,13 @@ pub struct Subnets { subnet6: Vec, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Distance { min: f32, max: f32, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Distribution { mean: f32, sigma: f32, @@ -170,7 +170,7 @@ pub struct Distribution { max: f32, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum Translation { None, @@ -185,7 +185,7 @@ impl Default for Translation { } } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Model { latency: Distribution, #[serde(default)] @@ -194,13 +194,13 @@ pub struct Model { loss: Probability, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Allocation { #[serde(flatten)] subnets: Subnets, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Config { seed: Option, default_network: String,