├── .github └── workflows │ └── rust.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── echo-example.yaml ├── echoes.example.com.yaml ├── showcase.gif └── src ├── crd.rs ├── echo.rs ├── finalizer.rs └── main.rs /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - uses: debianmaster/actions-k3s@master 21 | id: k3s 22 | with: 23 | version: 'latest' 24 | 25 | - name: Build 26 | run: cargo build --verbose 27 | 28 | - name: Run tests 29 | run: cargo test --verbose 30 | 31 | - name: Apply the custom resource definition 32 | run: kubectl apply -f echoes.example.com.yaml 33 | 34 | - name: Run the operator 35 | run: cargo run & 36 | 37 | - name: Apply the custom resource after a small pause 38 | run: sleep 1 && kubectl apply -f echo-example.yaml 39 | 40 | - name: Validate that the deployment has been created after a small pause 41 | run: sleep 1 && kubectl wait --for=condition=available --timeout=60s deployment/test-echo 42 | 43 | - name: Validate that the two pods have been created 44 | run: kubectl get pods | grep "test-echo" 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .idea/ -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "ahash" 22 | version = "0.8.12" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" 25 | dependencies = [ 26 | "cfg-if", 27 | "getrandom 0.3.3", 28 | "once_cell", 29 | "version_check", 30 | "zerocopy", 31 | ] 32 | 33 | [[package]] 34 | name = "aho-corasick" 35 | version = "1.1.3" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 38 | dependencies = [ 39 | "memchr", 40 | ] 41 | 42 | [[package]] 43 | name = "allocator-api2" 44 | version = "0.2.21" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" 47 | 48 | [[package]] 49 | name = "async-broadcast" 50 | version = "0.7.2" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" 53 | dependencies = [ 54 | "event-listener", 55 | "event-listener-strategy", 56 | "futures-core", 57 | "pin-project-lite", 58 | ] 59 | 60 | [[package]] 61 | name = "async-stream" 62 | version = "0.3.6" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" 65 | dependencies = [ 66 | "async-stream-impl", 67 | "futures-core", 68 | "pin-project-lite", 69 | ] 70 | 71 | [[package]] 72 | name = "async-stream-impl" 73 | version = "0.3.6" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" 76 | dependencies = [ 77 | "proc-macro2", 78 | "quote", 79 | "syn", 80 | ] 81 | 82 | [[package]] 83 | name = "autocfg" 84 | version = "1.4.0" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 87 | 88 | [[package]] 89 | name = "backon" 90 | version = "1.5.0" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "fd0b50b1b78dbadd44ab18b3c794e496f3a139abb9fbc27d9c94c4eebbb96496" 93 | dependencies = [ 94 | "fastrand", 95 | "gloo-timers", 96 | "tokio", 97 | ] 98 | 99 | [[package]] 100 | name = "backtrace" 101 | version = "0.3.75" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" 104 | dependencies = [ 105 | "addr2line", 106 | "cfg-if", 107 | "libc", 108 | "miniz_oxide", 109 | "object", 110 | "rustc-demangle", 111 | "windows-targets", 112 | ] 113 | 114 | [[package]] 115 | name = "base64" 116 | version = "0.21.7" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 119 | 120 | [[package]] 121 | name = "base64" 122 | version = "0.22.1" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 125 | 126 | [[package]] 127 | name = "bitflags" 128 | version = "2.9.1" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" 131 | 132 | [[package]] 133 | name = "block-buffer" 134 | version = "0.10.4" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 137 | dependencies = [ 138 | "generic-array", 139 | ] 140 | 141 | [[package]] 142 | name = "bumpalo" 143 | version = "3.17.0" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" 146 | 147 | [[package]] 148 | name = "bytes" 149 | version = "1.10.1" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 152 | 153 | [[package]] 154 | name = "cc" 155 | version = "1.2.23" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" 158 | dependencies = [ 159 | "shlex", 160 | ] 161 | 162 | [[package]] 163 | name = "cfg-if" 164 | version = "1.0.0" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 167 | 168 | [[package]] 169 | name = "chrono" 170 | version = "0.4.41" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" 173 | dependencies = [ 174 | "num-traits", 175 | "serde", 176 | ] 177 | 178 | [[package]] 179 | name = "concurrent-queue" 180 | version = "2.5.0" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 183 | dependencies = [ 184 | "crossbeam-utils", 185 | ] 186 | 187 | [[package]] 188 | name = "core-foundation" 189 | version = "0.9.4" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 192 | dependencies = [ 193 | "core-foundation-sys", 194 | "libc", 195 | ] 196 | 197 | [[package]] 198 | name = "core-foundation" 199 | version = "0.10.0" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" 202 | dependencies = [ 203 | "core-foundation-sys", 204 | "libc", 205 | ] 206 | 207 | [[package]] 208 | name = "core-foundation-sys" 209 | version = "0.8.7" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 212 | 213 | [[package]] 214 | name = "cpufeatures" 215 | version = "0.2.17" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 218 | dependencies = [ 219 | "libc", 220 | ] 221 | 222 | [[package]] 223 | name = "crossbeam-utils" 224 | version = "0.8.21" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" 227 | 228 | [[package]] 229 | name = "crypto-common" 230 | version = "0.1.6" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 233 | dependencies = [ 234 | "generic-array", 235 | "typenum", 236 | ] 237 | 238 | [[package]] 239 | name = "darling" 240 | version = "0.20.11" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" 243 | dependencies = [ 244 | "darling_core", 245 | "darling_macro", 246 | ] 247 | 248 | [[package]] 249 | name = "darling_core" 250 | version = "0.20.11" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" 253 | dependencies = [ 254 | "fnv", 255 | "ident_case", 256 | "proc-macro2", 257 | "quote", 258 | "strsim", 259 | "syn", 260 | ] 261 | 262 | [[package]] 263 | name = "darling_macro" 264 | version = "0.20.11" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" 267 | dependencies = [ 268 | "darling_core", 269 | "quote", 270 | "syn", 271 | ] 272 | 273 | [[package]] 274 | name = "derive_more" 275 | version = "2.0.1" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" 278 | dependencies = [ 279 | "derive_more-impl", 280 | ] 281 | 282 | [[package]] 283 | name = "derive_more-impl" 284 | version = "2.0.1" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" 287 | dependencies = [ 288 | "proc-macro2", 289 | "quote", 290 | "syn", 291 | ] 292 | 293 | [[package]] 294 | name = "digest" 295 | version = "0.10.7" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 298 | dependencies = [ 299 | "block-buffer", 300 | "crypto-common", 301 | ] 302 | 303 | [[package]] 304 | name = "dyn-clone" 305 | version = "1.0.19" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" 308 | 309 | [[package]] 310 | name = "educe" 311 | version = "0.6.0" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" 314 | dependencies = [ 315 | "enum-ordinalize", 316 | "proc-macro2", 317 | "quote", 318 | "syn", 319 | ] 320 | 321 | [[package]] 322 | name = "either" 323 | version = "1.15.0" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 326 | 327 | [[package]] 328 | name = "enum-ordinalize" 329 | version = "4.3.0" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" 332 | dependencies = [ 333 | "enum-ordinalize-derive", 334 | ] 335 | 336 | [[package]] 337 | name = "enum-ordinalize-derive" 338 | version = "4.3.1" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" 341 | dependencies = [ 342 | "proc-macro2", 343 | "quote", 344 | "syn", 345 | ] 346 | 347 | [[package]] 348 | name = "equivalent" 349 | version = "1.0.2" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 352 | 353 | [[package]] 354 | name = "event-listener" 355 | version = "5.4.0" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" 358 | dependencies = [ 359 | "concurrent-queue", 360 | "parking", 361 | "pin-project-lite", 362 | ] 363 | 364 | [[package]] 365 | name = "event-listener-strategy" 366 | version = "0.5.4" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" 369 | dependencies = [ 370 | "event-listener", 371 | "pin-project-lite", 372 | ] 373 | 374 | [[package]] 375 | name = "fastrand" 376 | version = "2.3.0" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 379 | 380 | [[package]] 381 | name = "fnv" 382 | version = "1.0.7" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 385 | 386 | [[package]] 387 | name = "foldhash" 388 | version = "0.1.5" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" 391 | 392 | [[package]] 393 | name = "form_urlencoded" 394 | version = "1.2.1" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 397 | dependencies = [ 398 | "percent-encoding", 399 | ] 400 | 401 | [[package]] 402 | name = "futures" 403 | version = "0.3.31" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 406 | dependencies = [ 407 | "futures-channel", 408 | "futures-core", 409 | "futures-executor", 410 | "futures-io", 411 | "futures-sink", 412 | "futures-task", 413 | "futures-util", 414 | ] 415 | 416 | [[package]] 417 | name = "futures-channel" 418 | version = "0.3.31" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 421 | dependencies = [ 422 | "futures-core", 423 | "futures-sink", 424 | ] 425 | 426 | [[package]] 427 | name = "futures-core" 428 | version = "0.3.31" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 431 | 432 | [[package]] 433 | name = "futures-executor" 434 | version = "0.3.31" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 437 | dependencies = [ 438 | "futures-core", 439 | "futures-task", 440 | "futures-util", 441 | ] 442 | 443 | [[package]] 444 | name = "futures-io" 445 | version = "0.3.31" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 448 | 449 | [[package]] 450 | name = "futures-macro" 451 | version = "0.3.31" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 454 | dependencies = [ 455 | "proc-macro2", 456 | "quote", 457 | "syn", 458 | ] 459 | 460 | [[package]] 461 | name = "futures-sink" 462 | version = "0.3.31" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 465 | 466 | [[package]] 467 | name = "futures-task" 468 | version = "0.3.31" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 471 | 472 | [[package]] 473 | name = "futures-util" 474 | version = "0.3.31" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 477 | dependencies = [ 478 | "futures-channel", 479 | "futures-core", 480 | "futures-io", 481 | "futures-macro", 482 | "futures-sink", 483 | "futures-task", 484 | "memchr", 485 | "pin-project-lite", 486 | "pin-utils", 487 | "slab", 488 | ] 489 | 490 | [[package]] 491 | name = "generic-array" 492 | version = "0.14.7" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 495 | dependencies = [ 496 | "typenum", 497 | "version_check", 498 | ] 499 | 500 | [[package]] 501 | name = "getrandom" 502 | version = "0.2.16" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" 505 | dependencies = [ 506 | "cfg-if", 507 | "libc", 508 | "wasi 0.11.0+wasi-snapshot-preview1", 509 | ] 510 | 511 | [[package]] 512 | name = "getrandom" 513 | version = "0.3.3" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" 516 | dependencies = [ 517 | "cfg-if", 518 | "libc", 519 | "r-efi", 520 | "wasi 0.14.2+wasi-0.2.4", 521 | ] 522 | 523 | [[package]] 524 | name = "gimli" 525 | version = "0.31.1" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 528 | 529 | [[package]] 530 | name = "gloo-timers" 531 | version = "0.3.0" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" 534 | dependencies = [ 535 | "futures-channel", 536 | "futures-core", 537 | "js-sys", 538 | "wasm-bindgen", 539 | ] 540 | 541 | [[package]] 542 | name = "hashbrown" 543 | version = "0.15.3" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" 546 | dependencies = [ 547 | "allocator-api2", 548 | "equivalent", 549 | "foldhash", 550 | ] 551 | 552 | [[package]] 553 | name = "headers" 554 | version = "0.4.0" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" 557 | dependencies = [ 558 | "base64 0.21.7", 559 | "bytes", 560 | "headers-core", 561 | "http", 562 | "httpdate", 563 | "mime", 564 | "sha1", 565 | ] 566 | 567 | [[package]] 568 | name = "headers-core" 569 | version = "0.3.0" 570 | source = "registry+https://github.com/rust-lang/crates.io-index" 571 | checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" 572 | dependencies = [ 573 | "http", 574 | ] 575 | 576 | [[package]] 577 | name = "home" 578 | version = "0.5.11" 579 | source = "registry+https://github.com/rust-lang/crates.io-index" 580 | checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" 581 | dependencies = [ 582 | "windows-sys 0.59.0", 583 | ] 584 | 585 | [[package]] 586 | name = "hostname" 587 | version = "0.4.1" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65" 590 | dependencies = [ 591 | "cfg-if", 592 | "libc", 593 | "windows-link", 594 | ] 595 | 596 | [[package]] 597 | name = "http" 598 | version = "1.3.1" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" 601 | dependencies = [ 602 | "bytes", 603 | "fnv", 604 | "itoa", 605 | ] 606 | 607 | [[package]] 608 | name = "http-body" 609 | version = "1.0.1" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 612 | dependencies = [ 613 | "bytes", 614 | "http", 615 | ] 616 | 617 | [[package]] 618 | name = "http-body-util" 619 | version = "0.1.3" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" 622 | dependencies = [ 623 | "bytes", 624 | "futures-core", 625 | "http", 626 | "http-body", 627 | "pin-project-lite", 628 | ] 629 | 630 | [[package]] 631 | name = "httparse" 632 | version = "1.10.1" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 635 | 636 | [[package]] 637 | name = "httpdate" 638 | version = "1.0.3" 639 | source = "registry+https://github.com/rust-lang/crates.io-index" 640 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 641 | 642 | [[package]] 643 | name = "hyper" 644 | version = "1.6.0" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 647 | dependencies = [ 648 | "bytes", 649 | "futures-channel", 650 | "futures-util", 651 | "http", 652 | "http-body", 653 | "httparse", 654 | "itoa", 655 | "pin-project-lite", 656 | "smallvec", 657 | "tokio", 658 | "want", 659 | ] 660 | 661 | [[package]] 662 | name = "hyper-http-proxy" 663 | version = "1.1.0" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "7ad4b0a1e37510028bc4ba81d0e38d239c39671b0f0ce9e02dfa93a8133f7c08" 666 | dependencies = [ 667 | "bytes", 668 | "futures-util", 669 | "headers", 670 | "http", 671 | "hyper", 672 | "hyper-rustls", 673 | "hyper-util", 674 | "pin-project-lite", 675 | "rustls-native-certs 0.7.3", 676 | "tokio", 677 | "tokio-rustls", 678 | "tower-service", 679 | ] 680 | 681 | [[package]] 682 | name = "hyper-rustls" 683 | version = "0.27.5" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" 686 | dependencies = [ 687 | "futures-util", 688 | "http", 689 | "hyper", 690 | "hyper-util", 691 | "log", 692 | "rustls", 693 | "rustls-native-certs 0.8.1", 694 | "rustls-pki-types", 695 | "tokio", 696 | "tokio-rustls", 697 | "tower-service", 698 | ] 699 | 700 | [[package]] 701 | name = "hyper-timeout" 702 | version = "0.5.2" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" 705 | dependencies = [ 706 | "hyper", 707 | "hyper-util", 708 | "pin-project-lite", 709 | "tokio", 710 | "tower-service", 711 | ] 712 | 713 | [[package]] 714 | name = "hyper-util" 715 | version = "0.1.11" 716 | source = "registry+https://github.com/rust-lang/crates.io-index" 717 | checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" 718 | dependencies = [ 719 | "bytes", 720 | "futures-channel", 721 | "futures-util", 722 | "http", 723 | "http-body", 724 | "hyper", 725 | "libc", 726 | "pin-project-lite", 727 | "socket2", 728 | "tokio", 729 | "tower-service", 730 | "tracing", 731 | ] 732 | 733 | [[package]] 734 | name = "ident_case" 735 | version = "1.0.1" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 738 | 739 | [[package]] 740 | name = "indexmap" 741 | version = "2.9.0" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" 744 | dependencies = [ 745 | "equivalent", 746 | "hashbrown", 747 | ] 748 | 749 | [[package]] 750 | name = "itoa" 751 | version = "1.0.15" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 754 | 755 | [[package]] 756 | name = "js-sys" 757 | version = "0.3.77" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 760 | dependencies = [ 761 | "once_cell", 762 | "wasm-bindgen", 763 | ] 764 | 765 | [[package]] 766 | name = "json-patch" 767 | version = "4.0.0" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "159294d661a039f7644cea7e4d844e6b25aaf71c1ffe9d73a96d768c24b0faf4" 770 | dependencies = [ 771 | "jsonptr", 772 | "serde", 773 | "serde_json", 774 | "thiserror 1.0.69", 775 | ] 776 | 777 | [[package]] 778 | name = "jsonpath-rust" 779 | version = "0.7.5" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "0c00ae348f9f8fd2d09f82a98ca381c60df9e0820d8d79fce43e649b4dc3128b" 782 | dependencies = [ 783 | "pest", 784 | "pest_derive", 785 | "regex", 786 | "serde_json", 787 | "thiserror 2.0.12", 788 | ] 789 | 790 | [[package]] 791 | name = "jsonptr" 792 | version = "0.7.1" 793 | source = "registry+https://github.com/rust-lang/crates.io-index" 794 | checksum = "a5a3cc660ba5d72bce0b3bb295bf20847ccbb40fd423f3f05b61273672e561fe" 795 | dependencies = [ 796 | "serde", 797 | "serde_json", 798 | ] 799 | 800 | [[package]] 801 | name = "k8s-openapi" 802 | version = "0.25.0" 803 | source = "registry+https://github.com/rust-lang/crates.io-index" 804 | checksum = "aa60a41b57ae1a0a071af77dbcf89fc9819cfe66edaf2beeb204c34459dcf0b2" 805 | dependencies = [ 806 | "base64 0.22.1", 807 | "chrono", 808 | "serde", 809 | "serde_json", 810 | ] 811 | 812 | [[package]] 813 | name = "kube" 814 | version = "1.0.0" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "1b49c39074089233c2bb7b1791d1b6c06c84dbab26757491fad9d233db0d432f" 817 | dependencies = [ 818 | "k8s-openapi", 819 | "kube-client", 820 | "kube-core", 821 | "kube-derive", 822 | "kube-runtime", 823 | ] 824 | 825 | [[package]] 826 | name = "kube-client" 827 | version = "1.0.0" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "e199797b1b08865041c9c698f0d11a91de0a8143e808b71e250cd4a1d7ce2b9f" 830 | dependencies = [ 831 | "base64 0.22.1", 832 | "bytes", 833 | "chrono", 834 | "either", 835 | "futures", 836 | "home", 837 | "http", 838 | "http-body", 839 | "http-body-util", 840 | "hyper", 841 | "hyper-http-proxy", 842 | "hyper-rustls", 843 | "hyper-timeout", 844 | "hyper-util", 845 | "jsonpath-rust", 846 | "k8s-openapi", 847 | "kube-core", 848 | "pem", 849 | "rustls", 850 | "secrecy", 851 | "serde", 852 | "serde_json", 853 | "serde_yaml", 854 | "thiserror 2.0.12", 855 | "tokio", 856 | "tokio-util", 857 | "tower", 858 | "tower-http", 859 | "tracing", 860 | ] 861 | 862 | [[package]] 863 | name = "kube-core" 864 | version = "1.0.0" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "1bdefbba89dea2d99ea822a1d7cd6945535efbfb10b790056ee9284bf9e698e7" 867 | dependencies = [ 868 | "chrono", 869 | "derive_more", 870 | "form_urlencoded", 871 | "http", 872 | "json-patch", 873 | "k8s-openapi", 874 | "schemars", 875 | "serde", 876 | "serde-value", 877 | "serde_json", 878 | "thiserror 2.0.12", 879 | ] 880 | 881 | [[package]] 882 | name = "kube-derive" 883 | version = "1.0.0" 884 | source = "registry+https://github.com/rust-lang/crates.io-index" 885 | checksum = "8e609a3633689a50869352a3c16e01d863b6137863c80eeb038383d5ab9f83bf" 886 | dependencies = [ 887 | "darling", 888 | "proc-macro2", 889 | "quote", 890 | "serde", 891 | "serde_json", 892 | "syn", 893 | ] 894 | 895 | [[package]] 896 | name = "kube-runtime" 897 | version = "1.0.0" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "1d4bd8a4554786f8f9a87bfa977fb7dbaa1d7f102a30477338b044b65de29d8e" 900 | dependencies = [ 901 | "ahash", 902 | "async-broadcast", 903 | "async-stream", 904 | "backon", 905 | "educe", 906 | "futures", 907 | "hashbrown", 908 | "hostname", 909 | "json-patch", 910 | "k8s-openapi", 911 | "kube-client", 912 | "parking_lot", 913 | "pin-project", 914 | "serde", 915 | "serde_json", 916 | "thiserror 2.0.12", 917 | "tokio", 918 | "tokio-util", 919 | "tracing", 920 | ] 921 | 922 | [[package]] 923 | name = "libc" 924 | version = "0.2.172" 925 | source = "registry+https://github.com/rust-lang/crates.io-index" 926 | checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" 927 | 928 | [[package]] 929 | name = "lock_api" 930 | version = "0.4.12" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 933 | dependencies = [ 934 | "autocfg", 935 | "scopeguard", 936 | ] 937 | 938 | [[package]] 939 | name = "log" 940 | version = "0.4.27" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 943 | 944 | [[package]] 945 | name = "memchr" 946 | version = "2.7.4" 947 | source = "registry+https://github.com/rust-lang/crates.io-index" 948 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 949 | 950 | [[package]] 951 | name = "mime" 952 | version = "0.3.17" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 955 | 956 | [[package]] 957 | name = "miniz_oxide" 958 | version = "0.8.8" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" 961 | dependencies = [ 962 | "adler2", 963 | ] 964 | 965 | [[package]] 966 | name = "mio" 967 | version = "1.0.3" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 970 | dependencies = [ 971 | "libc", 972 | "wasi 0.11.0+wasi-snapshot-preview1", 973 | "windows-sys 0.52.0", 974 | ] 975 | 976 | [[package]] 977 | name = "num-traits" 978 | version = "0.2.19" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 981 | dependencies = [ 982 | "autocfg", 983 | ] 984 | 985 | [[package]] 986 | name = "object" 987 | version = "0.36.7" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 990 | dependencies = [ 991 | "memchr", 992 | ] 993 | 994 | [[package]] 995 | name = "once_cell" 996 | version = "1.21.3" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 999 | 1000 | [[package]] 1001 | name = "openssl-probe" 1002 | version = "0.1.6" 1003 | source = "registry+https://github.com/rust-lang/crates.io-index" 1004 | checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" 1005 | 1006 | [[package]] 1007 | name = "operator" 1008 | version = "0.1.0" 1009 | dependencies = [ 1010 | "futures", 1011 | "k8s-openapi", 1012 | "kube", 1013 | "schemars", 1014 | "serde", 1015 | "serde_json", 1016 | "thiserror 2.0.12", 1017 | "tokio", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "ordered-float" 1022 | version = "2.10.1" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" 1025 | dependencies = [ 1026 | "num-traits", 1027 | ] 1028 | 1029 | [[package]] 1030 | name = "parking" 1031 | version = "2.2.1" 1032 | source = "registry+https://github.com/rust-lang/crates.io-index" 1033 | checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 1034 | 1035 | [[package]] 1036 | name = "parking_lot" 1037 | version = "0.12.3" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1040 | dependencies = [ 1041 | "lock_api", 1042 | "parking_lot_core", 1043 | ] 1044 | 1045 | [[package]] 1046 | name = "parking_lot_core" 1047 | version = "0.9.10" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1050 | dependencies = [ 1051 | "cfg-if", 1052 | "libc", 1053 | "redox_syscall", 1054 | "smallvec", 1055 | "windows-targets", 1056 | ] 1057 | 1058 | [[package]] 1059 | name = "pem" 1060 | version = "3.0.5" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" 1063 | dependencies = [ 1064 | "base64 0.22.1", 1065 | "serde", 1066 | ] 1067 | 1068 | [[package]] 1069 | name = "percent-encoding" 1070 | version = "2.3.1" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1073 | 1074 | [[package]] 1075 | name = "pest" 1076 | version = "2.8.0" 1077 | source = "registry+https://github.com/rust-lang/crates.io-index" 1078 | checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" 1079 | dependencies = [ 1080 | "memchr", 1081 | "thiserror 2.0.12", 1082 | "ucd-trie", 1083 | ] 1084 | 1085 | [[package]] 1086 | name = "pest_derive" 1087 | version = "2.8.0" 1088 | source = "registry+https://github.com/rust-lang/crates.io-index" 1089 | checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5" 1090 | dependencies = [ 1091 | "pest", 1092 | "pest_generator", 1093 | ] 1094 | 1095 | [[package]] 1096 | name = "pest_generator" 1097 | version = "2.8.0" 1098 | source = "registry+https://github.com/rust-lang/crates.io-index" 1099 | checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841" 1100 | dependencies = [ 1101 | "pest", 1102 | "pest_meta", 1103 | "proc-macro2", 1104 | "quote", 1105 | "syn", 1106 | ] 1107 | 1108 | [[package]] 1109 | name = "pest_meta" 1110 | version = "2.8.0" 1111 | source = "registry+https://github.com/rust-lang/crates.io-index" 1112 | checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0" 1113 | dependencies = [ 1114 | "once_cell", 1115 | "pest", 1116 | "sha2", 1117 | ] 1118 | 1119 | [[package]] 1120 | name = "pin-project" 1121 | version = "1.1.10" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" 1124 | dependencies = [ 1125 | "pin-project-internal", 1126 | ] 1127 | 1128 | [[package]] 1129 | name = "pin-project-internal" 1130 | version = "1.1.10" 1131 | source = "registry+https://github.com/rust-lang/crates.io-index" 1132 | checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" 1133 | dependencies = [ 1134 | "proc-macro2", 1135 | "quote", 1136 | "syn", 1137 | ] 1138 | 1139 | [[package]] 1140 | name = "pin-project-lite" 1141 | version = "0.2.16" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 1144 | 1145 | [[package]] 1146 | name = "pin-utils" 1147 | version = "0.1.0" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1150 | 1151 | [[package]] 1152 | name = "proc-macro2" 1153 | version = "1.0.95" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 1156 | dependencies = [ 1157 | "unicode-ident", 1158 | ] 1159 | 1160 | [[package]] 1161 | name = "quote" 1162 | version = "1.0.40" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 1165 | dependencies = [ 1166 | "proc-macro2", 1167 | ] 1168 | 1169 | [[package]] 1170 | name = "r-efi" 1171 | version = "5.2.0" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" 1174 | 1175 | [[package]] 1176 | name = "redox_syscall" 1177 | version = "0.5.12" 1178 | source = "registry+https://github.com/rust-lang/crates.io-index" 1179 | checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" 1180 | dependencies = [ 1181 | "bitflags", 1182 | ] 1183 | 1184 | [[package]] 1185 | name = "regex" 1186 | version = "1.11.1" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 1189 | dependencies = [ 1190 | "aho-corasick", 1191 | "memchr", 1192 | "regex-automata", 1193 | "regex-syntax", 1194 | ] 1195 | 1196 | [[package]] 1197 | name = "regex-automata" 1198 | version = "0.4.9" 1199 | source = "registry+https://github.com/rust-lang/crates.io-index" 1200 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1201 | dependencies = [ 1202 | "aho-corasick", 1203 | "memchr", 1204 | "regex-syntax", 1205 | ] 1206 | 1207 | [[package]] 1208 | name = "regex-syntax" 1209 | version = "0.8.5" 1210 | source = "registry+https://github.com/rust-lang/crates.io-index" 1211 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1212 | 1213 | [[package]] 1214 | name = "ring" 1215 | version = "0.17.14" 1216 | source = "registry+https://github.com/rust-lang/crates.io-index" 1217 | checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" 1218 | dependencies = [ 1219 | "cc", 1220 | "cfg-if", 1221 | "getrandom 0.2.16", 1222 | "libc", 1223 | "untrusted", 1224 | "windows-sys 0.52.0", 1225 | ] 1226 | 1227 | [[package]] 1228 | name = "rustc-demangle" 1229 | version = "0.1.24" 1230 | source = "registry+https://github.com/rust-lang/crates.io-index" 1231 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1232 | 1233 | [[package]] 1234 | name = "rustls" 1235 | version = "0.23.27" 1236 | source = "registry+https://github.com/rust-lang/crates.io-index" 1237 | checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" 1238 | dependencies = [ 1239 | "log", 1240 | "once_cell", 1241 | "ring", 1242 | "rustls-pki-types", 1243 | "rustls-webpki", 1244 | "subtle", 1245 | "zeroize", 1246 | ] 1247 | 1248 | [[package]] 1249 | name = "rustls-native-certs" 1250 | version = "0.7.3" 1251 | source = "registry+https://github.com/rust-lang/crates.io-index" 1252 | checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" 1253 | dependencies = [ 1254 | "openssl-probe", 1255 | "rustls-pemfile", 1256 | "rustls-pki-types", 1257 | "schannel", 1258 | "security-framework 2.11.1", 1259 | ] 1260 | 1261 | [[package]] 1262 | name = "rustls-native-certs" 1263 | version = "0.8.1" 1264 | source = "registry+https://github.com/rust-lang/crates.io-index" 1265 | checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" 1266 | dependencies = [ 1267 | "openssl-probe", 1268 | "rustls-pki-types", 1269 | "schannel", 1270 | "security-framework 3.2.0", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "rustls-pemfile" 1275 | version = "2.2.0" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" 1278 | dependencies = [ 1279 | "rustls-pki-types", 1280 | ] 1281 | 1282 | [[package]] 1283 | name = "rustls-pki-types" 1284 | version = "1.12.0" 1285 | source = "registry+https://github.com/rust-lang/crates.io-index" 1286 | checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" 1287 | dependencies = [ 1288 | "zeroize", 1289 | ] 1290 | 1291 | [[package]] 1292 | name = "rustls-webpki" 1293 | version = "0.103.3" 1294 | source = "registry+https://github.com/rust-lang/crates.io-index" 1295 | checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" 1296 | dependencies = [ 1297 | "ring", 1298 | "rustls-pki-types", 1299 | "untrusted", 1300 | ] 1301 | 1302 | [[package]] 1303 | name = "rustversion" 1304 | version = "1.0.20" 1305 | source = "registry+https://github.com/rust-lang/crates.io-index" 1306 | checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" 1307 | 1308 | [[package]] 1309 | name = "ryu" 1310 | version = "1.0.20" 1311 | source = "registry+https://github.com/rust-lang/crates.io-index" 1312 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 1313 | 1314 | [[package]] 1315 | name = "schannel" 1316 | version = "0.1.27" 1317 | source = "registry+https://github.com/rust-lang/crates.io-index" 1318 | checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" 1319 | dependencies = [ 1320 | "windows-sys 0.59.0", 1321 | ] 1322 | 1323 | [[package]] 1324 | name = "schemars" 1325 | version = "0.8.22" 1326 | source = "registry+https://github.com/rust-lang/crates.io-index" 1327 | checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" 1328 | dependencies = [ 1329 | "dyn-clone", 1330 | "schemars_derive", 1331 | "serde", 1332 | "serde_json", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "schemars_derive" 1337 | version = "0.8.22" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" 1340 | dependencies = [ 1341 | "proc-macro2", 1342 | "quote", 1343 | "serde_derive_internals", 1344 | "syn", 1345 | ] 1346 | 1347 | [[package]] 1348 | name = "scopeguard" 1349 | version = "1.2.0" 1350 | source = "registry+https://github.com/rust-lang/crates.io-index" 1351 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1352 | 1353 | [[package]] 1354 | name = "secrecy" 1355 | version = "0.10.3" 1356 | source = "registry+https://github.com/rust-lang/crates.io-index" 1357 | checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a" 1358 | dependencies = [ 1359 | "zeroize", 1360 | ] 1361 | 1362 | [[package]] 1363 | name = "security-framework" 1364 | version = "2.11.1" 1365 | source = "registry+https://github.com/rust-lang/crates.io-index" 1366 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 1367 | dependencies = [ 1368 | "bitflags", 1369 | "core-foundation 0.9.4", 1370 | "core-foundation-sys", 1371 | "libc", 1372 | "security-framework-sys", 1373 | ] 1374 | 1375 | [[package]] 1376 | name = "security-framework" 1377 | version = "3.2.0" 1378 | source = "registry+https://github.com/rust-lang/crates.io-index" 1379 | checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" 1380 | dependencies = [ 1381 | "bitflags", 1382 | "core-foundation 0.10.0", 1383 | "core-foundation-sys", 1384 | "libc", 1385 | "security-framework-sys", 1386 | ] 1387 | 1388 | [[package]] 1389 | name = "security-framework-sys" 1390 | version = "2.14.0" 1391 | source = "registry+https://github.com/rust-lang/crates.io-index" 1392 | checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" 1393 | dependencies = [ 1394 | "core-foundation-sys", 1395 | "libc", 1396 | ] 1397 | 1398 | [[package]] 1399 | name = "serde" 1400 | version = "1.0.219" 1401 | source = "registry+https://github.com/rust-lang/crates.io-index" 1402 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 1403 | dependencies = [ 1404 | "serde_derive", 1405 | ] 1406 | 1407 | [[package]] 1408 | name = "serde-value" 1409 | version = "0.7.0" 1410 | source = "registry+https://github.com/rust-lang/crates.io-index" 1411 | checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" 1412 | dependencies = [ 1413 | "ordered-float", 1414 | "serde", 1415 | ] 1416 | 1417 | [[package]] 1418 | name = "serde_derive" 1419 | version = "1.0.219" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 1422 | dependencies = [ 1423 | "proc-macro2", 1424 | "quote", 1425 | "syn", 1426 | ] 1427 | 1428 | [[package]] 1429 | name = "serde_derive_internals" 1430 | version = "0.29.1" 1431 | source = "registry+https://github.com/rust-lang/crates.io-index" 1432 | checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" 1433 | dependencies = [ 1434 | "proc-macro2", 1435 | "quote", 1436 | "syn", 1437 | ] 1438 | 1439 | [[package]] 1440 | name = "serde_json" 1441 | version = "1.0.140" 1442 | source = "registry+https://github.com/rust-lang/crates.io-index" 1443 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 1444 | dependencies = [ 1445 | "itoa", 1446 | "memchr", 1447 | "ryu", 1448 | "serde", 1449 | ] 1450 | 1451 | [[package]] 1452 | name = "serde_yaml" 1453 | version = "0.9.34+deprecated" 1454 | source = "registry+https://github.com/rust-lang/crates.io-index" 1455 | checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" 1456 | dependencies = [ 1457 | "indexmap", 1458 | "itoa", 1459 | "ryu", 1460 | "serde", 1461 | "unsafe-libyaml", 1462 | ] 1463 | 1464 | [[package]] 1465 | name = "sha1" 1466 | version = "0.10.6" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 1469 | dependencies = [ 1470 | "cfg-if", 1471 | "cpufeatures", 1472 | "digest", 1473 | ] 1474 | 1475 | [[package]] 1476 | name = "sha2" 1477 | version = "0.10.9" 1478 | source = "registry+https://github.com/rust-lang/crates.io-index" 1479 | checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" 1480 | dependencies = [ 1481 | "cfg-if", 1482 | "cpufeatures", 1483 | "digest", 1484 | ] 1485 | 1486 | [[package]] 1487 | name = "shlex" 1488 | version = "1.3.0" 1489 | source = "registry+https://github.com/rust-lang/crates.io-index" 1490 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1491 | 1492 | [[package]] 1493 | name = "signal-hook-registry" 1494 | version = "1.4.5" 1495 | source = "registry+https://github.com/rust-lang/crates.io-index" 1496 | checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" 1497 | dependencies = [ 1498 | "libc", 1499 | ] 1500 | 1501 | [[package]] 1502 | name = "slab" 1503 | version = "0.4.9" 1504 | source = "registry+https://github.com/rust-lang/crates.io-index" 1505 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1506 | dependencies = [ 1507 | "autocfg", 1508 | ] 1509 | 1510 | [[package]] 1511 | name = "smallvec" 1512 | version = "1.15.0" 1513 | source = "registry+https://github.com/rust-lang/crates.io-index" 1514 | checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" 1515 | 1516 | [[package]] 1517 | name = "socket2" 1518 | version = "0.5.9" 1519 | source = "registry+https://github.com/rust-lang/crates.io-index" 1520 | checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" 1521 | dependencies = [ 1522 | "libc", 1523 | "windows-sys 0.52.0", 1524 | ] 1525 | 1526 | [[package]] 1527 | name = "strsim" 1528 | version = "0.11.1" 1529 | source = "registry+https://github.com/rust-lang/crates.io-index" 1530 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1531 | 1532 | [[package]] 1533 | name = "subtle" 1534 | version = "2.6.1" 1535 | source = "registry+https://github.com/rust-lang/crates.io-index" 1536 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1537 | 1538 | [[package]] 1539 | name = "syn" 1540 | version = "2.0.101" 1541 | source = "registry+https://github.com/rust-lang/crates.io-index" 1542 | checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" 1543 | dependencies = [ 1544 | "proc-macro2", 1545 | "quote", 1546 | "unicode-ident", 1547 | ] 1548 | 1549 | [[package]] 1550 | name = "sync_wrapper" 1551 | version = "1.0.2" 1552 | source = "registry+https://github.com/rust-lang/crates.io-index" 1553 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 1554 | 1555 | [[package]] 1556 | name = "thiserror" 1557 | version = "1.0.69" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 1560 | dependencies = [ 1561 | "thiserror-impl 1.0.69", 1562 | ] 1563 | 1564 | [[package]] 1565 | name = "thiserror" 1566 | version = "2.0.12" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 1569 | dependencies = [ 1570 | "thiserror-impl 2.0.12", 1571 | ] 1572 | 1573 | [[package]] 1574 | name = "thiserror-impl" 1575 | version = "1.0.69" 1576 | source = "registry+https://github.com/rust-lang/crates.io-index" 1577 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 1578 | dependencies = [ 1579 | "proc-macro2", 1580 | "quote", 1581 | "syn", 1582 | ] 1583 | 1584 | [[package]] 1585 | name = "thiserror-impl" 1586 | version = "2.0.12" 1587 | source = "registry+https://github.com/rust-lang/crates.io-index" 1588 | checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 1589 | dependencies = [ 1590 | "proc-macro2", 1591 | "quote", 1592 | "syn", 1593 | ] 1594 | 1595 | [[package]] 1596 | name = "tokio" 1597 | version = "1.45.0" 1598 | source = "registry+https://github.com/rust-lang/crates.io-index" 1599 | checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" 1600 | dependencies = [ 1601 | "backtrace", 1602 | "bytes", 1603 | "libc", 1604 | "mio", 1605 | "pin-project-lite", 1606 | "signal-hook-registry", 1607 | "socket2", 1608 | "tokio-macros", 1609 | "windows-sys 0.52.0", 1610 | ] 1611 | 1612 | [[package]] 1613 | name = "tokio-macros" 1614 | version = "2.5.0" 1615 | source = "registry+https://github.com/rust-lang/crates.io-index" 1616 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 1617 | dependencies = [ 1618 | "proc-macro2", 1619 | "quote", 1620 | "syn", 1621 | ] 1622 | 1623 | [[package]] 1624 | name = "tokio-rustls" 1625 | version = "0.26.2" 1626 | source = "registry+https://github.com/rust-lang/crates.io-index" 1627 | checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" 1628 | dependencies = [ 1629 | "rustls", 1630 | "tokio", 1631 | ] 1632 | 1633 | [[package]] 1634 | name = "tokio-util" 1635 | version = "0.7.15" 1636 | source = "registry+https://github.com/rust-lang/crates.io-index" 1637 | checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" 1638 | dependencies = [ 1639 | "bytes", 1640 | "futures-core", 1641 | "futures-sink", 1642 | "pin-project-lite", 1643 | "slab", 1644 | "tokio", 1645 | ] 1646 | 1647 | [[package]] 1648 | name = "tower" 1649 | version = "0.5.2" 1650 | source = "registry+https://github.com/rust-lang/crates.io-index" 1651 | checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 1652 | dependencies = [ 1653 | "futures-core", 1654 | "futures-util", 1655 | "pin-project-lite", 1656 | "sync_wrapper", 1657 | "tokio", 1658 | "tokio-util", 1659 | "tower-layer", 1660 | "tower-service", 1661 | "tracing", 1662 | ] 1663 | 1664 | [[package]] 1665 | name = "tower-http" 1666 | version = "0.6.4" 1667 | source = "registry+https://github.com/rust-lang/crates.io-index" 1668 | checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e" 1669 | dependencies = [ 1670 | "base64 0.22.1", 1671 | "bitflags", 1672 | "bytes", 1673 | "http", 1674 | "http-body", 1675 | "mime", 1676 | "pin-project-lite", 1677 | "tower-layer", 1678 | "tower-service", 1679 | "tracing", 1680 | ] 1681 | 1682 | [[package]] 1683 | name = "tower-layer" 1684 | version = "0.3.3" 1685 | source = "registry+https://github.com/rust-lang/crates.io-index" 1686 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 1687 | 1688 | [[package]] 1689 | name = "tower-service" 1690 | version = "0.3.3" 1691 | source = "registry+https://github.com/rust-lang/crates.io-index" 1692 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 1693 | 1694 | [[package]] 1695 | name = "tracing" 1696 | version = "0.1.41" 1697 | source = "registry+https://github.com/rust-lang/crates.io-index" 1698 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 1699 | dependencies = [ 1700 | "log", 1701 | "pin-project-lite", 1702 | "tracing-attributes", 1703 | "tracing-core", 1704 | ] 1705 | 1706 | [[package]] 1707 | name = "tracing-attributes" 1708 | version = "0.1.28" 1709 | source = "registry+https://github.com/rust-lang/crates.io-index" 1710 | checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 1711 | dependencies = [ 1712 | "proc-macro2", 1713 | "quote", 1714 | "syn", 1715 | ] 1716 | 1717 | [[package]] 1718 | name = "tracing-core" 1719 | version = "0.1.33" 1720 | source = "registry+https://github.com/rust-lang/crates.io-index" 1721 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 1722 | dependencies = [ 1723 | "once_cell", 1724 | ] 1725 | 1726 | [[package]] 1727 | name = "try-lock" 1728 | version = "0.2.5" 1729 | source = "registry+https://github.com/rust-lang/crates.io-index" 1730 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1731 | 1732 | [[package]] 1733 | name = "typenum" 1734 | version = "1.18.0" 1735 | source = "registry+https://github.com/rust-lang/crates.io-index" 1736 | checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" 1737 | 1738 | [[package]] 1739 | name = "ucd-trie" 1740 | version = "0.1.7" 1741 | source = "registry+https://github.com/rust-lang/crates.io-index" 1742 | checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" 1743 | 1744 | [[package]] 1745 | name = "unicode-ident" 1746 | version = "1.0.18" 1747 | source = "registry+https://github.com/rust-lang/crates.io-index" 1748 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 1749 | 1750 | [[package]] 1751 | name = "unsafe-libyaml" 1752 | version = "0.2.11" 1753 | source = "registry+https://github.com/rust-lang/crates.io-index" 1754 | checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" 1755 | 1756 | [[package]] 1757 | name = "untrusted" 1758 | version = "0.9.0" 1759 | source = "registry+https://github.com/rust-lang/crates.io-index" 1760 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1761 | 1762 | [[package]] 1763 | name = "version_check" 1764 | version = "0.9.5" 1765 | source = "registry+https://github.com/rust-lang/crates.io-index" 1766 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 1767 | 1768 | [[package]] 1769 | name = "want" 1770 | version = "0.3.1" 1771 | source = "registry+https://github.com/rust-lang/crates.io-index" 1772 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1773 | dependencies = [ 1774 | "try-lock", 1775 | ] 1776 | 1777 | [[package]] 1778 | name = "wasi" 1779 | version = "0.11.0+wasi-snapshot-preview1" 1780 | source = "registry+https://github.com/rust-lang/crates.io-index" 1781 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1782 | 1783 | [[package]] 1784 | name = "wasi" 1785 | version = "0.14.2+wasi-0.2.4" 1786 | source = "registry+https://github.com/rust-lang/crates.io-index" 1787 | checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 1788 | dependencies = [ 1789 | "wit-bindgen-rt", 1790 | ] 1791 | 1792 | [[package]] 1793 | name = "wasm-bindgen" 1794 | version = "0.2.100" 1795 | source = "registry+https://github.com/rust-lang/crates.io-index" 1796 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 1797 | dependencies = [ 1798 | "cfg-if", 1799 | "once_cell", 1800 | "rustversion", 1801 | "wasm-bindgen-macro", 1802 | ] 1803 | 1804 | [[package]] 1805 | name = "wasm-bindgen-backend" 1806 | version = "0.2.100" 1807 | source = "registry+https://github.com/rust-lang/crates.io-index" 1808 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 1809 | dependencies = [ 1810 | "bumpalo", 1811 | "log", 1812 | "proc-macro2", 1813 | "quote", 1814 | "syn", 1815 | "wasm-bindgen-shared", 1816 | ] 1817 | 1818 | [[package]] 1819 | name = "wasm-bindgen-macro" 1820 | version = "0.2.100" 1821 | source = "registry+https://github.com/rust-lang/crates.io-index" 1822 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 1823 | dependencies = [ 1824 | "quote", 1825 | "wasm-bindgen-macro-support", 1826 | ] 1827 | 1828 | [[package]] 1829 | name = "wasm-bindgen-macro-support" 1830 | version = "0.2.100" 1831 | source = "registry+https://github.com/rust-lang/crates.io-index" 1832 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 1833 | dependencies = [ 1834 | "proc-macro2", 1835 | "quote", 1836 | "syn", 1837 | "wasm-bindgen-backend", 1838 | "wasm-bindgen-shared", 1839 | ] 1840 | 1841 | [[package]] 1842 | name = "wasm-bindgen-shared" 1843 | version = "0.2.100" 1844 | source = "registry+https://github.com/rust-lang/crates.io-index" 1845 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 1846 | dependencies = [ 1847 | "unicode-ident", 1848 | ] 1849 | 1850 | [[package]] 1851 | name = "windows-link" 1852 | version = "0.1.1" 1853 | source = "registry+https://github.com/rust-lang/crates.io-index" 1854 | checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" 1855 | 1856 | [[package]] 1857 | name = "windows-sys" 1858 | version = "0.52.0" 1859 | source = "registry+https://github.com/rust-lang/crates.io-index" 1860 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1861 | dependencies = [ 1862 | "windows-targets", 1863 | ] 1864 | 1865 | [[package]] 1866 | name = "windows-sys" 1867 | version = "0.59.0" 1868 | source = "registry+https://github.com/rust-lang/crates.io-index" 1869 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1870 | dependencies = [ 1871 | "windows-targets", 1872 | ] 1873 | 1874 | [[package]] 1875 | name = "windows-targets" 1876 | version = "0.52.6" 1877 | source = "registry+https://github.com/rust-lang/crates.io-index" 1878 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1879 | dependencies = [ 1880 | "windows_aarch64_gnullvm", 1881 | "windows_aarch64_msvc", 1882 | "windows_i686_gnu", 1883 | "windows_i686_gnullvm", 1884 | "windows_i686_msvc", 1885 | "windows_x86_64_gnu", 1886 | "windows_x86_64_gnullvm", 1887 | "windows_x86_64_msvc", 1888 | ] 1889 | 1890 | [[package]] 1891 | name = "windows_aarch64_gnullvm" 1892 | version = "0.52.6" 1893 | source = "registry+https://github.com/rust-lang/crates.io-index" 1894 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1895 | 1896 | [[package]] 1897 | name = "windows_aarch64_msvc" 1898 | version = "0.52.6" 1899 | source = "registry+https://github.com/rust-lang/crates.io-index" 1900 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1901 | 1902 | [[package]] 1903 | name = "windows_i686_gnu" 1904 | version = "0.52.6" 1905 | source = "registry+https://github.com/rust-lang/crates.io-index" 1906 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1907 | 1908 | [[package]] 1909 | name = "windows_i686_gnullvm" 1910 | version = "0.52.6" 1911 | source = "registry+https://github.com/rust-lang/crates.io-index" 1912 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1913 | 1914 | [[package]] 1915 | name = "windows_i686_msvc" 1916 | version = "0.52.6" 1917 | source = "registry+https://github.com/rust-lang/crates.io-index" 1918 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1919 | 1920 | [[package]] 1921 | name = "windows_x86_64_gnu" 1922 | version = "0.52.6" 1923 | source = "registry+https://github.com/rust-lang/crates.io-index" 1924 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1925 | 1926 | [[package]] 1927 | name = "windows_x86_64_gnullvm" 1928 | version = "0.52.6" 1929 | source = "registry+https://github.com/rust-lang/crates.io-index" 1930 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1931 | 1932 | [[package]] 1933 | name = "windows_x86_64_msvc" 1934 | version = "0.52.6" 1935 | source = "registry+https://github.com/rust-lang/crates.io-index" 1936 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1937 | 1938 | [[package]] 1939 | name = "wit-bindgen-rt" 1940 | version = "0.39.0" 1941 | source = "registry+https://github.com/rust-lang/crates.io-index" 1942 | checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 1943 | dependencies = [ 1944 | "bitflags", 1945 | ] 1946 | 1947 | [[package]] 1948 | name = "zerocopy" 1949 | version = "0.8.25" 1950 | source = "registry+https://github.com/rust-lang/crates.io-index" 1951 | checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" 1952 | dependencies = [ 1953 | "zerocopy-derive", 1954 | ] 1955 | 1956 | [[package]] 1957 | name = "zerocopy-derive" 1958 | version = "0.8.25" 1959 | source = "registry+https://github.com/rust-lang/crates.io-index" 1960 | checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" 1961 | dependencies = [ 1962 | "proc-macro2", 1963 | "quote", 1964 | "syn", 1965 | ] 1966 | 1967 | [[package]] 1968 | name = "zeroize" 1969 | version = "1.8.1" 1970 | source = "registry+https://github.com/rust-lang/crates.io-index" 1971 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 1972 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "operator" 3 | version = "0.1.0" 4 | authors = ["Pavel Pscheidl "] 5 | edition = "2021" 6 | 7 | [dependencies] 8 | tokio = { version = "1.45", features = [ 9 | "macros", 10 | "rt-multi-thread", 11 | ] } # Macros for easy project setup and testing, multi-threaded runtime for best utilization of resources 12 | kube = { version = "1.0.0", default-features = true, features = [ 13 | "derive", 14 | "runtime", 15 | ] } # Library for talking to Kubernetes API 16 | k8s-openapi = { version = "0.25.0", default-features = false, features = [ 17 | "v1_33", 18 | ] } # Kube-rs depends on k8s-openapi 19 | futures = "0.3" 20 | # All serde dependencies are used to serialize/deserialize CRDs and other Kubernetes-related structs 21 | serde = "1" 22 | serde_json = "1.0" 23 | schemars = "0.8" 24 | thiserror = "2" # Custom Error definitions and convenient error mappings 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2022] [Pavel Pscheidl] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust Kubernetes operator example 2 | 3 | [![Rust](https://github.com/Pscheidl/rust-kubernetes-operator-example/actions/workflows/rust.yml/badge.svg)](https://github.com/Pscheidl/rust-kubernetes-operator-example/actions/workflows/rust.yml) 4 | 5 | A Kubernetes operator built on top of [kube-rs](https://github.com/clux/kube-rs) project. There is 6 | an [explanatory article](https://www.pavel.cool/posts/rust-kubernetes-operators/) available. 7 | 8 | Steps to run on Linux: 9 | 10 | 1. [Install](https://www.rust-lang.org/tools/install) Rust 11 | 1. Install Kubernetes, [K3S.io](https://k3s.io/) is an excellent choice, installed simply 12 | with `curl -sfL https://get.k3s.io | sh -`. Make sure to `sudo chown $USER /etc/rancher/k3s/k3s.yaml` if you're 13 | accessing the Kubernetes cluster using the kubeconfig at `/etc/rancher/k3s/k3s.yaml` as non-root user. 14 | Also, `export KUBECONFIG=/etc/rancher/k3s/k3s.yaml`, so the operator can find the kubeconfig. 15 | 1. Use `kubectl apply -f echoes.example.com.yaml` to create the CustomResourceDefinition inside Kubernetes. 16 | 1. Build the project with `cargo build`. If the build fails, make sure `libssl-dev` is available. 17 | 1. Run the operator using `cargo run`. It will run outside of the Kubernetes cluster and connect to the Kubernetes REST 18 | API using the account inside the `KUBECONFIG` automatically. 19 | 20 | Finally, a custom `Echo` resource can be created with `kubectl apply -f echo-example.yaml`. A new deployment of two pods 21 | with `Echo` REST API service will be created. This can be checked with the `kubectl get pods` 22 | or `kubectl get deployments` command. 23 | 24 | ![Usage showcase](showcase.gif) 25 | -------------------------------------------------------------------------------- /echo-example.yaml: -------------------------------------------------------------------------------- 1 | # Example of Echo deployment. The operator will receive this specification and will create a deployment of two "echo" pods. 2 | apiVersion: example.com/v1 3 | kind: Echo # Identifier of the resource type. 4 | metadata: 5 | name: test-echo # Name of the "Echo" custom resource instance, may be changed to your liking 6 | namespace: default # Namespace must exist and account in KUBECONFIG must have sufficient permissions 7 | spec: 8 | replicas: 2 # Number of "Echo" pods created. -------------------------------------------------------------------------------- /echoes.example.com.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: echoes.example.com 5 | namespace: default # For easier deployment and avoid permissions collisions on most clusters, the resource is namespace-scoped. More information at: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/ 6 | spec: 7 | group: example.com 8 | names: 9 | kind: Echo 10 | plural: echoes # If not specified, Kubernetes would assume the plural is "Echos" 11 | singular: echo 12 | shortNames: 13 | - echo 14 | scope: Namespaced 15 | versions: 16 | - name: v1 17 | served: true 18 | storage: true 19 | schema: 20 | openAPIV3Schema: 21 | type: object 22 | properties: 23 | spec: # There is only one (required) field named "replicas" specifying how many pods are created by the Operator 24 | type: object 25 | properties: 26 | replicas: 27 | type: integer 28 | format: int32 29 | required: ["replicas"] -------------------------------------------------------------------------------- /showcase.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pscheidl/rust-kubernetes-operator-example/a87bc124b4d7a58a7d84301673715feb42c6afe5/showcase.gif -------------------------------------------------------------------------------- /src/crd.rs: -------------------------------------------------------------------------------- 1 | use kube::CustomResource; 2 | use schemars::JsonSchema; 3 | use serde::{Deserialize, Serialize}; 4 | 5 | /// Struct corresponding to the Specification (`spec`) part of the `Echo` resource, directly 6 | /// reflects context of the `echoes.example.com.yaml` file to be found in this repository. 7 | /// The `Echo` struct will be generated by the `CustomResource` derive macro. 8 | #[derive(CustomResource, Serialize, Deserialize, Debug, PartialEq, Clone, JsonSchema)] 9 | #[kube( 10 | group = "example.com", 11 | version = "v1", 12 | kind = "Echo", 13 | plural = "echoes", 14 | derive = "PartialEq", 15 | namespaced 16 | )] 17 | pub struct EchoSpec { 18 | pub replicas: i32, 19 | } 20 | -------------------------------------------------------------------------------- /src/echo.rs: -------------------------------------------------------------------------------- 1 | use k8s_openapi::api::apps::v1::{Deployment, DeploymentSpec}; 2 | use k8s_openapi::api::core::v1::{Container, ContainerPort, PodSpec, PodTemplateSpec}; 3 | use k8s_openapi::apimachinery::pkg::apis::meta::v1::LabelSelector; 4 | use kube::api::{DeleteParams, ObjectMeta, PostParams}; 5 | use kube::{Api, Client, Error}; 6 | use std::collections::BTreeMap; 7 | 8 | /// Creates a new deployment of `n` pods with the `inanimate/echo-server:latest` docker image inside, 9 | /// where `n` is the number of `replicas` given. 10 | /// Note: It is assumed the resource does not already exists for simplicity. Returns an `Error` if it does. 11 | /// # Arguments 12 | /// - `client` - A Kubernetes client to create the deployment with. 13 | /// - `name` - Name of the deployment to be created 14 | /// - `replicas` - Number of pod replicas for the Deployment to contain 15 | /// - `namespace` - Namespace to create the Kubernetes Deployment in. 16 | pub async fn deploy( 17 | client: Client, 18 | name: &str, 19 | replicas: i32, 20 | namespace: &str, 21 | ) -> Result { 22 | let mut labels: BTreeMap = BTreeMap::new(); 23 | labels.insert("app".to_owned(), name.to_owned()); 24 | 25 | // Definition of the deployment. Alternatively, a YAML representation could be used as well. 26 | let deployment: Deployment = Deployment { 27 | metadata: ObjectMeta { 28 | name: Some(name.to_owned()), 29 | namespace: Some(namespace.to_owned()), 30 | labels: Some(labels.clone()), 31 | ..ObjectMeta::default() 32 | }, 33 | spec: Some(DeploymentSpec { 34 | replicas: Some(replicas), 35 | selector: LabelSelector { 36 | match_expressions: None, 37 | match_labels: Some(labels.clone()), 38 | }, 39 | template: PodTemplateSpec { 40 | spec: Some(PodSpec { 41 | containers: vec![Container { 42 | name: name.to_owned(), 43 | image: Some("inanimate/echo-server:latest".to_owned()), 44 | ports: Some(vec![ContainerPort { 45 | container_port: 8080, 46 | ..ContainerPort::default() 47 | }]), 48 | ..Container::default() 49 | }], 50 | ..PodSpec::default() 51 | }), 52 | metadata: Some(ObjectMeta { 53 | labels: Some(labels), 54 | ..ObjectMeta::default() 55 | }), 56 | }, 57 | ..DeploymentSpec::default() 58 | }), 59 | ..Deployment::default() 60 | }; 61 | 62 | // Create the deployment defined above 63 | let deployment_api: Api = Api::namespaced(client, namespace); 64 | deployment_api 65 | .create(&PostParams::default(), &deployment) 66 | .await 67 | } 68 | 69 | /// Deletes an existing deployment. 70 | /// 71 | /// # Arguments: 72 | /// - `client` - A Kubernetes client to delete the Deployment with 73 | /// - `name` - Name of the deployment to delete 74 | /// - `namespace` - Namespace the existing deployment resides in 75 | /// 76 | /// Note: It is assumed the deployment exists for simplicity. Otherwise returns an Error. 77 | pub async fn delete(client: Client, name: &str, namespace: &str) -> Result<(), Error> { 78 | let api: Api = Api::namespaced(client, namespace); 79 | api.delete(name, &DeleteParams::default()).await?; 80 | Ok(()) 81 | } 82 | -------------------------------------------------------------------------------- /src/finalizer.rs: -------------------------------------------------------------------------------- 1 | use crate::crd::Echo; 2 | use kube::api::{Patch, PatchParams}; 3 | use kube::{Api, Client, Error}; 4 | use serde_json::{json, Value}; 5 | 6 | /// Adds a finalizer record into an `Echo` kind of resource. If the finalizer already exists, 7 | /// this action has no effect. 8 | /// 9 | /// # Arguments: 10 | /// - `client` - Kubernetes client to modify the `Echo` resource with. 11 | /// - `name` - Name of the `Echo` resource to modify. Existence is not verified 12 | /// - `namespace` - Namespace where the `Echo` resource with given `name` resides. 13 | /// 14 | /// Note: Does not check for resource's existence for simplicity. 15 | pub async fn add(client: Client, name: &str, namespace: &str) -> Result { 16 | let api: Api = Api::namespaced(client, namespace); 17 | let finalizer: Value = json!({ 18 | "metadata": { 19 | "finalizers": ["echoes.example.com/finalizer"] 20 | } 21 | }); 22 | 23 | let patch: Patch<&Value> = Patch::Merge(&finalizer); 24 | api.patch(name, &PatchParams::default(), &patch).await 25 | } 26 | 27 | /// Removes all finalizers from an `Echo` resource. If there are no finalizers already, this 28 | /// action has no effect. 29 | /// 30 | /// # Arguments: 31 | /// - `client` - Kubernetes client to modify the `Echo` resource with. 32 | /// - `name` - Name of the `Echo` resource to modify. Existence is not verified 33 | /// - `namespace` - Namespace where the `Echo` resource with given `name` resides. 34 | /// 35 | /// Note: Does not check for resource's existence for simplicity. 36 | pub async fn delete(client: Client, name: &str, namespace: &str) -> Result { 37 | let api: Api = Api::namespaced(client, namespace); 38 | let finalizer: Value = json!({ 39 | "metadata": { 40 | "finalizers": null 41 | } 42 | }); 43 | 44 | let patch: Patch<&Value> = Patch::Merge(&finalizer); 45 | api.patch(name, &PatchParams::default(), &patch).await 46 | } 47 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use futures::stream::StreamExt; 4 | use kube::runtime::watcher::Config; 5 | use kube::Resource; 6 | use kube::ResourceExt; 7 | use kube::{client::Client, runtime::controller::Action, runtime::Controller, Api}; 8 | use tokio::time::Duration; 9 | 10 | use crate::crd::Echo; 11 | 12 | pub mod crd; 13 | mod echo; 14 | mod finalizer; 15 | 16 | #[tokio::main] 17 | async fn main() { 18 | // First, a Kubernetes client must be obtained using the `kube` crate 19 | // The client will later be moved to the custom controller 20 | let kubernetes_client: Client = Client::try_default() 21 | .await 22 | .expect("Expected a valid KUBECONFIG environment variable."); 23 | 24 | // Preparation of resources used by the `kube_runtime::Controller` 25 | let crd_api: Api = Api::all(kubernetes_client.clone()); 26 | let context: Arc = Arc::new(ContextData::new(kubernetes_client.clone())); 27 | 28 | // The controller comes from the `kube_runtime` crate and manages the reconciliation process. 29 | // It requires the following information: 30 | // - `kube::Api` this controller "owns". In this case, `T = Echo`, as this controller owns the `Echo` resource, 31 | // - `kube::runtime::watcher::Config` can be adjusted for precise filtering of `Echo` resources before the actual reconciliation, e.g. by label, 32 | // - `reconcile` function with reconciliation logic to be called each time a resource of `Echo` kind is created/updated/deleted, 33 | // - `on_error` function to call whenever reconciliation fails. 34 | Controller::new(crd_api.clone(), Config::default()) 35 | .run(reconcile, on_error, context) 36 | .for_each(|reconciliation_result| async move { 37 | match reconciliation_result { 38 | Ok(echo_resource) => { 39 | println!("Reconciliation successful. Resource: {:?}", echo_resource); 40 | } 41 | Err(reconciliation_err) => { 42 | eprintln!("Reconciliation error: {:?}", reconciliation_err) 43 | } 44 | } 45 | }) 46 | .await; 47 | } 48 | 49 | /// Context injected with each `reconcile` and `on_error` method invocation. 50 | struct ContextData { 51 | /// Kubernetes client to make Kubernetes API requests with. Required for K8S resource management. 52 | client: Client, 53 | } 54 | 55 | impl ContextData { 56 | /// Constructs a new instance of ContextData. 57 | /// 58 | /// # Arguments: 59 | /// - `client`: A Kubernetes client to make Kubernetes REST API requests with. Resources 60 | /// will be created and deleted with this client. 61 | pub fn new(client: Client) -> Self { 62 | ContextData { client } 63 | } 64 | } 65 | 66 | /// Action to be taken upon an `Echo` resource during reconciliation 67 | enum EchoAction { 68 | /// Create the subresources, this includes spawning `n` pods with Echo service 69 | Create, 70 | /// Delete all subresources created in the `Create` phase 71 | Delete, 72 | /// This `Echo` resource is in desired state and requires no actions to be taken 73 | NoOp, 74 | } 75 | 76 | async fn reconcile(echo: Arc, context: Arc) -> Result { 77 | let client: Client = context.client.clone(); // The `Client` is shared -> a clone from the reference is obtained 78 | 79 | // The resource of `Echo` kind is required to have a namespace set. However, it is not guaranteed 80 | // the resource will have a `namespace` set. Therefore, the `namespace` field on object's metadata 81 | // is optional and Rust forces the programmer to check for it's existence first. 82 | let namespace: String = match echo.namespace() { 83 | None => { 84 | // If there is no namespace to deploy to defined, reconciliation ends with an error immediately. 85 | return Err(Error::UserInputError( 86 | "Expected Echo resource to be namespaced. Can't deploy to an unknown namespace." 87 | .to_owned(), 88 | )); 89 | } 90 | // If namespace is known, proceed. In a more advanced version of the operator, perhaps 91 | // the namespace could be checked for existence first. 92 | Some(namespace) => namespace, 93 | }; 94 | let name = echo.name_any(); // Name of the Echo resource is used to name the subresources as well. 95 | 96 | // Performs action as decided by the `determine_action` function. 97 | match determine_action(&echo) { 98 | EchoAction::Create => { 99 | // Creates a deployment with `n` Echo service pods, but applies a finalizer first. 100 | // Finalizer is applied first, as the operator might be shut down and restarted 101 | // at any time, leaving subresources in intermediate state. This prevents leaks on 102 | // the `Echo` resource deletion. 103 | 104 | // Apply the finalizer first. If that fails, the `?` operator invokes automatic conversion 105 | // of `kube::Error` to the `Error` defined in this crate. 106 | finalizer::add(client.clone(), &name, &namespace).await?; 107 | // Invoke creation of a Kubernetes built-in resource named deployment with `n` echo service pods. 108 | echo::deploy(client, &name, echo.spec.replicas, &namespace).await?; 109 | Ok(Action::requeue(Duration::from_secs(10))) 110 | } 111 | EchoAction::Delete => { 112 | // Deletes any subresources related to this `Echo` resources. If and only if all subresources 113 | // are deleted, the finalizer is removed and Kubernetes is free to remove the `Echo` resource. 114 | 115 | //First, delete the deployment. If there is any error deleting the deployment, it is 116 | // automatically converted into `Error` defined in this crate and the reconciliation is ended 117 | // with that error. 118 | // Note: A more advanced implementation would check for the Deployment's existence. 119 | echo::delete(client.clone(), &name, &namespace).await?; 120 | 121 | // Once the deployment is successfully removed, remove the finalizer to make it possible 122 | // for Kubernetes to delete the `Echo` resource. 123 | finalizer::delete(client, &name, &namespace).await?; 124 | Ok(Action::await_change()) // Makes no sense to delete after a successful delete, as the resource is gone 125 | } 126 | // The resource is already in desired state, do nothing and re-check after 10 seconds 127 | EchoAction::NoOp => Ok(Action::requeue(Duration::from_secs(10))), 128 | } 129 | } 130 | 131 | /// Resources arrives into reconciliation queue in a certain state. This function looks at 132 | /// the state of given `Echo` resource and decides which actions needs to be performed. 133 | /// The finite set of possible actions is represented by the `EchoAction` enum. 134 | /// 135 | /// # Arguments 136 | /// - `echo`: A reference to `Echo` being reconciled to decide next action upon. 137 | fn determine_action(echo: &Echo) -> EchoAction { 138 | if echo.meta().deletion_timestamp.is_some() { 139 | EchoAction::Delete 140 | } else if echo 141 | .meta() 142 | .finalizers 143 | .as_ref() 144 | .map_or(true, |finalizers| finalizers.is_empty()) 145 | { 146 | EchoAction::Create 147 | } else { 148 | EchoAction::NoOp 149 | } 150 | } 151 | 152 | /// Actions to be taken when a reconciliation fails - for whatever reason. 153 | /// Prints out the error to `stderr` and requeues the resource for another reconciliation after 154 | /// five seconds. 155 | /// 156 | /// # Arguments 157 | /// - `echo`: The erroneous resource. 158 | /// - `error`: A reference to the `kube::Error` that occurred during reconciliation. 159 | /// - `_context`: Unused argument. Context Data "injected" automatically by kube-rs. 160 | fn on_error(echo: Arc, error: &Error, _context: Arc) -> Action { 161 | eprintln!("Reconciliation error:\n{:?}.\n{:?}", error, echo); 162 | Action::requeue(Duration::from_secs(5)) 163 | } 164 | 165 | /// All errors possible to occur during reconciliation 166 | #[derive(Debug, thiserror::Error)] 167 | pub enum Error { 168 | /// Any error originating from the `kube-rs` crate 169 | #[error("Kubernetes reported error: {source}")] 170 | KubeError { 171 | #[from] 172 | source: kube::Error, 173 | }, 174 | /// Error in user input or Echo resource definition, typically missing fields. 175 | #[error("Invalid Echo CRD: {0}")] 176 | UserInputError(String), 177 | } 178 | --------------------------------------------------------------------------------