diff --git a/Cargo.lock b/Cargo.lock index 5010fe1de..755a22fbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -198,7 +198,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -209,7 +209,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -398,7 +398,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -512,7 +512,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -621,7 +621,7 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -667,13 +667,13 @@ checksum = "3fce8dd7fcfcbf3a0a87d8f515194b49d6135acab73e18bd380d1d93bb1a15eb" dependencies = [ "clap", "heck 0.4.1", - "indexmap 2.12.1", + "indexmap 2.13.0", "log", "proc-macro2", "quote", "serde", "serde_json", - "syn 2.0.113", + "syn 2.0.114", "tempfile", "toml", ] @@ -767,7 +767,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -854,7 +854,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1070,7 +1070,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -1084,7 +1084,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -1106,7 +1106,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -1117,7 +1117,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -1236,7 +1236,7 @@ version = "0.7.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -1379,7 +1379,7 @@ dependencies = [ "dataplane-tracectl", "derive_builder 0.20.2", "futures", - "libc 1.0.0-alpha.1", + "libc 1.0.0-alpha.2", "multi_index_map", "nix 0.30.1", "rtnetlink", @@ -1409,12 +1409,26 @@ dependencies = [ "serde", "serde-duration-ext", "serde_json", + "serde_yaml_ng", "thiserror 2.0.17", "tokio", "tracing", "ureq", ] +[[package]] +name = "dataplane-k8s-less" +version = "0.7.0" +dependencies = [ + "dataplane-gwname", + "dataplane-k8s-intf", + "dataplane-tracectl", + "inotify", + "tokio", + "tracing", + "tracing-test", +] + [[package]] name = "dataplane-left-right-tlcache" version = "0.7.0" @@ -1458,6 +1472,7 @@ dependencies = [ "dataplane-id", "dataplane-interface-manager", "dataplane-k8s-intf", + "dataplane-k8s-less", "dataplane-lpm", "dataplane-nat", "dataplane-net", @@ -1766,7 +1781,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -1786,7 +1801,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core 0.20.2", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -1808,7 +1823,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.113", + "syn 2.0.114", "unicode-xid", ] @@ -1869,7 +1884,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -1948,7 +1963,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -1960,7 +1975,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -1992,7 +2007,7 @@ checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -2008,7 +2023,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc 0.2.179", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2097,7 +2112,7 @@ source = "git+https://github.com/githedgehog/fixin?branch=main#5e0de31606466b173 dependencies = [ "proc-macro-error2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -2230,7 +2245,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -2363,9 +2378,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" dependencies = [ "atomic-waker", "bytes", @@ -2373,7 +2388,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.4.0", - "indexmap 2.12.1", + "indexmap 2.13.0", "slab", "tokio", "tokio-util", @@ -2409,6 +2424,7 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ + "equivalent", "foldhash 0.2.0", ] @@ -2793,9 +2809,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -2803,6 +2819,28 @@ dependencies = [ "serde_core", ] +[[package]] +name = "inotify" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" +dependencies = [ + "bitflags 2.10.0", + "futures-core", + "inotify-sys", + "libc 0.2.179", + "tokio", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc 0.2.179", +] + [[package]] name = "instant" version = "0.1.13" @@ -3033,7 +3071,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -3088,9 +3126,9 @@ checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" [[package]] name = "libc" -version = "1.0.0-alpha.1" +version = "1.0.0-alpha.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7222002e5385b4d9327755661e3847c970e8fbf9dea6da8c57f16e8cfbff53a8" +checksum = "85272f924988b0557659867ecbb172a88990b2c5175bebd38c44956e7c74e701" [[package]] name = "libflate" @@ -3149,7 +3187,7 @@ checksum = "e5cec0ec4228b4853bb129c84dbf093a27e6c7a20526da046defc334a1b017f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -3282,7 +3320,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3589659543c04c7dc5526ec858591015b87cd8746583b51b48ef4353f99dbcda" dependencies = [ "base64 0.22.1", - "indexmap 2.12.1", + "indexmap 2.13.0", "metrics", "metrics-util", "quanta", @@ -3332,7 +3370,7 @@ checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -3409,7 +3447,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -3441,7 +3479,7 @@ source = "git+https://github.com/githedgehog/testn.git?tag=v0.0.9#299344af36ed01 dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -3649,7 +3687,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -3752,11 +3790,11 @@ dependencies = [ [[package]] name = "ordermap" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed637741ced8fb240855d22a2b4f208dab7a06bcce73380162e5253000c16758" +checksum = "cfa78c92071bbd3628c22b1a964f7e0eb201dc1456555db072beb1662ecd6715" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.13.0", ] [[package]] @@ -3871,7 +3909,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -3939,7 +3977,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -3967,7 +4005,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" dependencies = [ "base64 0.22.1", - "indexmap 2.12.1", + "indexmap 2.13.0", "quick-xml", "serde", "time", @@ -4056,7 +4094,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" dependencies = [ "equivalent", - "indexmap 2.12.1", + "indexmap 2.13.0", ] [[package]] @@ -4087,14 +4125,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] name = "proc-macro2" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" dependencies = [ "unicode-ident", ] @@ -4163,7 +4201,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -4183,7 +4221,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -4241,9 +4279,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.42" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" dependencies = [ "proc-macro2", ] @@ -4431,7 +4469,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -4529,7 +4567,7 @@ dependencies = [ "bytecheck", "bytes", "hashbrown 0.16.1", - "indexmap 2.12.1", + "indexmap 2.13.0", "munge", "ptr_meta", "rancor", @@ -4547,7 +4585,7 @@ checksum = "7f6dffea3c91fa91a3c0fc8a061b0e27fef25c6304728038a6d6bcb1c58ba9bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -4610,14 +4648,14 @@ dependencies = [ "errno", "libc 0.2.179", "linux-raw-sys 0.11.0", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.35" +version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ "aws-lc-rs", "log", @@ -4762,7 +4800,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -4869,7 +4907,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -4880,14 +4918,14 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] name = "serde_json" -version = "1.0.148" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", @@ -4904,7 +4942,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -4938,7 +4976,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.12.1", + "indexmap 2.13.0", "schemars 0.9.0", "schemars 1.2.0", "serde_core", @@ -4952,7 +4990,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.13.0", "itoa", "ryu", "serde", @@ -4965,7 +5003,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b4db627b98b36d4203a7b458cf3573730f2bb591b28871d916dfa9efabfd41f" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.13.0", "itoa", "ryu", "serde", @@ -4992,7 +5030,7 @@ checksum = "6f50427f258fb77356e4cd4aa0e87e2bd2c66dbcee41dc405282cae2bfc26c83" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -5117,9 +5155,9 @@ dependencies = [ [[package]] name = "small-map" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3212e658a14154c44759b0e2fe264bcfa369cf2aa2f789b6915de9db366d8d19" +checksum = "64c0b79fa0e86d80062670059d27f93911776cdeba2555bf428b455d8738c32f" dependencies = [ "hashbrown 0.16.1", ] @@ -5182,7 +5220,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -5248,9 +5286,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.113" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -5274,7 +5312,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -5293,7 +5331,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -5353,7 +5391,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -5364,7 +5402,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -5466,7 +5504,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -5559,7 +5597,7 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.13.0", "toml_datetime", "winnow 0.5.40", ] @@ -5570,7 +5608,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.13.0", "serde", "serde_spanned", "toml_datetime", @@ -5632,7 +5670,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.12.1", + "indexmap 2.13.0", "pin-project-lite", "slab", "sync_wrapper", @@ -5696,7 +5734,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -5766,7 +5804,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -5880,14 +5918,15 @@ dependencies = [ [[package]] name = "url" -version = "2.5.7" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", + "serde_derive", ] [[package]] @@ -6039,7 +6078,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", "wasm-bindgen-shared", ] @@ -6114,7 +6153,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -6125,7 +6164,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -6387,28 +6426,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.31" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.31" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] @@ -6428,7 +6467,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", "synstructure", ] @@ -6468,11 +6507,11 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.114", ] [[package]] name = "zmij" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e0d8dffbae3d840f64bda38e28391faef673a7b5a6017840f2a106c8145868" +checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8" diff --git a/Cargo.toml b/Cargo.toml index 317eeb906..b0046f199 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ members = [ "init", "interface-manager", "k8s-intf", + "k8s-less", "left-right-tlcache", "mgmt", "nat", @@ -63,6 +64,7 @@ id = { path = "./id", package = "dataplane-id", features = [] } init = { path = "./init", package = "dataplane-init", features = [] } interface-manager = { path = "./interface-manager", package = "dataplane-interface-manager", features = [] } k8s-intf = { path = "./k8s-intf", package = "dataplane-k8s-intf", features = [] } +k8s-less = { path = "./k8s-less", package = "dataplane-k8s-less", features = [] } left-right-tlcache = { path = "./left-right-tlcache", package = "dataplane-left-right-tlcache", features = [] } lpm = { path = "./lpm", package = "dataplane-lpm", features = [] } mgmt = { path = "./mgmt", package = "dataplane-mgmt", features = [] } @@ -116,6 +118,7 @@ hashbrown = { version = "0.16.1", default-features = false, features = [] } hwlocality = { version = "1.0.0-alpha.11", default-features = false, features = [] } hyper = { version = "1.8.1", default-features = false, features = [] } hyper-util = { version = "0.1.19", default-features = false, features = [] } +inotify = { version = "0.11.0", default-features = false, features = [] } ipnet = { version = "2.11.0", default-features = false, features = [] } k8s-openapi = { version = "0.26.1", default-features = false, features = [] } kanal = { version = "0.1.1", default-features = false, features = [] } diff --git a/args/Cargo.toml b/args/Cargo.toml index 8a31b0cd5..ba9226a76 100644 --- a/args/Cargo.toml +++ b/args/Cargo.toml @@ -22,7 +22,7 @@ serde = { workspace = true, features = ["derive"] } sha2 = { workspace = true, features = [] } thiserror = { workspace = true, features = [] } tracing = { workspace = true, features = ["std"] } -url = { workspace = true, features = ["std"] } +url = { workspace = true, features = ["std", "serde"] } uuid = { workspace = true, features = [] } [dev-dependencies] diff --git a/args/src/lib.rs b/args/src/lib.rs index 32f2db251..5ead9fa62 100644 --- a/args/src/lib.rs +++ b/args/src/lib.rs @@ -555,7 +555,8 @@ pub struct RoutingConfigSection { #[rkyv(attr(derive(PartialEq, Eq, Debug)))] pub struct ConfigServerSection { /// gRPC server address (TCP or Unix socket) - pub address: GrpcAddress, + pub address: Option, + pub config_dir: Option, } /// Complete dataplane launch configuration. @@ -1088,12 +1089,12 @@ impl TryFrom for LaunchConfiguration { general: GeneralConfigSection { name: value.get_name().cloned(), }, - config_server: value - .grpc_address() - .map_err(InvalidCmdArguments::InvalidGrpcAddress)? - .map(|grpc_address| ConfigServerSection { - address: grpc_address, - }), + config_server: Some(ConfigServerSection { + address: value + .grpc_address() + .map_err(InvalidCmdArguments::InvalidGrpcAddress)?, + config_dir: value.config_dir().cloned(), + }), driver: match &value.driver { Some(driver) if driver == "dpdk" => { // TODO: adjust command line to specify lcore usage more flexibly in next PR @@ -1275,6 +1276,17 @@ E.g. default=error,all=info,nat=debug will set the default target to error, and #[arg(long, help = "Set the name of this gateway")] name: Option, + + #[arg( + long, + help = "Run in k8s-less mode using this directory to watch for configurations. +You can copy json/yaml config files in this directory to reconfigure dataplane. You can modify existing +files or just 'touch' them to trigger a new reconfiguration. Every change will increase the generation id by one. +NOTE: dataplane tracks file 'save' events. If you modify an existing file, depending on the editor used, this will +trigger more than one reconfiguration (e.g. gedit). If this is undesired, use nano or vi(m), or edit your file +elsewhere and copy it in the configuration directory. This mode is meant mostly for debugging or early testing." + )] + config_dir: Option, } impl CmdArgs { @@ -1464,6 +1476,14 @@ impl CmdArgs { pub fn get_name(&self) -> Option<&String> { self.name.as_ref() } + + /// Get the configuration directory. + /// Setting the configuration directory enables k8s-less mode, where configurations are retrieved from files + /// or their changes in the configuration directory. + #[must_use] + pub fn config_dir(&self) -> Option<&String> { + self.config_dir.as_ref() + } } #[cfg(test)] diff --git a/dataplane/src/main.rs b/dataplane/src/main.rs index bc95d53a2..4aad85604 100644 --- a/dataplane/src/main.rs +++ b/dataplane/src/main.rs @@ -158,6 +158,7 @@ fn main() { /* start management */ start_mgmt(MgmtParams { grpc_addr, + config_dir: args.config_dir().cloned(), hostname: get_gw_name().unwrap_or_else(|| unreachable!()).to_owned(), processor_params: ConfigProcessorParams { router_ctl: setup.router.get_ctl_tx(), diff --git a/k8s-intf/Cargo.toml b/k8s-intf/Cargo.toml index a3efed406..95fc5fc8f 100644 --- a/k8s-intf/Cargo.toml +++ b/k8s-intf/Cargo.toml @@ -27,6 +27,7 @@ schemars = { workspace = true, features = ["derive", "std"] } serde = { workspace = true } serde-duration-ext = { workspace = true } serde_json = { workspace = true } +serde_yaml_ng = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } diff --git a/k8s-intf/src/lib.rs b/k8s-intf/src/lib.rs index b6beb6718..d7d8dc0b2 100644 --- a/k8s-intf/src/lib.rs +++ b/k8s-intf/src/lib.rs @@ -9,6 +9,7 @@ pub mod bolero; pub mod client; pub mod generated; +pub mod utils; pub mod gateway_agent_crd { pub use crate::generated::gateway_agent_crd::*; diff --git a/k8s-intf/src/utils.rs b/k8s-intf/src/utils.rs new file mode 100644 index 000000000..1828da73c --- /dev/null +++ b/k8s-intf/src/utils.rs @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Open Network Fabric Authors + +//! Utils to build the gateway CRD `GatewayAgentSpec` from JSON / YAML text files. + +use crate::gateway_agent_crd::GatewayAgentSpec; +use serde_yaml_ng; +use std::fs; +use std::path::Path; + +/// Read the file at `path` and deserialize it from YAML into a `GatewayAgentSpec` object. +fn load_crd_from_yaml(path: &str) -> Result { + let yaml = fs::read_to_string(path) + .map_err(|e| format!("Failed to read CRD from YAML file ({path}): {e}"))?; + let crd: GatewayAgentSpec = serde_yaml_ng::from_str(&yaml) + .map_err(|e| format!("Failed to deserialize CRD from YAML file ({path}): {e}"))?; + Ok(crd) +} + +/// Read the file at `path` and deserialize it from JSON into a `GatewayAgentSpec` object. +fn load_crd_from_json(path: &str) -> Result { + let json = fs::read_to_string(path) + .map_err(|e| format!("Failed to read CRD from JSON file ({path}): {e}"))?; + let crd: GatewayAgentSpec = serde_json::from_str(&json) + .map_err(|e| format!("Failed to deserialize CRD from JSON file ({path}): {e}"))?; + Ok(crd) +} + +/// Read the file at `path` and deserialize into a `GatewayAgentSpec` object. +/// The file is assumed to contain a gateway spec CRD in JSON or YAML. +/// +/// # Errors +/// This function may fail if the file does not exist or cannot be opened / read, or if the contents +/// cannot be deserialized. +pub fn load_crd_from_file(path: &str) -> Result { + let ext = Path::new(path).extension(); + match ext { + Some(ext) if ext.eq_ignore_ascii_case("yaml") || ext.eq_ignore_ascii_case("yml") => { + load_crd_from_yaml(path) + } + Some(ext) if ext.eq_ignore_ascii_case("json") => load_crd_from_json(path), + Some(ext) => Err(format!("Unsupported file extension {}", ext.display())), + None => Err("Missing file extension".to_string()), + } +} diff --git a/k8s-less/Cargo.toml b/k8s-less/Cargo.toml new file mode 100644 index 000000000..bd4a62d94 --- /dev/null +++ b/k8s-less/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "dataplane-k8s-less" +version.workspace = true +edition.workspace = true +license.workspace = true +publish.workspace = true +repository.workspace = true + +[dependencies] +gwname = { workspace = true } +inotify = { workspace = true, features = ["stream"] } +k8s-intf = { workspace = true } +tokio = { workspace = true, features = ["macros", "rt", "fs"] } +tracectl = { workspace = true } +tracing = { workspace = true } +tracing-test = { workspace = true } \ No newline at end of file diff --git a/k8s-less/src/lib.rs b/k8s-less/src/lib.rs new file mode 100644 index 000000000..a72f5070e --- /dev/null +++ b/k8s-less/src/lib.rs @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Open Network Fabric Authors + +//! Support for k8s-less mode where CRDs are learnt from a file + +mod local; + +pub use local::kubeless_watch_gateway_agent_crd; diff --git a/k8s-less/src/local.rs b/k8s-less/src/local.rs new file mode 100644 index 000000000..f1e3c85d4 --- /dev/null +++ b/k8s-less/src/local.rs @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Open Network Fabric Authors + +use gwname::get_gw_name; +use inotify::{Event, EventMask, Inotify, WatchMask}; +use k8s_intf::gateway_agent_crd::GatewayAgent; +use k8s_intf::utils::load_crd_from_file; +use std::collections::BTreeSet; +use std::ffi::OsStr; +use std::os::fd::AsRawFd; +use std::path::{Path, PathBuf}; +use tokio::fs::create_dir_all; +use tokio::io::unix::AsyncFd; + +#[allow(unused)] +use tracing::{debug, error, trace, warn}; + +/// Tell if an event reported by `Inotify` is worth checking according +/// to our configuration. This function is somewhat heuristic to accommodate +/// for changes done by text editors, which may create temporary files when +/// editing them instead of modifying them in-place. This helper returns +/// the name of the file to process or `None` if the event should be ignored. +fn check_event(event: &Event<&OsStr>, dir: &str) -> Option { + // trace!("event: {:?}, name: {:?}", event.mask, event.name); + + // we watch a directory; so `Inotify` should report the name of a file. + let filename = event.name?; + + // OsStr should be valid Unicode + let filename = filename.to_str()?; + + // some editors create '.swp/.swx' (e.g. nano) files or temporary hidden files (vi) + if filename.contains(".sw") || filename.starts_with('.') { + return None; + } + + // This is sanity + if event.mask != EventMask::CLOSE_WRITE { + return None; + } + + // name of file to read a crd spec from + Some(Path::new(dir).join(filename)) +} + +/// Watch for changes in the directory named `path`. If the directory does not exist, +/// it gets created. When files are created or modified in the watched directory: +/// - read their contents (assumed to contain a crd spec in yaml or json) +/// - deserialize them into a `GatewayAgentSpec` +/// - build a GatewayAgent object +/// - call the caller-specified callback. +/// +/// The generation id of the GatewayAgent is automatically set by this function and +/// monotonically increases every time a `GatewayAgentSpec` is successfully deserialized +/// from a file. +/// +/// # Errors +/// Returns an error if the directory or the corresponding watch cannot be created. +pub async fn kubeless_watch_gateway_agent_crd( + path: &str, + callback: impl AsyncFn(&GatewayAgent), +) -> Result<(), String> { + let gwname = get_gw_name().unwrap_or_else(|| { + let name = "test-gw"; + warn!("Warning, gateway name is NOT set. Setting to '{name}'..."); + name + }); + + create_dir_all(path) + .await + .map_err(|e| format!("Failed to create directory '{path}': {e}"))?; + + let mut inotify = Inotify::init().map_err(|e| format!("Failed to initialize inotify: {e}"))?; + inotify + .watches() + .add(Path::new(path), WatchMask::CLOSE_WRITE) + .map_err(|e| format!("Failed to add watch for path {path}: {e}"))?; + + // generation id is automatically set and will monotonically increase + let mut generation: i64 = 1; + + let async_fd = AsyncFd::new(inotify.as_raw_fd()) + .map_err(|e| format!("Failed to create async fd for inotify: {e}"))?; + + debug!("Starting kubeless watcher for directory '{path}'..."); + loop { + trace!("Waiting for changes..."); + let Ok(mut guard) = async_fd.readable().await else { + error!("Failure checking async fd readiness"); + continue; + }; + + let mut buffer = [0u8; 4096]; + match inotify.read_events(&mut buffer) { + Ok(events) => { + // collapse all events by filename: `check_event` will filter out unwanted events. + let files: BTreeSet = + events.filter_map(|e| check_event(&e, path)).collect(); + + // iterate over the set of files. Deserialize their contents and call user callback. + for file in files.iter() { + debug!("Processing file {file:#?}..."); + match load_crd_from_file(file.to_str().unwrap()) { + Ok(crd_spec) => { + let mut crd = GatewayAgent::new(gwname, crd_spec); + crd.metadata.generation = Some(generation); + crd.metadata.namespace = Some("fab".to_string()); + generation += 1; + callback(&crd).await; + } + Err(e) => error!("Failed to load crd spec from file: {e}"), + }; + } + } + Err(e) => error!("Failed to read events from file: {e}"), + } + guard.clear_ready(); + } +} + +#[cfg(test)] +mod test { + use std::fs::File; + use std::io::Write; + use std::path::PathBuf; + use std::time::Duration; + + use super::kubeless_watch_gateway_agent_crd; + use tracing::debug; + use tracing_test::traced_test; + + #[tokio::test] + #[traced_test] + async fn test_kubeless() { + let path = "/tmp/kubeless-dir"; + + // spawn a task to create a config file in the directory watched by kubeless + tokio::spawn(async move { + // wait 2 seconds before creating config + tokio::time::sleep(Duration::from_secs(2)).await; + + // build minimal config for us to know that it was deserialized successfully + let yaml = " +agentVersion: MINIMAL +gateway: + asn: 65000 +"; + let mut filepath = PathBuf::from(path).join("minimal-config"); + filepath.add_extension("yaml"); + let mut file = File::create(filepath.to_str().unwrap()).unwrap(); + file.write_all(yaml.as_bytes()).unwrap(); + }); + + // start watcher. Watcher will exit as soon as a config is detected and successfully + // deserialized into a GatewayAgent object + kubeless_watch_gateway_agent_crd(path, async move |crd| { + let generation = crd.metadata.generation.unwrap(); + let name = crd.metadata.name.as_ref().unwrap(); + let asn = crd.spec.gateway.as_ref().unwrap().asn.unwrap(); + let agent_version = crd.spec.agent_version.as_ref().unwrap(); + debug!("Got CRD to chew:\n generation: {generation}\n name: {name}\n agentVersion: {agent_version}\n asn: {asn}"); + assert_eq!(generation, 1); + assert_eq!(name, "test-gw"); + assert_eq!(agent_version, "MINIMAL"); + assert_eq!(asn, 65000); + std::process::exit(0); + }) + .await + .unwrap(); + } +} diff --git a/mgmt/Cargo.toml b/mgmt/Cargo.toml index 5fb394b73..97cb77b86 100644 --- a/mgmt/Cargo.toml +++ b/mgmt/Cargo.toml @@ -24,6 +24,7 @@ gateway_config = { workspace = true } id = { workspace = true } interface-manager = { workspace = true } k8s-intf = { workspace = true } +k8s-less = { workspace = true } lpm = { workspace = true } nat = { workspace = true } net = { workspace = true } diff --git a/mgmt/src/processor/k8s_less_client.rs b/mgmt/src/processor/k8s_less_client.rs new file mode 100644 index 000000000..3dfc328c5 --- /dev/null +++ b/mgmt/src/processor/k8s_less_client.rs @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Open Network Fabric Authors + +use config::{ExternalConfig, GwConfig}; +use futures::TryFutureExt; +use k8s_less::kubeless_watch_gateway_agent_crd; +use std::sync::Arc; +use tracing::{error, info}; + +use crate::processor::mgmt_client::{ConfigClient, ConfigProcessorError}; + +#[derive(Debug, thiserror::Error)] +pub enum K8sLessError { + #[error("K8sless exited early")] + EarlyTermination, + #[error("Watching error: {0}")] + WatchError(String), +} + +pub struct K8sLess { + pathdir: String, + client: ConfigClient, +} + +impl K8sLess { + pub fn new(pathdir: &str, client: ConfigClient) -> Self { + Self { + pathdir: pathdir.to_string(), + client, + } + } + + pub async fn start_config_watch(k8sless: Arc) -> Result<(), K8sLessError> { + info!("Starting config watcher for directory {}", k8sless.pathdir); + + kubeless_watch_gateway_agent_crd(&k8sless.pathdir.clone(), async move |ga| { + info!("Attempting to deserialize new gateway CRD ..."); + + let external_config = ExternalConfig::try_from(ga); + match external_config { + Err(e) => error!("Failed to convert K8sGatewayAgent to ExternalConfig: {e}"), + Ok(external_config) => { + let genid = external_config.genid; + let applied_genid = match k8sless.client.get_generation().await { + Ok(genid) => genid, + Err(ConfigProcessorError::NoConfigApplied) => 0, + Err(e) => { + error!("Failed to get current config generation: {e}"); + return; + } + }; + info!("Current configuration is {applied_genid}"); + + let gwconfig = GwConfig::new(external_config); + + // request the config processor to apply the config and update status on success + match k8sless.client.apply_config(gwconfig).await { + Ok(()) => info!("Config for generation {genid} was successfully applied"), + Err(e) => error!("Failed to apply the config for generation {genid}: {e}"), + } + } + } + }) + .map_err(K8sLessError::WatchError) + .await?; + + Err(K8sLessError::EarlyTermination) + } +} diff --git a/mgmt/src/processor/launch.rs b/mgmt/src/processor/launch.rs index e51b17fa8..2e6882074 100644 --- a/mgmt/src/processor/launch.rs +++ b/mgmt/src/processor/launch.rs @@ -2,6 +2,7 @@ // Copyright Open Network Fabric Authors use crate::processor::k8s_client::{K8sClient, K8sClientError}; +use crate::processor::k8s_less_client::{K8sLess, K8sLessError}; use crate::processor::proc::ConfigProcessor; use std::fmt::Display; @@ -47,6 +48,9 @@ pub enum LaunchError { ProcessorError(std::io::Error), #[error("Error starting/waiting for Config Processor task: {0}")] ProcessorJoinError(tokio::task::JoinError), + + #[error("Error in k8s-less mode: {0}")] + K8LessError(#[from] K8sLessError), } /// Start the gRPC server on TCP @@ -181,6 +185,7 @@ impl Display for ServerAddress { pub struct MgmtParams { pub grpc_addr: Option, + pub config_dir: Option, pub hostname: String, pub processor_params: ConfigProcessorParams, } @@ -229,7 +234,17 @@ pub fn start_mgmt( Err(LaunchError::PrematureGrpcExit) } }) - } else { + } else if let Some(config_dir) = ¶ms.config_dir { + warn!("Running in k8s-less mode...."); + rt.block_on(async { + let (processor, client) = ConfigProcessor::new(params.processor_params); + let k8sless = Arc::new(K8sLess::new(config_dir, client)); + tokio::spawn(async { processor.run().await }); + K8sLess::start_config_watch(k8sless).await + })?; + Ok(()) + } + else { debug!("Will start watching k8s for configuration changes"); rt.block_on(async { let (processor, client) = ConfigProcessor::new(params.processor_params); diff --git a/mgmt/src/processor/mod.rs b/mgmt/src/processor/mod.rs index 05fff069f..20c8ddc36 100644 --- a/mgmt/src/processor/mod.rs +++ b/mgmt/src/processor/mod.rs @@ -8,6 +8,7 @@ pub(crate) mod confbuild; mod display; pub(crate) mod gwconfigdb; pub(crate) mod k8s_client; +pub(crate) mod k8s_less_client; pub(crate) mod launch; pub(crate) mod mgmt_client; pub(crate) mod proc;