Add threaded mt fetching, initial db tuff
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
/target
|
||||
config.toml
|
||||
/.env
|
||||
|
||||
324
Cargo.lock
generated
324
Cargo.lock
generated
@@ -116,6 +116,12 @@ version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.12.0"
|
||||
@@ -178,7 +184,7 @@ dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -193,6 +199,41 @@ version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt"
|
||||
version = "1.1.0"
|
||||
@@ -213,7 +254,7 @@ dependencies = [
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -225,6 +266,79 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel"
|
||||
version = "2.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "715377c6e464cb44bb89bd8487584240516c8d5052bc645d6babc50bb8be46c3"
|
||||
dependencies = [
|
||||
"bitflags 2.13.0",
|
||||
"byteorder",
|
||||
"diesel_derives",
|
||||
"downcast-rs",
|
||||
"itoa",
|
||||
"pq-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel_derives"
|
||||
version = "2.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1817b7f4279b947fc4cafddec12b0e5f8727141706561ce3ac94a60bddd1cf5"
|
||||
dependencies = [
|
||||
"diesel_table_macro_syntax",
|
||||
"dsl_auto_type",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel_migrations"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d0f4a98124ba6d4ca75da535f65984badec16a003b6e2f94a01e31a79490b8"
|
||||
dependencies = [
|
||||
"diesel",
|
||||
"migrations_internals",
|
||||
"migrations_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel_table_macro_syntax"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe2444076b48641147115697648dc743c2c00b61adade0f01ce67133c7babe8c"
|
||||
dependencies = [
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc"
|
||||
|
||||
[[package]]
|
||||
name = "dsl_auto_type"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd122633e4bef06db27737f21d3738fb89c8f6d5360d6d9d7635dda142a7757e"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"either",
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d"
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "2.0.0"
|
||||
@@ -282,6 +396,94 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 3.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.17"
|
||||
@@ -321,6 +523,12 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.14.0"
|
||||
@@ -365,7 +573,7 @@ checksum = "e165e897f662d428f3cd3828a919dbe067c2d42bb1031eede74ef9d27ecdedd2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -401,6 +609,27 @@ version = "2.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
|
||||
|
||||
[[package]]
|
||||
name = "migrations_internals"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36c791ecdf977c99f45f23280405d7723727470f6689a5e6dbf513ac547ae10d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"toml 0.9.12+spec-1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "migrations_macros"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36fc5ac76be324cfd2d3f2cf0fdf5d5d3c4f14ed8aaebadb09e304ba42282703"
|
||||
dependencies = [
|
||||
"migrations_internals",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mikrotik-proto"
|
||||
version = "0.2.0"
|
||||
@@ -516,6 +745,12 @@ version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.13.1"
|
||||
@@ -531,6 +766,17 @@ dependencies = [
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pq-sys"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "574ddd6a267294433f140b02a726b0640c43cf7c6f717084684aaa3b285aba61"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr2"
|
||||
version = "2.0.0"
|
||||
@@ -550,7 +796,7 @@ dependencies = [
|
||||
"proc-macro-error-attr2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -695,7 +941,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -736,6 +982,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
@@ -775,6 +1027,17 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tabled"
|
||||
version = "0.21.0"
|
||||
@@ -798,7 +1061,7 @@ dependencies = [
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -828,7 +1091,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -856,7 +1119,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -869,6 +1132,19 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.9.12+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_spanned",
|
||||
"toml_datetime 0.7.5+spec-1.1.0",
|
||||
"toml_parser",
|
||||
"winnow 0.7.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "1.1.2+spec-1.1.0"
|
||||
@@ -878,10 +1154,19 @@ dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_datetime 1.1.1+spec-1.1.0",
|
||||
"toml_parser",
|
||||
"toml_writer",
|
||||
"winnow",
|
||||
"winnow 1.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.7.5+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -899,7 +1184,7 @@ version = "1.1.2+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
|
||||
dependencies = [
|
||||
"winnow",
|
||||
"winnow 1.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -941,6 +1226,12 @@ dependencies = [
|
||||
"getrandom 0.4.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "vte"
|
||||
version = "0.14.1"
|
||||
@@ -958,7 +1249,10 @@ dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"clap",
|
||||
"diesel",
|
||||
"diesel_migrations",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"mikrotik-rs",
|
||||
@@ -967,7 +1261,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"tabled",
|
||||
"tokio",
|
||||
"toml",
|
||||
"toml 1.1.2+spec-1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1064,6 +1358,12 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "1.0.3"
|
||||
|
||||
@@ -11,7 +11,10 @@ authors = [
|
||||
anyhow = "1.0.103"
|
||||
camino = { version = "1.2.4", features = ["serde1"] }
|
||||
clap = { version = "4.6.1", features = ["derive"] }
|
||||
diesel = { version = "2.3.12", features = ["postgres"] }
|
||||
diesel_migrations = "2.3.2"
|
||||
env_logger = "0.11.11"
|
||||
futures = "0.3.34"
|
||||
lazy_static = "1.5.0"
|
||||
log = "0.4.33"
|
||||
mikrotik-rs = { version = "0.8.0", features = ["tokio-tls"] }
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
db_url="postgres://my_database_user:password@localhost/my_database"
|
||||
|
||||
[default_logins]
|
||||
username="monitor"
|
||||
password="HewoWorld"
|
||||
|
||||
9
diesel.toml
Normal file
9
diesel.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
# For documentation on how to configure this file,
|
||||
# see https://diesel.rs/guides/configuring-diesel-cli
|
||||
|
||||
[print_schema]
|
||||
file = "src/schema.rs"
|
||||
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
|
||||
|
||||
[migrations_directory]
|
||||
dir = "migrations"
|
||||
0
migrations/.keep
Normal file
0
migrations/.keep
Normal file
@@ -27,11 +27,11 @@ pub struct CliArgs {
|
||||
pub config_file: camino::Utf8PathBuf,
|
||||
|
||||
/// Output more information in logs
|
||||
#[arg(long = "verbose", short = 'v', conflicts_with="quiet")]
|
||||
#[arg(long = "verbose", short = 'v', conflicts_with = "quiet")]
|
||||
pub verbose: bool,
|
||||
|
||||
/// Output more information in logs
|
||||
#[arg(long = "quiet", short = 'q', conflicts_with="verbose")]
|
||||
#[arg(long = "quiet", short = 'q', conflicts_with = "verbose")]
|
||||
pub quiet: bool,
|
||||
|
||||
#[command(subcommand)]
|
||||
@@ -92,6 +92,7 @@ pub enum CliCommand {
|
||||
#[command(subcommand)]
|
||||
command: CliDeviceCommand,
|
||||
},
|
||||
BesWifi,
|
||||
|
||||
#[default]
|
||||
#[clap(skip)]
|
||||
@@ -104,20 +105,20 @@ pub enum CliDeviceCommand {
|
||||
List,
|
||||
Add {
|
||||
/// Device name
|
||||
#[arg(short='n', long)]
|
||||
#[arg(short = 'n', long)]
|
||||
name: String,
|
||||
/// Device address, ipv4 or ipv6
|
||||
#[arg(short='H', long)]
|
||||
#[arg(short = 'H', long)]
|
||||
host: IpAddr,
|
||||
/// Device Port (skip for default)
|
||||
#[arg(short='p', long)]
|
||||
#[arg(short = 'p', long)]
|
||||
port: Option<u16>,
|
||||
/// Username (skip for default)
|
||||
#[arg(short='U', long)]
|
||||
#[arg(short = 'U', long)]
|
||||
username: Option<String>,
|
||||
/// Password (skip for default)
|
||||
#[arg(short='P', long)]
|
||||
password: Option<String>
|
||||
#[arg(short = 'P', long)]
|
||||
password: Option<String>,
|
||||
},
|
||||
Remove {
|
||||
/// Name of the device
|
||||
|
||||
@@ -24,6 +24,8 @@ pub struct Config {
|
||||
#[serde(rename = "host")]
|
||||
pub hosts: Vec<ConfigHost>,
|
||||
|
||||
pub db_url: String,
|
||||
|
||||
#[serde(skip)]
|
||||
pub cli: CliArgs,
|
||||
}
|
||||
@@ -42,6 +44,14 @@ pub struct ConfigHost {
|
||||
pub port: Option<u16>,
|
||||
pub username: Option<String>,
|
||||
pub password: Option<String>,
|
||||
#[serde(default = "ConfigHost::default_tags")]
|
||||
pub tags: Vec<String>,
|
||||
}
|
||||
|
||||
impl ConfigHost {
|
||||
fn default_tags() -> Vec<String> {
|
||||
Vec::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Tabled)]
|
||||
@@ -119,6 +129,7 @@ impl Default for ConfigHost {
|
||||
port: None,
|
||||
username: None,
|
||||
password: None,
|
||||
tags: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
src/db/mod.rs
Normal file
17
src/db/mod.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
use diesel::pg::PgConnection;
|
||||
use diesel::prelude::*;
|
||||
use diesel_migrations::{EmbeddedMigrations, MigrationHarness, embed_migrations};
|
||||
|
||||
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
|
||||
|
||||
pub fn init_db(database_url: &str) -> PgConnection {
|
||||
let mut connection = PgConnection::establish(database_url)
|
||||
.unwrap_or_else(|e| panic!("Error connecting to database: {e}"));
|
||||
|
||||
connection
|
||||
.run_pending_migrations(MIGRATIONS)
|
||||
.unwrap_or_else(|e| panic!("Error running migrations: {e}"));
|
||||
|
||||
connection
|
||||
}
|
||||
|
||||
84
src/main.rs
84
src/main.rs
@@ -25,6 +25,7 @@ use crate::config::{
|
||||
};
|
||||
|
||||
mod config;
|
||||
mod db;
|
||||
mod mt_commander;
|
||||
|
||||
#[tokio::main]
|
||||
@@ -49,6 +50,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
mt_commander::MtCommander::init(cfg.clone())?;
|
||||
|
||||
match &cfg.cli.command {
|
||||
CliCommand::BesWifi => {}
|
||||
CliCommand::Run {
|
||||
all,
|
||||
devices,
|
||||
@@ -79,9 +81,22 @@ async fn main() -> anyhow::Result<()> {
|
||||
|
||||
let table = tabled::Table::new(devices);
|
||||
println!("{}", table);
|
||||
},
|
||||
CliDeviceCommand::Add { name, host, port, username, password } => {
|
||||
cfg.hosts.push(ConfigHost { name, ip: host, port, username, password });
|
||||
}
|
||||
CliDeviceCommand::Add {
|
||||
name,
|
||||
host,
|
||||
port,
|
||||
username,
|
||||
password,
|
||||
} => {
|
||||
cfg.hosts.push(ConfigHost {
|
||||
name,
|
||||
ip: host,
|
||||
port,
|
||||
username,
|
||||
password,
|
||||
tags: Vec::new(),
|
||||
});
|
||||
cfg.save()?;
|
||||
}
|
||||
CliDeviceCommand::Remove { name } => {
|
||||
@@ -131,7 +146,7 @@ fn get_devices(devices: &Vec<String>, all: bool, cfg: &Config) -> anyhow::Result
|
||||
|
||||
fn print_output(
|
||||
cfg: &Config,
|
||||
output: &HashMap<ConfigHost, Vec<HashMap<String, Option<String>>>>,
|
||||
output: &HashMap<ConfigHost, anyhow::Result<Vec<HashMap<String, Option<String>>>>>,
|
||||
format: &OutputFormat,
|
||||
) -> anyhow::Result<()> {
|
||||
match *format {
|
||||
@@ -140,10 +155,13 @@ fn print_output(
|
||||
let mut wanted_cols = Vec::new();
|
||||
let mut top_row_added = false;
|
||||
for (host, out) in output {
|
||||
match out {
|
||||
Ok(out) => {
|
||||
for out in out {
|
||||
let out: BTreeMap<_, _> = out.clone().into_iter().collect();
|
||||
if !top_row_added {
|
||||
let mut row = vec!["Name".to_string(), "IP".to_string()];
|
||||
let mut row =
|
||||
vec!["Name".to_string(), "IP".to_string(), "Error".to_string()];
|
||||
let mut data_cols = out.keys().cloned().collect::<Vec<String>>();
|
||||
wanted_cols = data_cols.clone();
|
||||
row.append(&mut data_cols);
|
||||
@@ -151,7 +169,11 @@ fn print_output(
|
||||
table.push(row);
|
||||
top_row_added = true;
|
||||
}
|
||||
let mut row = vec![host.name.clone(), host.ip.clone().to_string()];
|
||||
let mut row = vec![
|
||||
host.name.clone(),
|
||||
host.ip.clone().to_string(),
|
||||
String::from("None"),
|
||||
];
|
||||
|
||||
for wanted_col in &wanted_cols {
|
||||
let mut val = String::new();
|
||||
@@ -165,6 +187,20 @@ fn print_output(
|
||||
table.push(row);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
let mut row = vec![
|
||||
host.name.clone(),
|
||||
host.ip.clone().to_string(),
|
||||
e.to_string(),
|
||||
];
|
||||
|
||||
for wanted_col in &wanted_cols {
|
||||
row.push(String::new());
|
||||
}
|
||||
table.push(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut table_escaped = Vec::new();
|
||||
for line in table {
|
||||
let mut row = Vec::new();
|
||||
@@ -188,10 +224,16 @@ fn print_output(
|
||||
let mut wanted_cols = Vec::new();
|
||||
let mut top_row_added = false;
|
||||
for (host, out) in output {
|
||||
match out {
|
||||
Ok(out) => {
|
||||
for out in out {
|
||||
let out: BTreeMap<_, _> = out.clone().into_iter().collect();
|
||||
if !top_row_added {
|
||||
let mut row = vec!["Name".to_string(), "IP".to_string()];
|
||||
let mut row = vec![
|
||||
"Name".to_string(),
|
||||
"IP".to_string(),
|
||||
String::from("Error"),
|
||||
];
|
||||
let mut data_cols = out.keys().cloned().collect::<Vec<String>>();
|
||||
wanted_cols = data_cols.clone();
|
||||
row.append(&mut data_cols);
|
||||
@@ -199,7 +241,11 @@ fn print_output(
|
||||
builder.push_record(row);
|
||||
top_row_added = true;
|
||||
}
|
||||
let mut row = vec![host.name.clone(), host.ip.clone().to_string()];
|
||||
let mut row = vec![
|
||||
host.name.clone(),
|
||||
host.ip.clone().to_string(),
|
||||
String::from("None"),
|
||||
];
|
||||
for wanted_col in &wanted_cols {
|
||||
let mut val = String::new();
|
||||
if let Some(v) = out.get(wanted_col) {
|
||||
@@ -212,6 +258,15 @@ fn print_output(
|
||||
builder.push_record(row);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
let mut row = vec![
|
||||
host.name.clone(),
|
||||
host.ip.clone().to_string(),
|
||||
e.to_string(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
let table = builder.build();
|
||||
println!("{}", table);
|
||||
}
|
||||
@@ -219,12 +274,25 @@ fn print_output(
|
||||
let mut res = Vec::new();
|
||||
|
||||
for (host, out) in output {
|
||||
match out {
|
||||
Ok(out) => {
|
||||
let val = json!({
|
||||
"host": host.display_tabled(&cfg),
|
||||
"e": "None",
|
||||
"response": out,
|
||||
});
|
||||
res.push(val);
|
||||
}
|
||||
Err(e) => {
|
||||
let val = json!({
|
||||
"host": host.display_tabled(&cfg),
|
||||
"error": e.to_string(),
|
||||
"response": [],
|
||||
});
|
||||
res.push(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
let out_text = serde_json::to_string_pretty(&res)?;
|
||||
println!("{out_text}");
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ use std::{
|
||||
};
|
||||
|
||||
use anyhow::bail;
|
||||
use futures::future::join_all;
|
||||
use mikrotik_rs::{Command, CommandBuilder, Event, MikrotikDevice};
|
||||
use regex::Regex;
|
||||
|
||||
@@ -25,6 +26,7 @@ lazy_static::lazy_static! {
|
||||
}
|
||||
|
||||
pub struct MtCommander;
|
||||
#[derive(Debug, Clone)]
|
||||
struct MtCommanderInternal {
|
||||
cfg: Option<Config>,
|
||||
}
|
||||
@@ -39,19 +41,26 @@ impl MtCommander {
|
||||
pub async fn run_command_on_hosts(
|
||||
hosts: &[ConfigHost],
|
||||
command: &str,
|
||||
) -> anyhow::Result<HashMap<ConfigHost, Vec<HashMap<String, Option<String>>>>> {
|
||||
let mut res_map = HashMap::new();
|
||||
for host in hosts {
|
||||
let res = Self::run_command_on_host(host, command).await?;
|
||||
res_map.insert(host.clone(), res);
|
||||
}
|
||||
) -> anyhow::Result<HashMap<ConfigHost, anyhow::Result<Vec<HashMap<String, Option<String>>>>>>
|
||||
{
|
||||
let results = join_all(hosts.iter().map(|host| async move {
|
||||
let res = Self::run_command_on_host(host, command).await;
|
||||
(host.clone(), res)
|
||||
}))
|
||||
.await;
|
||||
|
||||
let res_map: HashMap<_, _> = results.into_iter().collect();
|
||||
Ok(res_map)
|
||||
}
|
||||
pub async fn run_command_on_host(
|
||||
host: &ConfigHost,
|
||||
command: &str,
|
||||
) -> anyhow::Result<Vec<HashMap<String, Option<String>>>> {
|
||||
let mtc = MTC.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?;
|
||||
let mtc = {
|
||||
MTC.lock()
|
||||
.map_err(|e| anyhow::anyhow!(e.to_string()))?
|
||||
.clone()
|
||||
};
|
||||
mtc.run_command(host, &command).await
|
||||
}
|
||||
|
||||
@@ -114,18 +123,16 @@ impl MtCommanderInternal {
|
||||
cmd: &str,
|
||||
) -> anyhow::Result<Vec<HashMap<String, Option<String>>>> {
|
||||
let addr = format!("{}:{}", &host.ip, host.port(&self.cfg()));
|
||||
let dev_res = MikrotikDevice::connect(
|
||||
&addr,
|
||||
&host.username(self.cfg()),
|
||||
Some(&host.password(self.cfg())),
|
||||
)
|
||||
let dev_res = MikrotikDevice::builder(&addr)
|
||||
.credentials(&host.username(self.cfg()), Some(&host.password(self.cfg())))
|
||||
.connect()
|
||||
.await;
|
||||
|
||||
let dev = match dev_res {
|
||||
Ok(dev) => {
|
||||
log::info!("({addr}) Connected successfully!");
|
||||
dev
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to connect to {addr}: {e}");
|
||||
bail!(e);
|
||||
@@ -142,7 +149,12 @@ impl MtCommanderInternal {
|
||||
match event {
|
||||
Event::Reply { response, tag: _ } => {
|
||||
log::debug!("({}) {:?}", &host.ip, response.attributes);
|
||||
size += response.attributes.values().flatten().map(|v| v.len()).sum::<usize>();
|
||||
size += response
|
||||
.attributes
|
||||
.values()
|
||||
.flatten()
|
||||
.map(|v| v.len())
|
||||
.sum::<usize>();
|
||||
res.push(response.attributes);
|
||||
}
|
||||
Event::Done { .. } => {
|
||||
|
||||
Reference in New Issue
Block a user