From f104e585c9caede57d9d2c0e907e870250052e10 Mon Sep 17 00:00:00 2001 From: Christopher Kolstad Date: Tue, 7 May 2024 14:05:57 +0200 Subject: [PATCH] Feature/add redis cluster support (#453) --- Cargo.lock | 924 +++++++++++++++++++-------- server/Cargo.toml | 38 +- server/src/builder.rs | 33 +- server/src/cli.rs | 25 +- server/src/http/feature_refresher.rs | 2 +- server/src/persistence/redis.rs | 93 ++- server/tests/redis_test.rs | 24 +- 7 files changed, 820 insertions(+), 319 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57834013..a66e01fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,7 +46,7 @@ dependencies = [ "actix-tls", "actix-utils", "ahash", - "base64", + "base64 0.21.7", "bitflags 2.4.2", "brotli", "bytes", @@ -95,7 +95,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "slab", - "socket2 0.5.5", + "socket2", "tokio", ] @@ -117,7 +117,7 @@ checksum = "02a8110b54d16d1ebb90216f2bd6f1800fbcedbda190ee6759e255b022b2341a" dependencies = [ "actix-service", "actix-web", - "base64", + "base64 0.21.7", "futures", "str-buf", "xxhash-rust", @@ -159,7 +159,7 @@ dependencies = [ "futures-core", "futures-util", "mio", - "socket2 0.5.5", + "socket2", "tokio", "tracing", ] @@ -242,7 +242,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.5.5", + "socket2", "time", "url", ] @@ -380,11 +380,20 @@ version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", @@ -409,7 +418,7 @@ dependencies = [ "actix-service", "actix-tls", "actix-utils", - "base64", + "base64 0.21.7", "bytes", "cfg-if", "derive_more", @@ -450,6 +459,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -471,13 +486,53 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bollard" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aed08d3adb6ebe0eff737115056652670ae290f177759aac19c30456135f94c" +dependencies = [ + "base64 0.22.1", + "bollard-stubs", + "bytes", + "futures-core", + "futures-util", + "hex", + "home", + "http 1.0.0", + "http-body-util", + "hyper 1.3.1", + "hyper-named-pipe", + "hyper-rustls 0.26.0", + "hyper-util", + "hyperlocal-next", + "log", + "pin-project-lite", + "rustls 0.22.2", + "rustls-native-certs", + "rustls-pemfile 2.1.2", + "rustls-pki-types", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "serde_urlencoded", + "thiserror", + "tokio", + "tokio-util", + "tower-service", + "url", + "winapi", +] + [[package]] name = "bollard-stubs" -version = "1.42.0-rc.3" +version = "1.44.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed59b5c00048f48d7af971b71f800fdf23e858844a6f9e4d32ca72e9399e7864" +checksum = "709d9aa1c37abb89d40f19f5d0ad6f0d88cb1581264e571c9350fc5bb89cf1c5" dependencies = [ "serde", + "serde_repr", "serde_with", ] @@ -508,12 +563,6 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.5.0" @@ -547,9 +596,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -568,9 +617,9 @@ checksum = "8d18b093eba54c9aaa1e3784d4361eb2ba944cf7d0a932a830132238f483e8d8" [[package]] name = "clap" -version = "4.5.1" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -587,9 +636,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -599,9 +648,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ "heck", "proc-macro2", @@ -712,11 +761,17 @@ dependencies = [ "libc", ] +[[package]] +name = "crc16" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338089f42c427b86394a5ee60ff321da23a5c89c9d89514c829687b26359fcff" + [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -748,29 +803,29 @@ dependencies = [ [[package]] name = "darling" -version = "0.13.4" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" dependencies = [ - "darling_core 0.13.4", - "darling_macro 0.13.4", + "darling_core 0.14.4", + "darling_macro 0.14.4", ] [[package]] name = "darling" -version = "0.14.4" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", + "darling_core 0.20.8", + "darling_macro 0.20.8", ] [[package]] name = "darling_core" -version = "0.13.4" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" dependencies = [ "fnv", "ident_case", @@ -782,38 +837,38 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.10.0", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] name = "darling_macro" -version = "0.13.4" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" dependencies = [ - "darling_core 0.13.4", + "darling_core 0.14.4", "quote", "syn 1.0.109", ] [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ - "darling_core 0.14.4", + "darling_core 0.20.8", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -823,7 +878,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown", + "hashbrown 0.14.3", "lock_api", "once_cell", "parking_lot_core", @@ -836,6 +891,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", +] + +[[package]] +name = "derive_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", ] [[package]] @@ -890,7 +957,61 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", - "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "dns-lookup" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5766087c2235fec47fafa4cfecc81e494ee679d0fd4a59887ea0919bfb0e4fc" +dependencies = [ + "cfg-if", + "libc", + "socket2", + "windows-sys 0.48.0", +] + +[[package]] +name = "docker_credential" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31951f49556e34d90ed28342e1df7e1cb7a229c4cab0aecc627b5d91edd41d07" +dependencies = [ + "base64 0.21.7", + "serde", + "serde_json", ] [[package]] @@ -920,9 +1041,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" dependencies = [ "anstream", "anstyle", @@ -1113,9 +1234,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "git2" -version = "0.18.1" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf97ba92db08df386e10c8ede66a2a0369bd277090afd8710e19e38de9ec0cd" +checksum = "232e6a7bfe35766bf715e55a88b39a700596c0ccfd88cd3680b4cdb40d66ef70" dependencies = [ "bitflags 2.4.2", "libc", @@ -1142,13 +1263,19 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.11", - "indexmap", + "indexmap 2.2.2", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.3" @@ -1157,9 +1284,9 @@ checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -1174,12 +1301,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] -name = "hmac" -version = "0.12.1" +name = "home" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "digest", + "windows-sys 0.52.0", ] [[package]] @@ -1226,6 +1353,29 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.0.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.0.0", + "http-body 1.0.0", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.8.0" @@ -1256,18 +1406,52 @@ dependencies = [ "futures-util", "h2", "http 0.2.11", - "http-body", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.5", + "socket2", "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "hyper" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-named-pipe" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b7d8abf35697b81a825e386fc151e0d503e8cb5fcb93cc8669c376dfd6f278" +dependencies = [ + "hex", + "hyper 1.3.1", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", + "winapi", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -1276,12 +1460,31 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.11", - "hyper", - "rustls 0.21.10", + "hyper 0.14.28", + "rustls 0.21.12", "tokio", "tokio-rustls 0.24.1", ] +[[package]] +name = "hyper-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" +dependencies = [ + "futures-util", + "http 1.0.0", + "hyper 1.3.1", + "hyper-util", + "log", + "rustls 0.22.2", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.25.0", + "tower-service", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -1289,12 +1492,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.28", "native-tls", "tokio", "tokio-native-tls", ] +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "hyper 1.3.1", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + +[[package]] +name = "hyperlocal-next" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf569d43fa9848e510358c07b80f4adf34084ddc28c6a4a651ee8474c070dcc" +dependencies = [ + "hex", + "http-body-util", + "hyper 1.3.1", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -1342,24 +1580,24 @@ checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" [[package]] name = "indexmap" -version = "2.2.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "equivalent", - "hashbrown", + "autocfg", + "hashbrown 0.12.3", "serde", ] [[package]] -name = "io-lifetimes" -version = "1.0.11" +name = "indexmap" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.48.0", + "equivalent", + "hashbrown 0.14.3", + "serde", ] [[package]] @@ -1385,9 +1623,9 @@ checksum = "06d198e9919d9822d5f7083ba8530e04de87841eaf21ead9af8f2304efd57c89" [[package]] name = "iter_tools" -version = "0.4.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a621162e5c4229abff44d46655dcb777f6064daa851e046df17baf74c9ddf079" +checksum = "0b8a2fd5781e38f94f3e9618169120858f9aaa5512239c0ea496fc4d656fffd1" dependencies = [ "itertools 0.11.0", ] @@ -1454,9 +1692,9 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libgit2-sys" -version = "0.16.1+1.7.1" +version = "0.16.2+1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2a2bb3680b094add03bb3732ec520ece34da31a8cd2d633d1389d0f0fb60d0c" +checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" dependencies = [ "cc", "libc", @@ -1464,6 +1702,16 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.4.2", + "libc", +] + [[package]] name = "libz-sys" version = "1.1.15" @@ -1476,12 +1724,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linux-raw-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" - [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -1517,9 +1759,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "maplit" @@ -1644,6 +1886,27 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "num_threads" version = "0.1.6" @@ -1720,7 +1983,7 @@ checksum = "1e32339a5dc40459130b3bd269e9892439f55b33e772d2a9d402a789baaf4e8a" dependencies = [ "futures-core", "futures-sink", - "indexmap", + "indexmap 2.2.2", "js-sys", "once_cell", "pin-project-lite", @@ -1772,6 +2035,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "ordered-float" version = "4.2.0" @@ -1810,6 +2079,31 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "parse-display" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06af5f9333eb47bd9ba8462d612e37a8328a5cb80b13f0af4de4c3b89f52dee5" +dependencies = [ + "parse-display-derive", + "regex", + "regex-syntax 0.8.2", +] + +[[package]] +name = "parse-display-derive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc9252f259500ee570c75adcc4e317fa6f57a1e47747d622e0bf838002a7b790" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "regex-syntax 0.8.2", + "structmeta", + "syn 2.0.48", +] + [[package]] name = "paste" version = "1.0.14" @@ -1867,6 +2161,26 @@ dependencies = [ "sha2", ] +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1897,6 +2211,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1932,22 +2255,32 @@ dependencies = [ [[package]] name = "procfs" -version = "0.14.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de8dacb0873f77e6aefc6d71e044761fcc68060290f5b1089fcdf84626bb69" +checksum = "731e0d9356b0c25f16f33b5be79b1c57b562f141ebfcdb0ad8ac2c13a24293b4" dependencies = [ - "bitflags 1.3.2", - "byteorder", + "bitflags 2.4.2", "hex", "lazy_static", - "rustix 0.36.17", + "procfs-core", + "rustix", +] + +[[package]] +name = "procfs-core" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3554923a69f4ce04c4a754260c338f505ce22642d3830e049a399fc2059a29" +dependencies = [ + "bitflags 2.4.2", + "hex", ] [[package]] name = "prometheus" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" dependencies = [ "cfg-if", "fnv", @@ -2019,26 +2352,28 @@ dependencies = [ [[package]] name = "redis" -version = "0.24.0" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c580d9cbbe1d1b479e8d67cf9daf6a62c957e6846048408b80b43ac3f6af84cd" +checksum = "6472825949c09872e8f2c50bde59fcefc17748b6be5c90fd67cd8b4daca73bfd" dependencies = [ "async-trait", "bytes", "combine", + "crc16", "futures-util", "itoa", "percent-encoding", "pin-project-lite", - "rustls 0.21.10", + "rand", + "rustls 0.22.2", "rustls-native-certs", - "rustls-pemfile 1.0.4", - "rustls-webpki 0.101.7", + "rustls-pemfile 2.1.2", + "rustls-pki-types", "ryu", "sha1_smol", - "socket2 0.4.10", + "socket2", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls 0.25.0", "tokio-util", "url", ] @@ -2052,6 +2387,17 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.10.3" @@ -2098,20 +2444,20 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.24" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", "futures-util", "h2", "http 0.2.11", - "http-body", - "hyper", - "hyper-rustls", + "http-body 0.4.6", + "hyper 0.14.28", + "hyper-rustls 0.24.2", "hyper-tls", "ipnet", "js-sys", @@ -2121,7 +2467,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.10", + "rustls 0.21.12", "rustls-pemfile 1.0.4", "serde", "serde_json", @@ -2136,8 +2482,50 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", - "winreg", + "webpki-roots 0.25.4", + "winreg 0.50.0", +] + +[[package]] +name = "reqwest" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.3.1", + "hyper-rustls 0.26.0", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.22.2", + "rustls-pemfile 2.1.2", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls 0.25.0", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.26.1", + "winreg 0.52.0", ] [[package]] @@ -2203,20 +2591,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.36.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305efbd14fde4139eb501df5f136994bb520b033fa9fbdce287507dc23b8c7ed" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.1.4", - "windows-sys 0.45.0", -] - [[package]] name = "rustix" version = "0.38.31" @@ -2226,15 +2600,15 @@ dependencies = [ "bitflags 2.4.2", "errno", "libc", - "linux-raw-sys 0.4.13", + "linux-raw-sys", "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring", @@ -2258,12 +2632,13 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", - "rustls-pemfile 1.0.4", + "rustls-pemfile 2.1.2", + "rustls-pki-types", "schannel", "security-framework", ] @@ -2274,24 +2649,24 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64", + "base64 0.21.7", ] [[package]] name = "rustls-pemfile" -version = "2.1.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c333bb734fcdedcea57de1602543590f545f127dc8b533324318fd492c5c70b" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64", + "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.3.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" +checksum = "51f344d206c5e1b010eec27349b815a4805f70a778895959d70b74b9b529b30a" [[package]] name = "rustls-webpki" @@ -2379,24 +2754,24 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", @@ -2405,9 +2780,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", @@ -2428,6 +2803,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2442,24 +2828,32 @@ dependencies = [ [[package]] name = "serde_with" -version = "1.14.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" +checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.2.2", "serde", + "serde_derive", + "serde_json", "serde_with_macros", + "time", ] [[package]] name = "serde_with_macros" -version = "1.5.2" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" +checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" dependencies = [ - "darling 0.13.4", + "darling 0.20.8", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -2492,9 +2886,9 @@ dependencies = [ [[package]] name = "shadow-rs" -version = "0.26.1" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5c5c8276991763b44ede03efaf966eaa0412fafbf299e6380704678ca3b997" +checksum = "7960cbd6ba74691bb15e7ebf97f7136bd02d1115f5695a58c1f31d5645750128" dependencies = [ "const_format", "git2", @@ -2536,16 +2930,6 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.5" @@ -2580,6 +2964,29 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +[[package]] +name = "structmeta" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e1575d8d40908d70f6fd05537266b90ae71b15dbbe7a8b7dffa2b759306d329" +dependencies = [ + "proc-macro2", + "quote", + "structmeta-derive", + "syn 2.0.48", +] + +[[package]] +name = "structmeta-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "subtle" version = "2.5.0" @@ -2643,7 +3050,7 @@ checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" dependencies = [ "cfg-if", "fastrand", - "rustix 0.38.31", + "rustix", "windows-sys 0.52.0", ] @@ -2682,26 +3089,32 @@ dependencies = [ [[package]] name = "testcontainers" -version = "0.15.0" +version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d2931d7f521af5bae989f716c3fa43a6af9af7ec7a5e21b59ae40878cec00" +checksum = "69d47265a44d1035a322691cf0a6cc227d79b62ef86ffb0dbc204b394fee3d07" dependencies = [ + "async-trait", + "bollard", "bollard-stubs", + "dirs", + "dns-lookup", + "docker_credential", "futures", - "hex", - "hmac", "log", - "rand", + "parse-display", "serde", "serde_json", - "sha2", + "serde_with", + "tokio", + "tokio-util", + "url", ] [[package]] name = "testcontainers-modules" -version = "0.3.4" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c391cd115649a8a14e5638d0606648d5348b216700a31f402987f57e58693766" +checksum = "e8da66a6ebd55684c8e3c58c7374dc2b2d0d1884ac688987e7ffb2d02103a3ee" dependencies = [ "testcontainers", ] @@ -2798,7 +3211,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2", "tokio-macros", "tracing", "windows-sys 0.48.0", @@ -2831,7 +3244,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls 0.21.12", "tokio", ] @@ -2860,6 +3273,45 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.2", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -3098,9 +3550,9 @@ dependencies = [ "prometheus-static-metric", "rand", "redis", - "reqwest", + "reqwest 0.11.27", "rustls 0.22.2", - "rustls-pemfile 2.1.0", + "rustls-pemfile 2.1.2", "rustls-pki-types", "semver", "serde", @@ -3127,7 +3579,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cad053850a28a8997168919c4c1ab4f0d86e490f62aefca27d0f2ff897a12f62" dependencies = [ - "base64", + "base64 0.21.7", "chrono", "derive_builder", "serde", @@ -3174,6 +3626,7 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -3190,11 +3643,11 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "utoipa" -version = "4.2.0" +version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "272ebdfbc99111033031d2f10e018836056e4d2c8e2acda76450ec7974269fa7" +checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" dependencies = [ - "indexmap", + "indexmap 2.2.2", "serde", "serde_json", "utoipa-gen", @@ -3202,9 +3655,9 @@ dependencies = [ [[package]] name = "utoipa-gen" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3c9f4d08338c1bfa70dde39412a040a884c6f318b3d09aaaf3437a1e52027fc" +checksum = "7bf0e16c02bc4bf5322ab65f10ab1149bdbcaa782cba66dc7057370a3f8190be" dependencies = [ "proc-macro-error", "proc-macro2", @@ -3215,13 +3668,14 @@ dependencies = [ [[package]] name = "utoipa-swagger-ui" -version = "6.0.0" +version = "7.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b39868d43c011961e04b41623e050aedf2cc93652562ff7935ce0f819aaf2da" +checksum = "6c49396bb19184d3ac1220bb56b3ec91e3d6275baa6cbd5a0f36f110a88d6afb" dependencies = [ "actix-web", "mime_guess", "regex", + "reqwest 0.12.4", "rust-embed", "serde", "serde_json", @@ -3364,6 +3818,15 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -3404,15 +3867,6 @@ dependencies = [ "windows-targets 0.52.0", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -3431,21 +3885,6 @@ dependencies = [ "windows-targets 0.52.0", ] -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-targets" version = "0.48.5" @@ -3476,12 +3915,6 @@ dependencies = [ "windows_x86_64_msvc 0.52.0", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -3494,12 +3927,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -3512,12 +3939,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -3530,12 +3951,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -3548,12 +3963,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -3566,12 +3975,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -3584,12 +3987,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3602,6 +3999,15 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" @@ -3612,6 +4018,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "xxhash-rust" version = "0.8.8" @@ -3646,14 +4062,18 @@ checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" [[package]] name = "zip" -version = "0.6.6" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +checksum = "006d078b7b6fc587bb25e022ad39e7086f44e5c4fef6076964ea601533241beb" dependencies = [ - "byteorder", + "arbitrary", "crc32fast", "crossbeam-utils", + "displaydoc", "flate2", + "indexmap 2.2.2", + "num_enum", + "thiserror", ] [[package]] diff --git a/server/Cargo.toml b/server/Cargo.toml index ea315715..2e0a7458 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -29,15 +29,15 @@ actix-web = { version = "4.5.1", features = ["rustls-0_22", "compress-zstd"] } ahash = "0.8.10" anyhow = "1.0.80" -async-trait = "0.1.77" -chrono = { version = "0.4.34", features = ["serde"] } +async-trait = "0.1.80" +chrono = { version = "0.4.38", features = ["serde"] } cidr = "0.2.2" -clap = { version = "4.5.1", features = ["derive", "env"] } +clap = { version = "4.5.4", features = ["derive", "env"] } clap-markdown = "0.1.3" dashmap = "5.5.3" futures = "0.3.30" futures-core = "0.3.30" -iter_tools = "0.4.0" +iter_tools = "0.15.0" itertools = "0.12.1" lazy_static = "1.4.0" num_cpus = "1.16.0" @@ -50,24 +50,24 @@ opentelemetry_sdk = { version = "0.21.2", features = [ "serde_json", "logs", ] } -prometheus = { version = "0.13.3", features = ["process"] } +prometheus = { version = "0.13.4", features = ["process"] } prometheus-static-metric = "0.5.1" rand = "0.8.5" -redis = { version = "0.24.0", features = ["tokio-comp", "tokio-rustls-comp"] } -reqwest = { version = "0.11.24", default-features = false, features = [ +redis = { version = "0.25.3", features = ["tokio-comp", "tokio-rustls-comp", "cluster"] } +reqwest = { version = "0.11.27", default-features = false, features = [ "rustls", "json", "rustls-tls", "native-tls", ] } rustls = "0.22.2" -rustls-pemfile = "2.1.0" -rustls-pki-types = "1.3.1" -semver = "1.0.22" -serde = { version = "1.0.197", features = ["derive"] } -serde_json = "1.0.114" +rustls-pemfile = "2.1.2" +rustls-pki-types = "1.6.0" +semver = "1.0.23" +serde = { version = "1.0.200", features = ["derive"] } +serde_json = "1.0.116" serde_qs = { version = "0.12.0", features = ["actix4", "tracing"] } -shadow-rs = { version = "0.26.1" } +shadow-rs = { version = "0.27.1" } tokio = { version = "1.36.0", features = [ "macros", "rt-multi-thread", @@ -79,19 +79,19 @@ tracing-subscriber = { version = "0.3.18", features = ["json", "env-filter"] } ulid = "1.1.2" unleash-types = { version = "0.12", features = ["openapi", "hashes"] } unleash-yggdrasil = { version = "0.12.0" } -utoipa = { version = "4.2.0", features = ["actix_extras", "chrono"] } -utoipa-swagger-ui = { version = "6", features = ["actix-web"] } +utoipa = { version = "4.2.3", features = ["actix_extras", "chrono"] } +utoipa-swagger-ui = { version = "7.0.1", features = ["actix-web"] } [dev-dependencies] actix-http = "3.6.0" actix-http-test = "3.2.0" actix-service = "2.0.2" -env_logger = "0.11.2" +env_logger = "0.11.3" maplit = "1.0.2" rand = "0.8.5" test-case = "3.3.1" -testcontainers = "0.15.0" -testcontainers-modules = { version = "0.3.4", features = ["redis"] } +testcontainers = "0.16.7" +testcontainers-modules = { version = "0.4.2", features = ["redis"] } tracing-test = "0.2.4" [build-dependencies] -shadow-rs = "0.26.1" +shadow-rs = "0.27.1" diff --git a/server/src/builder.rs b/server/src/builder.rs index ed82ec05..012f41c8 100644 --- a/server/src/builder.rs +++ b/server/src/builder.rs @@ -1,12 +1,16 @@ +use std::fs::File; +use std::io::{BufReader, Read}; +use std::str::FromStr; +use std::sync::Arc; + use chrono::Duration; use dashmap::DashMap; use reqwest::Url; -use std::fs::File; -use std::io::Read; -use std::sync::Arc; -use std::{io::BufReader, str::FromStr}; -use tracing::warn; +use tracing::{debug, warn}; +use unleash_types::client_features::ClientFeatures; +use unleash_yggdrasil::EngineState; +use crate::cli::RedisMode; use crate::offline::offline_hotload::{load_bootstrap, load_offline_engine_cache}; use crate::persistence::file::FilePersister; use crate::persistence::redis::RedisPersister; @@ -18,8 +22,6 @@ use crate::{ http::{feature_refresher::FeatureRefresher, unleash_client::UnleashClient}, types::{EdgeResult, EdgeToken, TokenType}, }; -use unleash_types::client_features::ClientFeatures; -use unleash_yggdrasil::EngineState; type CacheContainer = ( Arc>, @@ -122,12 +124,23 @@ fn build_offline(offline_args: OfflineArgs) -> EdgeResult { } async fn get_data_source(args: &EdgeArgs) -> Option> { - if let Some(redis_url) = args.redis.clone().and_then(|r| r.to_url()) { - let redis_client = RedisPersister::new(&redis_url).expect("Failed to connect to Redis"); - return Some(Arc::new(redis_client)); + if let Some(redis_args) = args.redis.clone() { + debug!("Configuring Redis persistence {redis_args:?}"); + let redis_persister = match redis_args.redis_mode { + RedisMode::Single => redis_args + .to_url() + .map(|url| RedisPersister::new(&url).expect("Failed to connect to redis")), + RedisMode::Cluster => redis_args.redis_url.map(|urls| { + RedisPersister::new_with_cluster(urls).expect("Failed to connect to redis cluster") + }), + } + .unwrap_or_else(|| panic!("Could not build a redis persister from redis_args {:?}", + args.redis)); + return Some(Arc::new(redis_persister)); } if let Some(backup_folder) = args.backup_folder.clone() { + debug!("Configuring file persistence {backup_folder:?}"); let backup_client = FilePersister::new(&backup_folder); return Some(Arc::new(backup_client)); } diff --git a/server/src/cli.rs b/server/src/cli.rs index 25a84fc1..b89dd94e 100644 --- a/server/src/cli.rs +++ b/server/src/cli.rs @@ -1,12 +1,13 @@ -use cidr::{Ipv4Cidr, Ipv6Cidr}; use std::fmt::{Display, Formatter}; use std::net::IpAddr; use std::path::PathBuf; use std::str::FromStr; -use crate::error; +use cidr::{Ipv4Cidr, Ipv6Cidr}; use clap::{ArgGroup, Args, Parser, Subcommand, ValueEnum}; +use crate::error; + #[derive(Subcommand, Debug, Clone)] #[allow(clippy::large_enum_variant)] pub enum EdgeMode { @@ -42,10 +43,18 @@ impl Display for RedisScheme { } } } +#[derive(Copy, Debug, Clone, Eq, PartialEq, PartialOrd, Ord, ValueEnum)] +pub enum RedisMode { + Single, + Cluster, +} + #[derive(Args, Debug, Clone)] pub struct RedisArgs { - #[clap(long, env)] - pub redis_url: Option, + #[clap(long, env, value_delimiter = ',')] + pub redis_url: Option>, + #[clap(long, env, value_enum, default_value_t = RedisMode::Single)] + pub redis_mode: RedisMode, #[clap(long, env)] pub redis_password: Option, #[clap(long, env)] @@ -65,7 +74,7 @@ impl RedisArgs { self.redis_url .clone() .map(|url| { - reqwest::Url::parse(&url).unwrap_or_else(|_| panic!("Failed to create url from REDIS_URL: {}, REDIS_USERNAME: {} and REDIS_PASSWORD: {}", self.redis_url.clone().unwrap_or("NO_URL".into()), self.redis_username.clone().unwrap_or("NO_USERNAME_SET".into()), self.redis_password.is_some())) + reqwest::Url::parse(&url[0]).unwrap_or_else(|_| panic!("Failed to create url from REDIS_URL: {:?}, REDIS_USERNAME: {} and REDIS_PASSWORD: {}", self.redis_url.clone().unwrap_or(vec!["NO_URL".into()]), self.redis_username.clone().unwrap_or("NO_USERNAME_SET".into()), self.redis_password.is_some())) }) .or_else(|| self.redis_host.clone().map(|host| { reqwest::Url::parse(format!("{}://{}", self.redis_scheme, &host).as_str()).expect("Failed to parse hostname from REDIS_HOSTNAME or --redis-hostname parameters") @@ -364,13 +373,13 @@ impl HttpServerArgs { #[cfg(test)] mod tests { - - use crate::cli::{CliArgs, EdgeMode, NetworkAddr}; - use crate::error; use clap::Parser; use tracing::info; use tracing_test::traced_test; + use crate::cli::{CliArgs, EdgeMode, NetworkAddr}; + use crate::error; + #[test] pub fn can_parse_multiple_client_headers() { let args = vec![ diff --git a/server/src/http/feature_refresher.rs b/server/src/http/feature_refresher.rs index f3a9e74e..57222c48 100644 --- a/server/src/http/feature_refresher.rs +++ b/server/src/http/feature_refresher.rs @@ -258,7 +258,7 @@ impl FeatureRefresher { /// Registers a token for refresh, the token will be discarded if it can be subsumed by another previously registered token pub async fn register_token_for_refresh(&self, token: EdgeToken, etag: Option) { if !self.tokens_to_refresh.contains_key(&token.token) { - let _ = self + self .unleash_client .register_as_client( token.token.clone(), diff --git a/server/src/persistence/redis.rs b/server/src/persistence/redis.rs index bb9d0db7..bcaa8a85 100644 --- a/server/src/persistence/redis.rs +++ b/server/src/persistence/redis.rs @@ -2,35 +2,50 @@ use std::collections::HashMap; use std::sync::Arc; use async_trait::async_trait; +use redis::cluster::ClusterClient; use redis::{Client, Commands, RedisError}; use tokio::sync::RwLock; +use tracing::{debug, info}; use unleash_types::client_features::ClientFeatures; -pub const FEATURES_KEY: &str = "unleash-features"; -pub const TOKENS_KEY: &str = "unleash-tokens"; -pub const REFRESH_TARGETS_KEY: &str = "unleash-refresh-targets"; - +use crate::persistence::redis::RedisClientOptions::{Cluster, Single}; use crate::types::{EdgeToken, TokenRefresh}; use crate::{error::EdgeError, types::EdgeResult}; use super::EdgePersistence; +pub const FEATURES_KEY: &str = "unleash-features"; +pub const TOKENS_KEY: &str = "unleash-tokens"; +pub const REFRESH_TARGETS_KEY: &str = "unleash-refresh-targets"; + impl From for EdgeError { fn from(err: RedisError) -> Self { EdgeError::PersistenceError(format!("Error connecting to Redis: {err}")) } } +enum RedisClientOptions { + Single(Client), + Cluster(ClusterClient), +} + pub struct RedisPersister { - redis_client: Arc>, + redis_client: Arc>, } impl RedisPersister { pub fn new(url: &str) -> Result { - let client = Arc::new(RwLock::new(redis::Client::open(url)?)); - + let client = Client::open(url)?; + info!("[REDIS Persister]: Configured single node client {client:?}"); Ok(Self { - redis_client: client, + redis_client: Arc::new(RwLock::new(Single(client))), + }) + } + pub fn new_with_cluster(urls: Vec) -> Result { + info!("[REDIS Persister]: Configuring cluster client against {urls:?}"); + let client = ClusterClient::new(urls)?; + Ok(Self { + redis_client: Arc::new(RwLock::new(Cluster(client))), }) } } @@ -38,47 +53,93 @@ impl RedisPersister { #[async_trait] impl EdgePersistence for RedisPersister { async fn load_tokens(&self) -> EdgeResult> { + debug!("Loading tokens from persistence"); let mut client = self.redis_client.write().await; - let raw_tokens: String = client.get(TOKENS_KEY)?; + let raw_tokens: String = match &mut *client { + Single(c) => c.get(TOKENS_KEY)?, + Cluster(c) => { + let mut conn = c.get_connection()?; + conn.get(TOKENS_KEY)? + } + }; serde_json::from_str::>(&raw_tokens) .map_err(|_e| EdgeError::TokenParseError("Failed to load tokens from redis".into())) } async fn save_tokens(&self, tokens: Vec) -> EdgeResult<()> { + debug!("Saving {} tokens to persistence", tokens.len()); let mut client = self.redis_client.write().await; let raw_tokens = serde_json::to_string(&tokens)?; - client.set(TOKENS_KEY, raw_tokens)?; + match &mut *client { + RedisClientOptions::Single(c) => c.set(TOKENS_KEY, raw_tokens)?, + RedisClientOptions::Cluster(c) => { + let mut conn = c.get_connection()?; + conn.set(TOKENS_KEY, raw_tokens)? + } + }; Ok(()) } async fn load_refresh_targets(&self) -> EdgeResult> { + debug!("Loading refresh targets"); let mut client = self.redis_client.write().await; - let refresh_targets: String = client.get(REFRESH_TARGETS_KEY)?; + let refresh_targets: String = match &mut *client { + Single(client) => client.get(REFRESH_TARGETS_KEY)?, + Cluster(client) => { + let mut conn = client.get_connection()?; + conn.get(REFRESH_TARGETS_KEY)? + } + }; serde_json::from_str::>(&refresh_targets).map_err(|_| { EdgeError::TokenParseError("Failed to load refresh targets from redis".into()) }) } async fn save_refresh_targets(&self, refresh_targets: Vec) -> EdgeResult<()> { + debug!("Saving refresh targets: {}", refresh_targets.len()); let mut client = self.redis_client.write().await; let refresh_targets = serde_json::to_string(&refresh_targets)?; - client.set(REFRESH_TARGETS_KEY, refresh_targets)?; + match &mut *client { + Single(client) => client.set(REFRESH_TARGETS_KEY, refresh_targets)?, + Cluster(client) => { + let mut conn = client.get_connection()?; + conn.set(REFRESH_TARGETS_KEY, refresh_targets)? + } + }; + debug!("Done saving refresh target"); Ok(()) } async fn load_features(&self) -> EdgeResult> { + debug!("Loading features from persistence"); let mut client = self.redis_client.write().await; - let raw_features: String = client.get(FEATURES_KEY)?; + let raw_features: String = match &mut *client { + Single(client) => client.get(FEATURES_KEY)?, + Cluster(client) => { + let mut conn = client.get_connection()?; + conn.get(FEATURES_KEY)? + } + }; let raw_features = serde_json::from_str::>(&raw_features) .map_err(|e| EdgeError::ClientFeaturesParseError(e.to_string()))?; Ok(raw_features.into_iter().collect()) } async fn save_features(&self, features: Vec<(String, ClientFeatures)>) -> EdgeResult<()> { + debug!("Saving {} features to persistence", features.len()); let mut client = self.redis_client.write().await; let raw_features = serde_json::to_string(&features)?; - client - .set(FEATURES_KEY, raw_features) - .map_err(EdgeError::from) + match &mut *client { + Single(client) => client + .set(FEATURES_KEY, raw_features) + .map_err(EdgeError::from)?, + Cluster(cluster) => { + let mut conn = cluster.get_connection()?; + conn.set(FEATURES_KEY, raw_features) + .map_err(EdgeError::from)? + } + }; + debug!("Done saving to persistence"); + Ok(()) } } diff --git a/server/tests/redis_test.rs b/server/tests/redis_test.rs index 374adb8a..99253a20 100644 --- a/server/tests/redis_test.rs +++ b/server/tests/redis_test.rs @@ -3,27 +3,27 @@ use std::str::FromStr; use actix_web::http::header::EntityTag; use chrono::Utc; use redis::Client; -use testcontainers::{clients::Cli, Container}; +use testcontainers::ContainerAsync; +use testcontainers::runners::AsyncRunner; use testcontainers_modules::redis::Redis; +use unleash_types::client_features::{ClientFeature, ClientFeatures}; use unleash_edge::{ - persistence::{redis::RedisPersister, EdgePersistence}, + persistence::{EdgePersistence, redis::RedisPersister}, types::{EdgeToken, TokenRefresh, TokenType}, }; -use unleash_types::client_features::{ClientFeature, ClientFeatures}; -fn setup_redis(docker: &Cli) -> (Client, String, Container) { - let node: Container = docker.run(Redis); - let host_port = node.get_host_port_ipv4(6379); +async fn setup_redis() -> (Client, String, ContainerAsync) { + let node = Redis.start().await; + let host_port = node.get_host_port_ipv4(6379).await; let url = format!("redis://127.0.0.1:{host_port}"); - (redis::Client::open(url.clone()).unwrap(), url, node) + (Client::open(url.clone()).unwrap(), url, node) } #[tokio::test] async fn redis_saves_and_restores_features_correctly() { - let docker = Cli::default(); - let (_client, url, _node) = setup_redis(&docker); + let (_client, url, _node) = setup_redis().await; let redis_persister = RedisPersister::new(&url).unwrap(); let features = ClientFeatures { @@ -46,8 +46,7 @@ async fn redis_saves_and_restores_features_correctly() { #[tokio::test] async fn redis_saves_and_restores_edge_tokens_correctly() { - let docker = Cli::default(); - let (_client, url, _node) = setup_redis(&docker); + let (_client, url, _node) = setup_redis().await; let redis_persister = RedisPersister::new(&url).unwrap(); let mut project_specific_token = EdgeToken::from_str("someproject:development.abcdefghijklmnopqr").unwrap(); @@ -64,8 +63,7 @@ async fn redis_saves_and_restores_edge_tokens_correctly() { #[tokio::test] async fn redis_saves_and_restores_token_refreshes_correctly() { - let docker = Cli::default(); - let (_client, url, _node) = setup_redis(&docker); + let (_client, url, _node) = setup_redis().await; let redis_persister = RedisPersister::new(&url).unwrap(); let edge_token = EdgeToken::from_str("someproject:development.abcdefghijklmnopqr").unwrap();