From ceaa25f0405583701068454443ce5a076857769b Mon Sep 17 00:00:00 2001 From: Ben Newton Date: Thu, 17 Sep 2026 17:43:39 +0100 Subject: [PATCH 1/9] fix(deps): Updating the deps (#11) * fix(deps): Updating the deps Bumping the deps Fixing tests and pre-existing bug * fix(clippy): Fixes to changes in crates --------- Co-authored-by: Ben Newton --- Cargo.lock | 1194 +++++++++++++++++---------------- cli/Cargo.toml | 20 +- common/Cargo.toml | 38 +- common/src/database/sqlite.rs | 31 +- server/Cargo.toml | 74 +- server/src/drivers/redis.rs | 4 +- server/src/kerberos.rs | 14 +- 7 files changed, 714 insertions(+), 661 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b37fa2b4..d294060e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,38 +2,20 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] @@ -103,6 +85,12 @@ dependencies = [ "rustversion", ] +[[package]] +name = "arcstr" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03918c3dbd7701a85c6b9887732e2921175f26c350b4563841d0958c21d57e6d" + [[package]] name = "asn1-rs" version = "0.7.2" @@ -115,7 +103,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror 2.0.19", + "thiserror 2.0.20", "time", ] @@ -128,7 +116,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.119", - "synstructure", + "synstructure 0.13.2", ] [[package]] @@ -142,15 +130,26 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-trait" -version = "0.1.91" +version = "0.1.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] @@ -167,9 +166,9 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.17.3" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bdb5da18dac48ca2cc7cd4a98e533e8635a58e2361d13a1a4ee3888e0d72f1" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" dependencies = [ "aws-lc-sys", "zeroize", @@ -177,9 +176,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.43.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43103168cc76fe62678a375e722fc9cb3a0146159ac5828bc4f0dfd755c2224c" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" dependencies = [ "cc", "cmake", @@ -194,13 +193,19 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "bindgen" version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "cexpr", "clang-sys", "itertools 0.13.0", @@ -214,24 +219,6 @@ dependencies = [ "syn 2.0.119", ] -[[package]] -name = "bindgen" -version = "0.72.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" -dependencies = [ - "bitflags 2.13.1", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex 1.3.0", - "syn 2.0.119", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -240,9 +227,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.1" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" dependencies = [ "serde_core", ] @@ -256,15 +243,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.12.1" @@ -300,9 +278,9 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cc" -version = "1.4.0" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9" +checksum = "a3eb0f42d6c360dc3f8a821f6bf2fdea7f72bfd36b3076eb0e6d1e9e0752fff4" dependencies = [ "find-msvc-tools", "jobserver", @@ -321,18 +299,18 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" [[package]] name = "chacha20" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", - "cpufeatures 0.3.0", + "cpufeatures", "rand_core 0.10.1", ] @@ -349,9 +327,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.8.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a" dependencies = [ "glob", "libc", @@ -360,18 +338,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.4" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.6.2" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" dependencies = [ "anstream", "anstyle", @@ -381,9 +359,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" [[package]] name = "cli" @@ -426,9 +404,9 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "combine" -version = "4.6.7" +version = "4.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" dependencies = [ "bytes", "futures-core", @@ -444,7 +422,7 @@ version = "0.3.0" dependencies = [ "anyhow", "async-trait", - "bitflags 2.13.1", + "bitflags 2.13.2", "chrono", "deadpool-postgres", "deadpool-sqlite", @@ -498,47 +476,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "core_detect" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] +checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48" [[package]] name = "cpufeatures" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] [[package]] name = "crossbeam-epoch" -version = "0.9.20" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] name = "crypto-common" @@ -560,44 +525,29 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" [[package]] name = "deadpool" -version = "0.9.5" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e" +checksum = "3e98a7e119cd347f4201e1159b19831029e203e2d8b790547708e8157b4acf1e" dependencies = [ - "async-trait", "deadpool-runtime", - "num_cpus", - "retain_mut", - "tokio", -] - -[[package]] -name = "deadpool" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0be2b1d1d6ec8d846f05e137292d0b89133caf95ef33695424c09568bdd39b1b" -dependencies = [ - "deadpool-runtime", - "lazy_static", - "num_cpus", "tokio", ] [[package]] name = "deadpool-postgres" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d697d376cbfa018c23eb4caab1fd1883dd9c906a8c034e8d9a3cb06a7e0bef9" +checksum = "65a536565624b97fc19f758cd01b15d12908d3344425066efc8162236fbd3749" dependencies = [ "async-trait", - "deadpool 0.12.3", - "getrandom 0.2.17", + "deadpool", + "getrandom 0.4.3", "tokio", "tokio-postgres", "tracing", @@ -605,29 +555,29 @@ dependencies = [ [[package]] name = "deadpool-runtime" -version = "0.1.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" +checksum = "2657f61fb1dd8bf37a8d51093cc7cee4e77125b22f7753f49b289f831bec2bae" dependencies = [ "tokio", ] [[package]] name = "deadpool-sqlite" -version = "0.5.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e026821eaacbce25ff0d54405e4421d71656fcae3e4a9323461280fcda6dbc7d" +checksum = "008b02743f8fad68dc9bb2851c0a4a1d63190d8e3885c5dea20f8a0a2a6bff9a" dependencies = [ - "deadpool 0.9.5", + "deadpool", "deadpool-sync", "rusqlite", ] [[package]] name = "deadpool-sync" -version = "0.1.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524bc3df0d57e98ecd022e21ba31166c2625e7d3e5bcc4510efaeeab4abcab04" +checksum = "e385cc95d3d582c328b36d1ff90feac061102b001894b555e6b465a2e0eaabbf" dependencies = [ "deadpool-runtime", ] @@ -660,7 +610,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" dependencies = [ - "thiserror 2.0.19", + "thiserror 2.0.20", ] [[package]] @@ -672,7 +622,7 @@ dependencies = [ "asn1-rs", "displaydoc", "nom", - "num-bigint", + "num-bigint 0.4.8", "num-traits", "rusticata-macros", ] @@ -711,37 +661,27 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7" -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "crypto-common 0.1.7", -] - [[package]] name = "digest" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ - "block-buffer 0.12.1", + "block-buffer", "const-oid", - "crypto-common 0.2.2", + "crypto-common", "ctutils", ] [[package]] name = "displaydoc" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.6", ] [[package]] @@ -764,17 +704,23 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "either" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "encoding_rs" -version = "0.8.35" +version = "0.8.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +checksum = "7b5ef0006ac9ab233c38522f5ae99cae3625151de8f706cacee1cba4b8e2832a" dependencies = [ "cfg-if", + "core_detect", + "multiversion", + "multiversion_no_op", + "rustversion", + "scopeguard", + "simdutf8", ] [[package]] @@ -816,12 +762,49 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "event-listener" +version = "5.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" +dependencies = [ + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "evmap" +version = "11.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8874945f036109c72242964c1174cf99434e30cfa45bf45fedc983f50046f8" +dependencies = [ + "hashbag", + "left-right", + "smallvec", +] + [[package]] name = "fallible-iterator" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + [[package]] name = "fallible-streaming-iterator" version = "0.1.9" @@ -836,9 +819,9 @@ checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" [[package]] name = "fnv" @@ -848,9 +831,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.5" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "foreign-types" @@ -884,9 +867,9 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "futures" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -899,9 +882,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -909,15 +892,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -926,38 +909,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-macro" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.6", ] [[package]] name = "futures-sink" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -971,13 +954,18 @@ dependencies = [ ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "generator" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" dependencies = [ - "typenum", - "version_check", + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows-link", + "windows-result", ] [[package]] @@ -987,10 +975,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi 0.11.1+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] @@ -1012,9 +998,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", + "wasm-bindgen", ] [[package]] @@ -1025,9 +1013,9 @@ checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "h2" -version = "0.4.15" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" +checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16" dependencies = [ "atomic-waker", "bytes", @@ -1043,20 +1031,16 @@ dependencies = [ ] [[package]] -name = "hashbrown" -version = "0.14.5" +name = "hashbag" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] +checksum = "7040a10f52cba493ddb09926e15d10a9d8a28043708a405931fe4c6f19fac064" [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "foldhash", ] @@ -1066,14 +1050,17 @@ name = "hashbrown" version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash", +] [[package]] name = "hashlink" -version = "0.8.4" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "a596f1b20ed2cc5ecac41a164aaebc7258057060f06c0cf7a2ba3991ee7990fb" dependencies = [ - "hashbrown 0.14.5", + "hashbrown 0.17.1", ] [[package]] @@ -1082,12 +1069,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - [[package]] name = "hex" version = "0.4.3" @@ -1100,14 +1081,14 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest 0.11.3", + "digest", ] [[package]] name = "http" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa", @@ -1125,9 +1106,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", @@ -1156,18 +1137,18 @@ checksum = "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15" [[package]] name = "hybrid-array" -version = "0.4.13" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" dependencies = [ "typenum", ] [[package]] name = "hyper" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" +checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" dependencies = [ "atomic-waker", "bytes", @@ -1207,7 +1188,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-util", @@ -1218,7 +1199,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.5", + "socket2", "system-configuration", "tokio", "tower-layer", @@ -1253,9 +1234,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" dependencies = [ "displaydoc", "potential_utf", @@ -1267,9 +1248,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" dependencies = [ "displaydoc", "litemap", @@ -1280,9 +1261,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1294,16 +1275,17 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" [[package]] name = "icu_properties" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" dependencies = [ + "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", @@ -1314,15 +1296,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -1356,9 +1338,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.14.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", "hashbrown 0.17.1", @@ -1366,9 +1348,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.12.0" +version = "2.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" +checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0" [[package]] name = "is_terminal_polyfill" @@ -1387,9 +1369,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" dependencies = [ "either", ] @@ -1402,9 +1384,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.34" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e184d09547b80eb7e20d141ba2fb1fbac843ca53f4cf1b31210adc4c1adc6e16" +checksum = "0ab1baf72f08796de0260609515130699b890ac25f30e610ad894bc5856cafdb" dependencies = [ "defmt", "jiff-core", @@ -1417,18 +1399,19 @@ dependencies = [ [[package]] name = "jiff-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" dependencies = [ "defmt", + "log", ] [[package]] name = "jiff-static" -version = "0.2.34" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "323da076b7a6faf914dc677cb05a4b907742ff7375c8322c9e7f5061e5e0e9de" +checksum = "378268a1116ad67ae6228701118ac9f491d78fda38a40a1f1a9e1348de6f7212" dependencies = [ "jiff-core", "proc-macro2", @@ -1448,9 +1431,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.103" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" dependencies = [ "cfg-if", "futures-util", @@ -1463,14 +1446,25 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "left-right" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bc015ded5d9b3054dbbdb63332cdd6ee42352ccef19e911e25117490e2f48ee" +dependencies = [ + "crossbeam-utils", + "loom", + "slab", +] + [[package]] name = "leon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a865ffec5587961f5afc6d365bccb304f4feaa1928f4fe94c91c9d210d7310" +checksum = "f503290456b1983913e7608c1bfdc7f48927e1d719e1ac525bfbf49f0ec8a307" dependencies = [ "miette", - "thiserror 2.0.19", + "thiserror 2.0.20", ] [[package]] @@ -1481,13 +1475,12 @@ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libgssapi" -version = "0.7.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8663f3a3a93dd394b669dd9b213b457c5e0d2bc5a1b13a0950bd733c6fb6e37" +checksum = "e440a6151f5ef06571612e4121709aed90cfc0c40f8161f9090c71656758086d" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "bytes", - "lazy_static", "libgssapi-sys", ] @@ -1497,7 +1490,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5103ac4557eacd36ff678b654b943f8966d3db9688fbd180a0b4c5464759ce17" dependencies = [ - "bindgen 0.71.1", + "bindgen", "pkg-config", ] @@ -1513,18 +1506,18 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.18" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" +checksum = "6480ccc157a1389bb2e4891b24751b0f798ba640d22386f23143fbcc89da195a" dependencies = [ "libc", ] [[package]] name = "libsqlite3-sys" -version = "0.25.2" +version = "0.38.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" +checksum = "f1d20bef17f513b9b3004532233187769cd072d790971f4e4da0e346eb6401e8" dependencies = [ "cc", "pkg-config", @@ -1551,9 +1544,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" [[package]] name = "lock_api" @@ -1566,9 +1559,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" dependencies = [ "serde_core", ] @@ -1601,13 +1594,26 @@ dependencies = [ "serde-value", "serde_json", "serde_yaml", - "thiserror 2.0.19", + "thiserror 2.0.20", "thread-id", "typemap-ors", "unicode-segmentation", "winapi", ] +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + [[package]] name = "lz4-sys" version = "1.11.1+lz4-1.10.0" @@ -1618,6 +1624,15 @@ dependencies = [ "libc", ] +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + [[package]] name = "md-5" version = "0.11.0" @@ -1625,7 +1640,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" dependencies = [ "cfg-if", - "digest 0.11.3", + "digest", ] [[package]] @@ -1646,11 +1661,12 @@ dependencies = [ [[package]] name = "metrics-exporter-prometheus" -version = "0.16.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7399781913e5393588a8d8c6a2867bf85fb38eaf2502fdce465aad2dc6f034" +checksum = "1db0d8f1fc9e62caebd0319e11eaec5822b0186c171568f0480b46a0137f9108" dependencies = [ - "base64", + "base64 0.22.1", + "evmap", "http-body-util", "hyper", "hyper-rustls", @@ -1660,24 +1676,26 @@ dependencies = [ "metrics", "metrics-util", "quanta", - "thiserror 1.0.69", + "rustls", + "thiserror 2.0.20", "tokio", "tracing", ] [[package]] name = "metrics-util" -version = "0.19.1" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8496cc523d1f94c1385dd8f0f0c2c480b2b8aeccb5b7e4485ad6365523ae376" +checksum = "96f8722f8562635f92f8ed992f26df0532266eb03d5202607c20c0d7e9745e13" dependencies = [ "crossbeam-epoch", "crossbeam-utils", - "hashbrown 0.15.5", + "hashbrown 0.16.1", "metrics", "quanta", "rand 0.9.5", "rand_xoshiro", + "rapidhash", "sketches-ddsketch", ] @@ -1717,9 +1735,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" +checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8" dependencies = [ "libc", "wasi 0.11.1+wasi-snapshot-preview1", @@ -1732,6 +1750,33 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb517913cfcfb9eeda59f36020269075a152701a01606c612f547e4890be399" +[[package]] +name = "multiversion" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ca4bea16ffc3f443cf7d866912118196bfef4c6a1556ca00f9f9b00bb43f7c" +dependencies = [ + "multiversion-macros", +] + +[[package]] +name = "multiversion-macros" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d416831a7317ef4b08bee00b69cbbb9c8763da7959a7026244d6266869f9c83" +dependencies = [ + "proc-macro2", + "quote", + "rustversion", + "syn 3.0.6", +] + +[[package]] +name = "multiversion_no_op" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d" + [[package]] name = "nom" version = "7.1.3" @@ -1742,6 +1787,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "num-bigint" version = "0.4.8" @@ -1752,6 +1806,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-conv" version = "0.2.2" @@ -1760,9 +1824,9 @@ checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] @@ -1776,16 +1840,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "num_enum" version = "0.7.6" @@ -1814,7 +1868,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", ] [[package]] @@ -1853,7 +1907,7 @@ version = "0.10.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "cfg-if", "foreign-types", "libc", @@ -1909,6 +1963,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.5" @@ -1965,21 +2025,21 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkg-config" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] name = "portable-atomic" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" dependencies = [ "portable-atomic", ] @@ -2002,10 +2062,10 @@ version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08808e3c483c46e999108051c78334f473d5adb59d78bb80a1268c7e6aa6c514" dependencies = [ - "base64", + "base64 0.22.1", "byteorder", "bytes", - "fallible-iterator", + "fallible-iterator 0.2.0", "hmac", "md-5", "memchr", @@ -2021,15 +2081,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "851ca9db4932932d69f3ea811b1abe63087a0f740a47692619dd40d4899b68be" dependencies = [ "bytes", - "fallible-iterator", + "fallible-iterator 0.2.0", "postgres-protocol", ] [[package]] name = "potential_utf" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ "zerovec", ] @@ -2074,7 +2134,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.13+spec-1.1.0", + "toml_edit", ] [[package]] @@ -2103,9 +2163,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.41.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" +checksum = "41b1177fdf999d2321d3fb46ff47159d9c1fb9ad66a4879f8c50a0b504615e9b" dependencies = [ "memchr", ] @@ -2201,14 +2261,14 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", ] [[package]] name = "rdkafka" -version = "0.37.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b52c81ac3cac39c9639b95c20452076e74b8d9a71bc6fc4d83407af2ea6fff" +checksum = "d7956f9ac12b5712e50372d9749a3102f4810a8d42481c5eae3748d36d585bcf" dependencies = [ "futures-channel", "futures-util", @@ -2240,23 +2300,27 @@ dependencies = [ [[package]] name = "redis" -version = "0.25.5" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e46922bd01fefcfdcf58d9cd626da082bb2cde27211920dacfde6b2ecf9a35b" +checksum = "2acbc41a996f7652b2ddd9dfd98cc4ff602cfd742ae35382f07f608405ab50ed" dependencies = [ - "async-trait", + "arcstr", + "async-lock", "bytes", + "cfg-if", "combine", "futures-util", "itoa", + "num-bigint 0.5.1", "percent-encoding", "pin-project-lite", "ryu", "sha1_smol", - "socket2 0.5.10", + "socket2", "tokio", "tokio-util", "url", + "xxhash-rust", ] [[package]] @@ -2265,7 +2329,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", ] [[package]] @@ -2282,9 +2346,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.16" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -2297,12 +2361,6 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" -[[package]] -name = "retain_mut" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" - [[package]] name = "ring" version = "0.17.14" @@ -2319,22 +2377,36 @@ dependencies = [ [[package]] name = "roxmltree" -version = "0.20.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" +checksum = "f1964b10c76125c36f8afe190065a4bf9a87bf324842c05701330bba9f1cacbb" +dependencies = [ + "memchr", +] + +[[package]] +name = "rsqlite-vfs" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51c9ae4df8a7fba42103df5c621fa3c37eccf3a3c650879e90fc48b11cc192c" +dependencies = [ + "hashbrown 0.16.1", + "thiserror 2.0.20", +] [[package]] name = "rusqlite" -version = "0.28.0" +version = "0.40.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" +checksum = "23f2a97da3e3873c73cb2a2e71b35c40ff95e0b1eefa8d72d8499a6928c3b5b3" dependencies = [ - "bitflags 1.3.2", - "fallible-iterator", + "bitflags 2.13.2", + "fallible-iterator 0.3.0", "fallible-streaming-iterator", "hashlink", "libsqlite3-sys", "smallvec", + "sqlite-wasm-rs", ] [[package]] @@ -2363,11 +2435,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "errno", "libc", "linux-raw-sys", @@ -2376,9 +2448,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.42" +version = "0.23.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138" +checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" dependencies = [ "aws-lc-rs", "log", @@ -2412,9 +2484,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.13" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ "aws-lc-rs", "ring", @@ -2455,6 +2527,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -2467,7 +2545,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -2527,7 +2605,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] @@ -2545,11 +2623,11 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.9" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -2567,9 +2645,9 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.5.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "699f4197115b8a7e7ff19c9a315a4bd6fffec26cc4626ef45ecaea389e081c6d" +checksum = "a6df5ed973ad8d834e09f824f9e9f449af6b9a3745f78dec7cc752770bd3bf11" dependencies = [ "futures-executor", "futures-util", @@ -2581,13 +2659,13 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.5.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c" +checksum = "a22144e767da4ddd8416dbf383700542ffd8a5dc493dfecedfe1fe3ad03c98ae" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.6", ] [[package]] @@ -2596,7 +2674,7 @@ version = "0.3.0" dependencies = [ "anyhow", "async-trait", - "base64", + "base64 0.23.1", "bitreader", "buf-read-ext", "chrono", @@ -2609,7 +2687,7 @@ dependencies = [ "httparse", "hyper", "hyper-util", - "itertools 0.14.0", + "itertools 0.15.0", "itoa", "leon", "libgssapi", @@ -2628,9 +2706,9 @@ dependencies = [ "serde", "serde_json", "sha1", - "socket2 0.6.5", + "socket2", "strum", - "thiserror 2.0.19", + "thiserror 2.0.20", "tokio", "tokio-rustls", "tokio-util", @@ -2642,13 +2720,13 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.7" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" +checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", - "digest 0.10.7", + "cpufeatures", + "digest", ] [[package]] @@ -2664,19 +2742,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures 0.3.0", - "digest 0.11.3", + "cpufeatures", + "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 = "shared_child" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7" +checksum = "607549934f6cc26b89cfecfdc46fa90f1e5d1536a68349b0c3a4f9d1c0d37959" dependencies = [ "libc", "sigchld", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2693,9 +2780,9 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "sigchld" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1" +checksum = "24f2b37f04360cd465089b87a9c3869c08220a2f3458463f0adf8badf5e77f2c" dependencies = [ "libc", "os_pipe", @@ -2704,9 +2791,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.18" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +checksum = "b2a0c28ca5908dbdbcd52e6fdaa00358ab88637f8ab33e1f188dd510eb44b53d" dependencies = [ "libc", "signal-hook-registry", @@ -2722,6 +2809,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "siphasher" version = "1.0.3" @@ -2742,28 +2835,30 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.2" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "ba467056f1b547ed52077911161fc86985becbc60e8e1857c8a144dab0def891" [[package]] name = "socket2" -version = "0.5.10" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] -name = "socket2" -version = "0.6.5" +name = "sqlite-wasm-rs" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +checksum = "dc3efc0da82635d7e1ced0053bbbfa8c7ab9645d0bf36ceb4f7127bb85315d75" dependencies = [ - "libc", - "windows-sys 0.61.2", + "cc", + "js-sys", + "rsqlite-vfs", + "wasm-bindgen", ] [[package]] @@ -2791,18 +2886,18 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.27.2" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.27.2" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" dependencies = [ "heck", "proc-macro2", @@ -2829,9 +2924,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.3" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" dependencies = [ "proc-macro2", "quote", @@ -2849,13 +2944,24 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "synstructure" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + [[package]] name = "system-configuration" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -2894,11 +3000,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.19" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ - "thiserror-impl 2.0.19", + "thiserror-impl 2.0.20", ] [[package]] @@ -2914,13 +3020,13 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.19" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] @@ -2933,11 +3039,20 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "thread_local" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" +dependencies = [ + "cfg-if", +] + [[package]] name = "time" -version = "0.3.54" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e1d5e639ff6bab73cb6885cc7e7b1de96c3f32c68ec55f3952614bec1092244" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" dependencies = [ "deranged", "num-conv", @@ -2965,9 +3080,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", "zerovec", @@ -2975,18 +3090,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" [[package]] name = "tokio" @@ -3000,20 +3106,20 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.5", + "socket2", "tokio-macros", "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.6", ] [[package]] @@ -3036,7 +3142,7 @@ dependencies = [ "async-trait", "byteorder", "bytes", - "fallible-iterator", + "fallible-iterator 0.2.0", "futures-channel", "futures-util", "log", @@ -3047,7 +3153,7 @@ dependencies = [ "postgres-protocol", "postgres-types", "rand 0.10.2", - "socket2 0.6.5", + "socket2", "tokio", "tokio-util", "whoami", @@ -3055,9 +3161,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.4" +version = "0.26.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +checksum = "b0c85f2c3ef0b1cd58b36682f4b17aaa995f0e5db534d85692b4903abce21f67" dependencies = [ "rustls", "tokio", @@ -3079,23 +3185,17 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.23" +version = "1.1.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +checksum = "920602543f0911ab71da12c50d59701da54c196d1a2bf5cb4b75667f137a406a" dependencies = [ - "serde", + "indexmap", + "serde_core", "serde_spanned", - "toml_datetime 0.6.11", - "toml_edit 0.22.27", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] @@ -3109,44 +3209,30 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.27" +version = "0.25.15+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "1340ea94a5856333492c9064b02c778b191dd2c853778d9609debdcdfea3a614" dependencies = [ "indexmap", - "serde", - "serde_spanned", - "toml_datetime 0.6.11", - "toml_write", - "winnow 0.7.15", -] - -[[package]] -name = "toml_edit" -version = "0.25.13+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" -dependencies = [ - "indexmap", - "toml_datetime 1.1.1+spec-1.1.0", + "toml_datetime", "toml_parser", - "winnow 1.0.4", + "winnow", ] [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ - "winnow 1.0.4", + "winnow", ] [[package]] -name = "toml_write" -version = "0.1.2" +name = "toml_writer" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tower-layer" @@ -3189,6 +3275,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" 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.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -3220,9 +3336,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" [[package]] name = "unicode-normalization" @@ -3304,9 +3420,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.24.0" +version = "1.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" +checksum = "2ef6dac1e96601b4fb3acccccff2139741fcb757cb9a36089bf5be91cfb285ce" dependencies = [ "getrandom 0.4.3", "js-sys", @@ -3316,16 +3432,16 @@ dependencies = [ ] [[package]] -name = "vcpkg" -version = "0.2.15" +name = "valuable" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] -name = "version_check" -version = "0.9.5" +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "want" @@ -3371,9 +3487,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" dependencies = [ "cfg-if", "once_cell", @@ -3384,9 +3500,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3394,31 +3510,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.6", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.103" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" +checksum = "9fbddc4a036f00ec4f18c83445bd3115cb306a91da554919a099d9222fe4a7f8" dependencies = [ "js-sys", "wasm-bindgen", @@ -3426,9 +3542,9 @@ dependencies = [ [[package]] name = "whoami" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "998767ef88740d1f5b0682a9c53c24431453923962269c2db68ee43788c5a40d" +checksum = "626c4bac6755d76ffc12cb01b2eac751db1996b9e0041de9aa02c8c211ddc82c" dependencies = [ "libc", "libredox", @@ -3535,16 +3651,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -3562,31 +3669,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -3595,105 +3685,48 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "1.0.4" @@ -3711,15 +3744,15 @@ checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "writeable" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] name = "x509-parser" -version = "0.17.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4569f339c0c402346d4a75a9e39cf8dad310e287eef1ff56d4c68e5067f53460" +checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" dependencies = [ "asn1-rs", "data-encoding", @@ -3728,7 +3761,7 @@ dependencies = [ "nom", "oid-registry", "rusticata-macros", - "thiserror 2.0.19", + "thiserror 2.0.20", "time", ] @@ -3738,6 +3771,12 @@ version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" +[[package]] +name = "xxhash-rust" +version = "0.8.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aee1b19627c7c60102ab80d3a9cbe18de90bfe03bfa6c3715447681f0e8c8af6" + [[package]] name = "yoke" version = "0.8.3" @@ -3751,30 +3790,30 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", - "synstructure", + "syn 3.0.6", + "synstructure 0.14.0", ] [[package]] name = "zerocopy" -version = "0.8.55" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.55" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" dependencies = [ "proc-macro2", "quote", @@ -3792,14 +3831,14 @@ dependencies = [ [[package]] name = "zerofrom-derive" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", - "synstructure", + "syn 3.0.6", + "synstructure 0.14.0", ] [[package]] @@ -3810,9 +3849,9 @@ checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zerotrie" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ "displaydoc", "yoke", @@ -3821,9 +3860,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -3832,13 +3871,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.3" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.6", ] [[package]] @@ -3849,11 +3888,10 @@ checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" [[package]] name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" +version = "2.1.0+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +checksum = "0ef0a8027ec3ee71300ab3bcbcd0393f434aa72b91ca6d635a39941deae8eea0" dependencies = [ - "bindgen 0.72.1", "cc", "pkg-config", ] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 7217622d..3f542787 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -10,15 +10,15 @@ path = "src/main.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0.71" -clap = { version = "4.4.2", features = ["cargo"] } +anyhow = "1.0.104" +clap = { version = "4.6.7", features = ["cargo"] } common = { path = "../common" } -env_logger = "0.11.3" -log = "0.4.19" -serde_json = "1.0.97" -tokio = { version = "1.41.0", features = ["full"] } -roxmltree = "0.20.0" +env_logger = "0.11.11" +log = "0.4.34" +serde_json = "1.0.151" +tokio = { version = "1.53.1", features = ["full"] } +roxmltree = "0.21.1" serde = { version = "1.0", features = ["derive"] } -uuid = { version = "1.12.1", features = ["v4", "fast-rng"] } -chrono = { version = "0.4.26", default-features = false, features = ["clock"] } -strum = { version = "0.27.1", features = ["derive"] } +uuid = { version = "1.26.1", features = ["v4", "fast-rng"] } +chrono = { version = "0.4.45", default-features = false, features = ["clock"] } +strum = { version = "0.28.0", features = ["derive"] } diff --git a/common/Cargo.toml b/common/Cargo.toml index bc9346e2..e3482ab3 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -9,29 +9,29 @@ description = "A Windows Event Collector server using WEF for GNU/Linux" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0.71" -rusqlite = { version = "0.28.0", features = ["bundled"] } -uuid = { version = "1.12.1", features = ["v4", "fast-rng", "serde"] } +anyhow = "1.0.104" +rusqlite = { version = "0.40.2", features = ["bundled"] } +uuid = { version = "1.26.1", features = ["v4", "fast-rng", "serde"] } serde = { version = "1.0", features = ["derive"] } -toml = "0.8.0" -log = "0.4.19" -tokio = { version = "1.41.0", features = ["full"] } -serde_json = "1.0.97" -async-trait = "0.1.68" +toml = "1.1.6" +log = "0.4.34" +tokio = { version = "1.53.1", features = ["full"] } +serde_json = "1.0.151" +async-trait = "0.1.92" tokio-postgres = "0.7" -chrono = { version = "0.4.26", default-features = false, features = ["clock"] } -encoding_rs = "0.8.32" -deadpool-postgres = "0.14.0" -deadpool-sqlite = "0.5.0" -openssl = "0.10.70" -postgres-openssl = "0.5.0" -strum = { version = "0.27.1", features = ["derive"] } -bitflags = { version = "2.6.0", features = ["serde"] } -glob = "0.3.1" +chrono = { version = "0.4.45", default-features = false, features = ["clock"] } +encoding_rs = "0.8.41" +deadpool-postgres = "0.14.2" +deadpool-sqlite = "0.14.0" +openssl = "0.10.81" +postgres-openssl = "0.5.3" +strum = { version = "0.28.0", features = ["derive"] } +bitflags = { version = "2.13.2", features = ["serde"] } +glob = "0.3.4" [dev-dependencies] -tempfile = "3.16.0" -serial_test = "3.2.0" +tempfile = "3.27.0" +serial_test = "4.0.1" # cargo-deb [package.metadata.deb] diff --git a/common/src/database/sqlite.rs b/common/src/database/sqlite.rs index b253484a..bd3a0255 100644 --- a/common/src/database/sqlite.rs +++ b/common/src/database/sqlite.rs @@ -453,12 +453,14 @@ impl Database for SQLiteDatabase { VALUES (?1, ?2, ?3, ?4, ?4, ?4) ON CONFLICT (machine, subscription) DO UPDATE SET last_seen = excluded.last_seen, - last_event_seen = excluded.last_event_seen"# + last_event_seen = excluded.last_event_seen, + ip = excluded.ip"# } else { r#"INSERT INTO heartbeats(machine, ip, subscription, first_seen, last_seen, last_event_seen) VALUES (?1, ?2, ?3, ?4, ?4, NULL) ON CONFLICT (machine, subscription) DO - UPDATE SET last_seen = excluded.last_seen"# + UPDATE SET last_seen = excluded.last_seen, + ip = excluded.ip"# }; let count = self @@ -468,7 +470,7 @@ impl Database for SQLiteDatabase { .interact(move |conn| { conn.execute( query, - params![&machine_owned, &ip, &subscription_owned, now], + params![&machine_owned, &ip, &subscription_owned, now as i64], ) }) .await @@ -492,12 +494,14 @@ impl Database for SQLiteDatabase { VALUES (?1, ?2, ?3, ?4, ?4, ?5) ON CONFLICT (machine, subscription) DO UPDATE SET last_seen = excluded.last_seen, - last_event_seen = excluded.last_event_seen"#)?; + last_event_seen = excluded.last_event_seen, + ip = excluded.ip"#)?; let mut query_without_event = transaction.prepare( r#"INSERT INTO heartbeats(machine, ip, subscription, first_seen, last_seen, last_event_seen) VALUES (?1, ?2, ?3, ?4, ?4, NULL) ON CONFLICT (machine, subscription) DO - UPDATE SET last_seen = excluded.last_seen"#)?; + UPDATE SET last_seen = excluded.last_seen, + ip = excluded.ip"#)?; for (key, value) in heartbeats_cloned { match value.last_event_seen { @@ -508,15 +512,15 @@ impl Database for SQLiteDatabase { &key.machine, &value.ip, &key.subscription, - &value.last_seen, - &last_event_seen, + value.last_seen as i64, + last_event_seen as i64, ], )?; } None => { query_without_event .execute( - params![&key.machine, &value.ip, &key.subscription, &value.last_seen], + params![&key.machine, &value.ip, &key.subscription, value.last_seen as i64], )?; } } @@ -1002,6 +1006,17 @@ mod tests { Ok(()) } + #[tokio::test] + async fn test_heartbeats_cache() -> Result<()> { + let temp_file = tempfile::NamedTempFile::new()?; + let path = temp_file.into_temp_path(); + { + crate::database::tests::test_heartbeats_cache(db_with_migrations(&path).await?).await?; + } + path.close()?; + Ok(()) + } + #[tokio::test] async fn test_subscriptions() -> Result<()> { let temp_file = tempfile::NamedTempFile::new()?; diff --git a/server/Cargo.toml b/server/Cargo.toml index be7e5be1..9c1e7115 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -11,46 +11,46 @@ path = "src/main.rs" [dependencies] common = { path = "../common" } -anyhow = "1.0.71" -base64 = "0.22.0" +anyhow = "1.0.104" +base64 = "0.23.1" buf-read-ext = "0.4.0" -httparse = "1.10.0" -hyper = { version = "1.5.0", features = ["full"] } -itoa = "1.0.6" -libgssapi = { version = "0.7.2", features = ["iov"] } -log = "0.4.19" +httparse = "1.10.1" +hyper = { version = "1.11.1", features = ["full"] } +itoa = "1.0.18" +libgssapi = { version = "0.11.0", features = ["iov"] } +log = "0.4.34" mime = "0.3.17" -quick-xml = "0.41.0" -roxmltree = "0.20.0" -tokio = { version = "1.41.0", features = ["full"] } -rdkafka = { version = "0.37.0", features = ["zstd", "libz", "external-lz4", "ssl", "sasl", "gssapi"] } -regex = "1.11.0" -uuid = { version = "1.12.1", features = ["v4", "fast-rng"] } -serde = { version = "1.0.164", features = ["derive", "rc"] } -serde_json = "1.0.97" -async-trait = "0.1.68" -chrono = { version = "0.4.26", default-features = false, features = ["clock"] } -clap = { version = "4.4.2", features = ["cargo"] } -futures-util = "0.3.28" -xmlparser = "0.13.5" -itertools = "0.14.0" -futures = "0.3.28" -bitreader = "0.3.7" -x509-parser = "0.17.0" -sha1 = "0.10.5" +quick-xml = "0.42.0" +roxmltree = "0.21.1" +tokio = { version = "1.53.1", features = ["full"] } +rdkafka = { version = "0.39.0", features = ["zstd", "libz", "external-lz4", "ssl", "sasl", "gssapi"] } +regex = "1.13.1" +uuid = { version = "1.26.1", features = ["v4", "fast-rng"] } +serde = { version = "1.0.229", features = ["derive", "rc"] } +serde_json = "1.0.151" +async-trait = "0.1.92" +chrono = { version = "0.4.45", default-features = false, features = ["clock"] } +clap = { version = "4.6.7", features = ["cargo"] } +futures-util = "0.3.34" +xmlparser = "0.13.6" +itertools = "0.15.0" +futures = "0.3.34" +bitreader = "0.3.11" +x509-parser = "0.18.1" +sha1 = "0.11.0" hex = "0.4.3" -redis = { version = "0.25.3", features = ["tokio-comp", "aio"]} -log4rs = "1.2.0" +redis = { version = "1.7.0", features = ["tokio-comp", "aio"]} +log4rs = "1.4.0" log-mdc = "0.1.0" -tokio-util = "0.7.10" -thiserror = "2.0.11" +tokio-util = "0.7.19" +thiserror = "2.0.20" hyper-util = { version = "0.1", features = ["full"] } -socket2 = "0.6.0" +socket2 = "0.6.5" http-body-util = "0.1" -ppp = "2.2.0" -tokio-rustls = "0.26.0" -strum = { version = "0.27.1", features = ["derive"] } -leon = "3.0.1" -metrics = "0.24.0" -metrics-exporter-prometheus = { version = "0.16.0", features = ["http-listener"] } -url = "2.5.4" +ppp = "2.3.0" +tokio-rustls = "0.26.5" +strum = { version = "0.28.0", features = ["derive"] } +leon = "3.0.3" +metrics = "0.24.6" +metrics-exporter-prometheus = { version = "0.18.3", features = ["http-listener"] } +url = "2.5.8" diff --git a/server/src/drivers/redis.rs b/server/src/drivers/redis.rs index a852e5a1..a17b7414 100644 --- a/server/src/drivers/redis.rs +++ b/server/src/drivers/redis.rs @@ -38,12 +38,12 @@ impl OutputDriver for OutputRedis { for event in events.iter() { let mut redis_cmd = cmd.clone(); - let mut redis_connection = self.producer.get_multiplexed_tokio_connection().await?; + let mut redis_connection = self.producer.get_multiplexed_async_connection().await?; results.push(async move { redis_cmd .arg(&[self.config.list(), event.as_ref()]) - .query_async::<_, Option>(&mut redis_connection) + .query_async::>(&mut redis_connection) .await }); } diff --git a/server/src/kerberos.rs b/server/src/kerberos.rs index ec9e9cb1..ee5d8cd5 100644 --- a/server/src/kerberos.rs +++ b/server/src/kerberos.rs @@ -61,16 +61,16 @@ impl State { fn setup_server_ctx(principal: &[u8]) -> Result { let desired_mechs = { - let mut s = OidSet::new()?; - s.add(&GSS_MECH_KRB5)?; - s.add(&GSS_MECH_SPNEGO)?; + let mut s = OidSet::new(); + s.add(GSS_MECH_KRB5)?; + s.add(GSS_MECH_SPNEGO)?; s }; - let name = Name::new(principal, Some(&GSS_NT_KRB5_PRINCIPAL))?; - let cname = name.canonicalize(Some(&GSS_MECH_KRB5))?; + let name = Name::new(principal, Some(GSS_NT_KRB5_PRINCIPAL))?; + let cname = name.canonicalize(Some(GSS_MECH_KRB5))?; let server_cred = Cred::acquire(Some(&cname), None, CredUsage::Accept, Some(&desired_mechs))?; debug!("Acquired server credentials: {:?}", server_cred.info()); - Ok(ServerCtx::new(server_cred)) + Ok(ServerCtx::new(Some(server_cred))) } pub struct AuthenticationData { @@ -162,7 +162,7 @@ pub async fn authenticate( .context("Failed to decode authorization header token as base64")?; match server_ctx - .step(&token) + .step(&token, None) .context("Failed to perform Kerberos operation")? { // TODO: should we return Ok in this case ? From 419a2e7cc495f46f2eb4fc3fe278e2cf2d828b72 Mon Sep 17 00:00:00 2001 From: Ben Newton Date: Thu, 17 Sep 2026 17:08:48 +0000 Subject: [PATCH 2/9] feat(grpc/otel): Implementation of GRPC/OTEL --- Cargo.lock | 283 ++++++++++++++++++++++++++++++++++++ common/src/models/config.rs | 25 ++++ common/src/models/export.rs | 41 ++++++ common/src/subscription.rs | 69 +++++++++ server/Cargo.toml | 6 + server/src/drivers/mod.rs | 1 + server/src/drivers/otlp.rs | 260 +++++++++++++++++++++++++++++++++ server/src/output.rs | 225 ++++++++++++++++++++++++++++ 8 files changed, 910 insertions(+) create mode 100644 server/src/drivers/otlp.rs diff --git a/Cargo.lock b/Cargo.lock index d294060e..ef892812 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aho-corasick" version = "1.1.5" @@ -490,6 +496,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-epoch" version = "0.9.21" @@ -823,6 +838,17 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" +[[package]] +name = "flate2" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +dependencies = [ + "crc32fast", + "miniz_oxide", + "zlib-rs", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1182,6 +1208,19 @@ dependencies = [ "tower-service", ] +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.20" @@ -1733,6 +1772,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + [[package]] name = "mio" version = "1.2.3" @@ -1944,6 +1993,68 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0142c63252a9e054e68a4c61a5778f7b14f576274d593f8ce883d191a099682" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror 2.0.20", + "tracing", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9966929966d17620d7c316c643ba62631826e10021409357772d5eea84f62c35" +dependencies = [ + "http", + "opentelemetry", + "opentelemetry-proto", + "opentelemetry_sdk", + "prost", + "thiserror 2.0.20", + "tokio", + "tonic", + "tonic-types", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56d658ba1faf63f7b9c492cfbe6e0ec365440a16132d3270c1065f7b33f1b638" +dependencies = [ + "opentelemetry", + "opentelemetry_sdk", + "prost", + "tonic", + "tonic-prost", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b59f80e1ac4d5ff7a2db8fb6c80badb7f0f3f858211fba08dd9aaec750894f9" +dependencies = [ + "futures-channel", + "futures-executor", + "futures-util", + "opentelemetry", + "percent-encoding", + "portable-atomic", + "rand 0.9.5", + "thiserror 2.0.20", + "tokio", + "tokio-stream", +] + [[package]] name = "ordered-float" version = "2.10.1" @@ -2017,6 +2128,26 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pin-project" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "pin-project-lite" version = "0.2.17" @@ -2146,6 +2277,38 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prost" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" +dependencies = [ + "anyhow", + "itertools 0.13.0", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "prost-types" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a" +dependencies = [ + "prost", +] + [[package]] name = "quanta" version = "0.12.6" @@ -2697,6 +2860,9 @@ dependencies = [ "metrics", "metrics-exporter-prometheus", "mime", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry_sdk", "ppp", "quick-xml", "rdkafka", @@ -2708,6 +2874,7 @@ dependencies = [ "sha1", "socket2", "strum", + "tempfile", "thiserror 2.0.20", "tokio", "tokio-rustls", @@ -2809,6 +2976,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + [[package]] name = "simdutf8" version = "0.1.5" @@ -2933,6 +3106,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + [[package]] name = "synstructure" version = "0.13.2" @@ -3169,6 +3348,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.19" @@ -3234,6 +3424,75 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" +[[package]] +name = "tonic" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bytes", + "flate2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "sync_wrapper", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", + "zstd", +] + +[[package]] +name = "tonic-prost" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" +dependencies = [ + "bytes", + "prost", + "tonic", +] + +[[package]] +name = "tonic-types" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab1b02061f83d519bba3caa167f88f261ef05720ab8ebc954ade70de3348e8" +dependencies = [ + "prost", + "prost-types", + "tonic", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "indexmap", + "pin-project-lite", + "slab", + "sync_wrapper", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -3880,12 +4139,36 @@ dependencies = [ "syn 3.0.6", ] +[[package]] +name = "zlib-rs" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" + [[package]] name = "zmij" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d80649ab6db9d9f6f9c80a40becd948eda4714a0a5ac8c4d157a32231c7882" +dependencies = [ + "zstd-sys", +] + [[package]] name = "zstd-sys" version = "2.1.0+zstd.1.5.7" diff --git a/common/src/models/config.rs b/common/src/models/config.rs index 04d9301b..7c348cc6 100644 --- a/common/src/models/config.rs +++ b/common/src/models/config.rs @@ -126,6 +126,27 @@ impl From for crate::subscription::UnixDatagramConfig } } +#[derive(Debug, Clone, Deserialize, Eq, PartialEq)] +#[serde(deny_unknown_fields)] +struct OtlpConfiguration { + pub endpoint: String, + pub timeout: Option, + pub compression: Option, +} + +impl TryFrom for crate::subscription::OtlpConfiguration { + type Error = anyhow::Error; + + fn try_from(value: OtlpConfiguration) -> std::result::Result { + crate::subscription::OtlpConfiguration::new( + value.endpoint.clone(), + value.timeout, + value.compression.clone(), + ) + .with_context(|| format!("Loading {:?}", value.endpoint)) + } +} + #[derive(Debug, Clone, Deserialize, Eq, PartialEq)] #[serde(tag = "driver", content = "config")] enum SubscriptionOutputDriver { @@ -134,6 +155,7 @@ enum SubscriptionOutputDriver { Tcp(TcpConfiguration), Redis(RedisConfiguration), UnixDatagram(UnixDatagramConfiguration), + Otlp(OtlpConfiguration), } impl TryFrom for crate::subscription::SubscriptionOutputDriver { @@ -156,6 +178,9 @@ impl TryFrom for crate::subscription::SubscriptionOutp SubscriptionOutputDriver::UnixDatagram(config) => { crate::subscription::SubscriptionOutputDriver::UnixDatagram(config.into()) } + SubscriptionOutputDriver::Otlp(config) => { + crate::subscription::SubscriptionOutputDriver::Otlp(config.try_into()?) + } }) } } diff --git a/common/src/models/export.rs b/common/src/models/export.rs index a9e96a9b..fedb4530 100644 --- a/common/src/models/export.rs +++ b/common/src/models/export.rs @@ -494,6 +494,9 @@ pub mod v2 { crate::subscription::SubscriptionOutputDriver::UnixDatagram(config) => { SubscriptionOutputDriver::UnixDatagram(config.into()) } + crate::subscription::SubscriptionOutputDriver::Otlp(_) => { + unimplemented!("OTLP output driver is not yet supported for subscription export/import") + } } } } @@ -879,6 +882,37 @@ pub mod v3 { } } + #[derive(Debug, Clone, Deserialize, Eq, PartialEq, Serialize)] + pub(super) struct OtlpConfiguration { + pub endpoint: String, + #[serde(default)] + pub timeout: Option, + #[serde(default)] + pub compression: Option, + } + + impl TryFrom for crate::subscription::OtlpConfiguration { + type Error = anyhow::Error; + + fn try_from(value: OtlpConfiguration) -> Result { + crate::subscription::OtlpConfiguration::new( + value.endpoint, + value.timeout, + value.compression, + ) + } + } + + impl From for OtlpConfiguration { + fn from(value: crate::subscription::OtlpConfiguration) -> Self { + Self { + endpoint: value.endpoint().to_string(), + timeout: value.timeout(), + compression: value.compression().map(|s| s.to_string()), + } + } + } + #[derive(Debug, Clone, Deserialize, Eq, PartialEq, Serialize)] pub(super) enum SubscriptionOutputDriver { Files(FilesConfiguration), @@ -886,6 +920,7 @@ pub mod v3 { Tcp(TcpConfiguration), Redis(RedisConfiguration), UnixDatagram(UnixDatagramConfiguration), + Otlp(OtlpConfiguration), } impl TryFrom for crate::subscription::SubscriptionOutputDriver { @@ -908,6 +943,9 @@ pub mod v3 { SubscriptionOutputDriver::UnixDatagram(config) => { crate::subscription::SubscriptionOutputDriver::UnixDatagram(config.into()) } + SubscriptionOutputDriver::Otlp(config) => { + crate::subscription::SubscriptionOutputDriver::Otlp(config.try_into()?) + } }) } } @@ -930,6 +968,9 @@ pub mod v3 { crate::subscription::SubscriptionOutputDriver::UnixDatagram(config) => { SubscriptionOutputDriver::UnixDatagram(config.into()) } + crate::subscription::SubscriptionOutputDriver::Otlp(config) => { + SubscriptionOutputDriver::Otlp(config.into()) + } } } } diff --git a/common/src/subscription.rs b/common/src/subscription.rs index bb881fdf..825d490b 100644 --- a/common/src/subscription.rs +++ b/common/src/subscription.rs @@ -176,6 +176,74 @@ impl UnixDatagramConfiguration { } } +/// Allowed compression algorithms for the OTLP output driver. +pub const OTLP_VALID_COMPRESSIONS: [&str; 2] = ["gzip", "zstd"]; +/// Minimum export timeout (in seconds) accepted for the OTLP output driver. +pub const OTLP_TIMEOUT_MIN_SECS: u64 = 1; +/// Maximum export timeout (in seconds) accepted for the OTLP output driver. +pub const OTLP_TIMEOUT_MAX_SECS: u64 = 300; + +#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] +pub struct OtlpConfiguration { + endpoint: String, + #[serde(default)] + timeout: Option, + #[serde(default)] + compression: Option, +} + +impl OtlpConfiguration { + pub fn new( + endpoint: String, + timeout: Option, + compression: Option, + ) -> Result { + if let Some(timeout) = timeout { + if !(OTLP_TIMEOUT_MIN_SECS..=OTLP_TIMEOUT_MAX_SECS).contains(&timeout) { + bail!( + "OTLP timeout must be between {} and {} seconds, found {}", + OTLP_TIMEOUT_MIN_SECS, + OTLP_TIMEOUT_MAX_SECS, + timeout + ); + } + } + + let compression = match compression { + Some(value) => { + let normalized = value.to_lowercase(); + if !OTLP_VALID_COMPRESSIONS.contains(&normalized.as_str()) { + bail!( + "Invalid OTLP compression '{}' (expected one of: {})", + value, + OTLP_VALID_COMPRESSIONS.join(", ") + ); + } + Some(normalized) + } + None => None, + }; + + Ok(Self { + endpoint, + timeout, + compression, + }) + } + + pub fn endpoint(&self) -> &str { + self.endpoint.as_ref() + } + + pub fn timeout(&self) -> Option { + self.timeout + } + + pub fn compression(&self) -> Option<&str> { + self.compression.as_deref() + } +} + #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, AsRefStr)] #[strum(serialize_all = "lowercase")] pub enum SubscriptionOutputDriver { @@ -184,6 +252,7 @@ pub enum SubscriptionOutputDriver { Tcp(TcpConfiguration), Redis(RedisConfiguration), UnixDatagram(UnixDatagramConfiguration), + Otlp(OtlpConfiguration), } #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] diff --git a/server/Cargo.toml b/server/Cargo.toml index 9c1e7115..65ee7567 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -54,3 +54,9 @@ leon = "3.0.3" metrics = "0.24.6" metrics-exporter-prometheus = { version = "0.18.3", features = ["http-listener"] } url = "2.5.8" +opentelemetry = "0.32" +opentelemetry_sdk = { version = "0.32", features = ["logs", "rt-tokio"] } +opentelemetry-otlp = { version = "0.32", default-features = false, features = ["grpc-tonic", "gzip-tonic", "zstd-tonic", "logs"] } + +[dev-dependencies] +tempfile = "3" diff --git a/server/src/drivers/mod.rs b/server/src/drivers/mod.rs index 78df637b..b1d118d3 100644 --- a/server/src/drivers/mod.rs +++ b/server/src/drivers/mod.rs @@ -1,5 +1,6 @@ pub mod files; pub mod kafka; +pub mod otlp; pub mod redis; pub mod tcp; pub mod unix; diff --git a/server/src/drivers/otlp.rs b/server/src/drivers/otlp.rs new file mode 100644 index 00000000..d11e4800 --- /dev/null +++ b/server/src/drivers/otlp.rs @@ -0,0 +1,260 @@ +use std::sync::Arc; +use std::time::{Duration, SystemTime}; + +use crate::{event::EventMetadata, output::OutputDriver}; +use anyhow::{anyhow, Context, Result}; +use async_trait::async_trait; +use chrono::DateTime; +use common::subscription::OtlpConfiguration; +use log::debug; +use opentelemetry::logs::{AnyValue, LogRecord, Logger, LoggerProvider as _, Severity}; +use opentelemetry::InstrumentationScope; +use opentelemetry_otlp::{Compression, WithExportConfig, WithTonicConfig}; +use opentelemetry_sdk::logs::{ + LogBatch, LogExporter as _, SdkLogRecord, SdkLogger, SdkLoggerProvider, +}; +use opentelemetry_sdk::Resource; +use regex::Regex; + +pub struct OutputOtlp { + endpoint: String, + exporter: opentelemetry_otlp::LogExporter, + logger: SdkLogger, + scope: InstrumentationScope, + re_level: Regex, + re_time: Regex, + // Kept alive so that `logger` remains usable for the lifetime of this driver. + _provider: SdkLoggerProvider, +} + +impl OutputOtlp { + pub fn new(config: &OtlpConfiguration) -> Result { + let endpoint = config.endpoint().to_string(); + debug!("Initialize OTLP output with endpoint {}", endpoint); + + let resource = Resource::builder().with_service_name("openwec").build(); + + let mut builder = opentelemetry_otlp::LogExporter::builder() + .with_tonic() + .with_endpoint(&endpoint); + + if let Some(timeout) = config.timeout() { + builder = builder.with_timeout(Duration::from_secs(timeout)); + } + + if let Some(compression) = config.compression() { + let compression = compression.parse::().with_context(|| { + format!( + "Invalid OTLP compression '{}' for endpoint {}", + compression, endpoint + ) + })?; + builder = builder.with_compression(compression); + } + + let mut exporter = builder.build().with_context(|| { + format!("Failed to build OTLP log exporter for endpoint {}", endpoint) + })?; + exporter.set_resource(&resource); + + let provider = SdkLoggerProvider::builder() + .with_resource(resource) + .build(); + let logger = provider.logger("openwec"); + let scope = InstrumentationScope::builder("openwec").build(); + + let re_level = Regex::new(r"(\d+)").expect("valid Level regex"); + let re_time = Regex::new(r#"]*SystemTime=['\"]([^'\"]+)['\"]"#) + .expect("valid TimeCreated regex"); + + Ok(OutputOtlp { + endpoint, + exporter, + logger, + scope, + re_level, + re_time, + _provider: provider, + }) + } + + fn event_severity(&self, content: &str) -> (Severity, &'static str) { + let level = self + .re_level + .captures(content) + .and_then(|caps| caps.get(1)) + .and_then(|m| m.as_str().parse::().ok()); + match level { + Some(1) => (Severity::Fatal, "CRITICAL"), + Some(2) => (Severity::Error, "ERROR"), + Some(3) => (Severity::Warn, "WARNING"), + Some(4) => (Severity::Info, "INFORMATION"), + Some(5) => (Severity::Debug, "VERBOSE"), + _ => (Severity::Info, "INFORMATION"), + } + } + + fn event_timestamp(&self, content: &str) -> Option { + let raw = self.re_time.captures(content)?.get(1)?.as_str(); + let dt = DateTime::parse_from_rfc3339(raw).ok()?; + Some(SystemTime::from(dt)) + } +} + +#[async_trait] +impl OutputDriver for OutputOtlp { + async fn write( + &self, + metadata: Arc, + events: Arc>>, + ) -> Result<()> { + if events.is_empty() { + return Ok(()); + } + + let observed = SystemTime::from(metadata.time_received()); + + let mut records: Vec = Vec::with_capacity(events.len()); + for event in events.iter() { + let mut record = self.logger.create_log_record(); + let (severity, severity_text) = self.event_severity(event); + record.set_timestamp(self.event_timestamp(event).unwrap_or(observed)); + record.set_observed_timestamp(observed); + record.set_severity_number(severity); + record.set_severity_text(severity_text); + record.set_body(AnyValue::from(event.to_string())); + record.add_attribute("subscription.name", metadata.subscription_name().to_string()); + record.add_attribute("subscription.uuid", metadata.subscription_uuid().to_string()); + record.add_attribute("client", metadata.client().to_string()); + record.add_attribute("client.address", metadata.addr().to_string()); + if let Some(node) = metadata.node_name() { + record.add_attribute("node", node.to_string()); + } + records.push(record); + } + + let batch_data: Vec<(&SdkLogRecord, &InstrumentationScope)> = + records.iter().map(|record| (record, &self.scope)).collect(); + let batch = LogBatch::new(&batch_data); + + self.exporter.export(batch).await.map_err(|err| { + anyhow!( + "Failed to export {} event(s) to OTLP endpoint {}: {}", + events.len(), + self.endpoint, + err + ) + })?; + + debug!( + "Exported {} event(s) to OTLP endpoint {}", + events.len(), + self.endpoint + ); + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn driver() -> OutputOtlp { + let config = OtlpConfiguration::new("http://localhost:4317".to_string(), None, None) + .expect("valid OTLP configuration"); + OutputOtlp::new(&config).expect("driver should build") + } + + #[tokio::test] + async fn test_new_with_valid_config() { + let config = OtlpConfiguration::new( + "http://localhost:4317".to_string(), + Some(30), + Some("gzip".to_string()), + ) + .expect("valid OTLP configuration"); + let output = OutputOtlp::new(&config).expect("driver should build"); + assert_eq!(output.endpoint, "http://localhost:4317"); + } + + #[tokio::test] + async fn test_new_accepts_zstd_compression() { + let config = OtlpConfiguration::new( + "http://localhost:4317".to_string(), + None, + Some("zstd".to_string()), + ) + .expect("valid OTLP configuration"); + assert!(OutputOtlp::new(&config).is_ok()); + } + + #[tokio::test] + async fn test_event_severity_mapping() { + let output = driver(); + + assert_eq!( + output.event_severity("1"), + (Severity::Fatal, "CRITICAL") + ); + assert_eq!( + output.event_severity("2"), + (Severity::Error, "ERROR") + ); + assert_eq!( + output.event_severity("3"), + (Severity::Warn, "WARNING") + ); + assert_eq!( + output.event_severity("4"), + (Severity::Info, "INFORMATION") + ); + assert_eq!( + output.event_severity("5"), + (Severity::Debug, "VERBOSE") + ); + } + + #[tokio::test] + async fn test_event_severity_falls_back_to_info() { + let output = driver(); + + assert_eq!( + output.event_severity("9"), + (Severity::Info, "INFORMATION") + ); + assert_eq!( + output.event_severity("no level here"), + (Severity::Info, "INFORMATION") + ); + assert_eq!( + output.event_severity("abc"), + (Severity::Info, "INFORMATION") + ); + } + + #[tokio::test] + async fn test_event_timestamp_extraction() { + let output = driver(); + + let content = r#""#; + let expected = SystemTime::from( + DateTime::parse_from_rfc3339("2024-01-02T03:04:05.123Z").unwrap(), + ); + assert_eq!(output.event_timestamp(content), Some(expected)); + + let content_single = r#""#; + assert_eq!(output.event_timestamp(content_single), Some(expected)); + } + + #[tokio::test] + async fn test_event_timestamp_missing_or_invalid() { + let output = driver(); + + assert_eq!(output.event_timestamp("no timestamp here"), None); + assert_eq!( + output.event_timestamp(r#""#), + None + ); + } +} diff --git a/server/src/output.rs b/server/src/output.rs index 156b7412..d147c111 100644 --- a/server/src/output.rs +++ b/server/src/output.rs @@ -11,6 +11,7 @@ use crate::{ drivers::{ files::{OutputFiles, OutputFilesContext}, kafka::{OutputKafka, OutputKafkaContext}, + otlp::OutputOtlp, redis::OutputRedis, tcp::OutputTcp, unix::OutputUnixDatagram, @@ -122,6 +123,7 @@ impl Output { SubscriptionOutputDriver::UnixDatagram(config) => { Arc::new(OutputUnixDatagram::new(config)?) } + SubscriptionOutputDriver::Otlp(config) => Arc::new(OutputOtlp::new(config)?), }; Ok(Self { @@ -179,3 +181,226 @@ pub fn get_formatter(format: &SubscriptionOutputFormat) -> Box SubscriptionOutputFormat::Nxlog => Box::new(NxlogFormat), } } + +#[cfg(test)] +mod tests { + use std::{net::SocketAddr, str::FromStr, sync::Arc}; + + use chrono::Utc; + use common::{ + settings, + subscription::{ + FilesConfiguration, SubscriptionData, SubscriptionOutput, SubscriptionOutputDriver, + SubscriptionOutputFormat, SubscriptionUuid, + }, + }; + use serde_json::Value; + use uuid::Uuid; + + use crate::{ + event::{EventData, EventMetadata}, + output::{Output, OutputDriversContext}, + subscription::Subscription, + }; + + // Windows Security Event 4688 (Process Creation) — reused from individual format tests. + const EVENT_4688: &str = r#"4688201331200x8020000000000000114689Securitywin10.windomain.localS-1-5-18WIN10$WINDOMAIN0x3e70x3a8C:\Program Files (x86)\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe%%19360x240S-1-0-0--0x0C:\Windows\System32\services.exeS-1-16-16384A new process has been created.InformationProcess CreationInfoSecurityMicrosoft Windows security auditing.Audit Success"#; + + // The sanitized client name written to the file path: '$' is stripped by sanitize_name. + const CLIENT_SANITIZED: &str = "WIN10@WINDOMAIN.LOCAL"; + + /// Build a Subscription and EventMetadata with fixed, reproducible values. + fn make_subscription_and_metadata( + output_context: &mut OutputDriversContext, + ) -> (Subscription, EventMetadata) { + let mut sub_data = SubscriptionData::new("Test", ""); + sub_data + .set_uuid(SubscriptionUuid( + Uuid::from_str("8B18D83D-2964-4F35-AC3B-6F4E6FFA727B").unwrap(), + )) + .set_uri(Some("/this/is/a/test".to_string())) + .set_revision(Some("testrev".to_string())); + + let subscription = Subscription::from_data(sub_data, output_context).unwrap(); + + let mut metadata = EventMetadata::new( + &SocketAddr::from_str("192.168.58.100:5985").unwrap(), + "WIN10$@WINDOMAIN.LOCAL", + Some("openwec".to_owned()), + &subscription, + "188BB736-9441-5C66-188B-B73694415C66".to_string(), + Some("rev1234".to_string()), + ); + metadata.set_time_received( + chrono::DateTime::parse_from_rfc3339("2022-12-14T17:07:03.331+01:00") + .unwrap() + .with_timezone(&Utc), + ); + + (subscription, metadata) + } + + /// Create a SubscriptionData that has a single enabled Files output for the given format, + /// pointing at `base_dir/{client}/events`. Used to trigger `initialize_missing` so that + /// the `OutputFilesContext` background thread is started. + fn sub_data_with_files_output( + base_dir: &std::path::Path, + format: SubscriptionOutputFormat, + ) -> SubscriptionData { + let path = format!("{}/{{}}/events", base_dir.display()); + let files_config = FilesConfiguration::new(path); + let output = SubscriptionOutput::new( + format, + SubscriptionOutputDriver::Files(files_config), + true, + ); + let mut sub_data = SubscriptionData::new("TestOutput", ""); + sub_data.add_output(output); + sub_data + } + + /// Run the full format → Files-driver pipeline for one format and return the file contents. + async fn run_pipeline( + base_dir: &std::path::Path, + format: SubscriptionOutputFormat, + ) -> String { + let mut output_context = OutputDriversContext::new(&settings::Outputs::default()); + + // Force the Files background thread to be initialized. + let init_sub = sub_data_with_files_output(base_dir, format.clone()); + output_context.initialize_missing(&[init_sub]).unwrap(); + + let (subscription, metadata) = make_subscription_and_metadata(&mut output_context); + let _ = subscription; // metadata borrows it internally via Arc + + // Build the Output (format + Files driver) through the public API. + let files_config = FilesConfiguration::new(format!( + "{}/{}/{{client}}/events", + base_dir.display(), + format!("{:?}", format).to_lowercase() + )); + let driver = SubscriptionOutputDriver::Files(files_config); + let output = Output::new(&format, &driver, &mut output_context).unwrap(); + + // Format the raw event. + let formatter = super::get_formatter(&format); + let event_data = EventData::new(Arc::new(EVENT_4688.to_string()), true); + let formatted = formatter.format(&metadata, &event_data).expect("format should succeed"); + + let metadata_arc = Arc::new(metadata); + let events: Arc>> = Arc::new(vec![formatted]); + + output.write(metadata_arc, events).await.unwrap(); + + // Read back from the file the driver wrote. + let file_path = base_dir + .join(format!("{:?}", format).to_lowercase()) + .join(CLIENT_SANITIZED) + .join("events"); + + std::fs::read_to_string(&file_path) + .unwrap_or_else(|e| panic!("failed to read {:?}: {}", file_path, e)) + } + + #[tokio::test] + async fn test_pipeline_raw_format() { + let tmp = tempfile::tempdir().unwrap(); + let content = run_pipeline(tmp.path(), SubscriptionOutputFormat::Raw).await; + + // Raw format writes the event XML verbatim, one event per line. + assert_eq!(content, format!("{}\n", EVENT_4688)); + } + + #[tokio::test] + async fn test_pipeline_raw_json_format() { + let tmp = tempfile::tempdir().unwrap(); + let content = run_pipeline(tmp.path(), SubscriptionOutputFormat::RawJson).await; + + let line = content.trim_end_matches('\n'); + let json: Value = serde_json::from_str(line) + .unwrap_or_else(|e| panic!("RawJson output is not valid JSON: {}\n---\n{}", e, line)); + + // RawJson wraps the raw XML in a `data` field alongside subscription metadata. + assert_eq!(json["data"].as_str().unwrap(), EVENT_4688); + assert_eq!(json["meta"]["IpAddress"].as_str().unwrap(), "192.168.58.100"); + assert_eq!( + json["meta"]["Principal"].as_str().unwrap(), + "WIN10$@WINDOMAIN.LOCAL" + ); + assert_eq!(json["meta"]["Node"].as_str().unwrap(), "openwec"); + } + + #[tokio::test] + async fn test_pipeline_json_format() { + let tmp = tempfile::tempdir().unwrap(); + let content = run_pipeline(tmp.path(), SubscriptionOutputFormat::Json).await; + + let line = content.trim_end_matches('\n'); + let json: Value = serde_json::from_str(line) + .unwrap_or_else(|e| panic!("Json output is not valid JSON: {}\n---\n{}", e, line)); + + assert_eq!(json["System"]["EventID"].as_u64().unwrap(), 4688); + assert_eq!( + json["System"]["Channel"].as_str().unwrap(), + "Security" + ); + assert_eq!( + json["System"]["Computer"].as_str().unwrap(), + "win10.windomain.local" + ); + // Subscription metadata is embedded in the OpenWEC field. + assert_eq!(json["OpenWEC"]["IpAddress"].as_str().unwrap(), "192.168.58.100"); + } + + #[tokio::test] + async fn test_pipeline_nxlog_format() { + let tmp = tempfile::tempdir().unwrap(); + let content = run_pipeline(tmp.path(), SubscriptionOutputFormat::Nxlog).await; + + let line = content.trim_end_matches('\n'); + let json: Value = serde_json::from_str(line) + .unwrap_or_else(|e| panic!("Nxlog output is not valid JSON: {}\n---\n{}", e, line)); + + // Nxlog format flattens event fields; EventID is a top-level integer. + assert_eq!(json["EventID"].as_u64().unwrap(), 4688); + assert_eq!(json["Channel"].as_str().unwrap(), "Security"); + assert_eq!(json["Hostname"].as_str().unwrap(), "win10.windomain.local"); + assert_eq!(json["OpenWEC"]["IpAddress"].as_str().unwrap(), "192.168.58.100"); + } + + #[tokio::test] + async fn test_pipeline_multiple_events_in_batch() { + let tmp = tempfile::tempdir().unwrap(); + let mut output_context = OutputDriversContext::new(&settings::Outputs::default()); + + let format = SubscriptionOutputFormat::Raw; + let init_sub = sub_data_with_files_output(tmp.path(), format.clone()); + output_context.initialize_missing(&[init_sub]).unwrap(); + + let (_, metadata) = make_subscription_and_metadata(&mut output_context); + + let files_config = FilesConfiguration::new(format!( + "{}/batch/{{client}}/events", + tmp.path().display() + )); + let driver = SubscriptionOutputDriver::Files(files_config); + let output = Output::new(&format, &driver, &mut output_context).unwrap(); + + // Write a batch of 3 identical events. + let formatted = Arc::new(EVENT_4688.to_string()); + let events: Arc>> = + Arc::new(vec![formatted.clone(), formatted.clone(), formatted]); + + output.write(Arc::new(metadata), events).await.unwrap(); + + let file_path = tmp.path().join("batch").join(CLIENT_SANITIZED).join("events"); + let content = std::fs::read_to_string(&file_path).unwrap(); + + // Each event is written on its own line. + let lines: Vec<&str> = content.lines().collect(); + assert_eq!(lines.len(), 3, "expected 3 events in file, got {}", lines.len()); + for line in &lines { + assert_eq!(*line, EVENT_4688); + } + } +} From 054009c51ea8a5f6cc9c41b610b32e49096f6b5a Mon Sep 17 00:00:00 2001 From: Ben Newton Date: Thu, 17 Sep 2026 17:21:08 +0000 Subject: [PATCH 3/9] fix: fmt Running FMT --- common/src/models/export.rs | 4 ++- server/src/drivers/otlp.rs | 24 ++++++++++------ server/src/output.rs | 55 +++++++++++++++++++++---------------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/common/src/models/export.rs b/common/src/models/export.rs index fedb4530..c8209d5c 100644 --- a/common/src/models/export.rs +++ b/common/src/models/export.rs @@ -495,7 +495,9 @@ pub mod v2 { SubscriptionOutputDriver::UnixDatagram(config.into()) } crate::subscription::SubscriptionOutputDriver::Otlp(_) => { - unimplemented!("OTLP output driver is not yet supported for subscription export/import") + unimplemented!( + "OTLP output driver is not yet supported for subscription export/import" + ) } } } diff --git a/server/src/drivers/otlp.rs b/server/src/drivers/otlp.rs index d11e4800..8d2e36b9 100644 --- a/server/src/drivers/otlp.rs +++ b/server/src/drivers/otlp.rs @@ -53,13 +53,14 @@ impl OutputOtlp { } let mut exporter = builder.build().with_context(|| { - format!("Failed to build OTLP log exporter for endpoint {}", endpoint) + format!( + "Failed to build OTLP log exporter for endpoint {}", + endpoint + ) })?; exporter.set_resource(&resource); - let provider = SdkLoggerProvider::builder() - .with_resource(resource) - .build(); + let provider = SdkLoggerProvider::builder().with_resource(resource).build(); let logger = provider.logger("openwec"); let scope = InstrumentationScope::builder("openwec").build(); @@ -123,8 +124,14 @@ impl OutputDriver for OutputOtlp { record.set_severity_number(severity); record.set_severity_text(severity_text); record.set_body(AnyValue::from(event.to_string())); - record.add_attribute("subscription.name", metadata.subscription_name().to_string()); - record.add_attribute("subscription.uuid", metadata.subscription_uuid().to_string()); + record.add_attribute( + "subscription.name", + metadata.subscription_name().to_string(), + ); + record.add_attribute( + "subscription.uuid", + metadata.subscription_uuid().to_string(), + ); record.add_attribute("client", metadata.client().to_string()); record.add_attribute("client.address", metadata.addr().to_string()); if let Some(node) = metadata.node_name() { @@ -238,9 +245,8 @@ mod tests { let output = driver(); let content = r#""#; - let expected = SystemTime::from( - DateTime::parse_from_rfc3339("2024-01-02T03:04:05.123Z").unwrap(), - ); + let expected = + SystemTime::from(DateTime::parse_from_rfc3339("2024-01-02T03:04:05.123Z").unwrap()); assert_eq!(output.event_timestamp(content), Some(expected)); let content_single = r#""#; diff --git a/server/src/output.rs b/server/src/output.rs index d147c111..f7e4efa0 100644 --- a/server/src/output.rs +++ b/server/src/output.rs @@ -249,21 +249,15 @@ mod tests { ) -> SubscriptionData { let path = format!("{}/{{}}/events", base_dir.display()); let files_config = FilesConfiguration::new(path); - let output = SubscriptionOutput::new( - format, - SubscriptionOutputDriver::Files(files_config), - true, - ); + let output = + SubscriptionOutput::new(format, SubscriptionOutputDriver::Files(files_config), true); let mut sub_data = SubscriptionData::new("TestOutput", ""); sub_data.add_output(output); sub_data } /// Run the full format → Files-driver pipeline for one format and return the file contents. - async fn run_pipeline( - base_dir: &std::path::Path, - format: SubscriptionOutputFormat, - ) -> String { + async fn run_pipeline(base_dir: &std::path::Path, format: SubscriptionOutputFormat) -> String { let mut output_context = OutputDriversContext::new(&settings::Outputs::default()); // Force the Files background thread to be initialized. @@ -285,7 +279,9 @@ mod tests { // Format the raw event. let formatter = super::get_formatter(&format); let event_data = EventData::new(Arc::new(EVENT_4688.to_string()), true); - let formatted = formatter.format(&metadata, &event_data).expect("format should succeed"); + let formatted = formatter + .format(&metadata, &event_data) + .expect("format should succeed"); let metadata_arc = Arc::new(metadata); let events: Arc>> = Arc::new(vec![formatted]); @@ -322,7 +318,10 @@ mod tests { // RawJson wraps the raw XML in a `data` field alongside subscription metadata. assert_eq!(json["data"].as_str().unwrap(), EVENT_4688); - assert_eq!(json["meta"]["IpAddress"].as_str().unwrap(), "192.168.58.100"); + assert_eq!( + json["meta"]["IpAddress"].as_str().unwrap(), + "192.168.58.100" + ); assert_eq!( json["meta"]["Principal"].as_str().unwrap(), "WIN10$@WINDOMAIN.LOCAL" @@ -340,16 +339,16 @@ mod tests { .unwrap_or_else(|e| panic!("Json output is not valid JSON: {}\n---\n{}", e, line)); assert_eq!(json["System"]["EventID"].as_u64().unwrap(), 4688); - assert_eq!( - json["System"]["Channel"].as_str().unwrap(), - "Security" - ); + assert_eq!(json["System"]["Channel"].as_str().unwrap(), "Security"); assert_eq!( json["System"]["Computer"].as_str().unwrap(), "win10.windomain.local" ); // Subscription metadata is embedded in the OpenWEC field. - assert_eq!(json["OpenWEC"]["IpAddress"].as_str().unwrap(), "192.168.58.100"); + assert_eq!( + json["OpenWEC"]["IpAddress"].as_str().unwrap(), + "192.168.58.100" + ); } #[tokio::test] @@ -365,7 +364,10 @@ mod tests { assert_eq!(json["EventID"].as_u64().unwrap(), 4688); assert_eq!(json["Channel"].as_str().unwrap(), "Security"); assert_eq!(json["Hostname"].as_str().unwrap(), "win10.windomain.local"); - assert_eq!(json["OpenWEC"]["IpAddress"].as_str().unwrap(), "192.168.58.100"); + assert_eq!( + json["OpenWEC"]["IpAddress"].as_str().unwrap(), + "192.168.58.100" + ); } #[tokio::test] @@ -379,10 +381,8 @@ mod tests { let (_, metadata) = make_subscription_and_metadata(&mut output_context); - let files_config = FilesConfiguration::new(format!( - "{}/batch/{{client}}/events", - tmp.path().display() - )); + let files_config = + FilesConfiguration::new(format!("{}/batch/{{client}}/events", tmp.path().display())); let driver = SubscriptionOutputDriver::Files(files_config); let output = Output::new(&format, &driver, &mut output_context).unwrap(); @@ -393,12 +393,21 @@ mod tests { output.write(Arc::new(metadata), events).await.unwrap(); - let file_path = tmp.path().join("batch").join(CLIENT_SANITIZED).join("events"); + let file_path = tmp + .path() + .join("batch") + .join(CLIENT_SANITIZED) + .join("events"); let content = std::fs::read_to_string(&file_path).unwrap(); // Each event is written on its own line. let lines: Vec<&str> = content.lines().collect(); - assert_eq!(lines.len(), 3, "expected 3 events in file, got {}", lines.len()); + assert_eq!( + lines.len(), + 3, + "expected 3 events in file, got {}", + lines.len() + ); for line in &lines { assert_eq!(*line, EVENT_4688); } From 49096b3e58c991895aaa679c2fae6564e96dae6b Mon Sep 17 00:00:00 2001 From: Ben Newton Date: Thu, 17 Sep 2026 17:40:57 +0000 Subject: [PATCH 4/9] feat(debian): Deprecate bullseye, provide build artifacts for Trixie Debian Bullseye hit end of life --- build-pkg/Dockerfile-debian-bookworm | 1 + .../{Dockerfile-debian-bullseye => Dockerfile-debian-trixie} | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename build-pkg/{Dockerfile-debian-bullseye => Dockerfile-debian-trixie} (90%) diff --git a/build-pkg/Dockerfile-debian-bookworm b/build-pkg/Dockerfile-debian-bookworm index 24081dde..12b87ab2 100644 --- a/build-pkg/Dockerfile-debian-bookworm +++ b/build-pkg/Dockerfile-debian-bookworm @@ -12,3 +12,4 @@ RUN set -eux; \ && cargo install cargo-deb WORKDIR /SRC +Review th diff --git a/build-pkg/Dockerfile-debian-bullseye b/build-pkg/Dockerfile-debian-trixie similarity index 90% rename from build-pkg/Dockerfile-debian-bullseye rename to build-pkg/Dockerfile-debian-trixie index cf6f1bbb..28367c1a 100644 --- a/build-pkg/Dockerfile-debian-bullseye +++ b/build-pkg/Dockerfile-debian-trixie @@ -1,4 +1,4 @@ -FROM rust:slim-bullseye +FROM rust:slim-trixie RUN set -eux; \ apt-get update && \ From a846e330a79ef70629dd50795f63196a801c6d50 Mon Sep 17 00:00:00 2001 From: Ben Newton Date: Thu, 17 Sep 2026 17:41:18 +0000 Subject: [PATCH 5/9] refactor(ci): Refactor to build in parallel --- .github/workflows/release-draft.yml | 104 +++++++++++++++------------- 1 file changed, 57 insertions(+), 47 deletions(-) diff --git a/.github/workflows/release-draft.yml b/.github/workflows/release-draft.yml index d1061926..503739f2 100644 --- a/.github/workflows/release-draft.yml +++ b/.github/workflows/release-draft.yml @@ -10,54 +10,64 @@ env: jobs: build: - name: build packages + name: Build ${{ matrix.target }} package runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - target: debian-bookworm + dockerfile: Dockerfile-debian-bookworm + artifact-name: openwec-deb-bookworm-package + artifact-path: ./target/debian/*.deb + deb-suffix: _deb12 + - target: debian-trixie + dockerfile: Dockerfile-debian-trixie + artifact-name: openwec-deb-trixie-package + artifact-path: ./target/debian/*.deb + deb-suffix: _deb13 + - target: almalinux-9 + dockerfile: Dockerfile-almalinux-9 + artifact-name: openwec-alma-9-package + artifact-path: ./target/generate-rpm/*.rpm + steps: - - uses: actions/checkout@v4 - - name: Make debian bookworm package - run: | - cd build-pkg && \ - docker build -t openwec-builder:debian-bookworm -f Dockerfile-debian-bookworm . && \ - docker run -t -u $(id -u):$(id -g) -v $(pwd)/../:/SRC \ - --env CARGO_HOME=/SRC/target/.cargo openwec-builder:debian-bookworm \ - sh -c "cargo build --release --locked && \ - cargo deb --no-build --manifest-path=./common/Cargo.toml" && \ - for i in ../target/debian/*.deb; do mv "$i" "${i/.deb/_deb12.deb}"; done; - - name: Upload debian bookworm package - uses: actions/upload-artifact@v4 - with: - name: openwec-deb-bookworm-package - path: ./target/debian/*.deb - - name: Make debian bullseye package - run: | - cargo clean && \ - cd build-pkg && \ - docker build -t openwec-builder:debian-bullseye -f Dockerfile-debian-bullseye . && \ - docker run -t -u $(id -u):$(id -g) -v $(pwd)/../:/SRC \ - --env CARGO_HOME=/SRC/target/.cargo openwec-builder:debian-bullseye \ + - uses: actions/checkout@v4 + + - name: Build Docker image + working-directory: build-pkg + run: docker build -t openwec-builder:${{ matrix.target }} -f ${{ matrix.dockerfile }} . + + - name: Build Debian package + if: startsWith(matrix.target, 'debian') + run: | + docker run -t -u $(id -u):$(id -g) \ + -v ${{ github.workspace }}:/SRC \ + --env CARGO_HOME=/SRC/target/.cargo \ + openwec-builder:${{ matrix.target }} \ sh -c "cargo build --release --locked && \ - cargo deb --no-build --manifest-path=./common/Cargo.toml" && \ - for i in ../target/debian/*.deb; do mv "$i" "${i/.deb/_deb11.deb}"; done; - - name: Upload debian bullseye package - uses: actions/upload-artifact@v4 - with: - name: openwec-deb-bullseye-package - path: ./target/debian/*.deb - - name: Make almalinux 9 package - run: | - cargo clean && \ - cd build-pkg && \ - docker build -t openwec-builder:almalinux-9 -f Dockerfile-almalinux-9 . && \ - docker run -t -u $(id -u):$(id -g) -v $(pwd)/../:/SRC \ - --env CARGO_HOME=/SRC/target/.cargo openwec-builder:almalinux-9 \ + cargo deb --no-build --manifest-path=./common/Cargo.toml" + for i in ./target/debian/*.deb; do mv "$i" "${i/.deb/${{ matrix.deb-suffix }}.deb}"; done + + - name: Build RPM package + if: matrix.target == 'almalinux-9' + run: | + docker run -t -u $(id -u):$(id -g) \ + -v ${{ github.workspace }}:/SRC \ + --env CARGO_HOME=/SRC/target/.cargo \ + openwec-builder:${{ matrix.target }} \ sh -c "cargo build --release --locked && \ strip -s target/release/openwec{d,} && \ - cargo generate-rpm --package common --metadata-overwrite=./common/Cargo.toml --set-metadata=\"release='1.el9'\"" - - name: Upload almalinux 9 package - uses: actions/upload-artifact@v4 - with: - name: openwec-alma-9-package - path: ./target/generate-rpm/*.rpm + cargo generate-rpm --package common \ + --metadata-overwrite=./common/Cargo.toml \ + --set-metadata=\"release='1.el9'\"" + + - name: Upload package + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.artifact-name }} + path: ${{ matrix.artifact-path }} + # Need to select "Read and write permissions" under Actions / General / Workflow Permissions release: name: Github release draft @@ -71,10 +81,10 @@ jobs: uses: actions/download-artifact@v4 with: name: openwec-deb-bookworm-package - - name: Download debian bullseye package + - name: Download debian trixie package uses: actions/download-artifact@v4 with: - name: openwec-deb-bullseye-package + name: openwec-deb-trixie-package - name: Download almalinux 9 package uses: actions/download-artifact@v4 with: @@ -83,7 +93,7 @@ jobs: id: artifacts_names run: | echo "U_PKG_DEB_BOOKWORM=$(ls openwec*_deb12.deb)" >> "$GITHUB_OUTPUT" && \ - echo "U_PKG_DEB_BULLSEYE=$(ls openwec*_deb11.deb)" >> "$GITHUB_OUTPUT" && \ + echo "U_PKG_DEB_TRIXIE=$(ls openwec*_deb13.deb)" >> "$GITHUB_OUTPUT" && \ echo "U_PKG_ALMA_9=$(ls openwec*el9*.rpm)" >> "$GITHUB_OUTPUT" - name: Create draft release uses: softprops/action-gh-release@v2 @@ -91,5 +101,5 @@ jobs: draft: true files: | ${{ steps.artifacts_names.outputs.U_PKG_DEB_BOOKWORM }} - ${{ steps.artifacts_names.outputs.U_PKG_DEB_BULLSEYE }} + ${{ steps.artifacts_names.outputs.U_PKG_DEB_TRIXIE }} ${{ steps.artifacts_names.outputs.U_PKG_ALMA_9 }} From 950ebe3aed8bfa4f9dceb9bc13906b29cf92125e Mon Sep 17 00:00:00 2001 From: Ben Newton Date: Thu, 17 Sep 2026 17:46:02 +0000 Subject: [PATCH 6/9] fix(typo): Incorrect text in build package --- build-pkg/Dockerfile-debian-bookworm | 1 - 1 file changed, 1 deletion(-) diff --git a/build-pkg/Dockerfile-debian-bookworm b/build-pkg/Dockerfile-debian-bookworm index 12b87ab2..24081dde 100644 --- a/build-pkg/Dockerfile-debian-bookworm +++ b/build-pkg/Dockerfile-debian-bookworm @@ -12,4 +12,3 @@ RUN set -eux; \ && cargo install cargo-deb WORKDIR /SRC -Review th From 105b0a2f21cd0d197fd43f462621523ba770bd52 Mon Sep 17 00:00:00 2001 From: Ben Newton Date: Thu, 17 Sep 2026 18:00:53 +0000 Subject: [PATCH 7/9] chore(dependabot): Cover actions, group rust 1 PR with all considered rather than individual PRs --- .github/dependabot.yml | 20 +++++++++++++++----- CHANGELOG.md | 23 +++++++++++++++++++++-- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2004353c..63594f09 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,8 +3,18 @@ updates: - package-ecosystem: cargo directory: "/" schedule: - interval: daily - open-pull-requests-limit: 10 - ignore: - - dependency-name: "*" - update-types: ["version-update:semver-patch"] + interval: weekly + open-pull-requests-limit: 1 + groups: + rust: + patterns: + - "*" +- package-ecosystem: "github-actions" + directory: "/" + target-branch: "main" + schedule: + interval: "weekly" + groups: + actions: + patterns: + - "*" diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a72acfb..f34ec22b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,19 +9,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- OTLP/gRPC output driver: forward Windows events to any OpenTelemetry-compatible collector endpoint, with optional gzip/zstd compression and configurable timeout +- Support for multiple CA certificates in TLS configuration + +### Changed + +- Release package build pipeline refactored to run Debian and RPM builds in parallel (matrix strategy), reducing release wall-clock time +- Debian Bullseye (11) build target replaced by Debian Trixie (13); Bullseye reached end-of-life August 2024 +- Alpine Docker base image upgraded to 3.24 + +### Fixed + +- Upgraded dependencies to resolve RustSec security advisories +- Adapted to breaking API changes in libgssapi 0.11 and redis 1.7 +- SQLite heartbeat UPSERT was not updating the client IP address on conflict + +## [v0.4.0] + +### Added + - Add `max_elements` subscription parameter (#185) - Add an optional Prometheus endpoint that exposes metrics (#190) - Optionally wrap TCP stream in a TLS session in TCP driver (#203) - Support for SPNEGO authentication (#307) -## Changed +### Changed - Rework subscription filters (#186) (**Warning: this require a databatase migration**) - In formats `Json`, `Nxlog` and `RawJson`, `OpenWEC.Principal` is replaced by `OpenWEC.Client` (#186) - In `Files` driver, `{principal}` is replaced by `{client}` in `path` config (#186) - In access log pattern, `{X(principal)}` is replaced by `{X(client)}` (#186) -## Removed +### Removed - Subscription filters can no longer be created nor edited using the cli (#186) From 3c65a1c8df4f3dda535d3b04b153eed42379a222 Mon Sep 17 00:00:00 2001 From: Ben Newton Date: Thu, 17 Sep 2026 18:02:44 +0000 Subject: [PATCH 8/9] chore(ci): Pin to SHA rather than tag More secure, prevents spiking --- .github/workflows/docker-image.yml | 6 +++--- .github/workflows/release-draft.yml | 12 ++++++------ .github/workflows/rust-test.yml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index fa430c6e..a2e1bbf7 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -43,7 +43,7 @@ jobs: echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 @@ -83,7 +83,7 @@ jobs: touch "/tmp/digests/${digest#sha256:}" - name: Upload digest - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: digests-${{ matrix.base-image }}-${{ env.PLATFORM_PAIR }} path: /tmp/digests/* @@ -113,7 +113,7 @@ jobs: fi - name: Download digests - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: path: /tmp/digests pattern: digests-${{ matrix.base-image }}-* diff --git a/.github/workflows/release-draft.yml b/.github/workflows/release-draft.yml index 503739f2..226055b9 100644 --- a/.github/workflows/release-draft.yml +++ b/.github/workflows/release-draft.yml @@ -32,7 +32,7 @@ jobs: artifact-path: ./target/generate-rpm/*.rpm steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Build Docker image working-directory: build-pkg @@ -63,7 +63,7 @@ jobs: --set-metadata=\"release='1.el9'\"" - name: Upload package - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: ${{ matrix.artifact-name }} path: ${{ matrix.artifact-path }} @@ -78,15 +78,15 @@ jobs: contents: write steps: - name: Download debian bookworm package - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: openwec-deb-bookworm-package - name: Download debian trixie package - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: openwec-deb-trixie-package - name: Download almalinux 9 package - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: openwec-alma-9-package - name: Get artifacts names @@ -96,7 +96,7 @@ jobs: echo "U_PKG_DEB_TRIXIE=$(ls openwec*_deb13.deb)" >> "$GITHUB_OUTPUT" && \ echo "U_PKG_ALMA_9=$(ls openwec*el9*.rpm)" >> "$GITHUB_OUTPUT" - name: Create draft release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 with: draft: true files: | diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index 77ec7782..b9556bcd 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -37,7 +37,7 @@ jobs: - 5432:5432 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Install dependencies run: | apt-get update && \ From 5036d0780ff5b7b47ad96bb17374fc220fab2b37 Mon Sep 17 00:00:00 2001 From: Ben Newton Date: Thu, 17 Sep 2026 18:05:57 +0000 Subject: [PATCH 9/9] chore(ci): Ignore non-build artifacts on CI triggers --- .github/workflows/docker-image.yml | 6 ++++++ .github/workflows/rust-test.yml | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index a2e1bbf7..4c0a4daf 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -5,6 +5,12 @@ name: Create and publish a Docker image on: workflow_dispatch: push: + paths-ignore: + - .git* + - "**/*.md" + - .dockerignore + - LICENSE + - .github/** branches: ['main'] tags: - 'v*' diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index b9556bcd..97f00a89 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -3,8 +3,20 @@ name: Build and run tests on: push: branches: [ main ] + paths-ignore: + - .git* + - "**/*.md" + - .dockerignore + - LICENSE + - .github/** pull_request: branches: [ main ] + paths-ignore: + - .git* + - "**/*.md" + - .dockerignore + - LICENSE + - .github/** env: CARGO_TERM_COLOR: always