From 1dcfbb40cac4fb5923d5be7ae33fd0bc2047566c Mon Sep 17 00:00:00 2001 From: toast Date: Sat, 14 Dec 2024 08:27:13 +1100 Subject: [PATCH] Refactor and add new iLO command --- Cargo.lock | 281 ++++++++---------------------------- Cargo.toml | 11 +- cmds/Cargo.toml | 3 +- cmds/src/dispatch/ilo.rs | 219 +++++++++++++++++----------- cmds/src/dispatch/status.rs | 2 +- 5 files changed, 198 insertions(+), 318 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c490bfa..2c118d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -108,11 +108,10 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bb8" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89aabfae550a5c44b43ab941844ffcd2e993cb6900b342debf59e9ea74acdb8" +checksum = "212d8b8e1a22743d9241575c6ba822cf9c8fef34771c86ab7e477a4fbfd254e5" dependencies = [ - "async-trait", "futures-util", "parking_lot", "tokio", @@ -120,11 +119,10 @@ dependencies = [ [[package]] name = "bb8-redis" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1781f22daa0ae97d934fdf04a5c66646f154a164c4bdc157ec8d3c11166c05cc" +checksum = "8416aa3639520757fd0ed659c8c12f7cd9f0ed638fa0cdd52a13d3b19946df2a" dependencies = [ - "async-trait", "bb8", "redis", ] @@ -217,9 +215,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.2" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" +checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" dependencies = [ "shlex", ] @@ -232,9 +230,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -449,18 +447,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "enum-as-inner" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.90", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -488,15 +474,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "feed-rs" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d57df0b823b3055c667ddde499736e0d8d7d486b269454eebd96a0fdd59ce051" +checksum = "850b6e1f3d306978db1b04d053f756eaa23268f3c5dcc7c85db45a4b3aabdd29" dependencies = [ "chrono", "mediatype", @@ -718,23 +704,6 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi", -] - [[package]] name = "http" version = "0.2.12" @@ -871,7 +840,7 @@ dependencies = [ "http 1.2.0", "hyper 1.5.1", "hyper-util", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-pki-types", "tokio", "tokio-rustls 0.26.1", @@ -1060,16 +1029,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "idna" version = "1.0.3" @@ -1101,18 +1060,6 @@ dependencies = [ "hashbrown 0.15.2", ] -[[package]] -name = "ipconfig" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" -dependencies = [ - "socket2", - "widestring", - "windows-sys 0.48.0", - "winreg", -] - [[package]] name = "ipnet" version = "2.10.1" @@ -1136,9 +1083,9 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ "once_cell", "wasm-bindgen", @@ -1146,7 +1093,7 @@ dependencies = [ [[package]] name = "kon" -version = "0.6.0" +version = "0.6.1" dependencies = [ "kon_cmds", "kon_libs", @@ -1158,10 +1105,11 @@ dependencies = [ [[package]] name = "kon_cmds" -version = "0.1.0" +version = "0.1.1" dependencies = [ "kon_libs", "kon_tokens", + "lazy_static", "poise", "regex", "reqwest 0.12.9", @@ -1214,16 +1162,16 @@ dependencies = [ ] [[package]] -name = "libc" -version = "0.2.167" +name = "lazy_static" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] -name = "linked-hash-map" -version = "0.5.6" +name = "libc" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "linux-raw-sys" @@ -1253,21 +1201,6 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - [[package]] name = "mediatype" version = "0.19.18" @@ -1574,12 +1507,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quick-xml" version = "0.37.1" @@ -1673,9 +1600,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -1796,16 +1723,6 @@ dependencies = [ "windows-registry", ] -[[package]] -name = "resolv-conf" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" -dependencies = [ - "hostname", - "quick-error", -] - [[package]] name = "ring" version = "0.17.8" @@ -1829,15 +1746,15 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.41" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1868,9 +1785,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "once_cell", "rustls-pki-types", @@ -1899,9 +1816,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" [[package]] name = "rustls-webpki" @@ -1999,18 +1916,18 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] @@ -2026,9 +1943,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -2381,32 +2298,16 @@ dependencies = [ "zerovec", ] -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokenservice-client" -version = "0.4.1" +version = "0.4.2" source = "sparse+https://git.toast-server.net/api/packages/toast/cargo/" -checksum = "cf11991da505b67c1a8201aa2d4746eefe338d34ce8d985c93474672d900c5cd" +checksum = "6c6f3da21601ea1072262024198c099bea1688714f13b13c36cc7f4a88c6b203" dependencies = [ "reqwest 0.12.9", "serde", "serde_json", "tokio", - "trust-dns-resolver", ] [[package]] @@ -2475,7 +2376,7 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ - "rustls 0.23.19", + "rustls 0.23.20", "tokio", ] @@ -2592,52 +2493,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" -[[package]] -name = "trust-dns-proto" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.4.0", - "ipnet", - "once_cell", - "rand", - "smallvec", - "thiserror", - "tinyvec", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" -dependencies = [ - "cfg-if", - "futures-util", - "ipconfig", - "lru-cache", - "once_cell", - "parking_lot", - "rand", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "tracing", - "trust-dns-proto", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -2712,27 +2567,12 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" -[[package]] -name = "unicode-bidi" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" - [[package]] name = "unicode-ident" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - [[package]] name = "untrusted" version = "0.9.0" @@ -2757,7 +2597,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", - "idna 1.0.3", + "idna", "percent-encoding", "serde", ] @@ -2828,9 +2668,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -2839,13 +2679,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn 2.0.90", @@ -2854,9 +2693,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.47" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", @@ -2867,9 +2706,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2877,9 +2716,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", @@ -2890,9 +2729,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wasm-streams" @@ -2909,9 +2748,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -2932,12 +2771,6 @@ dependencies = [ "rustls-pki-types", ] -[[package]] -name = "widestring" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" - [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 8674d45..94a33ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,23 +1,24 @@ [package] name = "kon" -version = "0.6.0" +version = "0.6.1" edition = "2024" [workspace] members = ["cmds", "libs", "repo", "tasks", "tokens"] [workspace.dependencies] -bb8 = "0.8.6" -bb8-redis = "0.17.0" +bb8 = "0.9.0" +bb8-redis = "0.18.0" cargo_toml = "0.21.0" -feed-rs = "2.2.0" +feed-rs = "2.3.0" once_cell = "1.20.2" poise = "0.6.1" regex = "1.11.1" reqwest = { version = "0.12.9", features = ["json", "native-tls-vendored"] } -serde = "1.0.215" +serde = "1.0.216" serde_json = "1.0.133" sysinfo = "0.33.0" +lazy_static = "1.5.0" tokio = { version = "1.42.0", features = ["macros", "signal", "rt-multi-thread"] } uptime_lib = "0.3.1" kon_libs = { path = "libs" } diff --git a/cmds/Cargo.toml b/cmds/Cargo.toml index 42e9a62..4af5c6d 100644 --- a/cmds/Cargo.toml +++ b/cmds/Cargo.toml @@ -1,11 +1,12 @@ [package] name = "kon_cmds" -version = "0.1.0" +version = "0.1.1" edition = "2024" [dependencies] kon_libs = { workspace = true } kon_tokens = { workspace = true } +lazy_static = { workspace = true } poise = { workspace = true } regex = { workspace = true } reqwest = { workspace = true } diff --git a/cmds/src/dispatch/ilo.rs b/cmds/src/dispatch/ilo.rs index fcb40c2..da39603 100644 --- a/cmds/src/dispatch/ilo.rs +++ b/cmds/src/dispatch/ilo.rs @@ -4,6 +4,7 @@ use { KonResult }, kon_tokens::token_path, + lazy_static::lazy_static, poise::{ CreateReply, serenity_prelude::{ @@ -12,15 +13,23 @@ use { } }, reqwest::{ + Client, ClientBuilder, Error as ReqError }, serde::{ Deserialize, - Serialize + Serialize, + de::DeserializeOwned } }; +const ILO_HOSTNAME: &str = "POMNI"; + +lazy_static! { + static ref REQWEST_CLIENT: Client = ClientBuilder::new().danger_accept_invalid_certs(true).build().unwrap(); +} + #[derive(Serialize, Deserialize)] struct Chassis { #[serde(rename = "Fans")] @@ -131,13 +140,29 @@ struct Event { status: Status } -const ILO_HOSTNAME: &str = "POMNI"; +#[derive(Serialize, Deserialize)] +/// HP calls this Integrated Management Log +struct Iml { + #[serde(rename = "Items")] + items: Vec +} + +#[derive(Serialize, Deserialize)] +struct ImlEntry { + #[serde(rename = "Created")] + created: String, + #[serde(rename = "Message")] + message: String, + #[serde(rename = "Severity")] + severity: String +} enum RedfishEndpoint { Thermal, Power, System, - EventService + EventService, + LogServices } impl RedfishEndpoint { @@ -146,55 +171,76 @@ impl RedfishEndpoint { RedfishEndpoint::Thermal => "Chassis/1/Thermal".to_string(), RedfishEndpoint::Power => "Chassis/1/Power".to_string(), RedfishEndpoint::System => "Systems/1".to_string(), - RedfishEndpoint::EventService => "EventService".to_string() + RedfishEndpoint::EventService => "EventService".to_string(), + RedfishEndpoint::LogServices => "Systems/1/LogServices/IML/Entries".to_string() } } } -async fn ilo_data(endpoint: RedfishEndpoint) -> Result, ReqError> { - let client = ClientBuilder::new().danger_accept_invalid_certs(true).build().unwrap(); - let res = client - .get(format!("https://{}/redfish/v1/{}", token_path().await.ilo_ip, endpoint.url())) - .basic_auth(token_path().await.ilo_user, Some(token_path().await.ilo_pw)) - .send() - .await - .unwrap(); +async fn ilo_data(endpoint: RedfishEndpoint) -> Result { + let client = &*REQWEST_CLIENT; + let token = token_path().await; + let redfish_url = format!("https://{}/redfish/v1/{}", token.ilo_ip, endpoint.url()); - match endpoint { - RedfishEndpoint::Thermal => { - let body: Chassis = res.json().await.unwrap(); - Ok(Box::new(body)) - }, - RedfishEndpoint::Power => { - let body: Power = res.json().await.unwrap(); - Ok(Box::new(body)) - }, - RedfishEndpoint::System => { - let body: System = res.json().await.unwrap(); - Ok(Box::new(body)) - }, - RedfishEndpoint::EventService => { - let body: Event = res.json().await.unwrap(); - Ok(Box::new(body)) - } - } + let res = client.get(redfish_url).basic_auth(token.ilo_user, Some(token.ilo_pw)).send().await?; + + res.json::().await } -/// Retrieve data from the HP iLO4 interface +fn embed_builder( + title: &str, + description: Option, + fields: Option> +) -> CreateEmbed { + let mut embed = CreateEmbed::new() + .color(BINARY_PROPERTIES.embed_color) + .timestamp(Timestamp::now()) + .title(format!("{ILO_HOSTNAME} - {title}")); + + if let Some(d) = description { + embed = embed.description(d); + } + + if let Some(f) = fields { + for (name, value, inline) in f { + embed = embed.field(name, value, inline); + } + } + + embed +} + +fn fmt_dt(input: &str) -> Option { + let parts: Vec<&str> = input.split('T').collect(); + if parts.len() != 2 { + return None; + } + + let date_parts: Vec<&str> = parts[0].split('-').collect(); + if date_parts.len() != 3 { + return None; + } + + let date = format!("{}/{}/{}", date_parts[1], date_parts[2], date_parts[0]); + let time = parts[1].trim_end_matches('Z'); + + Some(format!("{date} {time}")) +} + +/// Retrieve data from the HP iLO interface #[poise::command( slash_command, install_context = "Guild|User", interaction_context = "Guild|BotDm|PrivateChannel", - subcommands("temperature", "power", "system") + subcommands("temperature", "power", "system", "logs") )] pub async fn ilo(_: super::PoiseCtx<'_>) -> KonResult<()> { Ok(()) } /// Retrieve the server's temperature data #[poise::command(slash_command)] -pub async fn temperature(ctx: super::PoiseCtx<'_>) -> KonResult<()> { +async fn temperature(ctx: super::PoiseCtx<'_>) -> KonResult<()> { ctx.defer().await?; - let ilo = ilo_data(RedfishEndpoint::Thermal).await.unwrap(); - let data = ilo.downcast_ref::().unwrap(); + let data: Chassis = ilo_data(RedfishEndpoint::Thermal).await?; let mut tempdata = String::new(); let mut fandata = String::new(); @@ -212,7 +258,7 @@ pub async fn temperature(ctx: super::PoiseCtx<'_>) -> KonResult<()> { _ => "Unknown Sensor" }; - tempdata.push_str(&format!("**{}:** `{}°C`\n", name, temp.reading_celsius)); + tempdata.push_str(&format!("**{name}:** `{}°C`\n", temp.reading_celsius)); } for fan in &data.fans { if fan.current_reading == 0 { @@ -223,15 +269,11 @@ pub async fn temperature(ctx: super::PoiseCtx<'_>) -> KonResult<()> { } ctx - .send( - CreateReply::default().embed( - CreateEmbed::new() - .color(BINARY_PROPERTIES.embed_color) - .timestamp(Timestamp::now()) - .title(format!("{} - Temperatures", ILO_HOSTNAME)) - .fields(vec![("Temperatures", tempdata, false), ("Fans", fandata, false)]) - ) - ) + .send(CreateReply::default().embed(embed_builder( + "Temperatures", + None, + Some(vec![("Temperatures".to_string(), tempdata, false), ("Fans".to_string(), fandata, false)]) + ))) .await?; Ok(()) @@ -239,10 +281,9 @@ pub async fn temperature(ctx: super::PoiseCtx<'_>) -> KonResult<()> { /// Retrieve the server's power data #[poise::command(slash_command)] -pub async fn power(ctx: super::PoiseCtx<'_>) -> KonResult<()> { +async fn power(ctx: super::PoiseCtx<'_>) -> KonResult<()> { ctx.defer().await?; - let ilo = ilo_data(RedfishEndpoint::Power).await.unwrap(); - let data = ilo.downcast_ref::().unwrap(); + let data: Power = ilo_data(RedfishEndpoint::Power).await?; let mut powerdata = String::new(); @@ -253,15 +294,7 @@ pub async fn power(ctx: super::PoiseCtx<'_>) -> KonResult<()> { powerdata.push_str(&format!("**Min Consumed:** `{}w`", &data.power_metrics.min_consumed_watts)); ctx - .send( - CreateReply::default().embed( - CreateEmbed::new() - .color(BINARY_PROPERTIES.embed_color) - .timestamp(Timestamp::now()) - .title(format!("{} - Power", ILO_HOSTNAME)) - .description(powerdata) - ) - ) + .send(CreateReply::default().embed(embed_builder("Power", Some(powerdata), None))) .await?; Ok(()) @@ -269,55 +302,67 @@ pub async fn power(ctx: super::PoiseCtx<'_>) -> KonResult<()> { /// Retrieve the server's system data #[poise::command(slash_command)] -pub async fn system(ctx: super::PoiseCtx<'_>) -> KonResult<()> { +async fn system(ctx: super::PoiseCtx<'_>) -> KonResult<()> { ctx.defer().await?; let (ilo_sys, ilo_event) = tokio::join!(ilo_data(RedfishEndpoint::System), ilo_data(RedfishEndpoint::EventService)); - let ilo_sys = ilo_sys.unwrap(); - let ilo_event = ilo_event.unwrap(); - - let system_data = ilo_sys.downcast_ref::().unwrap(); - let event_data = ilo_event.downcast_ref::().unwrap(); + let ilo_sys: System = ilo_sys.unwrap(); + let ilo_event: Event = ilo_event.unwrap(); let mut data = String::new(); - let post_state = match system_data.oem.hp.post_state.as_str() { + let post_state = match ilo_sys.oem.hp.post_state.as_str() { "FinishedPost" => "Finished POST", "InPost" => "In POST (Booting)", "PowerOff" => "Powered off", _ => "Unknown State" }; - if system_data.oem.hp.post_state != "FinishedPost" { - println!("iLO:PostState = {}", system_data.oem.hp.post_state); + if ilo_sys.oem.hp.post_state != "FinishedPost" { + println!("iLO:PostState = {}", ilo_sys.oem.hp.post_state); } data.push_str(&format!( "**Health:** `{}`\n", - event_data.status.health.as_ref().unwrap_or(&"Unknown".to_string()) + ilo_event.status.health.as_ref().unwrap_or(&"Unknown".to_string()) )); - data.push_str(&format!("**POST:** `{}`\n", post_state)); - data.push_str(&format!("**Power:** `{}`\n", &system_data.power_state)); - data.push_str(&format!("**Model:** `{}`", &system_data.model)); + data.push_str(&format!("**POST:** `{post_state}`\n")); + data.push_str(&format!("**Power:** `{}`\n", &ilo_sys.power_state)); + data.push_str(&format!("**Model:** `{}`", &ilo_sys.model)); ctx - .send( - CreateReply::default().embed( - CreateEmbed::new() - .color(BINARY_PROPERTIES.embed_color) - .timestamp(Timestamp::now()) - .title(format!("{} - System", ILO_HOSTNAME)) - .description(data) - .fields(vec![ - ( - format!("CPU ({}x)", system_data.processor_summary.count), - system_data.processor_summary.cpu.trim().to_string(), - true - ), - ("RAM".to_string(), format!("{} GB", system_data.memory.total_system_memory), true), - ]) - ) - ) + .send(CreateReply::default().embed(embed_builder( + "System", + Some(data), + Some(vec![ + ( + format!("CPU ({}x)", ilo_sys.processor_summary.count), + ilo_sys.processor_summary.cpu.trim().to_string(), + true + ), + ("RAM".to_string(), format!("{} GB", ilo_sys.memory.total_system_memory), true), + ]) + ))) + .await?; + + Ok(()) +} + +/// Retrieve the server's IML data +#[poise::command(slash_command)] +async fn logs(ctx: super::PoiseCtx<'_>) -> KonResult<()> { + ctx.defer().await?; + + let data: Iml = ilo_data(RedfishEndpoint::LogServices).await?; + let mut log_entries = String::new(); + + for entry in data.items.iter().rev().take(5) { + let dt = fmt_dt(&entry.created).unwrap_or_else(|| "Unknown".to_string()); + log_entries.push_str(&format!("**[{}:{dt}]:** {}\n", entry.severity, entry.message)); + } + + ctx + .send(CreateReply::default().embed(embed_builder("IML", Some(log_entries), None))) .await?; Ok(()) diff --git a/cmds/src/dispatch/status.rs b/cmds/src/dispatch/status.rs index 5bbc906..b7a301c 100644 --- a/cmds/src/dispatch/status.rs +++ b/cmds/src/dispatch/status.rs @@ -83,7 +83,7 @@ pub async fn status(_: super::PoiseCtx<'_>) -> KonResult<()> { Ok(()) } /// Retrieve the server statuses from Wargaming #[poise::command(slash_command)] -pub async fn wg(ctx: super::PoiseCtx<'_>) -> KonResult<()> { +async fn wg(ctx: super::PoiseCtx<'_>) -> KonResult<()> { let pms_asia = token_path().await.wg_pms; let pms_eu = pms_asia.replace("asia", "eu"); let embed = CreateEmbed::new().color(BINARY_PROPERTIES.embed_color);