Personal collection of Kubernetes things.

manager: Add the "install" command

The install command will install the CRDs into a cluster. For example:

kind create clustr --kubeconfig kubeconfig --name kaap
KUBECONFIG=kubeconfig cargo run --bin manager -- install

+176 -3
+121
Cargo.lock
··· 31 31 checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" 32 32 33 33 [[package]] 34 + name = "anstream" 35 + version = "0.6.21" 36 + source = "registry+https://github.com/rust-lang/crates.io-index" 37 + checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" 38 + dependencies = [ 39 + "anstyle", 40 + "anstyle-parse", 41 + "anstyle-query", 42 + "anstyle-wincon", 43 + "colorchoice", 44 + "is_terminal_polyfill", 45 + "utf8parse", 46 + ] 47 + 48 + [[package]] 49 + name = "anstyle" 50 + version = "1.0.13" 51 + source = "registry+https://github.com/rust-lang/crates.io-index" 52 + checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" 53 + 54 + [[package]] 55 + name = "anstyle-parse" 56 + version = "0.2.7" 57 + source = "registry+https://github.com/rust-lang/crates.io-index" 58 + checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" 59 + dependencies = [ 60 + "utf8parse", 61 + ] 62 + 63 + [[package]] 64 + name = "anstyle-query" 65 + version = "1.1.5" 66 + source = "registry+https://github.com/rust-lang/crates.io-index" 67 + checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" 68 + dependencies = [ 69 + "windows-sys 0.61.2", 70 + ] 71 + 72 + [[package]] 73 + name = "anstyle-wincon" 74 + version = "3.0.11" 75 + source = "registry+https://github.com/rust-lang/crates.io-index" 76 + checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" 77 + dependencies = [ 78 + "anstyle", 79 + "once_cell_polyfill", 80 + "windows-sys 0.61.2", 81 + ] 82 + 83 + [[package]] 34 84 name = "anyhow" 35 85 version = "1.0.100" 36 86 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 143 193 checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" 144 194 145 195 [[package]] 196 + name = "clap" 197 + version = "4.5.57" 198 + source = "registry+https://github.com/rust-lang/crates.io-index" 199 + checksum = "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a" 200 + dependencies = [ 201 + "clap_builder", 202 + "clap_derive", 203 + ] 204 + 205 + [[package]] 206 + name = "clap_builder" 207 + version = "4.5.57" 208 + source = "registry+https://github.com/rust-lang/crates.io-index" 209 + checksum = "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238" 210 + dependencies = [ 211 + "anstream", 212 + "anstyle", 213 + "clap_lex", 214 + "strsim", 215 + ] 216 + 217 + [[package]] 218 + name = "clap_derive" 219 + version = "4.5.55" 220 + source = "registry+https://github.com/rust-lang/crates.io-index" 221 + checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" 222 + dependencies = [ 223 + "heck", 224 + "proc-macro2", 225 + "quote", 226 + "syn", 227 + ] 228 + 229 + [[package]] 230 + name = "clap_lex" 231 + version = "0.7.7" 232 + source = "registry+https://github.com/rust-lang/crates.io-index" 233 + checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" 234 + 235 + [[package]] 236 + name = "colorchoice" 237 + version = "1.0.4" 238 + source = "registry+https://github.com/rust-lang/crates.io-index" 239 + checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" 240 + 241 + [[package]] 146 242 name = "concurrent-queue" 147 243 version = "2.5.0" 148 244 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 499 595 ] 500 596 501 597 [[package]] 598 + name = "heck" 599 + version = "0.5.0" 600 + source = "registry+https://github.com/rust-lang/crates.io-index" 601 + checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 602 + 603 + [[package]] 502 604 name = "hostname" 503 605 version = "0.4.2" 504 606 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 637 739 ] 638 740 639 741 [[package]] 742 + name = "is_terminal_polyfill" 743 + version = "1.70.2" 744 + source = "registry+https://github.com/rust-lang/crates.io-index" 745 + checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" 746 + 747 + [[package]] 640 748 name = "itoa" 641 749 version = "1.0.17" 642 750 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 729 837 version = "0.1.0" 730 838 dependencies = [ 731 839 "anyhow", 840 + "clap", 732 841 "k8s-openapi", 733 842 "kube", 734 843 "schemars", ··· 904 1013 version = "1.21.3" 905 1014 source = "registry+https://github.com/rust-lang/crates.io-index" 906 1015 checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 1016 + 1017 + [[package]] 1018 + name = "once_cell_polyfill" 1019 + version = "1.70.2" 1020 + source = "registry+https://github.com/rust-lang/crates.io-index" 1021 + checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" 907 1022 908 1023 [[package]] 909 1024 name = "openssl-probe" ··· 1659 1774 version = "0.9.0" 1660 1775 source = "registry+https://github.com/rust-lang/crates.io-index" 1661 1776 checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1777 + 1778 + [[package]] 1779 + name = "utf8parse" 1780 + version = "0.2.2" 1781 + source = "registry+https://github.com/rust-lang/crates.io-index" 1782 + checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 1662 1783 1663 1784 [[package]] 1664 1785 name = "version_check"
+1
Cargo.toml
··· 5 5 6 6 [dependencies] 7 7 anyhow = "1.0.100" 8 + clap = { version = "4.5.57", features = ["derive"] } 8 9 k8s-openapi = { version = "0.27.0", features = ["latest", "schemars"] } 9 10 kube = { version = "3.0.1", features = ["runtime", "derive"] } 10 11 schemars = "1"
+18
kubeconfig
··· 1 + apiVersion: v1 2 + clusters: 3 + - cluster: 4 + certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJTXZNOGNmdXFib0F3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TmpBeU1EVXdORFF4TkRCYUZ3MHpOakF5TURNd05EUTJOREJhTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUURhTE5BK01TWnc0QUdIbGwzZ2dpU3k5YTdsVGtLMjJjazNUNzkxaXZ3ZHJZbmZFa0pJRVc3MTJOK1kKaThhcHpzaUNVUjNNWUFKRHRHVStUNHFOYmllNjk3WWJ0eVIrbnZQa3pTaWZjOWhOK0lTMUxEbGJpbmhablJ2OApNRWp3NXFUS01wdnJuSXY0RU9iOXNGek5zNXJRV3hBUE9zSk05UEdyTHR4SExSWTB0TE9XNWxiaUNucUxpNENFCmpUVWMwSk9SVkNSc2ZXa3YzRHpCRjBXQUxOSE5xQlFvNHBoSDl4TlR6VGhITzlNNVJPZG50VUdrZklKWmVsUDYKM2FVUXRGQXNpVFJFNitGeDU2ekU4OVFPanlyWW95SVl1REJUUWlvSC9pMzAvLzVZcHlFWk84bVpIRmFpTllhSAowS212em8zRFhqSThJSUx1TjlsTGhaTWl3S2daQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJUMFU1TUcvS2NCRm9EaDVYZW8yNFZvYWx1RVNEQVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQW5VMTMxZm5PUQpBZmd4aERaYmJTM3NINHJORDk0eWgxbmtJOUZCN2ZMcXczMm91ZGd1dHAwM1IvdlpyMzFUdGJ1L2pFdDJnMEVJCkMrVFhkNkZWR3RYK1NmU2Y3OGU5NTdMQXd4dDBCbmVkQTlLdmJQbVNuemVDVHZ0alFWZkN4aDYrNHJKaEVwNy8Kak1yTmMvMjVYUitHYldGWGJzTWVBVFFDMklJYktsUTk5blFranFMS3ljZ3duamJJSjJzV21qbUQ3K0FLczlOOApZNGl1ZDNvS3lVajBCRFhVbDlGUll1aVpyYS9acExQVDRXM0lKckgrT3E5QmV6U0lIQmRpazVLV1lGZE1oWW1pCm82dWZEK0YzdTZEOFZ4STQvdW1QYURXTkZYUXRZWndITUFaZytXSU1BMUVFNXhWblVDVWNHMy9lWVhDemtoNWgKTVEraWM5dlAxQ1VuCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K 5 + server: https://127.0.0.1:41431 6 + name: kind-kaap 7 + contexts: 8 + - context: 9 + cluster: kind-kaap 10 + user: kind-kaap 11 + name: kind-kaap 12 + current-context: kind-kaap 13 + kind: Config 14 + users: 15 + - name: kind-kaap 16 + user: 17 + client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURLVENDQWhHZ0F3SUJBZ0lJS24wRFBEQ3lPTTR3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TmpBeU1EVXdORFF4TkRCYUZ3MHlOekF5TURVd05EUTJOREJhTUR3eApIekFkQmdOVkJBb1RGbXQxWW1WaFpHMDZZMngxYzNSbGNpMWhaRzFwYm5NeEdUQVhCZ05WQkFNVEVHdDFZbVZ5CmJtVjBaWE10WVdSdGFXNHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFET0hYdXAKZmx5bU5TdHpMRUdsN204MkF3cGFPQ3BUMXFIQnFQQVR1WThkZTlHNThReWdiMmhwUFJWcktJQWlwdXhxY01neQpDcXRIVVI4dFYxSFFadTJWNHhDWEVpWXk3MUdkanJHbXp0V24wdytFNzl2eUJEMEx0SENtM0Q2WFNaSE9sNWdYCi91bWpwSmtWOHRNZ3FoOXZuZDNxZXErK1hlTDhQU0tiRTlGZFlJMEVUelk1dENzeHRjZC85Vk5Ga1F6YXQwSUQKZFNJSzNyc0pQYStySHNtVDFPQ3VTSDRVd0dpVlBicDg1dFRwdzFpdDlNRVI1WGFvbEZnYW1lNzlmSmNFejIxQgoxWUdrOTB2ZnZ4K2ZHT1FlZnpzeEZ0K0pyTTZ3YmJQU2Z5NlNWTjdyOWpBWTVEajBWZkVYYVBDSHM3OWY5RUJ1CnNXMmxHSVJwV2RhYzExdnJBZ01CQUFHalZqQlVNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUsKQmdnckJnRUZCUWNEQWpBTUJnTlZIUk1CQWY4RUFqQUFNQjhHQTFVZEl3UVlNQmFBRlBSVGt3Yjhwd0VXZ09IbApkNmpiaFdocVc0UklNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUURRd09ycXNsVk9aUFArWkc1Q0lrRG4zVDRkCkdVamllUXJEbTMxYS96LzRMLzZGOUcxTkhLbTkrVHlnSWR3TDdJVFkzQURjTElUYXpUOXhlY0xodEJjbjVBR00KcXV4QnpHTzNJNHlYaUg3RU85dkhMSmRVbkJiN0h1YlFZemdRbGZoa2pZUExIV1RHZERnYjBTa04yVmw2OVVZVQpBSVgxN3paUmpITzFRMnRlbFFqZ0hJVUZESG5SRVlKMkxCOFFyWFhMWnhBaU0wemtPUWdhUmp3azA3eVNVbmcyClhaMmZ3eERWNkZpbzdTOWIwQ3prSU9JdjhmeWZHamJEWDYyb1Y4UHg5Mjhxcmwvd0lTdGtETy9GeXlEMEZwSEwKSnYreVN0SGt5Y3ZCUHVmRU0ycDMvOXpMSzFpajhRcEpnTjZIS250bkI4cG5JdTZXSWVRRW44RkVKVndnCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K 18 + client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBemgxN3FYNWNwalVyY3l4QnBlNXZOZ01LV2pncVU5YWh3YWp3RTdtUEhYdlJ1ZkVNCm9HOW9hVDBWYXlpQUlxYnNhbkRJTWdxclIxRWZMVmRSMEdidGxlTVFseEltTXU5Um5ZNnhwczdWcDlNUGhPL2IKOGdROUM3UndwdHcrbDBtUnpwZVlGLzdwbzZTWkZmTFRJS29mYjUzZDZucXZ2bDNpL0QwaW14UFJYV0NOQkU4MgpPYlFyTWJYSGYvVlRSWkVNMnJkQ0EzVWlDdDY3Q1QydnF4N0prOVRncmtoK0ZNQm9sVDI2Zk9iVTZjTllyZlRCCkVlVjJxSlJZR3BudS9YeVhCTTl0UWRXQnBQZEwzNzhmbnhqa0huODdNUmJmaWF6T3NHMnowbjh1a2xUZTYvWXcKR09RNDlGWHhGMmp3aDdPL1gvUkFickZ0cFJpRWFWblduTmRiNndJREFRQUJBb0lCQUVKWUhTRHVpcFg1VVZZTwpMY2RpV3l1d2lObUhjS0J4MnJsQ1RweWF3dVZEb0x0UVNyY3RoUmN5MFQwZjJUYk9NaFVFM251MUVYS3dPdS9XClJvQmxVUjVJNjJNbE5XUjV3ZlNNSk1URG1PUWZQTVNXakY1M1hNcnl0cndPOHBxeDFKd0NFYlBQbXBiUStYR20KS3EwOTlVWnhNeWd4ZTNZME5FYnF5c1BOK2pzcXI5bHdMZ09raG5vbFg0ZkZmd1FUZXFic2liMWpzWUFsWjJTOAptdGN2UkR1K1pvYk81b0lEdjVQd1hORitTNFdESjlhbTR0NG5xTEEwTm5RUVFJdmJNNFNQYmZjTXA5Yzl0bGlnCk4yMC9mRCs1amxCb2U4RkdneHJjTXB3WXY4QmNXOEoxWkNQNGdzbXJzLzhCQzhraVZyS08yTkFyRmtsMnZNdjEKOHc2bnJBa0NnWUVBN3pjTmM2ZURRT21Sbnl5SkxiazJKM3pnYTErZ0FZQlVFd01LZWRzU1VpN2lxcEs1QTNtWgoxTjdKTXVRVkhvNzFsRUFvTzYzQjlhemJNZWNBYkVONmFYaTFpUjY3UitDMWZGQTFVQ0o4LzZNWmJjMmpGZ255Cmd1bVArRkcrT1NMdmZZVktIREdiZUVvUGxUUTVMUDRtdnhCMXd1bGIrS0lzVkE3ejF6enFVUVVDZ1lFQTNKUGUKREhSaEtpMzZqNG1GeEhnRm4yQTBEazZHdTQwRXVMaVgwYnV2RS9yRHArL1VyeTJzSzU0V2NndkEvVVBsVGxvaApaektGcFdwOFlOK3NiMHZWS1pzcGVwL2xyaEFvaksxcjRpNmFQNGhmZXF3K2N3TDRncStQNmRVLzJhU3hzeHkwCk9iLzdOWTJGQ3hGc01IMERZc1NJL3NiVXF6YmY3Y1RVblBYQlRDOENnWUJONi96eHc0czV4ZHV0b2ZBOWVLdHYKU1hwQS83RTdTL1lYQzFLS1J4WTh0eEVXeHh5RlNVTVcyRXRwekdva3ZpUzQyZjFCRTJTdkJsT1FlZExsY1VXYQp2YnRFbzBJV005aHFXaVpEcURoWGZXVjNJeGtRd01UQ2FCcUJwUDcxMWE5MWo4bUlUWkI3S29UUThXWCtoZnRSCkdhZUNpa2x2UUVSNFRUYVkwanJ4a1FLQmdBT0tiQm9QRkRBMUpMeUJIS0NXdktCZVR2ZWIweFhYb2FmRmJzcHoKRk5CaFNocThBdEg5RGJKMWl5NnhlWnVYSjJzbWp6cTAyT2hhMlR4RTJ1TytkK0YvR0I5YnliZ05rbGtQdjVlVgozK3Y5S0dzenNKendBMFUxeEQyZ3FyRzNyeEtNOTJlbDZVWm15eWZ1VTZwRGwzWlNhVkNOcUlSSEVUa2oyN1haClRBMEpBb0dBYUVjanJTOUFvT0UyczRNV0U4LzhRdFRsb1JWcnAyRzZEbDVaaDBpNGZHMGs0WERNeml1eGlQN0wKeHJBOUVrYUV3NHNCaWpiY3ZhaEFKVDlVTWVmN2JadXpoUTNIQ3FpSWhkVTBIbEVwckVZZVBLemNIMlFiampjeQpIVnRnYUlLWHo2Qll4R2RNOGxEclgrcjlTajdCREJEd3NpVzVuSlNLYnZhZ1NneGhQTEU9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
+36 -3
src/bin/manager.rs
··· 1 1 use anyhow::Result; 2 - // use k8s_openapi::apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition; 2 + use clap::{Parser, Subcommand}; 3 + use k8s_openapi::apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition; 4 + use kube::Client; 5 + use kube::api::{Api, PostParams, ResourceExt}; 3 6 use kube::core::crd::CustomResourceExt; 4 7 5 8 use kaap::api::v1alpha1::Application; 6 9 10 + #[derive(Parser)] 11 + #[command(version,about,long_about=None)] 12 + struct Manager { 13 + #[command(subcommand)] 14 + command: Commands, 15 + } 16 + 17 + #[derive(Subcommand)] 18 + enum Commands { 19 + /// Install custom resources to the cluster. 20 + Install, 21 + } 22 + 7 23 #[tokio::main] 8 24 async fn main() -> Result<()> { 9 - let app_crd = Application::crd(); 10 - println!("{}", serde_json::to_string_pretty(&app_crd)?); 25 + let cli = Manager::parse(); 26 + match cli.command { 27 + Commands::Install => { 28 + let client = Client::try_default().await?; 29 + 30 + let crds: Api<CustomResourceDefinition> = Api::all(client.clone()); 31 + 32 + let app_crd = Application::crd(); 33 + let params = PostParams::default(); 34 + match crds.create(&params, &app_crd).await { 35 + Ok(o) => { 36 + eprintln!("Created {} ({:?})", o.name_any(), o.status.unwrap()); 37 + } 38 + Err(kube::Error::Api(err)) => assert_eq!(err.code, 409), 39 + Err(err) => return Err(err.into()), 40 + } 41 + } 42 + } 43 + 11 44 Ok(()) 12 45 }