diff --git a/Cargo.lock b/Cargo.lock index 30942b7..f70be28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,6 +99,8 @@ dependencies = [ "libc", "num-integer", "num-traits", + "serde", + "time 0.1.43", "winapi", ] @@ -173,6 +175,12 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +[[package]] +name = "dyn-clone" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" + [[package]] name = "encoding_rs" version = "0.8.31" @@ -253,6 +261,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.21" @@ -260,6 +283,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -285,6 +309,17 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +[[package]] +name = "futures-macro" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.21" @@ -303,13 +338,27 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + [[package]] name = "getrandom" version = "0.2.6" @@ -336,7 +385,7 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util", + "tokio-util 0.7.1", "tracing", ] @@ -367,6 +416,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "home" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654" +dependencies = [ + "winapi", +] + [[package]] name = "hostname" version = "0.3.1" @@ -474,6 +532,7 @@ checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg", "hashbrown", + "serde", ] [[package]] @@ -606,16 +665,6 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "mio" version = "0.8.3" @@ -699,6 +748,17 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +[[package]] +name = "openapiv3" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b4689110fd71f196934fbdf1ad0f0a4b49ea41fbc6f19008c00dba735b544c" +dependencies = [ + "indexmap", + "serde", + "serde_json", +] + [[package]] name = "openssl" version = "0.10.40" @@ -789,6 +849,15 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -846,6 +915,75 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "progenitor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54484468975e18aa57ed3e9a13ac0468160a433af89eee1189f681292eafc5d1" +dependencies = [ + "anyhow", + "getopts", + "openapiv3", + "progenitor-client", + "progenitor-impl", + "progenitor-macro", + "serde", + "serde_json", +] + +[[package]] +name = "progenitor-client" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45c7752120152426ce577c3de6b341fecdaae59883f31296d91871a6d7843206" +dependencies = [ + "bytes", + "futures-core", + "percent-encoding", + "reqwest", + "serde", + "serde_json", +] + +[[package]] +name = "progenitor-impl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1980a31d714128082fe8dd6a7cb6086c15080cdb9a693feba171361fb961b034" +dependencies = [ + "getopts", + "heck", + "indexmap", + "openapiv3", + "proc-macro2", + "quote", + "regex", + "rustfmt-wrapper", + "schemars", + "serde", + "serde_json", + "syn", + "thiserror", + "typify", + "unicode-xid", +] + +[[package]] +name = "progenitor-macro" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0993b8f5bbcf35ec130f9d305cefbbd81f00c014c049bf298bd218529989b054" +dependencies = [ + "openapiv3", + "proc-macro2", + "progenitor-impl", + "quote", + "serde", + "serde_json", + "serde_tokenstream", + "syn", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -966,7 +1104,6 @@ dependencies = [ "lazy_static", "log", "mime", - "mime_guess", "native-tls", "percent-encoding", "pin-project-lite", @@ -975,6 +1112,7 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-native-tls", + "tokio-util 0.6.9", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -992,12 +1130,32 @@ dependencies = [ "quick-error", ] +[[package]] +name = "rustfmt-wrapper" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7733577fb5b13c8b256232e7ca84aa424f915efae6ec980082d60a03f99da3f8" +dependencies = [ + "tempfile", + "thiserror", + "toolchain_find", +] + [[package]] name = "ryu" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.19" @@ -1008,6 +1166,32 @@ dependencies = [ "winapi", ] +[[package]] +name = "schemars" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6b5a3c80cea1ab61f4260238409510e814e38b4b563c06044edf91e7dc070e3" +dependencies = [ + "chrono", + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "schemars_derive" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ae4dce13e8614c46ac3c38ef1c0d668b101df6ac39817aebdaa26642ddae9b" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -1037,6 +1221,24 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.137" @@ -1057,6 +1259,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_derive_internals" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_json" version = "1.0.81" @@ -1068,6 +1281,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_tokenstream" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6deb15c3a535e81438110111d90168d91721652f502abb147f31cde129f683d" +dependencies = [ + "proc-macro2", + "serde", + "syn", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1140,9 +1364,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04066589568b72ec65f42d65a1a52436e954b168773148893c020269563decf2" +checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a" dependencies = [ "proc-macro2", "quote", @@ -1207,6 +1431,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "time" version = "0.3.9" @@ -1295,6 +1529,20 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-util" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.1" @@ -1318,6 +1566,19 @@ dependencies = [ "serde", ] +[[package]] +name = "toolchain_find" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e85654a10e7a07a47c6f19d93818f3f343e22927f2fa280c84f7c8042743413" +dependencies = [ + "home", + "lazy_static", + "regex", + "semver", + "walkdir", +] + [[package]] name = "tower-service" version = "0.3.1" @@ -1416,7 +1677,7 @@ dependencies = [ "radix_trie", "rand", "thiserror", - "time", + "time 0.3.9", "tokio", "trust-dns-proto", ] @@ -1488,7 +1749,7 @@ dependencies = [ "openssl", "serde", "thiserror", - "time", + "time 0.3.9", "tokio", "tokio-openssl", "toml", @@ -1504,14 +1765,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] -name = "unicase" -version = "2.6.0" +name = "typify" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +checksum = "75e642ba5bfa5a7b2e085a700f5f5111b069a833156f82c53a365210e545258d" dependencies = [ - "version_check", + "typify-impl", + "typify-macro", +] + +[[package]] +name = "typify-impl" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b1b5a377f1e0dceb8a18b25c86c80b32d0882b01e1585fd520354a56b7c30c" +dependencies = [ + "heck", + "log", + "proc-macro2", + "quote", + "rustfmt-wrapper", + "schemars", + "serde_json", + "syn", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "typify-macro" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cad3517ce4190a7f108cd6360da245c7e289060003d077156f2da7dcf1f568" +dependencies = [ + "proc-macro2", + "quote", + "schemars", + "serde", + "serde_json", + "serde_tokenstream", + "syn", + "typify-impl", ] +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + [[package]] name = "unicode-bidi" version = "0.3.8" @@ -1527,6 +1829,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + [[package]] name = "unicode-xid" version = "0.2.3" @@ -1546,6 +1854,16 @@ dependencies = [ "serde", ] +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + [[package]] name = "valuable" version = "0.1.0" @@ -1564,6 +1882,17 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + [[package]] name = "want" version = "0.3.0" @@ -1783,6 +2112,7 @@ dependencies = [ "openssl", "rand", "regex", + "reqwest", "serde", "serde_json", "serde_yaml", @@ -1800,26 +2130,34 @@ dependencies = [ [[package]] name = "zerotier-central-api" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9944068ba3ed2b0c17c2bc0a8b006741ef55db122994e2b835515b2bbc6b7ec" +checksum = "a0ba5b7104ad0ac89d5c4a7f6f371a8ffaf0bee6da4e34ca6b41799b74793301" dependencies = [ + "anyhow", + "chrono", + "futures", + "progenitor", + "progenitor-client", "reqwest", "serde", - "serde_derive", "serde_json", - "url", + "uuid", ] [[package]] name = "zerotier-one-api" -version = "1.0.5" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68d4f5b250dff3e61267c248cb50550161bef160380902cae78f81cfa28a3a78" +checksum = "7988d9fb9b4f8f0679c05f49c785d23e7de7e6d671d48a7d1c07f616ad7cc4a0" dependencies = [ + "anyhow", + "chrono", + "futures", + "progenitor", + "progenitor-client", "reqwest", "serde", - "serde_derive", "serde_json", - "url", + "uuid", ] diff --git a/Cargo.toml b/Cargo.toml index 6c038d6..c08d3a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,11 +21,11 @@ ipnetwork = ">=0" trust-dns-resolver = { version = "^0.21.0", features = ["tokio-runtime", "dns-over-openssl"] } trust-dns-server = { version = "^0.21.0", features = ["trust-dns-resolver", "dns-over-openssl"] } tokio = { version = "1", features = ["full"] } -zerotier-central-api = { version = "=1.0.3" } -zerotier-one-api = { version = "=1.0.5" } serde = ">=0" serde_json = ">=0" serde_yaml = ">=0" +zerotier-central-api = "=1.1.0" +zerotier-one-api = "=1.1.0" toml = ">=0" tinytemplate = ">=0" rand = ">=0" @@ -36,6 +36,7 @@ hex = ">=0" openssl = ">=0" async-trait = ">=0" lazy_static = ">=0" +reqwest = ">=0" [features] vendored-openssl = [ "openssl/vendored" ] diff --git a/src/addresses.rs b/src/addresses.rs index ea1dabb..de979fa 100644 --- a/src/addresses.rs +++ b/src/addresses.rs @@ -3,7 +3,7 @@ use std::net::{IpAddr, Ipv6Addr}; use hex::FromHexError; use ipnetwork::IpNetwork; -use zerotier_central_api::models::{Member, Network}; +use zerotier_central_api::types::{Member, Network}; fn digest_hex(code: String) -> Result { Ok(hex::decode(code)? diff --git a/src/authority.rs b/src/authority.rs index eb939b3..f547766 100644 --- a/src/authority.rs +++ b/src/authority.rs @@ -7,6 +7,13 @@ use std::{ time::Duration, }; +use crate::{ + addresses::Calculator, + hosts::{parse_hosts, HostsFile}, + traits::{ToHostname, ToPointerSOA, ToWildcard}, + utils::parse_member_name, +}; + use async_trait::async_trait; use ipnetwork::IpNetwork; use trust_dns_resolver::{ @@ -22,17 +29,6 @@ use trust_dns_server::{ in_memory::InMemoryAuthority, }, }; -use zerotier_central_api::{ - apis::configuration::Configuration, - models::{Member, Network}, -}; - -use crate::{ - addresses::Calculator, - hosts::{parse_hosts, HostsFile}, - traits::{ToHostname, ToPointerSOA, ToWildcard}, - utils::parse_member_name, -}; pub async fn find_members(mut zt: ZTAuthority) { let mut timer = tokio::time::interval(zt.update_interval); @@ -101,7 +97,7 @@ pub async fn init_catalog(zt: ZTAuthority) -> Result { pub struct ZTAuthority { pub network_id: String, pub hosts_file: Option, - pub config: Configuration, + pub client: zerotier_central_api::Client, pub reverse_authority_map: HashMap, pub forward_authority: RecordAuthority, pub wildcard: bool, @@ -129,8 +125,8 @@ impl ZTAuthority { pub async fn configure_members( &self, - network: Network, - members: Vec, + network: zerotier_central_api::types::Network, + members: Vec, ) -> Result<(), anyhow::Error> { let mut forward_records = vec![self.forward_authority.domain_name.clone()]; let mut reverse_records = HashMap::new(); @@ -151,7 +147,7 @@ impl ZTAuthority { let v6assign = network.config.clone().unwrap().v6_assign_mode; if v6assign.is_some() { let v6assign = v6assign.unwrap().clone(); - if v6assign.var_6plane.unwrap_or(false) { + if v6assign._6plane.unwrap_or(false) { let s = network.clone().sixplane()?; sixplane = Some(s); } @@ -180,9 +176,9 @@ impl ZTAuthority { .await?; if let Some(ips) = member.clone().config.and_then(|c| { - c.ip_assignments.and_then(|ips| { + c.ip_assignments.map_or(None, |v| { Some( - ips.iter() + v.iter() .filter_map(|ip| IpAddr::from_str(ip).map_or(None, |ip| Some(ip))) .collect::>(), ) @@ -228,21 +224,22 @@ impl ZTAuthority { Ok(()) } - pub async fn get_members(&self) -> Result<(Network, Vec), anyhow::Error> { - let config = self.config.clone(); + pub async fn get_members( + &self, + ) -> Result< + ( + zerotier_central_api::types::Network, + Vec, + ), + anyhow::Error, + > { + let client = self.client.clone(); let network_id = self.network_id.clone(); - let members = zerotier_central_api::apis::network_member_api::get_network_member_list( - &config, - &network_id, - ) - .await?; - - let network = - zerotier_central_api::apis::network_api::get_network_by_id(&config, &network_id) - .await?; + let members = client.get_network_member_list(&network_id).await?; + let network = client.get_network_by_id(&network_id).await?; - Ok((network, members)) + Ok((network.to_owned(), members.to_owned())) } } @@ -604,7 +601,7 @@ struct ZTRecord { impl ZTRecord { pub fn new( - member: &Member, + member: &zerotier_central_api::types::Member, sixplane: Option, rfc4193: Option, domain_name: Name, @@ -630,15 +627,16 @@ impl ZTRecord { ptr_name = name; } - let mut ips: Vec = member + let mut ips = member .clone() .config .expect("Member config does not exist") .ip_assignments - .expect("IP assignments for member do not exist") - .into_iter() - .map(|s| IpAddr::from_str(&s).expect("Could not parse IP address")) - .collect(); + .map_or(Vec::new(), |v| { + v.iter() + .map(|s| IpAddr::from_str(s).expect("Could not parse IP address")) + .collect() + }); if sixplane.is_some() { ips.push(member.clone().sixplane()?.ip()); diff --git a/src/init.rs b/src/init.rs index 654a7d7..b08456b 100644 --- a/src/init.rs +++ b/src/init.rs @@ -103,7 +103,7 @@ impl Launcher { let domain_name = domain_or_default(self.domain.as_deref())?; let authtoken = authtoken_path(self.secret.as_deref()); - let config = central_config(central_token(self.token.as_deref())?); + let client = central_client(central_token(self.token.as_deref())?)?; info!("Welcome to ZeroNS!"); let ips = get_listen_ips(&authtoken, &self.network_id.clone().unwrap()).await?; @@ -115,7 +115,7 @@ impl Launcher { ips.iter() .map(|i| parse_ip_from_cidr(i.clone()).to_string()) .collect(), - config.clone(), + client.clone(), self.network_id.clone().unwrap(), ) .await?; @@ -143,14 +143,12 @@ impl Launcher { let member_name = get_member_name(authtoken, domain_name.clone()).await?; - let network = zerotier_central_api::apis::network_api::get_network_by_id( - &config, - &self.network_id.clone().unwrap(), - ) - .await?; + let network = client + .get_network_by_id(&self.network_id.clone().unwrap()) + .await?; if let Some(v6assign) = network.config.clone().unwrap().v6_assign_mode { - if v6assign.var_6plane.unwrap_or(false) { + if v6assign._6plane.unwrap_or(false) { warn!("6PLANE PTR records are not yet supported"); } @@ -169,7 +167,7 @@ impl Launcher { RecordAuthority::new(domain_name.clone().into(), member_name.clone()).await?; let ztauthority = ZTAuthority { - config, + client, network_id: self.network_id.clone().unwrap(), hosts: None, // this will be parsed later. hosts_file: self.hosts.clone(), diff --git a/src/traits.rs b/src/traits.rs index c9343e2..deda1c7 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -6,7 +6,7 @@ use lazy_static::lazy_static; use regex::Regex; use trust_dns_resolver::{proto::error::ProtoError, IntoName, Name}; use trust_dns_server::client::rr::LowerName; -use zerotier_central_api::models::Member; +use zerotier_central_api::types::Member; pub trait ToPointerSOA { fn to_ptr_soa_name(&self) -> Result; @@ -106,7 +106,7 @@ mod tests { use ipnetwork::IpNetwork; use trust_dns_resolver::Name; use trust_dns_server::client::rr::LowerName; - use zerotier_central_api::models::Member; + use zerotier_central_api::types::Member; #[test] fn test_to_ptr_soa_name() { @@ -153,7 +153,22 @@ mod tests { #[test] fn test_to_hostname_member() { - let mut member = Member::new(); + let mut member = Member { + supports_rules_engine: None, + protocol_version: None, + physical_address: None, + node_id: None, + network_id: None, + name: None, + last_online: None, + id: None, + hidden: None, + description: None, + controller_id: None, + config: None, + client_version: None, + clock: None, + }; member.node_id = Some("foo".to_string()); let hostname = member.to_hostname().unwrap(); assert_eq!(hostname, Name::from_str("zt-foo").unwrap()); diff --git a/src/utils.rs b/src/utils.rs index 289327f..da5a568 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,12 +1,11 @@ use std::{net::IpAddr, path::Path, str::FromStr, sync::Once}; use ipnetwork::IpNetwork; +use reqwest::header::{HeaderMap, HeaderValue}; use tracing::warn; use trust_dns_server::client::rr::{LowerName, Name}; -use zerotier_central_api::apis::configuration::Configuration; use anyhow::anyhow; -use zerotier_one_api::apis::configuration::Configuration as ZTOneConfiguration; use crate::traits::ToHostname; @@ -16,6 +15,10 @@ pub const TEST_HOSTS_DIR: &str = "testdata/hosts-files"; pub const DOMAIN_NAME: &str = "home.arpa."; // zeronsd version calculated from Cargo.toml pub const VERSION_STRING: &str = env!("CARGO_PKG_VERSION"); +// address of Central +pub const CENTRAL_BASEURL: &str = "https://my.zerotier.com/api/v1"; +// address of local zerotier instance +pub const ZEROTIER_LOCAL_URL: &str = "http://127.0.0.1:9993"; // this really needs to be replaced with lazy_static! magic fn version() -> String { @@ -64,18 +67,21 @@ pub fn init_logger(level: Option) { } // this provides the production configuration for talking to central through the openapi libraries. -pub fn central_config(token: String) -> Configuration { - let mut config = Configuration { - user_agent: Some(version()), - bearer_access_token: Some(token), - ..Default::default() - }; - - if let Ok(instance) = std::env::var("ZEROTIER_CENTRAL_INSTANCE") { - config.base_path = instance; - } - - config +pub fn central_client(token: String) -> Result { + let mut headers = HeaderMap::new(); + headers.insert( + "Authorization", + HeaderValue::from_str(&format!("bearer {}", token))?, + ); + + Ok(zerotier_central_api::Client::new_with_client( + &std::env::var("ZEROTIER_CENTRAL_INSTANCE").unwrap_or(CENTRAL_BASEURL.to_string()), + reqwest::Client::builder() + .user_agent(version()) + .https_only(true) + .default_headers(headers) + .build()?, + )) } // extracts the ip from the CIDR. 10.0.0.1/32 becomes 10.0.0.1 @@ -155,11 +161,11 @@ pub async fn get_member_name( authtoken_path: &Path, domain_name: Name, ) -> Result { - let configuration = get_local_config(authtoken_path)?; + let client = local_client_from_file(authtoken_path)?; - let status = zerotier_one_api::apis::status_api::get_status(&configuration).await?; - if let Some(address) = status.address { - return Ok(("zt-".to_string() + &address).to_fqdn(domain_name)?.into()); + let status = client.get_status().await?; + if let Some(address) = &status.address { + return Ok(("zt-".to_string() + address).to_fqdn(domain_name)?.into()); } Err(anyhow!( @@ -167,17 +173,24 @@ pub async fn get_member_name( )) } -fn get_local_config(authtoken_path: &Path) -> Result { +fn local_client_from_file( + authtoken_path: &Path, +) -> Result { let authtoken = std::fs::read_to_string(authtoken_path)?; - let mut configuration = ZTOneConfiguration::default(); - let api_key = zerotier_one_api::apis::configuration::ApiKey { - prefix: None, - key: authtoken, - }; + local_client(authtoken) +} - configuration.user_agent = Some(version()); - configuration.api_key = Some(api_key); - Ok(configuration) +pub fn local_client(authtoken: String) -> Result { + let mut headers = HeaderMap::new(); + headers.insert("X-ZT1-Auth", HeaderValue::from_str(&authtoken)?); + + Ok(zerotier_one_api::Client::new_with_client( + "http://127.0.0.1:9993", + reqwest::Client::builder() + .user_agent(version()) + .default_headers(headers) + .build()?, + )) } // get_listen_ips returns the IPs that the network is providing to the instance running zeronsd. @@ -186,29 +199,21 @@ pub async fn get_listen_ips( authtoken_path: &Path, network_id: &str, ) -> Result, anyhow::Error> { - let configuration = get_local_config(authtoken_path)?; - - match zerotier_one_api::apis::network_api::get_network(&configuration, network_id).await { - Err(error) => { - match error { - zerotier_one_api::apis::Error::ResponseError(_) => { - Err(anyhow!("Are you joined to {}?", network_id)) - } - zerotier_one_api::apis::Error::Reqwest(_) => Err(anyhow!( - "Can't connect to zerotier-one at {:}. Is it installed and running?", - configuration.base_path - )), - // TODO ERROR - error in response: status code 403 Forbidden (wrong authtoken) - other_error => Err(anyhow!(other_error)), - } - } + let client = local_client_from_file(authtoken_path)?; + + match client.get_network(network_id).await { + Err(error) => Err(anyhow!( + "Error: {}. Are you joined to {}?", + error, + network_id + )), Ok(listen) => { - if let Some(assigned) = listen.assigned_addresses { - if assigned.len() > 0 { - return Ok(assigned); - } + let assigned = listen.subtype_1.assigned_addresses.to_owned(); + if assigned.len() > 0 { + Ok(assigned) + } else { + Err(anyhow!("No listen IPs available on this network")) } - Err(anyhow!("No listen IPs available on this network")) } } } @@ -217,16 +222,15 @@ pub async fn get_listen_ips( pub async fn update_central_dns( domain_name: Name, ips: Vec, - config: Configuration, + client: zerotier_central_api::Client, network: String, ) -> Result<(), anyhow::Error> { - let mut zt_network = - zerotier_central_api::apis::network_api::get_network_by_id(&config, &network).await?; + let mut zt_network = client.get_network_by_id(&network).await?; let mut domain_name = domain_name; domain_name.set_fqdn(false); - let dns = Some(zerotier_central_api::models::Dns { + let dns = Some(zerotier_central_api::types::Dns { domain: Some(domain_name.to_string()), servers: Some(ips), }); @@ -234,8 +238,7 @@ pub async fn update_central_dns( if let Some(mut zt_network_config) = zt_network.config.to_owned() { zt_network_config.dns = dns; zt_network.config = Some(zt_network_config); - zerotier_central_api::apis::network_api::update_network(&config, &network, zt_network) - .await?; + client.update_network(&network, &zt_network).await?; } Ok(()) diff --git a/tests/service/context.rs b/tests/service/context.rs index b236af9..01fceb0 100644 --- a/tests/service/context.rs +++ b/tests/service/context.rs @@ -1,27 +1,23 @@ -use zeronsd::utils::central_config; -use zerotier_central_api::{ - apis::configuration::Configuration, - models::{Member, MemberConfig}, -}; +use zeronsd::utils::{central_client, local_client}; +use zerotier_central_api::types::{Member, MemberConfig}; use super::{ member::MemberUtil, - utils::{get_authtoken, get_identity, zerotier_config}, + utils::{get_authtoken, get_identity}, }; // TestContext provides all the stuff we need to talk to run tests smoothly #[derive(Clone)] pub struct TestContext { - pub member_config: Option>, + pub member_config: Option, pub identity: String, - pub zerotier: zerotier_one_api::apis::configuration::Configuration, - pub central: Configuration, + pub zerotier: zerotier_one_api::Client, + pub central: zerotier_central_api::Client, } impl TestContext { pub fn get_member(&mut self, network_id: String) -> Member { - let mut member = Member::new(); - member.set_defaults(network_id, self.identity.clone()); + let mut member = Member::new(network_id, self.identity.clone()); if self.member_config.is_some() { member.config = self.member_config.clone(); } @@ -31,13 +27,13 @@ impl TestContext { pub async fn default() -> Self { let authtoken = get_authtoken(None).expect("Could not read authtoken"); - let zerotier = zerotier_config(authtoken.clone()); + let zerotier = local_client(authtoken.clone()).unwrap(); let identity = get_identity(&zerotier) .await .expect("Could not retrieve identity from zerotier"); let token = std::env::var("TOKEN").expect("Please provide TOKEN in the environment"); - let central = central_config(token.clone()); + let central = central_client(token.clone()).unwrap(); Self { member_config: None, diff --git a/tests/service/member.rs b/tests/service/member.rs index 42073e0..4965c2e 100644 --- a/tests/service/member.rs +++ b/tests/service/member.rs @@ -1,24 +1,38 @@ -use zerotier_central_api::models::{Member, MemberConfig}; +use zerotier_central_api::types::{Member, MemberConfig}; // monkeypatches to Member pub trait MemberUtil { // set some member defaults for testing - fn set_defaults(&mut self, network_id: String, identity: String); + fn new(network_id: String, identity: String) -> Self; } // monkeypatches to MemberConfig pub trait MemberConfigUtil { fn set_ip_assignments(&mut self, ips: Vec<&str>); - fn set_defaults(&mut self, identity: String); + fn new(identity: String) -> Self; } impl MemberUtil for Member { - fn set_defaults(&mut self, network_id: String, identity: String) { - self.node_id = Some(identity.clone()); - self.network_id = Some(network_id); - let mut mc = MemberConfig::new(); - mc.set_defaults(identity); - self.config = Some(Box::new(mc)); + fn new(network_id: String, identity: String) -> Self { + let mut s = Self { + protocol_version: None, + supports_rules_engine: None, + physical_address: None, + name: None, + last_online: None, + id: None, + hidden: None, + description: None, + controller_id: None, + config: None, + clock: None, + client_version: None, + node_id: Some(identity.clone()), + network_id: Some(network_id), + }; + + s.config = Some(MemberConfig::new(identity)); + s } } @@ -27,22 +41,24 @@ impl MemberConfigUtil for MemberConfig { self.ip_assignments = Some(ips.into_iter().map(|s| s.to_string()).collect()) } - fn set_defaults(&mut self, identity: String) { - self.v_rev = None; - self.v_major = None; - self.v_proto = None; - self.v_minor = None; - self.tags = None; - self.revision = None; - self.no_auto_assign_ips = Some(false); - self.last_authorized_time = None; - self.last_deauthorized_time = None; - self.id = None; - self.creation_time = None; - self.capabilities = None; - self.ip_assignments = None; - self.authorized = Some(true); - self.active_bridge = None; - self.identity = Some(identity); + fn new(identity: String) -> Self { + Self { + v_rev: None, + v_major: None, + v_proto: None, + v_minor: None, + tags: Some(Vec::new()), + revision: None, + no_auto_assign_ips: Some(false), + last_authorized_time: None, + last_deauthorized_time: None, + id: None, + creation_time: None, + capabilities: Some(Vec::new()), + ip_assignments: Some(Vec::new()), + authorized: Some(true), + active_bridge: None, + identity: Some(identity), + } } } diff --git a/tests/service/mod.rs b/tests/service/mod.rs index ce7a0ac..1462ce8 100644 --- a/tests/service/mod.rs +++ b/tests/service/mod.rs @@ -192,8 +192,8 @@ impl Service { } } - if let Some(v6assign) = tn.network.config.clone().unwrap().v6_assign_mode { - if v6assign.rfc4193.unwrap_or(false) { + if let Some(v6assign) = tn.network.config.clone().unwrap().v_6_assign_mode { + if v6assign.rfc_4193.unwrap_or(false) { let cidr = tn.network.clone().rfc4193().unwrap(); if !authority_map.contains_key(&cidr) { let ptr_authority = RecordAuthority::new( @@ -219,7 +219,7 @@ impl Service { let ztauthority = ZTAuthority { network_id: tn.network.clone().id.unwrap(), - config: tn.central(), + client: tn.central(), hosts_file: format_hosts_file(hosts), reverse_authority_map: authority_map, update_interval, @@ -271,24 +271,28 @@ impl Service { } pub async fn change_name(&self, name: &'static str) { - let mut member = zerotier_central_api::apis::network_member_api::get_network_member( - &self.network().central(), - &self.network().network.clone().id.unwrap(), - &self.network().identity(), - ) - .await - .unwrap(); + let mut member = self + .network() + .central() + .get_network_member( + &self.network().network.clone().id.unwrap(), + &self.network().identity(), + ) + .await + .unwrap(); member.name = Some(name.to_string()); - zerotier_central_api::apis::network_member_api::update_network_member( - &self.network().central(), - &self.network().network.clone().id.unwrap(), - &self.network().identity(), - member, - ) - .await - .unwrap(); + let _ = &self + .network() + .central() + .update_network_member( + &self.network().network.clone().id.unwrap(), + &self.network().identity(), + &member.to_owned(), + ) + .await + .unwrap(); tokio::time::sleep(self.update_interval).await; // wait for it to update } diff --git a/tests/service/network.rs b/tests/service/network.rs index c3075b6..3d5d2fa 100644 --- a/tests/service/network.rs +++ b/tests/service/network.rs @@ -2,10 +2,8 @@ use std::time::Duration; use tracing::warn; use zeronsd::utils::{authtoken_path, get_listen_ips}; -use zerotier_central_api::{ - apis::configuration::Configuration, - models::{Member, MemberConfig, Network}, -}; +use zerotier_central_api::types::{Member, MemberConfig, Network}; +use zerotier_one_api::types::{NetworkSubtype0, NetworkSubtype1}; use super::{context::TestContext, member::MemberConfigUtil, utils::network_definition}; @@ -25,35 +23,29 @@ impl TestNetwork { tc: &mut TestContext, ips: Vec<&str>, ) -> Result { - let mut mc = MemberConfig::new(); - mc.set_defaults(tc.identity.clone()); + let mut mc = MemberConfig::new(tc.identity.clone()); mc.set_ip_assignments(ips); - tc.member_config = Some(Box::new(mc)); + tc.member_config = Some(mc); Self::new(network_def, tc).await } // constructor. pub async fn new(network_def: &str, tc: &mut TestContext) -> Result { - let network = zerotier_central_api::apis::network_api::new_network( - &tc.central, - serde_json::Value::Object(network_definition(network_def.to_string())?), - ) - .await - .unwrap(); + let network = tc + .central + .new_network(&network_definition(network_def.to_string())?) + .await + .unwrap(); let member = tc.get_member(network.clone().id.unwrap()); - zerotier_central_api::apis::network_member_api::update_network_member( - &tc.central, - &network.clone().id.unwrap(), - &tc.identity, - member.clone(), - ) - .await - .unwrap(); + tc.central + .update_network_member(&network.clone().id.unwrap(), &tc.identity, &member) + .await + .unwrap(); let s = Self { - network, + network: network.to_owned(), member, context: tc.clone(), }; @@ -65,13 +57,40 @@ impl TestNetwork { // join zerotier-one to the test network pub async fn join(&self) -> Result<(), anyhow::Error> { - let network = zerotier_one_api::models::Network::new(); - zerotier_one_api::apis::network_api::update_network( - &self.context.zerotier, - &self.network.id.clone().unwrap(), - network, - ) - .await?; + let network = zerotier_one_api::types::Network { + subtype_0: NetworkSubtype0 { + allow_dns: Some(true), + allow_global: Some(false), + allow_default: Some(false), + allow_managed: Some(true), + }, + subtype_1: NetworkSubtype1 { + status: None, + type_: None, + routes: Vec::new(), + port_error: None, + port_device_name: None, + netconf_revision: None, + name: None, + multicast_subscriptions: Vec::new(), + mtu: None, + mac: None, + id: None, + dns: None, + broadcast_enabled: None, + bridge: None, + assigned_addresses: Vec::new(), + allow_dns: Some(true), + allow_global: Some(false), + allow_default: Some(false), + allow_managed: Some(true), + }, + }; + + self.context + .zerotier + .update_network(&self.network.id.clone().unwrap(), &network) + .await?; let id = self.network.id.clone().unwrap(); let mut count = 0; @@ -89,18 +108,19 @@ impl TestNetwork { // leave the test network pub async fn leave(&self) -> Result<(), anyhow::Error> { - Ok(zerotier_one_api::apis::network_api::delete_network( - &self.context.zerotier, - &self.network.id.clone().unwrap(), - ) - .await?) + Ok(self + .context + .zerotier + .delete_network(&self.network.id.clone().unwrap()) + .await? + .to_owned()) } pub fn identity(&self) -> String { self.context.identity.clone() } - pub fn central(&self) -> Configuration { + pub fn central(&self) -> zerotier_central_api::Client { self.context.central.clone() } @@ -113,12 +133,10 @@ impl TestNetwork { tokio::runtime::Handle::current().block_on(async { self.leave().await.unwrap(); let central = self.central(); - zerotier_central_api::apis::network_api::delete_network( - ¢ral, - &self.network.id.clone().unwrap(), - ) - .await - .unwrap(); + central + .delete_network(&self.network.id.clone().unwrap()) + .await + .unwrap(); }) }) } diff --git a/tests/service/utils.rs b/tests/service/utils.rs index 0d955ff..bc43db7 100644 --- a/tests/service/utils.rs +++ b/tests/service/utils.rs @@ -1,4 +1,7 @@ -use std::path::{Path, PathBuf}; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; use zeronsd::utils::authtoken_path; @@ -22,8 +25,8 @@ pub fn randstring(len: u8) -> String { // extract a network definiton from testdata. templates in a new name. pub fn network_definition( name: String, -) -> Result, anyhow::Error> { - let mut res: serde_json::Map = serde_json::from_reader( +) -> Result, anyhow::Error> { + let mut res: HashMap = serde_json::from_reader( std::fs::File::open(format!("testdata/networks/{}.json", name))?, )?; @@ -41,12 +44,11 @@ pub fn network_definition( } // returns the public identity of this instance of zerotier -pub async fn get_identity( - configuration: &zerotier_one_api::apis::configuration::Configuration, -) -> Result { - let status = zerotier_one_api::apis::status_api::get_status(configuration).await?; +pub async fn get_identity(client: &zerotier_one_api::Client) -> Result { + let status = client.get_status().await?; Ok(status + .to_owned() .public_identity .unwrap() .splitn(3, ":") @@ -62,17 +64,6 @@ pub fn get_authtoken(or: Option<&str>) -> Result { ))?) } -// zerotier_config returns the openapi configuration required to talk to the local ztone instance -pub fn zerotier_config(authtoken: String) -> zerotier_one_api::apis::configuration::Configuration { - let mut zerotier = zerotier_one_api::apis::configuration::Configuration::default(); - zerotier.api_key = Some(zerotier_one_api::apis::configuration::ApiKey { - prefix: None, - key: authtoken.clone(), - }); - - zerotier -} - pub enum HostsType { Path(&'static str), Fixture(&'static str),