diff --git a/Cargo.lock b/Cargo.lock index 73ba5ed3..bbc135e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -194,9 +194,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.16.1" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" +checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" dependencies = [ "aws-lc-sys", "zeroize", @@ -204,9 +204,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.38.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" +checksum = "1fa7e52a4c5c547c741610a2c6f123f3881e409b714cd27e6798ef020c514f0a" dependencies = [ "cc", "cmake", @@ -890,6 +890,18 @@ version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04" +[[package]] +name = "dialoguer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f104b501bf2364e78d0d3974cbc774f738f5865306ed128e1e0d7499c0ad96" +dependencies = [ + "console", + "shell-words", + "tempfile", + "zeroize", +] + [[package]] name = "digest" version = "0.10.7" @@ -1758,9 +1770,9 @@ checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "d8e7418f59cc01c88316161279a7f665217ae316b388e58a0d10e29f54f1e5eb" dependencies = [ "memchr", "serde", @@ -1792,9 +1804,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "java-properties" @@ -1857,7 +1869,7 @@ dependencies = [ "cesu8", "cfg-if", "combine", - "jni-sys", + "jni-sys 0.3.1", "log", "thiserror 1.0.69", "walkdir", @@ -1866,9 +1878,31 @@ dependencies = [ [[package]] name = "jni-sys" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.117", +] [[package]] name = "jobserver" @@ -2297,9 +2331,9 @@ dependencies = [ [[package]] name = "opentelemetry-otlp" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf" +checksum = "1f69cd6acbb9af919df949cd1ec9e5e7fdc2ef15d234b6b795aaa525cc02f71f" dependencies = [ "http", "opentelemetry", @@ -3154,9 +3188,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ "aws-lc-rs", "ring", @@ -3345,9 +3379,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +checksum = "876ac351060d4f882bb1032b6369eb0aef79ad9df1ea8bc404874d8cc3d0cd98" dependencies = [ "serde_core", ] @@ -3408,6 +3442,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shell-words" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" + [[package]] name = "shlex" version = "1.3.0" @@ -3545,6 +3585,7 @@ version = "0.0.0-dev" dependencies = [ "bcrypt", "clap", + "either", "futures", "helm-sys", "indexmap", @@ -3729,6 +3770,7 @@ dependencies = [ "clap_complete", "clap_complete_nushell", "comfy-table", + "dialoguer", "directories", "dotenvy", "futures", @@ -3831,6 +3873,19 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.2", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + [[package]] name = "tera" version = "1.20.1" @@ -4044,9 +4099,9 @@ dependencies = [ [[package]] name = "toml" -version = "1.0.7+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd28d57d8a6f6e458bc0b8784f8fdcc4b99a437936056fa122cb234f18656a96" +checksum = "f8195ca05e4eb728f4ba94f3e3291661320af739c4e43779cbdfae82ab239fcc" dependencies = [ "indexmap", "serde_core", @@ -4059,18 +4114,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "1.0.1+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9" +checksum = "97251a7c317e03ad83774a8752a7e81fb6067740609f75ea2b585b569a59198f" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.25.5+spec-1.1.0" +version = "0.25.8+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1" +checksum = "16bff38f1d86c47f9ff0647e6838d7bb362522bdf44006c7068c2b1e606f1f3c" dependencies = [ "indexmap", "toml_datetime", @@ -4080,18 +4135,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.10+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420" +checksum = "2334f11ee363607eb04df9b8fc8a13ca1715a72ba8662a26ac285c98aabb4011" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.0.7+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17aaa1c6e3dc22b1da4b6bba97d066e354c7945cac2f7852d4e4e7ca7a6b56d" +checksum = "d282ade6016312faf3e41e57ebbba0c073e4056dab1232ab1cb624199648f8ed" [[package]] name = "tonic" @@ -5150,18 +5205,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.42" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" +checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.42" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" +checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.nix b/Cargo.nix index 7ee3108b..1968492a 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -600,10 +600,10 @@ rec { }; "aws-lc-rs" = rec { crateName = "aws-lc-rs"; - version = "1.16.1"; + version = "1.16.2"; edition = "2021"; - links = "aws_lc_rs_1_16_1_sys"; - sha256 = "1gzlb3c82vv3b9adi15kqpk8wps699rjssc3ijkc42pidl0grgwl"; + links = "aws_lc_rs_1_16_2_sys"; + sha256 = "1z6i8qs0xjnzvslxnkhvywzzwfkafb1s4nrpg3f2k1nii4i92m50"; libName = "aws_lc_rs"; authors = [ "AWS-LibCrypto" @@ -635,10 +635,10 @@ rec { }; "aws-lc-sys" = rec { crateName = "aws-lc-sys"; - version = "0.38.0"; + version = "0.39.0"; edition = "2021"; - links = "aws_lc_0_38_0"; - sha256 = "0bkqm9adn7f8c8hd3dnp16cgh39cgjckfzqs55ymmfw9xmlfa8a3"; + links = "aws_lc_0_39_0"; + sha256 = "02jga4605vwqcxzd4k3ikd01x27k4gqwd8hh2rs7qm2w9hmfb9qz"; build = "builder/main.rs"; libName = "aws_lc_sys"; authors = [ @@ -666,6 +666,7 @@ rec { features = { "bindgen" = [ "dep:bindgen" ]; "default" = [ "all-bindings" ]; + "fips" = [ "dep:bindgen" ]; "ssl" = [ "bindgen" "all-bindings" ]; }; resolvedDefaultFeatures = [ "prebuilt-nasm" ]; @@ -2833,6 +2834,42 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "default" ]; }; + "dialoguer" = rec { + crateName = "dialoguer"; + version = "0.12.0"; + edition = "2021"; + sha256 = "15mdq2cp838yiq9fs1jkhvskixvlqz5p8f8dipkn88xz06sh9w95"; + dependencies = [ + { + name = "console"; + packageId = "console"; + } + { + name = "shell-words"; + packageId = "shell-words"; + } + { + name = "tempfile"; + packageId = "tempfile"; + optional = true; + } + { + name = "zeroize"; + packageId = "zeroize"; + optional = true; + } + ]; + features = { + "default" = [ "editor" "password" ]; + "editor" = [ "tempfile" ]; + "fuzzy-matcher" = [ "dep:fuzzy-matcher" ]; + "fuzzy-select" = [ "fuzzy-matcher" ]; + "password" = [ "zeroize" ]; + "tempfile" = [ "dep:tempfile" ]; + "zeroize" = [ "dep:zeroize" ]; + }; + resolvedDefaultFeatures = [ "default" "editor" "password" "tempfile" "zeroize" ]; + }; "digest" = rec { crateName = "digest"; version = "0.10.7"; @@ -3377,7 +3414,7 @@ rec { "js" = [ "std" "getrandom" ]; "std" = [ "alloc" ]; }; - resolvedDefaultFeatures = [ "alloc" "std" ]; + resolvedDefaultFeatures = [ "alloc" "default" "std" ]; }; "find-msvc-tools" = rec { crateName = "find-msvc-tools"; @@ -5593,9 +5630,9 @@ rec { }; "iri-string" = rec { crateName = "iri-string"; - version = "0.7.10"; + version = "0.7.11"; edition = "2021"; - sha256 = "06kk3a5jz576p7vrpf7zz9jv3lrgcyp7pczcblcxdnryg3q3h4y9"; + sha256 = "1sz5y5a9zqhh1n5fb25k2vipl8b5yskpj4hn2s1wh0fcb67l3ryq"; libName = "iri_string"; authors = [ "YOSHIOKA Takuma " @@ -5676,9 +5713,9 @@ rec { }; "itoa" = rec { crateName = "itoa"; - version = "1.0.17"; + version = "1.0.18"; edition = "2021"; - sha256 = "1lh93xydrdn1g9x547bd05g0d3hra7pd1k4jfd2z1pl1h5hwdv4j"; + sha256 = "10jnd1vpfkb8kj38rlkn2a6k02afvj3qmw054dfpzagrpl6achlg"; authors = [ "David Tolnay " ]; @@ -5875,7 +5912,7 @@ rec { } { name = "jni-sys"; - packageId = "jni-sys"; + packageId = "jni-sys 0.3.1"; } { name = "log"; @@ -5904,15 +5941,65 @@ rec { "libloading" = [ "dep:libloading" ]; }; }; - "jni-sys" = rec { + "jni-sys 0.3.1" = rec { crateName = "jni-sys"; - version = "0.3.0"; - edition = "2015"; - sha256 = "0c01zb9ygvwg9wdx2fii2d39myzprnpqqhy7yizxvjqp5p04pbwf"; + version = "0.3.1"; + edition = "2021"; + sha256 = "0n1j8fbz081w1igfrpc79n6vgm7h3ik34nziy5fjgq5nz7hm59j1"; libName = "jni_sys"; authors = [ "Steven Fackler " ]; + dependencies = [ + { + name = "jni-sys"; + packageId = "jni-sys 0.4.1"; + rename = "jni_sys_04"; + } + ]; + features = { + }; + resolvedDefaultFeatures = [ "default" ]; + }; + "jni-sys 0.4.1" = rec { + crateName = "jni-sys"; + version = "0.4.1"; + edition = "2021"; + sha256 = "1wlahx6f2zhczdjqyn8mk7kshb8x5vsd927sn3lvw41rrf47ldy6"; + libName = "jni_sys"; + authors = [ + "Steven Fackler " + "Robert Bragg " + ]; + dependencies = [ + { + name = "jni-sys-macros"; + packageId = "jni-sys-macros"; + } + ]; + + }; + "jni-sys-macros" = rec { + crateName = "jni-sys-macros"; + version = "0.4.1"; + edition = "2021"; + sha256 = "0r32gbabrak15a7p487765b5wc0jcna2yv88mk6m1zjqyi1bkh1q"; + procMacro = true; + libName = "jni_sys_macros"; + authors = [ + "Robert Bragg " + ]; + dependencies = [ + { + name = "quote"; + packageId = "quote"; + } + { + name = "syn"; + packageId = "syn 2.0.117"; + features = [ "full" ]; + } + ]; }; "jobserver" = rec { @@ -7427,9 +7514,9 @@ rec { }; "opentelemetry-otlp" = rec { crateName = "opentelemetry-otlp"; - version = "0.31.0"; + version = "0.31.1"; edition = "2021"; - sha256 = "1gv3h75z8c0p9b85mbq7f1rgsi18wip1xlfa6g82lkfa5pdnc8vs"; + sha256 = "07zp0b62b9dajnvvcd6j2ppw5zg7wp4ixka9z6fr3bxrrdmcss8z"; libName = "opentelemetry_otlp"; dependencies = [ { @@ -7541,6 +7628,9 @@ rec { "serde_json" = [ "dep:serde_json" ]; "serialize" = [ "serde" "serde_json" ]; "tls" = [ "tonic/tls-ring" ]; + "tls-aws-lc" = [ "tonic/tls-aws-lc" ]; + "tls-provider-agnostic" = [ "tonic/_tls-any" ]; + "tls-ring" = [ "tonic/tls-ring" ]; "tls-roots" = [ "tls" "tonic/tls-native-roots" ]; "tls-webpki-roots" = [ "tls" "tonic/tls-webpki-roots" ]; "tokio" = [ "dep:tokio" ]; @@ -10233,7 +10323,7 @@ rec { "thread" = [ "linux-raw-sys/prctl" ]; "use-libc" = [ "libc_errno" "libc" ]; }; - resolvedDefaultFeatures = [ "alloc" "std" "stdio" "termios" ]; + resolvedDefaultFeatures = [ "alloc" "default" "fs" "std" "stdio" "termios" ]; }; "rustls" = rec { crateName = "rustls"; @@ -10504,9 +10594,9 @@ rec { }; "rustls-webpki" = rec { crateName = "rustls-webpki"; - version = "0.103.9"; + version = "0.103.10"; edition = "2021"; - sha256 = "0lwg1nnyv7pp2lfwwjhy81bxm233am99jnsp3iymdhd6k8827pyp"; + sha256 = "1vyipcdbazvhl6kyi1m8n0bg98sk25iv12bby2xcly653awb4cyz"; libName = "webpki"; dependencies = [ { @@ -11086,9 +11176,9 @@ rec { }; "serde_spanned" = rec { crateName = "serde_spanned"; - version = "1.0.4"; - edition = "2021"; - sha256 = "0xkp0qdzams5sqwndbw3xrhf4c0bb5r46w2ywkp1aqsdb8ggkfzq"; + version = "1.1.0"; + edition = "2024"; + sha256 = "166ds31qqkc70k28pspiknnpkvqaxdln6aq3n4mqhkqd0r8w6sl7"; dependencies = [ { name = "serde_core"; @@ -11263,6 +11353,20 @@ rec { "loom" = [ "dep:loom" ]; }; }; + "shell-words" = rec { + crateName = "shell-words"; + version = "1.1.1"; + edition = "2015"; + sha256 = "0xzd5p53xl0ndnk63r0by52rhdrh6pd37szfxszkg73zb6ffcvyw"; + libName = "shell_words"; + authors = [ + "Tomasz Miąsko " + ]; + features = { + "default" = [ "std" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; "shlex" = rec { crateName = "shlex"; version = "1.3.0"; @@ -11652,6 +11756,10 @@ rec { packageId = "clap"; features = [ "derive" "env" ]; } + { + name = "either"; + packageId = "either"; + } { name = "futures"; packageId = "futures"; @@ -12418,6 +12526,10 @@ rec { packageId = "comfy-table"; features = [ "custom_styling" ]; } + { + name = "dialoguer"; + packageId = "dialoguer"; + } { name = "directories"; packageId = "directories"; @@ -12736,6 +12848,54 @@ rec { }; resolvedDefaultFeatures = [ "default" "proc-macro" ]; }; + "tempfile" = rec { + crateName = "tempfile"; + version = "3.27.0"; + edition = "2021"; + sha256 = "1gblhnyfjsbg9wjg194n89wrzah7jy3yzgnyzhp56f3v9jd7wj9j"; + authors = [ + "Steven Allen " + "The Rust Project Developers" + "Ashley Mannix " + "Jason White " + ]; + dependencies = [ + { + name = "fastrand"; + packageId = "fastrand"; + } + { + name = "getrandom"; + packageId = "getrandom 0.4.2"; + optional = true; + usesDefaultFeatures = false; + target = { target, features }: ((target."unix" or false) || (target."windows" or false) || ("wasi" == target."os" or null)); + } + { + name = "once_cell"; + packageId = "once_cell"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "rustix"; + packageId = "rustix"; + target = { target, features }: ((target."unix" or false) || ("wasi" == target."os" or null)); + features = [ "fs" ]; + } + { + name = "windows-sys"; + packageId = "windows-sys 0.61.2"; + target = { target, features }: (target."windows" or false); + features = [ "Win32_Storage_FileSystem" "Win32_Foundation" ]; + } + ]; + features = { + "default" = [ "getrandom" ]; + "getrandom" = [ "dep:getrandom" ]; + }; + resolvedDefaultFeatures = [ "default" "getrandom" ]; + }; "tera" = rec { crateName = "tera"; version = "1.20.1"; @@ -13480,9 +13640,9 @@ rec { }; "toml" = rec { crateName = "toml"; - version = "1.0.7+spec-1.1.0"; - edition = "2021"; - sha256 = "15kaclc4y8yb4ahny19ng51rmff4vj7lyy5qq25lavkgi9yxaa6x"; + version = "1.1.0+spec-1.1.0"; + edition = "2024"; + sha256 = "1k4z4fmq5bnzrdwkgr6477vhlck12qly7wwlpbs2idsfbsh5q6gq"; dependencies = [ { name = "indexmap"; @@ -13544,9 +13704,9 @@ rec { }; "toml_datetime" = rec { crateName = "toml_datetime"; - version = "1.0.1+spec-1.1.0"; - edition = "2021"; - sha256 = "1sgk7zc6x187iib7kj1nzn44mp0zrk9hgii69rbar35m3ms0wclv"; + version = "1.1.0+spec-1.1.0"; + edition = "2024"; + sha256 = "13qrb6d5cnsq5gm7b7v081vhddhzx2km51safy1ss0vy65y1l9cp"; dependencies = [ { name = "serde_core"; @@ -13565,9 +13725,9 @@ rec { }; "toml_edit" = rec { crateName = "toml_edit"; - version = "0.25.5+spec-1.1.0"; - edition = "2021"; - sha256 = "1qgjkq687jkdrc3wq4fi95lj6d0bvwqs9xi3d41wx2x28h3a98cc"; + version = "0.25.8+spec-1.1.0"; + edition = "2024"; + sha256 = "0g0zdxh1wawc0v3hch7lpli2admvsww6hzk4y2gpzi463n7z7gqn"; dependencies = [ { name = "indexmap"; @@ -13600,9 +13760,9 @@ rec { }; "toml_parser" = rec { crateName = "toml_parser"; - version = "1.0.10+spec-1.1.0"; - edition = "2021"; - sha256 = "081lsv63zphnff9ssb0yjavcc82sblvj808rvwb4h76kxx5mpwkx"; + version = "1.1.0+spec-1.1.0"; + edition = "2024"; + sha256 = "04a0pfm9hp18mhk2lrm85fkia5ya2f5grf7r9nq7wq33wcgg2d13"; dependencies = [ { name = "winnow"; @@ -13620,9 +13780,9 @@ rec { }; "toml_writer" = rec { crateName = "toml_writer"; - version = "1.0.7+spec-1.1.0"; - edition = "2021"; - sha256 = "0vdmlskpqkjf5n2zghna8mwlqdbf0ryskfxnlhfjphixdqfalypi"; + version = "1.1.0+spec-1.1.0"; + edition = "2024"; + sha256 = "1vgq92b1j95n3jmk44mbdl2y8wy0l2xynmqywkrzl4k307kav0nj"; features = { "default" = [ "std" ]; "std" = [ "alloc" ]; @@ -18250,9 +18410,9 @@ rec { }; "zerocopy" = rec { crateName = "zerocopy"; - version = "0.8.42"; + version = "0.8.47"; edition = "2021"; - sha256 = "1qq50mj06rds2iac197kpkdlvgql1j3vvm82gy5qayladxqqnmzj"; + sha256 = "11zdl3708210fsiax93qbvw8kiadg9lnzriw26xg44g35c32mfzg"; authors = [ "Joshua Liebow-Feeser " "Jack Wrenn " @@ -18286,9 +18446,9 @@ rec { }; "zerocopy-derive" = rec { crateName = "zerocopy-derive"; - version = "0.8.42"; + version = "0.8.47"; edition = "2021"; - sha256 = "0bx010zlchg4y8xixvkb4c74634j7ypnbpl7cqjdcfsdxacc0v3y"; + sha256 = "12dbrk2w8mszdq9v01ls930bi446iyk4llggxrx8whalkckcg2qf"; procMacro = true; libName = "zerocopy_derive"; authors = [ diff --git a/Cargo.toml b/Cargo.toml index 26abd4e3..25e2e0f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,8 +28,10 @@ clap = { version = "4.5", features = ["derive", "env"] } clap_complete = "4.5" clap_complete_nushell = "4.5" comfy-table = { version = "7.1", features = ["custom_styling"] } +dialoguer = "0.12.0" directories = "6.0" dotenvy = "0.15" +either = "1.15.0" futures = "0.3" indexmap = { version = "2.2", features = ["serde"] } indicatif = "0.18" diff --git a/docs/modules/stackablectl/partials/commands/demo.adoc b/docs/modules/stackablectl/partials/commands/demo.adoc index c5b2d39b..21f5b844 100644 --- a/docs/modules/stackablectl/partials/commands/demo.adoc +++ b/docs/modules/stackablectl/partials/commands/demo.adoc @@ -6,10 +6,11 @@ Interact with demos, which are end-to-end usage demonstrations of the Stackable Usage: stackablectl demo [OPTIONS] Commands: - list List available demos - describe Print out detailed demo information - install Install a specific demo - help Print this message or the help of the given subcommand(s) + list List available demos + describe Print out detailed demo information + install Install a specific demo + uninstall Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs + help Print this message or the help of the given subcommand(s) Options: -l, --log-level diff --git a/docs/modules/stackablectl/partials/commands/stack.adoc b/docs/modules/stackablectl/partials/commands/stack.adoc index 639b1621..9bc0a561 100644 --- a/docs/modules/stackablectl/partials/commands/stack.adoc +++ b/docs/modules/stackablectl/partials/commands/stack.adoc @@ -6,10 +6,11 @@ Interact with stacks, which are ready-to-use product combinations Usage: stackablectl stack [OPTIONS] Commands: - list List available stacks - describe Describe a specific stack - install Install a specific stack - help Print this message or the help of the given subcommand(s) + list List available stacks + describe Describe a specific stack + install Install a specific stack + uninstall Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs + help Print this message or the help of the given subcommand(s) Options: -l, --log-level diff --git a/extra/completions/_stackablectl b/extra/completions/_stackablectl index abba1406..e60dcaae 100644 --- a/extra/completions/_stackablectl +++ b/extra/completions/_stackablectl @@ -672,7 +672,40 @@ repo\:"index.yaml-based repositories\: resolution (dev, test, stable) is based o '--help[Print help (see more with '\''--help'\'')]' \ '-V[Print version]' \ '--version[Print version]' \ -':stack_name -- Name of the stack to describe:_default' \ +':stack_name -- Name of the stack to install:_default' \ +&& ret=0 +;; +(uninstall) +_arguments "${_arguments_options[@]}" : \ +'--operator-namespace=[Namespace where the operators are deployed]:OPERATOR_NAMESPACE:_default' \ +'--operator-ns=[Namespace where the operators are deployed]:OPERATOR_NAMESPACE:_default' \ +'-n+[Namespace where the stacks or demos are deployed]:NAMESPACE:_default' \ +'--namespace=[Namespace where the stacks or demos are deployed]:NAMESPACE:_default' \ +'--product-ns=[Namespace where the stacks or demos are deployed]:NAMESPACE:_default' \ +'--release=[Target a specific Stackable release]:RELEASE:_default' \ +'-l+[Log level this application uses]:LOG_LEVEL:_default' \ +'--log-level=[Log level this application uses]:LOG_LEVEL:_default' \ +'*-d+[Provide one or more additional (custom) demo file(s)]:DEMO_FILE:_files' \ +'*--demo-file=[Provide one or more additional (custom) demo file(s)]:DEMO_FILE:_files' \ +'*-s+[Provide one or more additional (custom) stack file(s)]:STACK_FILE:_files' \ +'*--stack-file=[Provide one or more additional (custom) stack file(s)]:STACK_FILE:_files' \ +'*-r+[Provide one or more additional (custom) release file(s)]:RELEASE_FILE:_files' \ +'*--release-file=[Provide one or more additional (custom) release file(s)]:RELEASE_FILE:_files' \ +'-f+[Path to a Helm values file that will be used for the installation of operators]:VALUES_FILE:_files' \ +'--operator-values=[Path to a Helm values file that will be used for the installation of operators]:VALUES_FILE:_files' \ +'--helm-repo-stable=[Provide a custom Helm stable repository URL]:URL:_urls' \ +'--helm-repo-test=[Provide a custom Helm test repository URL]:URL:_urls' \ +'--helm-repo-dev=[Provide a custom Helm dev repository URL]:URL:_urls' \ +'--chart-source=[Source the charts from either a OCI registry or from index.yaml-based repositories]:CHART_SOURCE:((oci\:"OCI registry" +repo\:"index.yaml-based repositories\: resolution (dev, test, stable) is based on the version and thus will be operator-specific"))' \ +'--listener-class-preset=[Choose the ListenerClass preset (\`none\`, \`ephemeral-nodes\` or \`stable-nodes\`)]:LISTENER_CLASS_PRESET:(none stable-nodes ephemeral-nodes)' \ +'--skip-operators-and-crds[Skip uninstalling Stackable operators and CRDs]' \ +'--no-cache[Do not cache the remote (default) demo, stack and release files]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'-V[Print version]' \ +'--version[Print version]' \ +':stack_name -- Name of the stack to uninstall:_default' \ && ret=0 ;; (help) @@ -699,6 +732,10 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ && ret=0 ;; +(uninstall) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" : \ && ret=0 @@ -988,6 +1025,39 @@ repo\:"index.yaml-based repositories\: resolution (dev, test, stable) is based o ':DEMO -- Demo to install:_default' \ && ret=0 ;; +(uninstall) +_arguments "${_arguments_options[@]}" : \ +'--operator-namespace=[Namespace where the operators are deployed]:OPERATOR_NAMESPACE:_default' \ +'--operator-ns=[Namespace where the operators are deployed]:OPERATOR_NAMESPACE:_default' \ +'-n+[Namespace where the stacks or demos are deployed]:NAMESPACE:_default' \ +'--namespace=[Namespace where the stacks or demos are deployed]:NAMESPACE:_default' \ +'--product-ns=[Namespace where the stacks or demos are deployed]:NAMESPACE:_default' \ +'--release=[Target a specific Stackable release]:RELEASE:_default' \ +'-l+[Log level this application uses]:LOG_LEVEL:_default' \ +'--log-level=[Log level this application uses]:LOG_LEVEL:_default' \ +'*-d+[Provide one or more additional (custom) demo file(s)]:DEMO_FILE:_files' \ +'*--demo-file=[Provide one or more additional (custom) demo file(s)]:DEMO_FILE:_files' \ +'*-s+[Provide one or more additional (custom) stack file(s)]:STACK_FILE:_files' \ +'*--stack-file=[Provide one or more additional (custom) stack file(s)]:STACK_FILE:_files' \ +'*-r+[Provide one or more additional (custom) release file(s)]:RELEASE_FILE:_files' \ +'*--release-file=[Provide one or more additional (custom) release file(s)]:RELEASE_FILE:_files' \ +'-f+[Path to a Helm values file that will be used for the installation of operators]:VALUES_FILE:_files' \ +'--operator-values=[Path to a Helm values file that will be used for the installation of operators]:VALUES_FILE:_files' \ +'--helm-repo-stable=[Provide a custom Helm stable repository URL]:URL:_urls' \ +'--helm-repo-test=[Provide a custom Helm test repository URL]:URL:_urls' \ +'--helm-repo-dev=[Provide a custom Helm dev repository URL]:URL:_urls' \ +'--chart-source=[Source the charts from either a OCI registry or from index.yaml-based repositories]:CHART_SOURCE:((oci\:"OCI registry" +repo\:"index.yaml-based repositories\: resolution (dev, test, stable) is based on the version and thus will be operator-specific"))' \ +'--listener-class-preset=[Choose the ListenerClass preset (\`none\`, \`ephemeral-nodes\` or \`stable-nodes\`)]:LISTENER_CLASS_PRESET:(none stable-nodes ephemeral-nodes)' \ +'--skip-operators-and-crds[Skip uninstalling Stackable operators and CRDs]' \ +'--no-cache[Do not cache the remote (default) demo, stack and release files]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'-V[Print version]' \ +'--version[Print version]' \ +':demo_name -- Demo to uninstall:_default' \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" : \ ":: :_stackablectl__demo__help_commands" \ @@ -1012,6 +1082,10 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ && ret=0 ;; +(uninstall) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" : \ && ret=0 @@ -1568,6 +1642,10 @@ _arguments "${_arguments_options[@]}" : \ (install) _arguments "${_arguments_options[@]}" : \ && ret=0 +;; +(uninstall) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 ;; esac ;; @@ -1620,6 +1698,10 @@ _arguments "${_arguments_options[@]}" : \ (install) _arguments "${_arguments_options[@]}" : \ && ret=0 +;; +(uninstall) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 ;; esac ;; @@ -1866,6 +1948,7 @@ _stackablectl__demo_commands() { 'list:List available demos' \ 'describe:Print out detailed demo information' \ 'install:Install a specific demo' \ +'uninstall:Uninstall a specific stack. Caution\: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'stackablectl demo commands' commands "$@" @@ -1881,6 +1964,7 @@ _stackablectl__demo__help_commands() { 'list:List available demos' \ 'describe:Print out detailed demo information' \ 'install:Install a specific demo' \ +'uninstall:Uninstall a specific stack. Caution\: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'stackablectl demo help commands' commands "$@" @@ -1905,6 +1989,11 @@ _stackablectl__demo__help__list_commands() { local commands; commands=() _describe -t commands 'stackablectl demo help list commands' commands "$@" } +(( $+functions[_stackablectl__demo__help__uninstall_commands] )) || +_stackablectl__demo__help__uninstall_commands() { + local commands; commands=() + _describe -t commands 'stackablectl demo help uninstall commands' commands "$@" +} (( $+functions[_stackablectl__demo__install_commands] )) || _stackablectl__demo__install_commands() { local commands; commands=() @@ -1915,6 +2004,11 @@ _stackablectl__demo__list_commands() { local commands; commands=() _describe -t commands 'stackablectl demo list commands' commands "$@" } +(( $+functions[_stackablectl__demo__uninstall_commands] )) || +_stackablectl__demo__uninstall_commands() { + local commands; commands=() + _describe -t commands 'stackablectl demo uninstall commands' commands "$@" +} (( $+functions[_stackablectl__experimental-debug_commands] )) || _stackablectl__experimental-debug_commands() { local commands; commands=() @@ -1996,6 +2090,7 @@ _stackablectl__help__demo_commands() { 'list:List available demos' \ 'describe:Print out detailed demo information' \ 'install:Install a specific demo' \ +'uninstall:Uninstall a specific stack. Caution\: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' \ ) _describe -t commands 'stackablectl help demo commands' commands "$@" } @@ -2014,6 +2109,11 @@ _stackablectl__help__demo__list_commands() { local commands; commands=() _describe -t commands 'stackablectl help demo list commands' commands "$@" } +(( $+functions[_stackablectl__help__demo__uninstall_commands] )) || +_stackablectl__help__demo__uninstall_commands() { + local commands; commands=() + _describe -t commands 'stackablectl help demo uninstall commands' commands "$@" +} (( $+functions[_stackablectl__help__experimental-debug_commands] )) || _stackablectl__help__experimental-debug_commands() { local commands; commands=() @@ -2102,6 +2202,7 @@ _stackablectl__help__stack_commands() { 'list:List available stacks' \ 'describe:Describe a specific stack' \ 'install:Install a specific stack' \ +'uninstall:Uninstall a specific stack. Caution\: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' \ ) _describe -t commands 'stackablectl help stack commands' commands "$@" } @@ -2120,6 +2221,11 @@ _stackablectl__help__stack__list_commands() { local commands; commands=() _describe -t commands 'stackablectl help stack list commands' commands "$@" } +(( $+functions[_stackablectl__help__stack__uninstall_commands] )) || +_stackablectl__help__stack__uninstall_commands() { + local commands; commands=() + _describe -t commands 'stackablectl help stack uninstall commands' commands "$@" +} (( $+functions[_stackablectl__help__stacklet_commands] )) || _stackablectl__help__stacklet_commands() { local commands; commands=( @@ -2314,6 +2420,7 @@ _stackablectl__stack_commands() { 'list:List available stacks' \ 'describe:Describe a specific stack' \ 'install:Install a specific stack' \ +'uninstall:Uninstall a specific stack. Caution\: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'stackablectl stack commands' commands "$@" @@ -2329,6 +2436,7 @@ _stackablectl__stack__help_commands() { 'list:List available stacks' \ 'describe:Describe a specific stack' \ 'install:Install a specific stack' \ +'uninstall:Uninstall a specific stack. Caution\: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'stackablectl stack help commands' commands "$@" @@ -2353,6 +2461,11 @@ _stackablectl__stack__help__list_commands() { local commands; commands=() _describe -t commands 'stackablectl stack help list commands' commands "$@" } +(( $+functions[_stackablectl__stack__help__uninstall_commands] )) || +_stackablectl__stack__help__uninstall_commands() { + local commands; commands=() + _describe -t commands 'stackablectl stack help uninstall commands' commands "$@" +} (( $+functions[_stackablectl__stack__install_commands] )) || _stackablectl__stack__install_commands() { local commands; commands=() @@ -2363,6 +2476,11 @@ _stackablectl__stack__list_commands() { local commands; commands=() _describe -t commands 'stackablectl stack list commands' commands "$@" } +(( $+functions[_stackablectl__stack__uninstall_commands] )) || +_stackablectl__stack__uninstall_commands() { + local commands; commands=() + _describe -t commands 'stackablectl stack uninstall commands' commands "$@" +} (( $+functions[_stackablectl__stacklet_commands] )) || _stackablectl__stacklet_commands() { local commands; commands=( diff --git a/extra/completions/stackablectl.bash b/extra/completions/stackablectl.bash index be0544fa..13c0028a 100644 --- a/extra/completions/stackablectl.bash +++ b/extra/completions/stackablectl.bash @@ -112,6 +112,9 @@ _stackablectl() { stackablectl__demo,list) cmd="stackablectl__demo__list" ;; + stackablectl__demo,uninstall) + cmd="stackablectl__demo__uninstall" + ;; stackablectl__demo__help,describe) cmd="stackablectl__demo__help__describe" ;; @@ -124,6 +127,9 @@ _stackablectl() { stackablectl__demo__help,list) cmd="stackablectl__demo__help__list" ;; + stackablectl__demo__help,uninstall) + cmd="stackablectl__demo__help__uninstall" + ;; stackablectl__help,cache) cmd="stackablectl__help__cache" ;; @@ -184,6 +190,9 @@ _stackablectl() { stackablectl__help__demo,list) cmd="stackablectl__help__demo__list" ;; + stackablectl__help__demo,uninstall) + cmd="stackablectl__help__demo__uninstall" + ;; stackablectl__help__operator,describe) cmd="stackablectl__help__operator__describe" ;; @@ -223,6 +232,9 @@ _stackablectl() { stackablectl__help__stack,list) cmd="stackablectl__help__stack__list" ;; + stackablectl__help__stack,uninstall) + cmd="stackablectl__help__stack__uninstall" + ;; stackablectl__help__stacklet,credentials) cmd="stackablectl__help__stacklet__credentials" ;; @@ -316,6 +328,9 @@ _stackablectl() { stackablectl__stack,list) cmd="stackablectl__stack__list" ;; + stackablectl__stack,uninstall) + cmd="stackablectl__stack__uninstall" + ;; stackablectl__stack__help,describe) cmd="stackablectl__stack__help__describe" ;; @@ -328,6 +343,9 @@ _stackablectl() { stackablectl__stack__help,list) cmd="stackablectl__stack__help__list" ;; + stackablectl__stack__help,uninstall) + cmd="stackablectl__stack__help__uninstall" + ;; stackablectl__stacklet,credentials) cmd="stackablectl__stacklet__credentials" ;; @@ -2139,7 +2157,7 @@ _stackablectl() { return 0 ;; stackablectl__demo) - opts="-l -d -s -r -f -h -V --release --log-level --no-cache --demo-file --stack-file --release-file --operator-values --helm-repo-stable --helm-repo-test --helm-repo-dev --chart-source --listener-class-preset --help --version list describe install help" + opts="-l -d -s -r -f -h -V --release --log-level --no-cache --demo-file --stack-file --release-file --operator-values --helm-repo-stable --helm-repo-test --helm-repo-dev --chart-source --listener-class-preset --help --version list describe install uninstall help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2479,7 +2497,7 @@ _stackablectl() { return 0 ;; stackablectl__demo__help) - opts="list describe install help" + opts="list describe install uninstall help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2548,6 +2566,20 @@ _stackablectl() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + stackablectl__demo__help__uninstall) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; stackablectl__demo__install) opts="-c -n -l -d -s -r -f -h -V --skip-release --stack-parameters --parameters --cluster --cluster-name --cluster-nodes --cluster-cp-nodes --operator-ns --operator-namespace --product-ns --namespace --release --log-level --no-cache --demo-file --stack-file --release-file --operator-values --helm-repo-stable --helm-repo-test --helm-repo-dev --chart-source --listener-class-preset --help --version " if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -2936,6 +2968,192 @@ _stackablectl() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + stackablectl__demo__uninstall) + opts="-n -l -d -s -r -f -h -V --operator-ns --operator-namespace --product-ns --namespace --skip-operators-and-crds --release --log-level --no-cache --demo-file --stack-file --release-file --operator-values --helm-repo-stable --helm-repo-test --helm-repo-dev --chart-source --listener-class-preset --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --operator-namespace) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --operator-ns) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --namespace) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --product-ns) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -n) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --release) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --log-level) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -l) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --demo-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -d) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --stack-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -s) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --release-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -r) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --operator-values) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -f) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --helm-repo-stable) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --helm-repo-test) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --helm-repo-dev) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chart-source) + COMPREPLY=($(compgen -W "oci repo" -- "${cur}")) + return 0 + ;; + --listener-class-preset) + COMPREPLY=($(compgen -W "none stable-nodes ephemeral-nodes" -- "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; stackablectl__experimental__debug) opts="-n -c -l -d -s -r -f -h -V --namespace --container --image --log-level --no-cache --demo-file --stack-file --release-file --operator-values --helm-repo-stable --helm-repo-test --helm-repo-dev --chart-source --listener-class-preset --help --version [CMD]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then @@ -3259,7 +3477,7 @@ _stackablectl() { return 0 ;; stackablectl__help__demo) - opts="list describe install" + opts="list describe install uninstall" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3314,6 +3532,20 @@ _stackablectl() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + stackablectl__help__demo__uninstall) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; stackablectl__help__experimental__debug) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -3511,7 +3743,7 @@ _stackablectl() { return 0 ;; stackablectl__help__stack) - opts="list describe install" + opts="list describe install uninstall" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3566,6 +3798,20 @@ _stackablectl() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + stackablectl__help__stack__uninstall) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; stackablectl__help__stacklet) opts="credentials list" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -5937,7 +6183,7 @@ _stackablectl() { return 0 ;; stackablectl__stack) - opts="-l -d -s -r -f -h -V --release --log-level --no-cache --demo-file --stack-file --release-file --operator-values --helm-repo-stable --helm-repo-test --helm-repo-dev --chart-source --listener-class-preset --help --version list describe install help" + opts="-l -d -s -r -f -h -V --release --log-level --no-cache --demo-file --stack-file --release-file --operator-values --helm-repo-stable --helm-repo-test --helm-repo-dev --chart-source --listener-class-preset --help --version list describe install uninstall help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -6277,7 +6523,7 @@ _stackablectl() { return 0 ;; stackablectl__stack__help) - opts="list describe install help" + opts="list describe install uninstall help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -6346,6 +6592,20 @@ _stackablectl() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + stackablectl__stack__help__uninstall) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; stackablectl__stack__install) opts="-c -n -l -d -s -r -f -h -V --skip-release --stack-parameters --parameters --cluster --cluster-name --cluster-nodes --cluster-cp-nodes --operator-ns --operator-namespace --product-ns --namespace --release --log-level --no-cache --demo-file --stack-file --release-file --operator-values --helm-repo-stable --helm-repo-test --helm-repo-dev --chart-source --listener-class-preset --help --version " if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -6734,6 +6994,192 @@ _stackablectl() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + stackablectl__stack__uninstall) + opts="-n -l -d -s -r -f -h -V --operator-ns --operator-namespace --product-ns --namespace --skip-operators-and-crds --release --log-level --no-cache --demo-file --stack-file --release-file --operator-values --helm-repo-stable --helm-repo-test --helm-repo-dev --chart-source --listener-class-preset --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --operator-namespace) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --operator-ns) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --namespace) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --product-ns) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -n) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --release) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --log-level) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -l) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --demo-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -d) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --stack-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -s) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --release-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -r) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --operator-values) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -f) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --helm-repo-stable) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --helm-repo-test) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --helm-repo-dev) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chart-source) + COMPREPLY=($(compgen -W "oci repo" -- "${cur}")) + return 0 + ;; + --listener-class-preset) + COMPREPLY=($(compgen -W "none stable-nodes ephemeral-nodes" -- "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; stackablectl__stacklet) opts="-l -d -s -r -f -h -V --log-level --no-cache --demo-file --stack-file --release-file --operator-values --helm-repo-stable --helm-repo-test --helm-repo-dev --chart-source --listener-class-preset --help --version credentials list help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then diff --git a/extra/completions/stackablectl.elv b/extra/completions/stackablectl.elv index e98558e7..4faf691a 100644 --- a/extra/completions/stackablectl.elv +++ b/extra/completions/stackablectl.elv @@ -430,6 +430,7 @@ set edit:completion:arg-completer[stackablectl] = {|@words| cand list 'List available stacks' cand describe 'Describe a specific stack' cand install 'Install a specific stack' + cand uninstall 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' cand help 'Print this message or the help of the given subcommand(s)' } &'stackablectl;stack;list'= { @@ -518,10 +519,40 @@ set edit:completion:arg-completer[stackablectl] = {|@words| cand -V 'Print version' cand --version 'Print version' } + &'stackablectl;stack;uninstall'= { + cand --operator-namespace 'Namespace where the operators are deployed' + cand --operator-ns 'Namespace where the operators are deployed' + cand -n 'Namespace where the stacks or demos are deployed' + cand --namespace 'Namespace where the stacks or demos are deployed' + cand --product-ns 'Namespace where the stacks or demos are deployed' + cand --release 'Target a specific Stackable release' + cand -l 'Log level this application uses' + cand --log-level 'Log level this application uses' + cand -d 'Provide one or more additional (custom) demo file(s)' + cand --demo-file 'Provide one or more additional (custom) demo file(s)' + cand -s 'Provide one or more additional (custom) stack file(s)' + cand --stack-file 'Provide one or more additional (custom) stack file(s)' + cand -r 'Provide one or more additional (custom) release file(s)' + cand --release-file 'Provide one or more additional (custom) release file(s)' + cand -f 'Path to a Helm values file that will be used for the installation of operators' + cand --operator-values 'Path to a Helm values file that will be used for the installation of operators' + cand --helm-repo-stable 'Provide a custom Helm stable repository URL' + cand --helm-repo-test 'Provide a custom Helm test repository URL' + cand --helm-repo-dev 'Provide a custom Helm dev repository URL' + cand --chart-source 'Source the charts from either a OCI registry or from index.yaml-based repositories' + cand --listener-class-preset 'Choose the ListenerClass preset (`none`, `ephemeral-nodes` or `stable-nodes`)' + cand --skip-operators-and-crds 'Skip uninstalling Stackable operators and CRDs' + cand --no-cache 'Do not cache the remote (default) demo, stack and release files' + cand -h 'Print help (see more with ''--help'')' + cand --help 'Print help (see more with ''--help'')' + cand -V 'Print version' + cand --version 'Print version' + } &'stackablectl;stack;help'= { cand list 'List available stacks' cand describe 'Describe a specific stack' cand install 'Install a specific stack' + cand uninstall 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' cand help 'Print this message or the help of the given subcommand(s)' } &'stackablectl;stack;help;list'= { @@ -530,6 +561,8 @@ set edit:completion:arg-completer[stackablectl] = {|@words| } &'stackablectl;stack;help;install'= { } + &'stackablectl;stack;help;uninstall'= { + } &'stackablectl;stack;help;help'= { } &'stackablectl;stacklet'= { @@ -646,6 +679,7 @@ set edit:completion:arg-completer[stackablectl] = {|@words| cand list 'List available demos' cand describe 'Print out detailed demo information' cand install 'Install a specific demo' + cand uninstall 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' cand help 'Print this message or the help of the given subcommand(s)' } &'stackablectl;demo;list'= { @@ -734,10 +768,40 @@ set edit:completion:arg-completer[stackablectl] = {|@words| cand -V 'Print version' cand --version 'Print version' } + &'stackablectl;demo;uninstall'= { + cand --operator-namespace 'Namespace where the operators are deployed' + cand --operator-ns 'Namespace where the operators are deployed' + cand -n 'Namespace where the stacks or demos are deployed' + cand --namespace 'Namespace where the stacks or demos are deployed' + cand --product-ns 'Namespace where the stacks or demos are deployed' + cand --release 'Target a specific Stackable release' + cand -l 'Log level this application uses' + cand --log-level 'Log level this application uses' + cand -d 'Provide one or more additional (custom) demo file(s)' + cand --demo-file 'Provide one or more additional (custom) demo file(s)' + cand -s 'Provide one or more additional (custom) stack file(s)' + cand --stack-file 'Provide one or more additional (custom) stack file(s)' + cand -r 'Provide one or more additional (custom) release file(s)' + cand --release-file 'Provide one or more additional (custom) release file(s)' + cand -f 'Path to a Helm values file that will be used for the installation of operators' + cand --operator-values 'Path to a Helm values file that will be used for the installation of operators' + cand --helm-repo-stable 'Provide a custom Helm stable repository URL' + cand --helm-repo-test 'Provide a custom Helm test repository URL' + cand --helm-repo-dev 'Provide a custom Helm dev repository URL' + cand --chart-source 'Source the charts from either a OCI registry or from index.yaml-based repositories' + cand --listener-class-preset 'Choose the ListenerClass preset (`none`, `ephemeral-nodes` or `stable-nodes`)' + cand --skip-operators-and-crds 'Skip uninstalling Stackable operators and CRDs' + cand --no-cache 'Do not cache the remote (default) demo, stack and release files' + cand -h 'Print help (see more with ''--help'')' + cand --help 'Print help (see more with ''--help'')' + cand -V 'Print version' + cand --version 'Print version' + } &'stackablectl;demo;help'= { cand list 'List available demos' cand describe 'Print out detailed demo information' cand install 'Install a specific demo' + cand uninstall 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' cand help 'Print this message or the help of the given subcommand(s)' } &'stackablectl;demo;help;list'= { @@ -746,6 +810,8 @@ set edit:completion:arg-completer[stackablectl] = {|@words| } &'stackablectl;demo;help;install'= { } + &'stackablectl;demo;help;uninstall'= { + } &'stackablectl;demo;help;help'= { } &'stackablectl;completions'= { @@ -1119,6 +1185,7 @@ set edit:completion:arg-completer[stackablectl] = {|@words| cand list 'List available stacks' cand describe 'Describe a specific stack' cand install 'Install a specific stack' + cand uninstall 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' } &'stackablectl;help;stack;list'= { } @@ -1126,6 +1193,8 @@ set edit:completion:arg-completer[stackablectl] = {|@words| } &'stackablectl;help;stack;install'= { } + &'stackablectl;help;stack;uninstall'= { + } &'stackablectl;help;stacklet'= { cand credentials 'Display credentials for a stacklet' cand list 'List deployed stacklets' @@ -1138,6 +1207,7 @@ set edit:completion:arg-completer[stackablectl] = {|@words| cand list 'List available demos' cand describe 'Print out detailed demo information' cand install 'Install a specific demo' + cand uninstall 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' } &'stackablectl;help;demo;list'= { } @@ -1145,6 +1215,8 @@ set edit:completion:arg-completer[stackablectl] = {|@words| } &'stackablectl;help;demo;install'= { } + &'stackablectl;help;demo;uninstall'= { + } &'stackablectl;help;completions'= { cand bash 'Generate shell completions for Bash' cand elvish 'Generate shell completions for Elvish' diff --git a/extra/completions/stackablectl.fish b/extra/completions/stackablectl.fish index ba0bb555..d60c7d99 100644 --- a/extra/completions/stackablectl.fish +++ b/extra/completions/stackablectl.fish @@ -306,27 +306,28 @@ complete -c stackablectl -n "__fish_stackablectl_using_subcommand release; and _ complete -c stackablectl -n "__fish_stackablectl_using_subcommand release; and __fish_seen_subcommand_from help" -f -a "uninstall" -d 'Uninstall a release' complete -c stackablectl -n "__fish_stackablectl_using_subcommand release; and __fish_seen_subcommand_from help" -f -a "upgrade" -d 'Upgrade a release' complete -c stackablectl -n "__fish_stackablectl_using_subcommand release; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -l release -d 'Target a specific Stackable release' -r -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -s l -l log-level -d 'Log level this application uses' -r -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -s d -l demo-file -d 'Provide one or more additional (custom) demo file(s)' -r -F -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -s s -l stack-file -d 'Provide one or more additional (custom) stack file(s)' -r -F -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -s r -l release-file -d 'Provide one or more additional (custom) release file(s)' -r -F -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -s f -l operator-values -d 'Path to a Helm values file that will be used for the installation of operators' -r -F -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -l helm-repo-stable -d 'Provide a custom Helm stable repository URL' -r -f -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -l helm-repo-test -d 'Provide a custom Helm test repository URL' -r -f -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -l helm-repo-dev -d 'Provide a custom Helm dev repository URL' -r -f -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -l chart-source -d 'Source the charts from either a OCI registry or from index.yaml-based repositories' -r -f -a "oci\t'OCI registry' -repo\t'index.yaml-based repositories: resolution (dev, test, stable) is based on the version and thus will be operator-specific'" -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -l listener-class-preset -d 'Choose the ListenerClass preset (`none`, `ephemeral-nodes` or `stable-nodes`)' -r -f -a "none\t'' -stable-nodes\t'' -ephemeral-nodes\t''" -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -l no-cache -d 'Do not cache the remote (default) demo, stack and release files' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -s V -l version -d 'Print version' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -f -a "list" -d 'List available stacks' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -f -a "describe" -d 'Describe a specific stack' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -f -a "install" -d 'Install a specific stack' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -l release -d 'Target a specific Stackable release' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -s l -l log-level -d 'Log level this application uses' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -s d -l demo-file -d 'Provide one or more additional (custom) demo file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -s s -l stack-file -d 'Provide one or more additional (custom) stack file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -s r -l release-file -d 'Provide one or more additional (custom) release file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -s f -l operator-values -d 'Path to a Helm values file that will be used for the installation of operators' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -l helm-repo-stable -d 'Provide a custom Helm stable repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -l helm-repo-test -d 'Provide a custom Helm test repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -l helm-repo-dev -d 'Provide a custom Helm dev repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -l chart-source -d 'Source the charts from either a OCI registry or from index.yaml-based repositories' -r -f -a "oci\t'OCI registry' +repo\t'index.yaml-based repositories: resolution (dev, test, stable) is based on the version and thus will be operator-specific'" +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -l listener-class-preset -d 'Choose the ListenerClass preset (`none`, `ephemeral-nodes` or `stable-nodes`)' -r -f -a "none\t'' +stable-nodes\t'' +ephemeral-nodes\t''" +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -l no-cache -d 'Do not cache the remote (default) demo, stack and release files' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -s V -l version -d 'Print version' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -f -a "list" -d 'List available stacks' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -f -a "describe" -d 'Describe a specific stack' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -f -a "install" -d 'Install a specific stack' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -f -a "uninstall" -d 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and not __fish_seen_subcommand_from list describe install uninstall help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from list" -s o -l output -r -f -a "plain\t'Print output formatted as plain text' table\t'Print output formatted as a table' json\t'Print output formatted as JSON' @@ -396,9 +397,30 @@ complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __f complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from install" -l no-cache -d 'Do not cache the remote (default) demo, stack and release files' complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from install" -s h -l help -d 'Print help (see more with \'--help\')' complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from install" -s V -l version -d 'Print version' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -l operator-namespace -l operator-ns -d 'Namespace where the operators are deployed' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -s n -l namespace -l product-ns -d 'Namespace where the stacks or demos are deployed' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -l release -d 'Target a specific Stackable release' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -s l -l log-level -d 'Log level this application uses' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -s d -l demo-file -d 'Provide one or more additional (custom) demo file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -s s -l stack-file -d 'Provide one or more additional (custom) stack file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -s r -l release-file -d 'Provide one or more additional (custom) release file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -s f -l operator-values -d 'Path to a Helm values file that will be used for the installation of operators' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -l helm-repo-stable -d 'Provide a custom Helm stable repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -l helm-repo-test -d 'Provide a custom Helm test repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -l helm-repo-dev -d 'Provide a custom Helm dev repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -l chart-source -d 'Source the charts from either a OCI registry or from index.yaml-based repositories' -r -f -a "oci\t'OCI registry' +repo\t'index.yaml-based repositories: resolution (dev, test, stable) is based on the version and thus will be operator-specific'" +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -l listener-class-preset -d 'Choose the ListenerClass preset (`none`, `ephemeral-nodes` or `stable-nodes`)' -r -f -a "none\t'' +stable-nodes\t'' +ephemeral-nodes\t''" +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -l skip-operators-and-crds -d 'Skip uninstalling Stackable operators and CRDs' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -l no-cache -d 'Do not cache the remote (default) demo, stack and release files' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from uninstall" -s V -l version -d 'Print version' complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from help" -f -a "list" -d 'List available stacks' complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from help" -f -a "describe" -d 'Describe a specific stack' complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from help" -f -a "install" -d 'Install a specific stack' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from help" -f -a "uninstall" -d 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' complete -c stackablectl -n "__fish_stackablectl_using_subcommand stack; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c stackablectl -n "__fish_stackablectl_using_subcommand stacklet; and not __fish_seen_subcommand_from credentials list help" -s l -l log-level -d 'Log level this application uses' -r complete -c stackablectl -n "__fish_stackablectl_using_subcommand stacklet; and not __fish_seen_subcommand_from credentials list help" -s d -l demo-file -d 'Provide one or more additional (custom) demo file(s)' -r -F @@ -461,27 +483,28 @@ complete -c stackablectl -n "__fish_stackablectl_using_subcommand stacklet; and complete -c stackablectl -n "__fish_stackablectl_using_subcommand stacklet; and __fish_seen_subcommand_from help" -f -a "credentials" -d 'Display credentials for a stacklet' complete -c stackablectl -n "__fish_stackablectl_using_subcommand stacklet; and __fish_seen_subcommand_from help" -f -a "list" -d 'List deployed stacklets' complete -c stackablectl -n "__fish_stackablectl_using_subcommand stacklet; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -l release -d 'Target a specific Stackable release' -r -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -s l -l log-level -d 'Log level this application uses' -r -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -s d -l demo-file -d 'Provide one or more additional (custom) demo file(s)' -r -F -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -s s -l stack-file -d 'Provide one or more additional (custom) stack file(s)' -r -F -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -s r -l release-file -d 'Provide one or more additional (custom) release file(s)' -r -F -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -s f -l operator-values -d 'Path to a Helm values file that will be used for the installation of operators' -r -F -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -l helm-repo-stable -d 'Provide a custom Helm stable repository URL' -r -f -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -l helm-repo-test -d 'Provide a custom Helm test repository URL' -r -f -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -l helm-repo-dev -d 'Provide a custom Helm dev repository URL' -r -f -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -l chart-source -d 'Source the charts from either a OCI registry or from index.yaml-based repositories' -r -f -a "oci\t'OCI registry' -repo\t'index.yaml-based repositories: resolution (dev, test, stable) is based on the version and thus will be operator-specific'" -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -l listener-class-preset -d 'Choose the ListenerClass preset (`none`, `ephemeral-nodes` or `stable-nodes`)' -r -f -a "none\t'' -stable-nodes\t'' -ephemeral-nodes\t''" -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -l no-cache -d 'Do not cache the remote (default) demo, stack and release files' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -s V -l version -d 'Print version' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -f -a "list" -d 'List available demos' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -f -a "describe" -d 'Print out detailed demo information' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -f -a "install" -d 'Install a specific demo' -complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -l release -d 'Target a specific Stackable release' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -s l -l log-level -d 'Log level this application uses' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -s d -l demo-file -d 'Provide one or more additional (custom) demo file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -s s -l stack-file -d 'Provide one or more additional (custom) stack file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -s r -l release-file -d 'Provide one or more additional (custom) release file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -s f -l operator-values -d 'Path to a Helm values file that will be used for the installation of operators' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -l helm-repo-stable -d 'Provide a custom Helm stable repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -l helm-repo-test -d 'Provide a custom Helm test repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -l helm-repo-dev -d 'Provide a custom Helm dev repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -l chart-source -d 'Source the charts from either a OCI registry or from index.yaml-based repositories' -r -f -a "oci\t'OCI registry' +repo\t'index.yaml-based repositories: resolution (dev, test, stable) is based on the version and thus will be operator-specific'" +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -l listener-class-preset -d 'Choose the ListenerClass preset (`none`, `ephemeral-nodes` or `stable-nodes`)' -r -f -a "none\t'' +stable-nodes\t'' +ephemeral-nodes\t''" +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -l no-cache -d 'Do not cache the remote (default) demo, stack and release files' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -s V -l version -d 'Print version' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -f -a "list" -d 'List available demos' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -f -a "describe" -d 'Print out detailed demo information' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -f -a "install" -d 'Install a specific demo' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -f -a "uninstall" -d 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and not __fish_seen_subcommand_from list describe install uninstall help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from list" -s o -l output -r -f -a "plain\t'Print output formatted as plain text' table\t'Print output formatted as a table' json\t'Print output formatted as JSON' @@ -551,9 +574,30 @@ complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fi complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from install" -l no-cache -d 'Do not cache the remote (default) demo, stack and release files' complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from install" -s h -l help -d 'Print help (see more with \'--help\')' complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from install" -s V -l version -d 'Print version' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -l operator-namespace -l operator-ns -d 'Namespace where the operators are deployed' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -s n -l namespace -l product-ns -d 'Namespace where the stacks or demos are deployed' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -l release -d 'Target a specific Stackable release' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -s l -l log-level -d 'Log level this application uses' -r +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -s d -l demo-file -d 'Provide one or more additional (custom) demo file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -s s -l stack-file -d 'Provide one or more additional (custom) stack file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -s r -l release-file -d 'Provide one or more additional (custom) release file(s)' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -s f -l operator-values -d 'Path to a Helm values file that will be used for the installation of operators' -r -F +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -l helm-repo-stable -d 'Provide a custom Helm stable repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -l helm-repo-test -d 'Provide a custom Helm test repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -l helm-repo-dev -d 'Provide a custom Helm dev repository URL' -r -f +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -l chart-source -d 'Source the charts from either a OCI registry or from index.yaml-based repositories' -r -f -a "oci\t'OCI registry' +repo\t'index.yaml-based repositories: resolution (dev, test, stable) is based on the version and thus will be operator-specific'" +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -l listener-class-preset -d 'Choose the ListenerClass preset (`none`, `ephemeral-nodes` or `stable-nodes`)' -r -f -a "none\t'' +stable-nodes\t'' +ephemeral-nodes\t''" +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -l skip-operators-and-crds -d 'Skip uninstalling Stackable operators and CRDs' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -l no-cache -d 'Do not cache the remote (default) demo, stack and release files' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from uninstall" -s V -l version -d 'Print version' complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from help" -f -a "list" -d 'List available demos' complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from help" -f -a "describe" -d 'Print out detailed demo information' complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from help" -f -a "install" -d 'Install a specific demo' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from help" -f -a "uninstall" -d 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' complete -c stackablectl -n "__fish_stackablectl_using_subcommand demo; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c stackablectl -n "__fish_stackablectl_using_subcommand completions; and not __fish_seen_subcommand_from bash elvish fish nushell zsh help" -s l -l log-level -d 'Log level this application uses' -r complete -c stackablectl -n "__fish_stackablectl_using_subcommand completions; and not __fish_seen_subcommand_from bash elvish fish nushell zsh help" -s d -l demo-file -d 'Provide one or more additional (custom) demo file(s)' -r -F @@ -796,11 +840,13 @@ complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fi complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from stack" -f -a "list" -d 'List available stacks' complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from stack" -f -a "describe" -d 'Describe a specific stack' complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from stack" -f -a "install" -d 'Install a specific stack' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from stack" -f -a "uninstall" -d 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from stacklet" -f -a "credentials" -d 'Display credentials for a stacklet' complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from stacklet" -f -a "list" -d 'List deployed stacklets' complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from demo" -f -a "list" -d 'List available demos' complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from demo" -f -a "describe" -d 'Print out detailed demo information' complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from demo" -f -a "install" -d 'Install a specific demo' +complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from demo" -f -a "uninstall" -d 'Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs' complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from completions" -f -a "bash" -d 'Generate shell completions for Bash' complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from completions" -f -a "elvish" -d 'Generate shell completions for Elvish' complete -c stackablectl -n "__fish_stackablectl_using_subcommand help; and __fish_seen_subcommand_from completions" -f -a "fish" -d 'Generate shell completions for Fish' diff --git a/extra/completions/stackablectl.nu b/extra/completions/stackablectl.nu index ee82490f..b5b95011 100644 --- a/extra/completions/stackablectl.nu +++ b/extra/completions/stackablectl.nu @@ -573,7 +573,39 @@ module completions { --listener-class-preset: string@"nu-complete stackablectl stack install listener_class_preset" # Choose the ListenerClass preset (`none`, `ephemeral-nodes` or `stable-nodes`) --help(-h) # Print help (see more with '--help') --version(-V) # Print version - stack_name: string # Name of the stack to describe + stack_name: string # Name of the stack to install + ] + + def "nu-complete stackablectl stack uninstall chart_source" [] { + [ "oci" "repo" ] + } + + def "nu-complete stackablectl stack uninstall listener_class_preset" [] { + [ "none" "stable-nodes" "ephemeral-nodes" ] + } + + # Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs + export extern "stackablectl stack uninstall" [ + --operator-namespace: string # Namespace where the operators are deployed + --operator-ns: string # Namespace where the operators are deployed + --namespace(-n): string # Namespace where the stacks or demos are deployed + --product-ns: string # Namespace where the stacks or demos are deployed + --skip-operators-and-crds # Skip uninstalling Stackable operators and CRDs + --release: string # Target a specific Stackable release + --log-level(-l): string # Log level this application uses + --no-cache # Do not cache the remote (default) demo, stack and release files + --demo-file(-d): path # Provide one or more additional (custom) demo file(s) + --stack-file(-s): path # Provide one or more additional (custom) stack file(s) + --release-file(-r): path # Provide one or more additional (custom) release file(s) + --operator-values(-f): path # Path to a Helm values file that will be used for the installation of operators + --helm-repo-stable: string # Provide a custom Helm stable repository URL + --helm-repo-test: string # Provide a custom Helm test repository URL + --helm-repo-dev: string # Provide a custom Helm dev repository URL + --chart-source: string@"nu-complete stackablectl stack uninstall chart_source" # Source the charts from either a OCI registry or from index.yaml-based repositories + --listener-class-preset: string@"nu-complete stackablectl stack uninstall listener_class_preset" # Choose the ListenerClass preset (`none`, `ephemeral-nodes` or `stable-nodes`) + --help(-h) # Print help (see more with '--help') + --version(-V) # Print version + stack_name: string # Name of the stack to uninstall ] # Print this message or the help of the given subcommand(s) @@ -592,6 +624,10 @@ module completions { export extern "stackablectl stack help install" [ ] + # Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs + export extern "stackablectl stack help uninstall" [ + ] + # Print this message or the help of the given subcommand(s) export extern "stackablectl stack help help" [ ] @@ -830,6 +866,38 @@ module completions { DEMO: string # Demo to install ] + def "nu-complete stackablectl demo uninstall chart_source" [] { + [ "oci" "repo" ] + } + + def "nu-complete stackablectl demo uninstall listener_class_preset" [] { + [ "none" "stable-nodes" "ephemeral-nodes" ] + } + + # Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs + export extern "stackablectl demo uninstall" [ + --operator-namespace: string # Namespace where the operators are deployed + --operator-ns: string # Namespace where the operators are deployed + --namespace(-n): string # Namespace where the stacks or demos are deployed + --product-ns: string # Namespace where the stacks or demos are deployed + --skip-operators-and-crds # Skip uninstalling Stackable operators and CRDs + --release: string # Target a specific Stackable release + --log-level(-l): string # Log level this application uses + --no-cache # Do not cache the remote (default) demo, stack and release files + --demo-file(-d): path # Provide one or more additional (custom) demo file(s) + --stack-file(-s): path # Provide one or more additional (custom) stack file(s) + --release-file(-r): path # Provide one or more additional (custom) release file(s) + --operator-values(-f): path # Path to a Helm values file that will be used for the installation of operators + --helm-repo-stable: string # Provide a custom Helm stable repository URL + --helm-repo-test: string # Provide a custom Helm test repository URL + --helm-repo-dev: string # Provide a custom Helm dev repository URL + --chart-source: string@"nu-complete stackablectl demo uninstall chart_source" # Source the charts from either a OCI registry or from index.yaml-based repositories + --listener-class-preset: string@"nu-complete stackablectl demo uninstall listener_class_preset" # Choose the ListenerClass preset (`none`, `ephemeral-nodes` or `stable-nodes`) + --help(-h) # Print help (see more with '--help') + --version(-V) # Print version + demo_name: string # Demo to uninstall + ] + # Print this message or the help of the given subcommand(s) export extern "stackablectl demo help" [ ] @@ -846,6 +914,10 @@ module completions { export extern "stackablectl demo help install" [ ] + # Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs + export extern "stackablectl demo help uninstall" [ + ] + # Print this message or the help of the given subcommand(s) export extern "stackablectl demo help help" [ ] @@ -1281,6 +1353,10 @@ module completions { export extern "stackablectl help stack install" [ ] + # Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs + export extern "stackablectl help stack uninstall" [ + ] + # Interact with deployed stacklets, which are bundles of resources and containers required to run the product export extern "stackablectl help stacklet" [ ] @@ -1309,6 +1385,10 @@ module completions { export extern "stackablectl help demo install" [ ] + # Uninstall a specific stack. Caution: This will delete the provided stack namespace, the operators and provided operator namespace, and all Stackable CRDs + export extern "stackablectl help demo uninstall" [ + ] + # Generate shell completions for this tool export extern "stackablectl help completions" [ ] diff --git a/rust/stackable-cockpit/Cargo.toml b/rust/stackable-cockpit/Cargo.toml index f6292a8e..15ec1139 100644 --- a/rust/stackable-cockpit/Cargo.toml +++ b/rust/stackable-cockpit/Cargo.toml @@ -17,6 +17,7 @@ helm-sys = { path = "../helm-sys" } bcrypt.workspace = true clap.workspace = true +either.workspace = true indexmap.workspace = true rand.workspace = true reqwest.workspace = true diff --git a/rust/stackable-cockpit/src/platform/demo/params.rs b/rust/stackable-cockpit/src/platform/demo/params.rs index 3f1486ac..3cadda74 100644 --- a/rust/stackable-cockpit/src/platform/demo/params.rs +++ b/rust/stackable-cockpit/src/platform/demo/params.rs @@ -22,3 +22,13 @@ pub struct DemoInstallParameters { pub chart_source: ChartSourceType, pub operator_values: Mapping, } + +pub struct DemoUninstallParameters { + pub demo_name: String, + + pub operator_namespace: String, + pub demo_namespace: String, + + pub skip_operators: bool, + pub skip_crds: bool, +} diff --git a/rust/stackable-cockpit/src/platform/demo/spec.rs b/rust/stackable-cockpit/src/platform/demo/spec.rs index bce047dc..153a03bd 100644 --- a/rust/stackable-cockpit/src/platform/demo/spec.rs +++ b/rust/stackable-cockpit/src/platform/demo/spec.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; use snafu::{OptionExt, ResultExt, Snafu}; +use stackable_operator::kube::api::{ApiResource, GroupVersionKind}; use tracing::{Span, debug, info, instrument, warn}; use tracing_indicatif::span_ext::IndicatifSpanExt as _; #[cfg(feature = "openapi")] @@ -9,13 +10,13 @@ use crate::{ common::manifest::ManifestSpec, platform::{ cluster::{ResourceRequests, ResourceRequestsError}, - demo::DemoInstallParameters, + demo::{DemoInstallParameters, DemoUninstallParameters}, manifests::{self, InstallManifestsExt}, release::ReleaseList, - stack::{self, StackInstallParameters, StackList}, + stack::{self, StackInstallParameters, StackList, StackSpec}, }, utils::{ - k8s::Client, + k8s::{self, Client}, params::{ IntoParameters, IntoParametersError, Parameter, RawParameter, RawParameterParseError, }, @@ -47,8 +48,18 @@ pub enum Error { #[snafu(display("failed to install stack"))] InstallStack { source: stack::Error }, + /// This error indicates that the release failed to uninstall. + #[snafu(display("failed to uninstall release"))] + UninstallRelease { source: stack::Error }, + #[snafu(display("failed to install stack manifests"))] InstallManifests { source: manifests::Error }, + + #[snafu(display("failed to uninstall Helm manifests"))] + UninstallHelmManifests { source: manifests::Error }, + + #[snafu(display("failed to delete object"))] + DeleteObject { source: k8s::Error }, } impl InstallManifestsExt for DemoSpec {} @@ -180,33 +191,138 @@ impl DemoSpec { } #[instrument(skip_all, fields( + demo_name = %uninstall_parameters.demo_name, + demo_namespace = %uninstall_parameters.demo_namespace, stack_name = %self.stack, - operator_namespace = %install_params.operator_namespace, - demo_namespace = %install_params.demo_namespace, + ))] + pub async fn uninstall( + &self, + release_list: ReleaseList, + uninstall_parameters: DemoUninstallParameters, + client: &Client, + transfer_client: &xfer::Client, + stack: StackSpec, + ) -> Result<(), Error> { + // Uninstall Helm Charts + let parameters = &mut Vec::new() + .into_params(self.parameters.clone()) + .context(ParseParametersSnafu)?; + + // We add the DEMO parameter, so that demos can use that to render e.g. the demo label + parameters.insert("DEMO".to_owned(), uninstall_parameters.demo_name.clone()); + + Self::uninstall_helm_manifests( + &self.manifests, + parameters, + &uninstall_parameters.demo_namespace.to_owned(), + transfer_client, + ) + .await + .context(UninstallHelmManifestsSnafu)?; + + let stack_parameters = &mut Vec::new() + .into_params(stack.parameters.clone()) + .context(ParseParametersSnafu)?; + + // We add the STACK and DEMO parameter, so that stacks can use that to render e.g. the stack label + stack_parameters.insert("STACK".to_owned(), self.stack.clone()); + stack_parameters.insert("DEMO".to_owned(), uninstall_parameters.demo_name.clone()); + + Self::uninstall_helm_manifests( + &stack.manifests, + stack_parameters, + &uninstall_parameters.demo_namespace.to_owned(), + transfer_client, + ) + .await + .context(UninstallHelmManifestsSnafu)?; + + // Delete demo namespace + client + .delete_object( + &uninstall_parameters.demo_namespace, + &ApiResource::from_gvk(&GroupVersionKind { + group: "".to_owned(), + version: "v1".to_owned(), + kind: "Namespace".to_owned(), + }), + None, + ) + .await + .context(DeleteObjectSnafu)?; + + // Delete remaining objects not namespace scoped + client + .delete_all_objects_with_label( + "stackable.tech/demo", + &uninstall_parameters.demo_name, + None, + ) + .await + .context(DeleteObjectSnafu)?; + + // Delete operators and the operator namespace + if !uninstall_parameters.skip_operators { + stack + .uninstall_release(release_list, &uninstall_parameters.operator_namespace) + .await + .context(UninstallReleaseSnafu)?; + + client + .delete_object( + &uninstall_parameters.operator_namespace, + &ApiResource::from_gvk(&GroupVersionKind { + group: "".to_owned(), + version: "v1".to_owned(), + kind: "Namespace".to_owned(), + }), + None, + ) + .await + .context(DeleteObjectSnafu)?; + } + + // Delete CRDs + if !uninstall_parameters.skip_crds { + client + .delete_crds_with_group_suffix("stackable.tech") + .await + .context(DeleteObjectSnafu)?; + } + + Ok(()) + } + + #[instrument(skip_all, fields( + stack_name = %self.stack, + operator_namespace = %install_parameters.operator_namespace, + demo_namespace = %install_parameters.demo_namespace, indicatif.pb_show = true ))] async fn prepare_manifests( &self, - install_params: DemoInstallParameters, + install_parameters: DemoInstallParameters, client: &Client, transfer_client: &xfer::Client, ) -> Result<(), Error> { info!("Installing demo manifests"); Span::current().pb_set_message("Installing manifests"); - let params = install_params + let mut parameters = install_parameters .parameters .to_owned() .into_params(&self.parameters) .context(ParseParametersSnafu)?; + // We add the STACK and DEMO parameter, so that demos can use that to render e.g. the demo label + parameters.insert("STACK".to_owned(), install_parameters.stack_name); + parameters.insert("DEMO".to_owned(), install_parameters.demo_name); + Self::install_manifests( &self.manifests, - ¶ms, - &install_params.demo_namespace, - &install_params.stack_name, - Some(&install_params.demo_name), - install_params.labels, + ¶meters, + &install_parameters.demo_namespace, + install_parameters.labels, client, transfer_client, ) diff --git a/rust/stackable-cockpit/src/platform/manifests.rs b/rust/stackable-cockpit/src/platform/manifests.rs index 56181dde..62cae9b3 100644 --- a/rust/stackable-cockpit/src/platform/manifests.rs +++ b/rust/stackable-cockpit/src/platform/manifests.rs @@ -40,7 +40,7 @@ pub enum Error { repo_name: String, }, - /// This error indicates that the Hlm wrapper failed to install the Helm + /// This error indicates that the Helm wrapper failed to install the Helm /// release. #[snafu(display("failed to install Helm release {release_name}"))] InstallHelmRelease { @@ -48,6 +48,14 @@ pub enum Error { source: helm::Error, }, + /// This error indicates that the Helm wrapper failed to uninstall the Helm + /// release. + #[snafu(display("failed to uninstall Helm chart"))] + UninstallHelmRelease { + release_name: String, + source: helm::Error, + }, + /// This error indicates that Helm chart options could not be serialized /// into YAML. #[snafu(display("failed to serialize Helm chart options"))] @@ -65,13 +73,11 @@ pub enum Error { pub trait InstallManifestsExt { // TODO (Techassi): This step shouldn't care about templating the manifests nor fetching them from remote #[instrument(skip_all, fields(%namespace, indicatif.pb_show = true))] - #[allow(clippy::too_many_arguments, async_fn_in_trait)] + #[allow(async_fn_in_trait)] async fn install_manifests( manifests: &[ManifestSpec], parameters: &HashMap, namespace: &str, - stack_name: &str, - demo_name: Option<&str>, labels: Labels, client: &Client, transfer_client: &xfer::Client, @@ -85,31 +91,15 @@ pub trait InstallManifestsExt { // We need some additional templating capabilities, e.g. the namespace, so that stacks/demos // can use that to render e.g. the fqdn service names [which contain the namespace]. parameters.insert("NAMESPACE".to_owned(), namespace.to_owned()); - parameters.insert("STACK".to_owned(), stack_name.into()); - if let Some(demo_name) = demo_name { - parameters.insert("DEMO".to_owned(), demo_name.into()); - } for manifest in manifests { let parameters = parameters.clone(); - let labels = labels.clone(); match manifest { ManifestSpec::HelmChart(helm_file) => { debug!(helm_file, "Installing manifest from Helm chart"); - // Read Helm chart YAML and apply templating - let helm_file = helm_file.into_path_or_url().context(ParsePathOrUrlSnafu { - path_or_url: helm_file.clone(), - })?; - - let helm_chart: helm::Chart = transfer_client - .get( - &helm_file, - &Template::new(¶meters).then(Yaml::default()), - ) - .await - .context(FileTransferSnafu)?; + let helm_chart = get_helmchart(helm_file, transfer_client, ¶meters).await?; info!(helm_chart.name, helm_chart.version, "Installing Helm chart",); @@ -168,4 +158,65 @@ pub trait InstallManifestsExt { Ok(()) } + + #[instrument(skip_all, fields(%namespace, indicatif.pb_show = true))] + #[allow(async_fn_in_trait)] + async fn uninstall_helm_manifests( + manifests: &[ManifestSpec], + parameters: &mut HashMap, + namespace: &str, + transfer_client: &xfer::Client, + ) -> Result<(), Error> { + debug!("Uninstalling Helm manifests"); + Span::current().pb_set_message("Uninstalling Helm charts"); + + // We add the NAMESPACE parameter, so that stacks/demos can use that to render e.g. the + // fqdn service names [which contain the namespace]. + parameters.insert("NAMESPACE".to_owned(), namespace.to_owned()); + + for manifest in manifests { + match manifest { + ManifestSpec::HelmChart(helm_file) => { + debug!(helm_file, "Uninstalling manifest from Helm chart"); + + let helm_chart = get_helmchart(helm_file, transfer_client, parameters).await?; + + info!( + helm_chart.name, + helm_chart.version, "Uninstalling Helm chart", + ); + + helm::uninstall_release(&helm_chart.release_name, namespace, true).context( + UninstallHelmReleaseSnafu { + release_name: &helm_chart.release_name, + }, + )?; + } + ManifestSpec::PlainYaml(_) => {} + } + } + + Ok(()) + } +} + +pub async fn get_helmchart( + helm_file: &str, + transfer_client: &xfer::Client, + parameters: &HashMap, +) -> Result { + // Read Helm chart YAML and apply templating + let helm_file_location = helm_file.into_path_or_url().context(ParsePathOrUrlSnafu { + path_or_url: helm_file, + })?; + + let helmchart = transfer_client + .get( + &helm_file_location, + &Template::new(parameters).then(Yaml::default()), + ) + .await + .context(FileTransferSnafu)?; + + Ok(helmchart) } diff --git a/rust/stackable-cockpit/src/platform/stack/params.rs b/rust/stackable-cockpit/src/platform/stack/params.rs index b3cf9717..5e89ef34 100644 --- a/rust/stackable-cockpit/src/platform/stack/params.rs +++ b/rust/stackable-cockpit/src/platform/stack/params.rs @@ -21,3 +21,17 @@ pub struct StackInstallParameters { pub chart_source: ChartSourceType, pub operator_values: Mapping, } + +pub struct StackUninstallParameters { + pub stack_name: String, + + /// Optional name of the demo, which is only present in case this stack is uninstalled as part of + /// a demo. This is unset in case a stack is uninstalled directly. + pub demo_name: Option, + + pub operator_namespace: String, + pub stack_namespace: String, + + pub skip_operators: bool, + pub skip_crds: bool, +} diff --git a/rust/stackable-cockpit/src/platform/stack/spec.rs b/rust/stackable-cockpit/src/platform/stack/spec.rs index 58ace389..38e67f28 100644 --- a/rust/stackable-cockpit/src/platform/stack/spec.rs +++ b/rust/stackable-cockpit/src/platform/stack/spec.rs @@ -1,6 +1,7 @@ use serde::{Deserialize, Serialize}; use serde_yaml::Mapping; use snafu::{OptionExt, ResultExt, Snafu}; +use stackable_operator::kube::api::{ApiResource, GroupVersionKind}; use tracing::{Span, debug, info, instrument, log::warn}; use tracing_indicatif::span_ext::IndicatifSpanExt as _; #[cfg(feature = "openapi")] @@ -14,10 +15,10 @@ use crate::{ namespace, operator::ChartSourceType, release, - stack::StackInstallParameters, + stack::{StackInstallParameters, StackUninstallParameters}, }, utils::{ - k8s::Client, + k8s::{self, Client}, params::{ IntoParameters, IntoParametersError, Parameter, RawParameter, RawParameterParseError, }, @@ -45,6 +46,10 @@ pub enum Error { #[snafu(display("failed to install release"))] InstallRelease { source: release::Error }, + /// This error indicates that the release failed to uninstall. + #[snafu(display("failed to uninstall release"))] + UninstallRelease { source: release::Error }, + #[snafu(display("stack resource requests error"), context(false))] StackResourceRequests { source: ResourceRequestsError }, @@ -64,6 +69,12 @@ pub enum Error { #[snafu(display("failed to install stack manifests"))] InstallManifests { source: manifests::Error }, + + #[snafu(display("failed to uninstall Helm manifests"))] + UninstallHelmManifests { source: manifests::Error }, + + #[snafu(display("failed to delete object"))] + DeleteObject { source: k8s::Error }, } /// This struct describes a stack with the v2 spec @@ -71,7 +82,7 @@ pub enum Error { #[serde(rename_all = "camelCase")] #[cfg_attr(feature = "openapi", derive(ToSchema))] pub struct StackSpec { - /// A short description of the demo + /// A short description of the stack pub description: String, /// The release used by the stack, e.g. 23.4 @@ -150,10 +161,7 @@ impl StackSpec { // TODO (Techassi): Can we get rid of the release list and just use the release spec instead #[instrument(skip_all, fields( stack_name = %install_parameters.stack_name, - // NOTE (@NickLarsenNZ): Option doesn't impl Display, so we need to call - // display for the inner type if it exists. Otherwise we gte the Debug - // impl for the whole Option. - demo_name = install_parameters.demo_name.as_ref().map(tracing::field::display), + stack_namespace = %install_parameters.stack_namespace, ))] pub async fn install( &self, @@ -177,7 +185,6 @@ impl StackSpec { self.install_release( release_list, &install_parameters.operator_namespace, - &install_parameters.stack_namespace, &install_parameters.chart_source, &install_parameters.operator_values, ) @@ -197,12 +204,96 @@ impl StackSpec { .await } + #[instrument(skip_all, fields( + stack_name = %uninstall_parameters.stack_name, + stack_namespace = %uninstall_parameters.stack_namespace, + ))] + pub async fn uninstall( + &self, + release_list: release::ReleaseList, + uninstall_parameters: StackUninstallParameters, + client: &Client, + transfer_client: &xfer::Client, + ) -> Result<(), Error> { + // Uninstall Helm Charts + let parameters = &mut Vec::new() + .into_params(self.parameters.clone()) + .context(ParseParametersSnafu)?; + + // We add the STACK and optionally DEMO parameter, so that stacks can use that to render e.g. the stack label + parameters.insert("STACK".to_owned(), uninstall_parameters.stack_name.clone()); + if let Some(demo_name) = uninstall_parameters.demo_name { + parameters.insert("DEMO".to_owned(), demo_name); + } + + Self::uninstall_helm_manifests( + &self.manifests, + parameters, + &uninstall_parameters.stack_namespace.to_owned(), + transfer_client, + ) + .await + .context(UninstallHelmManifestsSnafu)?; + + // Delete stack namespace + client + .delete_object( + &uninstall_parameters.stack_namespace, + &ApiResource::from_gvk(&GroupVersionKind { + group: "".to_owned(), + version: "v1".to_owned(), + kind: "Namespace".to_owned(), + }), + None, + ) + .await + .context(DeleteObjectSnafu)?; + + // Delete remaining objects not namespace scoped + client + .delete_all_objects_with_label( + "stackable.tech/stack", + &uninstall_parameters.stack_name, + None, + ) + .await + .context(DeleteObjectSnafu)?; + + // Delete operators and the operator namespace + if !uninstall_parameters.skip_operators { + self.uninstall_release(release_list, &uninstall_parameters.operator_namespace) + .await?; + + client + .delete_object( + &uninstall_parameters.operator_namespace, + &ApiResource::from_gvk(&GroupVersionKind { + group: "".to_owned(), + version: "v1".to_owned(), + kind: "Namespace".to_owned(), + }), + None, + ) + .await + .context(DeleteObjectSnafu)?; + } + + // Delete CRDs + if !uninstall_parameters.skip_crds { + client + .delete_crds_with_group_suffix("stackable.tech") + .await + .context(DeleteObjectSnafu)?; + } + + Ok(()) + } + #[instrument(skip_all, fields(release = %self.release, %operator_namespace, indicatif.pb_show = true))] pub async fn install_release( &self, release_list: release::ReleaseList, operator_namespace: &str, - _namespace: &str, // TODO (@NickLarsenNZ): remove this field chart_source: &ChartSourceType, operator_values: &Mapping, ) -> Result<(), Error> { @@ -229,29 +320,55 @@ impl StackSpec { .context(InstallReleaseSnafu) } + #[instrument(skip_all, fields(release = %self.release, %operator_namespace, indicatif.pb_show = true))] + pub async fn uninstall_release( + &self, + release_list: release::ReleaseList, + operator_namespace: &str, + ) -> Result<(), Error> { + info!(self.release, "Trying to uninstall release"); + Span::current().pb_set_message("Uninstalling operators"); + + // Get the release by name + let release = release_list + .get(&self.release) + .context(NoSuchReleaseSnafu { + name: self.release.clone(), + })?; + + // Uninstall the release + release + .uninstall(&self.operators, &[], operator_namespace) + .context(UninstallReleaseSnafu) + } + #[instrument(skip_all, fields(indicatif.pb_show = true))] pub async fn prepare_manifests( &self, - install_params: StackInstallParameters, + install_parameters: StackInstallParameters, client: &Client, transfer_client: &xfer::Client, ) -> Result<(), Error> { info!("Installing stack manifests"); Span::current().pb_set_message("Installing manifests"); - let parameters = install_params + let mut parameters = install_parameters .parameters .to_owned() .into_params(&self.parameters) .context(ParseParametersSnafu)?; + // We add the STACK and optionally DEMO parameter, so that stacks can use that to render e.g. the stack label + parameters.insert("STACK".to_owned(), install_parameters.stack_name); + if let Some(demo_name) = install_parameters.demo_name { + parameters.insert("DEMO".to_owned(), demo_name); + } + Self::install_manifests( &self.manifests, ¶meters, - &install_params.stack_namespace, - &install_params.stack_name, - install_params.demo_name.as_deref(), - install_params.labels, + &install_parameters.stack_namespace, + install_parameters.labels, client, transfer_client, ) diff --git a/rust/stackable-cockpit/src/utils/k8s/client.rs b/rust/stackable-cockpit/src/utils/k8s/client.rs index 6fb44d6f..330f293b 100644 --- a/rust/stackable-cockpit/src/utils/k8s/client.rs +++ b/rust/stackable-cockpit/src/utils/k8s/client.rs @@ -1,22 +1,29 @@ use std::{collections::BTreeMap, string::FromUtf8Error}; +use reqwest::StatusCode; use serde::Deserialize; use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ crd::listener::v1alpha1::Listener, - k8s_openapi::api::{ - apps::v1::{Deployment, StatefulSet}, - core::v1::{Endpoints, Namespace, Node, Secret, Service}, + k8s_openapi::{ + api::{ + apps::v1::{Deployment, StatefulSet}, + core::v1::{Endpoints, Namespace, Node, Secret, Service}, + }, + apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition, }, kube::{ self, Api, Discovery, ResourceExt, - api::{ListParams, Patch, PatchParams, PostParams}, + api::{DeleteParams, ListParams, Patch, PatchParams, PostParams}, core::{DynamicObject, GroupVersionKind, ObjectList, ObjectMeta, TypeMeta}, - discovery::{ApiCapabilities, ApiResource, Scope}, + discovery::{self, ApiCapabilities, ApiResource, Scope}, }, kvp::Labels, }; -use tokio::sync::RwLock; +use tokio::{ + sync::RwLock, + time::{self, sleep}, +}; use tracing::{Span, info, instrument}; use tracing_indicatif::{indicatif_eprintln, span_ext::IndicatifSpanExt as _}; @@ -47,6 +54,9 @@ pub enum Error { gvk: GroupVersionKind, }, + #[snafu(display("failed to delete object"))] + KubeClientDelete { source: kube::error::Error }, + #[snafu(display("failed to deserialize YAML data"))] DeserializeYaml { source: serde_yaml::Error }, @@ -237,6 +247,28 @@ impl Client { Ok(()) } + /// Deletes CRDs for the given group suffix + pub async fn delete_crds_with_group_suffix(&self, group_suffix: &str) -> Result<()> { + let api_client = Api::::all(self.client.clone()); + + for crd in api_client + .list(&ListParams::default()) + .await + .context(KubeClientFetchSnafu)? + { + if crd.spec.group.ends_with(group_suffix) { + if let Some(name) = crd.metadata.name { + api_client + .delete(&name, &DeleteParams::default()) + .await + .context(KubeClientDeleteSnafu)?; + } + } + } + + Ok(()) + } + /// Lists objects by looking up a GVK via the discovery. It returns an /// optional list of dynamic objects. The method returns `Ok(None)` /// if the client was unable to resolve the GVK. An error is returned @@ -287,6 +319,116 @@ impl Client { )) } + /// Deletes all objects with a given label in the provided namespace. + /// If no namespace is provided, deletes all clusterwide objects with the given label. + pub async fn delete_all_objects_with_label( + &self, + label_key: &str, + label_value: &str, + namespace: Option<&str>, + ) -> Result<(), Error> { + let api_resources = self + .get_api_resources() + .await + .into_iter() + .filter(|(_, capability)| { + capability.supports_operation(discovery::verbs::LIST) + && match namespace { + Some(_) => capability.scope == kube::discovery::Scope::Namespaced, + None => capability.scope == kube::discovery::Scope::Cluster, + } + }); + + for (api_resource, _) in api_resources { + let objects = self + .list_objects( + &GroupVersionKind { + group: api_resource.group.clone(), + version: api_resource.version.clone(), + kind: api_resource.kind.clone(), + }, + namespace, + ) + .await?; + + if let Some(objectlist) = objects { + for object in objectlist { + if let Some(value) = object.labels().get(label_key) { + if value.eq(label_value) { + self.delete_object( + &object.metadata.name.unwrap(), + &api_resource, + object.metadata.namespace.as_deref(), + ) + .await?; + } + } + } + } + } + + Ok(()) + } + + #[instrument(skip_all, fields(indicatif.pb_show = true))] + pub async fn delete_object( + &self, + object_name: &str, + api_resource: &ApiResource, + namespace: Option<&str>, + ) -> Result<(), Error> { + let object_api = match namespace { + Some(namespace) => { + Api::::namespaced_with(self.client.clone(), namespace, api_resource) + } + None => Api::::all_with(self.client.clone(), api_resource), + }; + + let mut delete_request = object_api + .delete(object_name, &DeleteParams::foreground()) + .await; + + // Wait for object to be deleted + // Otherwise might result in race condition scenarios + while let Ok(delete_status) = delete_request { + match delete_status { + // Left side of Either, when deletion is in progress + either::Either::Left(_) => { + Span::current() + .pb_set_message(&format!("Deleting {} {}", api_resource.kind, object_name)); + // Short sleep to reduce number of requests + sleep(time::Duration::from_millis(600)).await; + // Resend request to get deletion status + delete_request = object_api + .delete(object_name, &DeleteParams::foreground()) + .await; + } + // Right side of Either, when deletion is done + either::Either::Right(_) => { + return Ok(()); + } + } + } + + if let Err(error) = delete_request { + match error { + kube::Error::Api(ref error_response) => { + // If object is already deleted/gone, delete operation is done + if error_response.code == StatusCode::NOT_FOUND.as_u16() { + return Ok(()); + } else { + return Err(error).context(KubeClientDeleteSnafu); + } + } + _ => { + return Err(error).context(KubeClientDeleteSnafu); + } + } + } + + Ok(()) + } + /// Lists [`Service`]s by matching labels. The Services can be matched by /// the product labels. [`ListParamsExt`] provides a utility function to /// create [`ListParams`] based on a product name and optional instance @@ -482,6 +624,16 @@ impl Client { endpoints_api.get(name).await.context(KubeClientFetchSnafu) } + pub async fn get_api_resources(&self) -> Vec<(ApiResource, ApiCapabilities)> { + let mut api_resources = Vec::new(); + + for group in self.discovery.read().await.groups() { + api_resources.append(group.recommended_resources().as_mut()); + } + + api_resources + } + /// Try to resolve the given [`GroupVersionKind`]. In case the resolution fails a discovery is run to pull in new /// GVKs that are not present in the [`Discovery`] cache. Afterwards a normal resolution is issued. async fn resolve_gvk( diff --git a/rust/stackablectl/CHANGELOG.md b/rust/stackablectl/CHANGELOG.md index 495020e9..bd868fc0 100644 --- a/rust/stackablectl/CHANGELOG.md +++ b/rust/stackablectl/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Added + +- Add `uninstall` subcommand for `demo`/`stack` commands ([#429]). + +[#429]: https://github.com/stackabletech/stackable-cockpit/pull/429 + ## [1.4.0] - 2026-03-18 ### Added diff --git a/rust/stackablectl/Cargo.toml b/rust/stackablectl/Cargo.toml index 83388405..15db1c9d 100644 --- a/rust/stackablectl/Cargo.toml +++ b/rust/stackablectl/Cargo.toml @@ -17,6 +17,7 @@ clap_complete.workspace = true clap_complete_nushell.workspace = true clap.workspace = true comfy-table.workspace = true +dialoguer.workspace = true directories.workspace = true dotenvy.workspace = true indexmap.workspace = true diff --git a/rust/stackablectl/src/cmds/demo.rs b/rust/stackablectl/src/cmds/demo.rs index 4980ff30..35afeaee 100644 --- a/rust/stackablectl/src/cmds/demo.rs +++ b/rust/stackablectl/src/cmds/demo.rs @@ -5,12 +5,13 @@ use comfy_table::{ ContentArrangement, Row, Table, presets::{NOTHING, UTF8_FULL}, }; +use dialoguer::Confirm; use snafu::{OptionExt as _, ResultExt, Snafu, ensure}; use stackable_cockpit::{ common::list, constants::{DEFAULT_NAMESPACE, DEFAULT_OPERATOR_NAMESPACE}, platform::{ - demo::{self, DemoInstallParameters}, + demo::{self, DemoInstallParameters, DemoUninstallParameters}, operator::ChartSourceType, release, stack, }, @@ -22,7 +23,7 @@ use stackable_cockpit::{ }; use stackable_operator::kvp::{LabelError, Labels}; use tracing::{Span, debug, info, instrument}; -use tracing_indicatif::span_ext::IndicatifSpanExt as _; +use tracing_indicatif::{self, span_ext::IndicatifSpanExt as _}; use crate::{ args::{CommonClusterArgs, CommonClusterArgsError, CommonNamespaceArgs}, @@ -53,6 +54,11 @@ pub enum DemoCommands { /// Install a specific demo #[command(aliases(["i", "in"]))] Install(DemoInstallArgs), + + /// Uninstall a specific stack. Caution: This will delete the provided stack namespace, + /// the operators and provided operator namespace, and all Stackable CRDs + #[command(aliases(["u", "un"]))] + Uninstall(DemoUninstallArgs), } #[derive(Debug, Args)] @@ -118,7 +124,17 @@ to specify operator versions." } #[derive(Debug, Args)] -pub struct DemoUninstallArgs {} +pub struct DemoUninstallArgs { + /// Demo to uninstall + demo_name: String, + + #[command(flatten)] + namespaces: CommonNamespaceArgs, + + /// Skip uninstalling Stackable operators and CRDs + #[arg(long)] + skip_operators_and_crds: bool, +} #[derive(Debug, Snafu)] pub enum CmdError { @@ -155,6 +171,15 @@ pub enum CmdError { demo_name: String, }, + #[snafu(display("failed to confirm user input"))] + ConfirmDialog { source: dialoguer::Error }, + + #[snafu(display("failed to uninstall demo {demo_name:?}"))] + UninstallDemo { + source: demo::Error, + demo_name: String, + }, + #[snafu(display("failed to build labels for demo resources"))] BuildLabels { source: LabelError }, @@ -214,6 +239,9 @@ impl DemoArgs { DemoCommands::Install(args) => { install_cmd(args, cli, list, &transfer_client, &release_branch).await } + DemoCommands::Uninstall(args) => { + uninstall_cmd(args, cli, list, &transfer_client, &release_branch).await + } } } } @@ -338,7 +366,7 @@ async fn install_cmd( release_branch: &str, ) -> Result { info!(demo_name = %args.demo_name, "Installing demo"); - Span::current().pb_set_message("Installing demo"); + Span::current().pb_set_message(&format!("Installing demo {}", args.demo_name)); // Init result output and progress output let mut output = Cli::result(); @@ -382,6 +410,33 @@ async fn install_cmd( .parse_insert(("stackable.tech/stack", &demo.stack)) .context(BuildLabelsSnafu)?; + // `stackablectl demo uninstall` relies on namespace deletion, suggest installing in a non-default namespace + // It should still be possible to skip that if either uninstall is not needed + // or installing an older version of the demo which only supports the 'default' namespace + let demo_namespace = tracing_indicatif::suspend_tracing_indicatif( + || -> Result { + if args.namespaces.namespace == DEFAULT_NAMESPACE { + if Confirm::new() + .with_prompt( + format!( + "Demos installed in the '{DEFAULT_NAMESPACE}' namespace cannot be uninstalled with stackablectl. Install the demo in the '{demo_namespace}' namespace instead?", + demo_namespace = args.demo_name.clone()) + ) + .default(true) + .interact() + .context(ConfirmDialogSnafu)? { + // User selected to install in suggested namespace + Ok(args.demo_name.clone()) + } else { + // User selected to install in default namespace + Ok(args.namespaces.namespace.clone()) + } + } else { + Ok(args.namespaces.namespace.clone()) + } + }, + )?; + let values_file = cli.get_values_file().context(PathOrUrlParseSnafu)?; let operator_values = load_operator_values(values_file.as_ref(), transfer_client) .await @@ -391,7 +446,7 @@ async fn install_cmd( stack_name: demo.stack.clone(), demo_name: args.demo_name.clone(), operator_namespace: args.namespaces.operator_namespace.clone(), - demo_namespace: args.namespaces.namespace.clone(), + demo_namespace: demo_namespace.clone(), stack_parameters: args.stack_parameters.clone(), parameters: args.parameters.clone(), skip_release: args.skip_release, @@ -427,11 +482,8 @@ async fn install_cmd( let stacklet_cmd = format!( "stackablectl stacklet list{option}", - option = if args.namespaces.namespace != DEFAULT_NAMESPACE { - format!( - " --namespace {namespace}", - namespace = args.namespaces.namespace - ) + option = if demo_namespace != DEFAULT_NAMESPACE { + format!(" --namespace {namespace}", namespace = demo_namespace) } else { "".into() } @@ -447,3 +499,70 @@ async fn install_cmd( Ok(output.render()) } + +#[instrument(skip_all, fields( + demo_name = %args.demo_name, + %release_branch, + indicatif.pb_show = true +))] +async fn uninstall_cmd( + args: &DemoUninstallArgs, + cli: &Cli, + list: demo::List, + transfer_client: &xfer::Client, + release_branch: &str, +) -> Result { + info!(demo_name = %args.demo_name, "Uninstalling demo"); + Span::current().pb_set_message(&format!("Uninstalling demo {}", args.demo_name)); + + // Init result output and progress output + let mut output = Cli::result(); + + let demo = list.get(&args.demo_name).ok_or(CmdError::NoSuchDemo { + name: args.demo_name.clone(), + })?; + + let stack_files = cli + .get_stack_files(release_branch) + .context(PathOrUrlParseSnafu)?; + let stack_list = stack::StackList::build(&stack_files, transfer_client) + .await + .context(BuildListSnafu)?; + + // Get the stack spec based on the name defined in the demo spec + let stack = stack_list.get(&demo.stack).context(NoSuchStackSnafu { + name: demo.stack.clone(), + })?; + + let client = Client::new().await.context(KubeClientCreateSnafu)?; + + let release_files = cli.get_release_files().context(PathOrUrlParseSnafu)?; + let release_list = release::ReleaseList::build(&release_files, transfer_client) + .await + .context(BuildListSnafu)?; + + demo.uninstall( + release_list, + DemoUninstallParameters { + demo_name: args.demo_name.clone(), + operator_namespace: args.namespaces.operator_namespace.clone(), + demo_namespace: args.namespaces.namespace.clone(), + skip_operators: args.skip_operators_and_crds, + skip_crds: args.skip_operators_and_crds, + }, + &client, + transfer_client, + stack.to_owned(), + ) + .await + .context(UninstallDemoSnafu { + demo_name: args.demo_name.clone(), + })?; + + output.with_output(format!( + "Uninstalled demo {demo_name:?}", + demo_name = args.demo_name + )); + + Ok(output.render()) +} diff --git a/rust/stackablectl/src/cmds/stack.rs b/rust/stackablectl/src/cmds/stack.rs index 490d74e0..a3958e7b 100644 --- a/rust/stackablectl/src/cmds/stack.rs +++ b/rust/stackablectl/src/cmds/stack.rs @@ -5,6 +5,7 @@ use comfy_table::{ ContentArrangement, Table, presets::{NOTHING, UTF8_FULL}, }; +use dialoguer::Confirm; use snafu::{OptionExt as _, ResultExt, Snafu, ensure}; use stackable_cockpit::{ common::list, @@ -12,7 +13,7 @@ use stackable_cockpit::{ platform::{ operator::ChartSourceType, release, - stack::{self, StackInstallParameters}, + stack::{self, StackInstallParameters, StackUninstallParameters}, }, utils::{ k8s::{self, Client}, @@ -53,6 +54,11 @@ pub enum StackCommands { /// Install a specific stack #[command(aliases(["i", "in"]))] Install(StackInstallArgs), + + /// Uninstall a specific stack. Caution: This will delete the provided stack namespace, + /// the operators and provided operator namespace, and all Stackable CRDs + #[command(aliases(["u", "un"]))] + Uninstall(StackUninstallArgs), } #[derive(Debug, Args)] @@ -72,7 +78,7 @@ pub struct StackDescribeArgs { #[derive(Debug, Args)] pub struct StackInstallArgs { - /// Name of the stack to describe + /// Name of the stack to install stack_name: String, /// Skip the installation of the release during the stack install process @@ -113,6 +119,19 @@ Use \"stackablectl stack describe \" to list available parameters for eac namespaces: CommonNamespaceArgs, } +#[derive(Debug, Args)] +pub struct StackUninstallArgs { + /// Name of the stack to uninstall + stack_name: String, + + #[command(flatten)] + namespaces: CommonNamespaceArgs, + + /// Skip uninstalling Stackable operators and CRDs + #[arg(long)] + skip_operators_and_crds: bool, +} + #[derive(Debug, Snafu)] pub enum CmdError { #[snafu(display("path/url parse error"))] @@ -143,6 +162,16 @@ pub enum CmdError { stack_name: String, }, + #[snafu(display("failed to confirm user input"))] + ConfirmDialog { source: dialoguer::Error }, + + #[snafu(display("failed to uninstall stack {stack_name:?}"))] + UninstallStack { + #[snafu(source(from(stack::Error, Box::new)))] + source: Box, + stack_name: String, + }, + #[snafu(display("failed to build labels for stack resources"))] BuildLabels { source: LabelError }, @@ -201,6 +230,9 @@ impl StackArgs { StackCommands::Install(args) => { install_cmd(args, cli, stack_list, &transfer_client).await } + StackCommands::Uninstall(args) => { + uninstall_cmd(args, cli, stack_list, &transfer_client).await + } } } } @@ -325,7 +357,7 @@ async fn install_cmd( transfer_client: &xfer::Client, ) -> Result { info!(stack_name = %args.stack_name, "Installing stack"); - Span::current().pb_set_message("Installing stack"); + Span::current().pb_set_message(&format!("Installing stack {}", args.stack_name)); let files = cli.get_release_files().context(PathOrUrlParseSnafu)?; let release_list = release::ReleaseList::build(&files, transfer_client) @@ -353,6 +385,33 @@ async fn install_cmd( ]) .context(BuildLabelsSnafu)?; + // `stackablectl stack uninstall` relies on namespace deletion, suggest installing in a non-default namespace + // It should still be possible to skip that if either uninstall is not needed + // or installing an older version of the stack which only supports the 'default' namespace + let stack_namespace = tracing_indicatif::suspend_tracing_indicatif( + || -> Result { + if args.namespaces.namespace == DEFAULT_NAMESPACE { + if Confirm::new() + .with_prompt( + format!( + "Stacks installed in the '{DEFAULT_NAMESPACE}' namespace cannot be uninstalled with stackablectl. Install the stack in the '{stack_namespace}' namespace instead?", + stack_namespace = args.stack_name.clone()) + ) + .default(true) + .interact() + .context(ConfirmDialogSnafu)? { + // User selected to install in suggested namespace + Ok(args.stack_name.clone()) + } else { + // User selected to install in default namespace + Ok(args.namespaces.namespace.clone()) + } + } else { + Ok(args.namespaces.namespace.clone()) + } + }, + )?; + let values_file = cli.get_values_file().context(PathOrUrlParseSnafu)?; let operator_values = load_operator_values(values_file.as_ref(), transfer_client) .await @@ -363,7 +422,7 @@ async fn install_cmd( // There is no demo when installing only a stack demo_name: None, operator_namespace: args.namespaces.operator_namespace.clone(), - stack_namespace: args.namespaces.namespace.clone(), + stack_namespace: stack_namespace.clone(), parameters: args.parameters.clone(), skip_release: args.skip_release, labels, @@ -392,11 +451,8 @@ async fn install_cmd( let stacklet_cmd = format!( "stackablectl stacklet list{option}", - option = if args.namespaces.namespace != DEFAULT_NAMESPACE { - format!( - " --namespace {namespace}", - namespace = args.namespaces.namespace - ) + option = if stack_namespace != DEFAULT_NAMESPACE { + format!(" --namespace {namespace}", namespace = stack_namespace) } else { "".into() } @@ -415,3 +471,54 @@ async fn install_cmd( None => Ok("No such stack".into()), } } + +#[instrument(skip(cli, stack_list, transfer_client), fields(indicatif.pb_show = true))] +async fn uninstall_cmd( + args: &StackUninstallArgs, + cli: &Cli, + stack_list: stack::StackList, + transfer_client: &xfer::Client, +) -> Result { + info!(stack_name = %args.stack_name, "Uninstalling stack"); + Span::current().pb_set_message(&format!("Uninstalling stack {}", args.stack_name)); + + match stack_list.get(&args.stack_name) { + Some(stack) => { + let mut output = Cli::result(); + let client = Client::new().await.context(KubeClientCreateSnafu)?; + + let files = cli.get_release_files().context(PathOrUrlParseSnafu)?; + let release_list = release::ReleaseList::build(&files, transfer_client) + .await + .context(BuildListSnafu)?; + + stack + .uninstall( + release_list, + StackUninstallParameters { + stack_name: args.stack_name.clone(), + // There is no demo when uninstalling only a stack + demo_name: None, + operator_namespace: args.namespaces.operator_namespace.clone(), + stack_namespace: args.namespaces.namespace.clone(), + skip_operators: args.skip_operators_and_crds, + skip_crds: args.skip_operators_and_crds, + }, + &client, + transfer_client, + ) + .await + .context(UninstallStackSnafu { + stack_name: args.stack_name.clone(), + })?; + + output.with_output(format!( + "Uninstalled stack {stack_name:?}", + stack_name = args.stack_name + )); + + Ok(output.render()) + } + None => Ok("No such stack".into()), + } +}