mirror of
https://codeberg.org/icewind/wifi-prometheus-exporter.git
synced 2026-06-03 08:34:25 +02:00
switch to configfile instead of env
This commit is contained in:
parent
881c06173b
commit
c4d579b033
9 changed files with 629 additions and 274 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -4,3 +4,5 @@
|
|||
key*
|
||||
.direnv
|
||||
result
|
||||
passwordfile
|
||||
config.toml
|
||||
514
Cargo.lock
generated
514
Cargo.lock
generated
|
|
@ -17,6 +17,54 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
|
|
@ -65,12 +113,6 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
|
|
@ -98,6 +140,52 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
|
|
@ -174,6 +262,12 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.11.0"
|
||||
|
|
@ -182,7 +276,7 @@ checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
|
|||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"spin 0.9.8",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -281,7 +375,7 @@ dependencies = [
|
|||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
|
|
@ -294,6 +388,12 @@ version = "0.12.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "headers"
|
||||
version = "0.3.9"
|
||||
|
|
@ -318,6 +418,12 @@ dependencies = [
|
|||
"http",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.4"
|
||||
|
|
@ -399,7 +505,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -417,15 +533,6 @@ version = "1.0.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
|
|
@ -542,7 +649,7 @@ dependencies = [
|
|||
"log",
|
||||
"memchr",
|
||||
"mime",
|
||||
"spin 0.9.8",
|
||||
"spin",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
|
|
@ -557,6 +664,16 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||
dependencies = [
|
||||
"overload",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
|
|
@ -578,9 +695,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.8.0"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
|
|
@ -600,6 +717,12 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
|
|
@ -648,7 +771,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -732,21 +855,6 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin 0.5.2",
|
||||
"untrusted 0.7.1",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.7"
|
||||
|
|
@ -756,23 +864,23 @@ dependencies = [
|
|||
"cc",
|
||||
"getrandom",
|
||||
"libc",
|
||||
"spin 0.9.8",
|
||||
"untrusted 0.9.0",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rumqttc"
|
||||
version = "0.23.0"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d8941c6791801b667d52bfe9ff4fc7c968d4f3f9ae8ae7abdaaa1c966feafc8"
|
||||
checksum = "e1568e15fab2d546f940ed3a21f48bbbd1c494c90c99c4481339364a497f94a9"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"flume",
|
||||
"futures-util",
|
||||
"log",
|
||||
"rustls-native-certs",
|
||||
"rustls-pemfile",
|
||||
"rustls-pemfile 2.1.0",
|
||||
"rustls-webpki",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
|
|
@ -787,24 +895,27 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
|||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.21.10"
|
||||
version = "0.22.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
|
||||
checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring 0.17.7",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki",
|
||||
"sct",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.6.3"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
|
||||
checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792"
|
||||
dependencies = [
|
||||
"openssl-probe",
|
||||
"rustls-pemfile",
|
||||
"rustls-pemfile 2.1.0",
|
||||
"rustls-pki-types",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
]
|
||||
|
|
@ -819,13 +930,30 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.101.7"
|
||||
name = "rustls-pemfile"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
|
||||
checksum = "3c333bb734fcdedcea57de1602543590f545f127dc8b533324318fd492c5c70b"
|
||||
dependencies = [
|
||||
"ring 0.17.7",
|
||||
"untrusted 0.9.0",
|
||||
"base64",
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.102.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -856,13 +984,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.7.0"
|
||||
name = "secretfile"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||
checksum = "746c54b939ab8d393b536765393c0bd7634fca94eed62321ec3e3559293f6c21"
|
||||
dependencies = [
|
||||
"ring 0.16.20",
|
||||
"untrusted 0.7.1",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -890,22 +1017,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.196"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.196"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -919,6 +1046,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"
|
||||
|
|
@ -942,6 +1078,15 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
|
|
@ -967,12 +1112,6 @@ dependencies = [
|
|||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
|
|
@ -995,15 +1134,16 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
|
|
@ -1018,22 +1158,32 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.56"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
|
||||
checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.56"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
|
||||
checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1076,16 +1226,17 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.24.1"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
|
||||
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
|
@ -1126,6 +1277,40 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[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"
|
||||
version = "0.22.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6"
|
||||
dependencies = [
|
||||
"indexmap 2.2.5",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
|
|
@ -1134,23 +1319,60 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
|||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.34"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
|
||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.26"
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f"
|
||||
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||
dependencies = [
|
||||
"nu-ansi-term",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1214,12 +1436,6 @@ dependencies = [
|
|||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
|
|
@ -1243,6 +1459,18 @@ version = "0.7.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
|
|
@ -1282,7 +1510,7 @@ dependencies = [
|
|||
"multer",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"rustls-pemfile",
|
||||
"rustls-pemfile 1.0.4",
|
||||
"scoped-tls",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
@ -1301,80 +1529,23 @@ version = "0.11.0+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wifi-prometheus-exporter"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"ctrlc",
|
||||
"dotenvy",
|
||||
"main_error",
|
||||
"rumqttc",
|
||||
"secretfile",
|
||||
"serde",
|
||||
"ssh2",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"warp",
|
||||
]
|
||||
|
||||
|
|
@ -1531,3 +1702,18 @@ name = "windows_x86_64_msvc"
|
|||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
|
||||
|
|
|
|||
12
Cargo.toml
12
Cargo.toml
|
|
@ -3,8 +3,7 @@ name = "wifi-prometheus-exporter"
|
|||
version = "0.1.0"
|
||||
authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
ssh2 = "0.9.4"
|
||||
|
|
@ -13,4 +12,11 @@ main_error = "0.1.2"
|
|||
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] }
|
||||
warp = "0.3.6"
|
||||
ctrlc = "3.4.2"
|
||||
rumqttc = "0.23.0"
|
||||
thiserror = "1.0.57"
|
||||
rumqttc = "0.24.0"
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
toml = "0.8.10"
|
||||
secretfile = { version = "0.1.0" }
|
||||
clap = { version = "=4.4.18", features = ["derive"] }
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = "0.3.18"
|
||||
13
config.sample.toml
Normal file
13
config.sample.toml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[mqtt]
|
||||
hostname = "mqtt.example.com"
|
||||
username = "wifi-exporter"
|
||||
password_file = "/path/to/password"
|
||||
|
||||
[exporter]
|
||||
port = 1234
|
||||
interfaces = ["eth1", "eth2"]
|
||||
|
||||
[ssh]
|
||||
host = "accesspoint.example.com:22"
|
||||
key_file = "/path/to/ssh/key"
|
||||
pubkey_file = "/path/to/ssh/key.pub"
|
||||
91
module.nix
91
module.nix
|
|
@ -6,23 +6,67 @@
|
|||
}:
|
||||
with lib; let
|
||||
cfg = config.services.wifi-prometheus-exporter;
|
||||
format = pkgs.formats.toml {};
|
||||
configFile = format.generate "wifi-prometheus-exporter-config.toml" {
|
||||
ssh = {
|
||||
inherit (cfg.ssh) address;
|
||||
key_file = "$CREDENTIALS_DIRECTORY/ssh_key";
|
||||
pubkey_file = "$CREDENTIALS_DIRECTORY/ssh_pub_key";
|
||||
};
|
||||
exporter = {
|
||||
inherit (cfg) interfaces port;
|
||||
};
|
||||
mqtt = {
|
||||
inherit (cfg.mqtt) hostname port username;
|
||||
password_file = "$CREDENTIALS_DIRECTORY/mqtt_password";
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
options.services.wifi-prometheus-exporter = {
|
||||
enable = mkEnableOption "WiFi prometheus exporter";
|
||||
|
||||
sshAddress = mkOption {
|
||||
type = types.str;
|
||||
description = "ssh address of the wifi access point";
|
||||
ssh = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
description = "ssh address of the access point";
|
||||
};
|
||||
keyFile = mkOption {
|
||||
type = types.str;
|
||||
description = "path to ssh key file";
|
||||
};
|
||||
pubKeyFile = mkOption {
|
||||
type = types.str;
|
||||
description = "path to ssh public key";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sshKeyFile = mkOption {
|
||||
type = types.str;
|
||||
description = "path containing the ssh private key";
|
||||
};
|
||||
|
||||
sshPubKeyFile = mkOption {
|
||||
type = types.str;
|
||||
description = "path containing the ssh public key";
|
||||
mqtt = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
hostname = mkOption {
|
||||
type = types.str;
|
||||
description = "mqtt server hostname";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
description = "mqtt server port";
|
||||
default = 1883;
|
||||
};
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
description = "mqtt username";
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
type = types.str;
|
||||
description = "path containing the mqtt password";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
interfaces = mkOption {
|
||||
|
|
@ -36,32 +80,33 @@ in {
|
|||
description = "port to listen to";
|
||||
};
|
||||
|
||||
mqttSecretFile = mkOption {
|
||||
type = types.str;
|
||||
description = "path containing MQTT_HOSTNAME, MQTT_USERNAME and MQTT_PASSWORD environment variables";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
defaultText = literalExpression "pkgs.dispenser";
|
||||
description = "package to use";
|
||||
};
|
||||
|
||||
log = mkOption {
|
||||
type = types.str;
|
||||
description = "log level";
|
||||
default = "info";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services."wifi-prometheus-exporter" = {
|
||||
wantedBy = ["multi-user.target"];
|
||||
environment = {
|
||||
PORT = toString cfg.port;
|
||||
ADDR = cfg.sshAddress;
|
||||
KEYFILE = cfg.sshKeyFile;
|
||||
PUBFILE = cfg.sshPubKeyFile;
|
||||
INTERFACES = concatStringsSep " " cfg.interfaces;
|
||||
RUST_LOG = cfg.log;
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.wifi-prometheus-exporter}/bin/wifi-prometheus-exporter";
|
||||
EnvironmentFile = cfg.mqttSecretFile;
|
||||
ExecStart = "${pkgs.wifi-prometheus-exporter}/bin/wifi-prometheus-exporter ${configFile}";
|
||||
LoadCredential = [
|
||||
"ssh_key:${cfg.ssh.keyFile}"
|
||||
"ssh_pub_key:${cfg.ssh.pubKeyFile}"
|
||||
"mqtt_password:${cfg.mqtt.passwordFile}"
|
||||
];
|
||||
Restart = "on-failure";
|
||||
DynamicUser = true;
|
||||
PrivateTmp = true;
|
||||
|
|
|
|||
68
src/config.rs
Normal file
68
src/config.rs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
use crate::error::Error;
|
||||
use secretfile::load;
|
||||
use serde::Deserialize;
|
||||
use std::fs::read_to_string;
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Config {
|
||||
pub mqtt: Option<MqttConfig>,
|
||||
pub ssh: SshConfig,
|
||||
pub exporter: ExporterConfig,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn load(path: &Path) -> Result<Self, Error> {
|
||||
let content = read_to_string(path).map_err(Error::ReadConfig)?;
|
||||
toml::from_str(&content).map_err(Error::ParseConfig)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct MqttConfig {
|
||||
pub hostname: String,
|
||||
#[serde(default = "default_mqtt_port")]
|
||||
pub port: u16,
|
||||
pub username: String,
|
||||
password_file: String,
|
||||
}
|
||||
|
||||
fn default_mqtt_port() -> u16 {
|
||||
1883
|
||||
}
|
||||
|
||||
impl MqttConfig {
|
||||
pub fn password(&self) -> Result<String, Error> {
|
||||
Ok(load(&self.password_file)?)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct SshConfig {
|
||||
pub address: String,
|
||||
pubkey_file: String,
|
||||
key_file: String,
|
||||
}
|
||||
|
||||
impl SshConfig {
|
||||
pub fn key(&self) -> Result<String, Error> {
|
||||
Ok(load(&self.key_file)?)
|
||||
}
|
||||
|
||||
pub fn pubkey(&self) -> Result<String, Error> {
|
||||
Ok(load(&self.pubkey_file)?)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ExporterConfig {
|
||||
#[serde(default = "default_address")]
|
||||
pub address: IpAddr,
|
||||
pub port: u16,
|
||||
pub interfaces: Vec<String>,
|
||||
}
|
||||
|
||||
fn default_address() -> IpAddr {
|
||||
Ipv4Addr::new(127, 0, 0, 1).into()
|
||||
}
|
||||
18
src/error.rs
Normal file
18
src/error.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
use secretfile::SecretError;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
#[error("failed to read config: {0}")]
|
||||
ReadConfig(std::io::Error),
|
||||
#[error("failed to parse config: {0}")]
|
||||
ParseConfig(toml::de::Error),
|
||||
#[error("failed to secret: {0:#}")]
|
||||
Secret(#[from] SecretError),
|
||||
#[error("failed to connect to ssh server: {0}")]
|
||||
SshConnect(std::io::Error),
|
||||
#[error("failed to start ssh session: {0}")]
|
||||
SshSession(ssh2::Error),
|
||||
#[error("failed to authenticate ssh session: {0}")]
|
||||
SshAuth(ssh2::Error),
|
||||
}
|
||||
61
src/listener.rs
Normal file
61
src/listener.rs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
use crate::error::Error;
|
||||
use ssh2::{ErrorCode, Session};
|
||||
use std::fmt::Debug;
|
||||
use std::io::Read;
|
||||
use std::net::{TcpStream, ToSocketAddrs};
|
||||
use tracing::{debug, info};
|
||||
|
||||
pub struct WifiLister {
|
||||
command: String,
|
||||
session: Session,
|
||||
}
|
||||
|
||||
impl WifiLister {
|
||||
pub fn new<A: ToSocketAddrs + Debug>(
|
||||
addr: A,
|
||||
key: &str,
|
||||
pubkey: &str,
|
||||
interfaces: &[String],
|
||||
) -> Result<Self, Error> {
|
||||
debug!(address = ?addr, "connecting to ssh");
|
||||
let tcp = TcpStream::connect(&addr).map_err(Error::SshConnect)?;
|
||||
let mut session = Session::new().map_err(Error::SshSession)?;
|
||||
session.set_tcp_stream(tcp);
|
||||
session.handshake().map_err(Error::SshSession)?;
|
||||
session
|
||||
.userauth_pubkey_memory("admin", Some(pubkey), key, None)
|
||||
.map_err(Error::SshAuth)?;
|
||||
|
||||
let command = if interfaces.is_empty() {
|
||||
"wl assoclist".to_string()
|
||||
} else {
|
||||
let commands: Vec<String> = interfaces
|
||||
.iter()
|
||||
.map(|interface| format!("wl -a {} assoclist", interface))
|
||||
.collect();
|
||||
commands.join(" && ")
|
||||
};
|
||||
|
||||
info!("ssh connected");
|
||||
|
||||
Ok(WifiLister { session, command })
|
||||
}
|
||||
|
||||
pub fn list_connected_devices(&self) -> Result<Vec<String>, ssh2::Error> {
|
||||
let mut channel = self.session.channel_session()?;
|
||||
debug!(command = self.command, "sending ssh command");
|
||||
channel.exec(&self.command)?;
|
||||
let mut s = String::new();
|
||||
channel.read_to_string(&mut s).map_err(|e| {
|
||||
ssh2::Error::new(
|
||||
ErrorCode::Session(e.raw_os_error().unwrap_or_default()),
|
||||
"error reading from ssh stream",
|
||||
)
|
||||
})?;
|
||||
channel.wait_close()?;
|
||||
|
||||
Ok(s.lines()
|
||||
.map(|s| s.trim_start_matches("assoclist ").to_string())
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
126
src/main.rs
126
src/main.rs
|
|
@ -1,109 +1,63 @@
|
|||
mod config;
|
||||
mod error;
|
||||
mod listener;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::listener::WifiLister;
|
||||
use clap::Parser;
|
||||
use main_error::MainError;
|
||||
use rumqttc::{AsyncClient, ClientError, MqttOptions, QoS};
|
||||
use ssh2::{ErrorCode, Session};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt::{Display, Formatter, Write};
|
||||
use std::io::prelude::*;
|
||||
use std::net::{TcpStream, ToSocketAddrs};
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use tokio::{spawn, time::sleep};
|
||||
use tracing::{error, info};
|
||||
use warp::Filter;
|
||||
|
||||
struct WifiLister {
|
||||
command: String,
|
||||
session: Session,
|
||||
}
|
||||
|
||||
impl WifiLister {
|
||||
pub fn new<A: ToSocketAddrs, Priv: AsRef<OsStr>, Pub: AsRef<OsStr>>(
|
||||
addr: A,
|
||||
keyfile: Priv,
|
||||
pubkey: Pub,
|
||||
interfaces: &[&str],
|
||||
) -> Result<Self, MainError> {
|
||||
let tcp = TcpStream::connect(addr)?;
|
||||
let mut session = Session::new()?;
|
||||
session.set_tcp_stream(tcp);
|
||||
session.handshake()?;
|
||||
let keyfile = Path::new(keyfile.as_ref());
|
||||
let pubkey = Path::new(pubkey.as_ref());
|
||||
session.userauth_pubkey_file("admin", Some(pubkey), keyfile, None)?;
|
||||
|
||||
let command = if interfaces.is_empty() {
|
||||
"wl assoclist".to_string()
|
||||
} else {
|
||||
let commands: Vec<String> = interfaces
|
||||
.iter()
|
||||
.map(|interface| format!("wl -a {} assoclist", interface))
|
||||
.collect();
|
||||
commands.join(" && ")
|
||||
};
|
||||
|
||||
Ok(WifiLister { session, command })
|
||||
}
|
||||
|
||||
pub fn list_connected_devices(&self) -> Result<Vec<String>, ssh2::Error> {
|
||||
let mut channel = self.session.channel_session()?;
|
||||
channel.exec(&self.command)?;
|
||||
let mut s = String::new();
|
||||
channel.read_to_string(&mut s).map_err(|e| {
|
||||
ssh2::Error::new(
|
||||
ErrorCode::Session(e.raw_os_error().unwrap_or_default()),
|
||||
"error reading from ssh stream",
|
||||
)
|
||||
})?;
|
||||
channel.wait_close()?;
|
||||
|
||||
Ok(s.lines()
|
||||
.map(|s| s.trim_start_matches("assoclist ").to_string())
|
||||
.collect())
|
||||
}
|
||||
#[derive(Parser, Debug)]
|
||||
struct Args {
|
||||
/// Path to config file
|
||||
config: PathBuf,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), MainError> {
|
||||
let mut env: HashMap<String, String> = dotenvy::vars().collect();
|
||||
let addr = env.remove("ADDR").ok_or("No ADDR set")?;
|
||||
let keyfile = env.remove("KEYFILE").ok_or("No KEYFILE set")?;
|
||||
let pubfile = env.remove("PUBFILE").ok_or("No PUBFILE set")?;
|
||||
let port = env
|
||||
.get("PORT")
|
||||
.and_then(|s| u16::from_str(s).ok())
|
||||
.unwrap_or(80);
|
||||
let mqtt_host = env.remove("MQTT_HOSTNAME");
|
||||
let mqtt_user = env.remove("MQTT_USERNAME");
|
||||
let mqtt_pass = env.remove("MQTT_PASSWORD");
|
||||
let interfaces: Vec<&str> = env
|
||||
.get("INTERFACES")
|
||||
.map(|interfaces| interfaces.split(' ').collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let mqtt_options = match (mqtt_host, mqtt_user, mqtt_pass) {
|
||||
(Some(host), Some(user), Some(pass)) => {
|
||||
let mut mqtt_options = MqttOptions::new("wifi-exporter", host, 1883);
|
||||
tracing_subscriber::fmt::init();
|
||||
let args = Args::parse();
|
||||
let config = Config::load(&args.config)?;
|
||||
let mqtt_options = match &config.mqtt {
|
||||
Some(mqtt_config) => {
|
||||
let mut mqtt_options =
|
||||
MqttOptions::new("wifi-exporter", &mqtt_config.hostname, mqtt_config.port);
|
||||
mqtt_options.set_keep_alive(Duration::from_secs(5));
|
||||
mqtt_options.set_credentials(user, pass);
|
||||
println!("mqtt enabled");
|
||||
mqtt_options.set_credentials(&mqtt_config.username, mqtt_config.password()?);
|
||||
info!("mqtt enabled");
|
||||
Some(mqtt_options)
|
||||
}
|
||||
_ => {
|
||||
println!("mqtt disabled");
|
||||
info!("mqtt disabled");
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
if interfaces.is_empty() {
|
||||
println!("Listening on default interface");
|
||||
if config.exporter.interfaces.is_empty() {
|
||||
info!("Listening on default interface");
|
||||
} else {
|
||||
println!("Listening on interfaces: {}", interfaces.join(", "));
|
||||
info!(
|
||||
"Listening on interfaces: {}",
|
||||
config.exporter.interfaces.join(", ")
|
||||
);
|
||||
}
|
||||
|
||||
let connected: Arc<Mutex<DeviceStates>> = Default::default();
|
||||
let wifi_listener = WifiLister::new(addr, &keyfile, &pubfile, &interfaces)?;
|
||||
let wifi_listener = WifiLister::new(
|
||||
&config.ssh.address,
|
||||
&config.ssh.key()?,
|
||||
&config.ssh.pubkey()?,
|
||||
&config.exporter.interfaces,
|
||||
)?;
|
||||
|
||||
spawn(listener(wifi_listener, connected.clone(), mqtt_options));
|
||||
|
||||
|
|
@ -114,7 +68,9 @@ async fn main() -> Result<(), MainError> {
|
|||
})
|
||||
.expect("Error setting Ctrl-C handler");
|
||||
|
||||
warp::serve(metrics).run(([0, 0, 0, 0], port)).await;
|
||||
warp::serve(metrics)
|
||||
.run((config.exporter.address, config.exporter.port))
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -207,15 +163,15 @@ async fn listener(
|
|||
Ok(devices) => {
|
||||
let updates = connected.lock().unwrap().update(devices);
|
||||
for (mac, update) in updates {
|
||||
println!("{} {}", mac, update);
|
||||
info!(mac, %update, "change detected");
|
||||
if let Some(client) = client.as_mut() {
|
||||
if let Err(e) = send_update(client, mac, update).await {
|
||||
eprintln!("Error while sending mqtt update: {:?}", e);
|
||||
error!(e = ?e, "Error while sending mqtt update: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => eprintln!("Error while listing devices {:#?}", e),
|
||||
Err(e) => error!(e = ?e, "Error while listing devices {e}"),
|
||||
}
|
||||
sleep(Duration::from_secs(5)).await;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue