diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 406b182..ca81c6b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,8 @@ jobs: - run: cargo test --lib # integration tests - run: cargo build --bin kopium + # Test stdout of commands + - run: just test-trycmd-verify # Test reasonably complicated CRDs; promethesurules and servicemonitors - run: just test-pr - run: just test-sm diff --git a/Cargo.lock b/Cargo.lock index a0666d9..6b898c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,6 +86,17 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "automod" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebb4bd301db2e2ca1f5be131c24eb8ebf2d9559bc3744419e93baf8ddea7e670" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -98,7 +109,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -208,6 +219,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "content_inspector" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38" +dependencies = [ + "memchr", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -233,6 +253,31 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "crypto-common" version = "0.1.6" @@ -308,6 +353,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "dyn-clone" version = "1.0.17" @@ -349,6 +400,34 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "filetime" +version = "0.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.60.2", +] + [[package]] name = "fnv" version = "1.0.7" @@ -447,7 +526,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.7+wasi-0.2.4", ] [[package]] @@ -456,6 +547,12 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + [[package]] name = "hashbrown" version = "0.14.5" @@ -529,6 +626,16 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime", + "serde", +] + [[package]] name = "hyper" version = "1.6.0" @@ -681,6 +788,7 @@ dependencies = [ "serde_yaml", "syn", "tokio", + "trycmd", "typed-builder", ] @@ -770,6 +878,23 @@ version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +[[package]] +name = "libredox" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0" +dependencies = [ + "bitflags", + "libc", + "redox_syscall", +] + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + [[package]] name = "lock_api" version = "0.4.12" @@ -815,10 +940,16 @@ checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + [[package]] name = "num-traits" version = "0.2.19" @@ -858,6 +989,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "os_pipe" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db335f4760b14ead6290116f2427bf33a14d4f0617d49f78a246de10c1831224" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "parking_lot" version = "0.12.3" @@ -878,7 +1019,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -972,6 +1113,32 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.5.3" @@ -1038,7 +1205,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", "spin", "untrusted", @@ -1051,6 +1218,19 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + [[package]] name = "rustls" version = "0.23.18" @@ -1112,6 +1292,15 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.24" @@ -1186,10 +1375,11 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.225" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d" dependencies = [ + "serde_core", "serde_derive", ] @@ -1203,11 +1393,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_core" +version = "1.0.225" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.225" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516" dependencies = [ "proc-macro2", "quote", @@ -1237,6 +1436,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2789234a13a53fc4be1b51ea1bab45a3c338bdb884862a257d10e5a74ae009e6" +dependencies = [ + "serde_core", +] + [[package]] name = "serde_yaml" version = "0.9.34+deprecated" @@ -1276,6 +1484,12 @@ dependencies = [ "libc", ] +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + [[package]] name = "slab" version = "0.4.9" @@ -1291,6 +1505,37 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "snapbox" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96dcfc4581e3355d70ac2ee14cfdf81dce3d85c85f1ed9e2c1d3013f53b3436b" +dependencies = [ + "anstream", + "anstyle", + "content_inspector", + "dunce", + "filetime", + "libc", + "normalize-line-endings", + "os_pipe", + "similar", + "snapbox-macros", + "tempfile", + "wait-timeout", + "walkdir", + "windows-sys 0.59.0", +] + +[[package]] +name = "snapbox-macros" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16569f53ca23a41bb6f62e0a5084aa1661f4814a67fa33696a79073e03a664af" +dependencies = [ + "anstream", +] + [[package]] name = "socket2" version = "0.6.0" @@ -1336,6 +1581,19 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "tempfile" +version = "3.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "thiserror" version = "1.0.63" @@ -1431,6 +1689,45 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml_datetime" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a197c0ec7d131bfc6f7e82c8442ba1595aeab35da7adbf05b6b73cd06a16b6be" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ad0b7ae9cfeef5605163839cb9221f453399f15cfb5c10be9885fcf56611f9" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" + [[package]] name = "tower" version = "0.5.1" @@ -1516,6 +1813,24 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "trycmd" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "659488a954e37cc663704c169f829952c49b315e2fe5fd375508baffa698f106" +dependencies = [ + "anstream", + "automod", + "glob", + "humantime", + "humantime-serde", + "rayon", + "serde", + "shlex", + "snapbox", + "toml_edit", +] + [[package]] name = "typed-builder" version = "0.21.2" @@ -1578,6 +1893,25 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -1593,13 +1927,46 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -1608,7 +1975,16 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", ] [[package]] @@ -1617,14 +1993,31 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -1633,48 +2026,111 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + [[package]] name = "zeroize" version = "1.8.1" diff --git a/Cargo.toml b/Cargo.toml index 9bd2c63..4f5432f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ features = ["derive"] [dev-dependencies] schemars = "1.0.4" +trycmd = { version = "0.15.10" } typed-builder = "0.21.2" [dev-dependencies.k8s-openapi] diff --git a/README.md b/README.md index f1a7115..fb514c5 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,7 @@ Unit tests and running `kopium` from a file do not require a cluster and can be ```sh cargo test --lib cargo run --bin kopium -- -f mycrd.yaml -A +cargo test --test trycmd_tests ``` Full integration tests use your current cluster to try to read a CRD and a `gen` object (instance of the CRD type) and parse it into the generated type: diff --git a/justfile b/justfile index 2d45da3..136451d 100644 --- a/justfile +++ b/justfile @@ -7,7 +7,7 @@ fmt: lint: cargo clippy -test: test-pr test-sm test-mv test-argo test-agent test-certmanager test-cluster test-gateway-route test-linkerd-serverauth test-linkerd-server +test: test-pr test-sm test-mv test-argo test-agent test-certmanager test-cluster test-gateway-route test-linkerd-serverauth test-linkerd-server test-trycmd-verify test-pr: kubectl apply --force-conflicts --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml @@ -100,5 +100,11 @@ test-podmon: kubectl apply -f tests/podmon.yaml cargo test --test runner -- --nocapture +test-trycmd: + TRYCMD=overwrite cargo test --test trycmd_tests + +test-trycmd-verify: + cargo test --test trycmd_tests + release: cargo release minor --execute diff --git a/tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml b/tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml new file mode 100644 index 0000000..e87df40 --- /dev/null +++ b/tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml @@ -0,0 +1,183 @@ +apiVersion: "apiextensions.k8s.io/v1" +kind: "CustomResourceDefinition" +metadata: + annotations: + controller-gen.kubebuilder.io/version: "v0.16.2" + name: "apis.apigatewayv2.services.k8s.aws" +spec: + group: "apigatewayv2.services.k8s.aws" + names: + kind: "API" + listKind: "APIList" + plural: "apis" + singular: "api" + scope: "Namespaced" + versions: + - name: "v1alpha1" + schema: + openAPIV3Schema: + description: "API is the Schema for the APIS API" + properties: + apiVersion: + description: "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: "string" + kind: + description: "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: "string" + metadata: + type: "object" + spec: + description: "ApiSpec defines the desired state of Api.\n\nRepresents an API." + properties: + apiKeySelectionExpression: + description: "An API key selection expression. Supported only for WebSocket APIs. See API\nKey Selection Expressions (https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-selection-expressions.html#apigateway-websocket-api-apikey-selection-expressions)." + type: "string" + basepath: + description: "Specifies how to interpret the base path of the API during import. Valid\nvalues are ignore, prepend, and split. The default value is ignore. To learn\nmore, see Set the OpenAPI basePath Property (https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api-basePath.html).\nSupported only for HTTP APIs." + type: "string" + body: + description: "The OpenAPI definition. Supported only for HTTP APIs." + type: "string" + corsConfiguration: + description: "A CORS configuration. Supported only for HTTP APIs. See Configuring CORS\n(https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-cors.html)\nfor more information." + properties: + allowCredentials: + type: "boolean" + allowHeaders: + description: "Represents a collection of allowed headers. Supported only for HTTP APIs." + items: + type: "string" + type: "array" + allowMethods: + description: "Represents a collection of methods. Supported only for HTTP APIs." + items: + type: "string" + type: "array" + allowOrigins: + description: "Represents a collection of origins. Supported only for HTTP APIs." + items: + type: "string" + type: "array" + exposeHeaders: + description: "Represents a collection of allowed headers. Supported only for HTTP APIs." + items: + type: "string" + type: "array" + maxAge: + description: "An integer with a value between -1 and 86400. Supported only for HTTP APIs." + format: "int64" + type: "integer" + type: "object" + credentialsARN: + description: "This property is part of quick create. It specifies the credentials required\nfor the integration, if any. For a Lambda integration, three options are\navailable. To specify an IAM Role for API Gateway to assume, use the role's\nAmazon Resource Name (ARN). To require that the caller's identity be passed\nthrough from the request, specify arn:aws:iam::*:user/*. To use resource-based\npermissions on supported AWS services, specify null. Currently, this property\nis not used for HTTP integrations. Supported only for HTTP APIs." + type: "string" + description: + description: "The description of the API." + type: "string" + disableExecuteAPIEndpoint: + description: "Specifies whether clients can invoke your API by using the default execute-api\nendpoint. By default, clients can invoke your API with the default https://{api_id}.execute-api.{region}.amazonaws.com\nendpoint. To require that clients use a custom domain name to invoke your\nAPI, disable the default endpoint." + type: "boolean" + disableSchemaValidation: + description: "Avoid validating models when creating a deployment. Supported only for WebSocket\nAPIs." + type: "boolean" + failOnWarnings: + description: "Specifies whether to rollback the API creation when a warning is encountered.\nBy default, API creation continues if a warning is encountered." + type: "boolean" + name: + description: "The name of the API." + type: "string" + protocolType: + description: "The API protocol." + type: "string" + routeKey: + description: "This property is part of quick create. If you don't specify a routeKey, a\ndefault route of $default is created. The $default route acts as a catch-all\nfor any request made to your API, for a particular stage. The $default route\nkey can't be modified. You can add routes after creating the API, and you\ncan update the route keys of additional routes. Supported only for HTTP APIs." + type: "string" + routeSelectionExpression: + description: "The route selection expression for the API. For HTTP APIs, the routeSelectionExpression\nmust be ${request.method} ${request.path}. If not provided, this will be\nthe default for HTTP APIs. This property is required for WebSocket APIs." + type: "string" + tags: + additionalProperties: + type: "string" + description: "The collection of tags. Each tag element is associated with a given resource." + type: "object" + target: + description: "This property is part of quick create. Quick create produces an API with\nan integration, a default catch-all route, and a default stage which is configured\nto automatically deploy changes. For HTTP integrations, specify a fully qualified\nURL. For Lambda integrations, specify a function ARN. The type of the integration\nwill be HTTP_PROXY or AWS_PROXY, respectively. Supported only for HTTP APIs." + type: "string" + version: + description: "A version identifier for the API." + type: "string" + type: "object" + status: + description: "APIStatus defines the observed state of API" + properties: + ackResourceMetadata: + description: "All CRs managed by ACK have a common `Status.ACKResourceMetadata` member\nthat is used to contain resource sync state, account ownership,\nconstructed ARN for the resource" + properties: + arn: + description: "ARN is the Amazon Resource Name for the resource. This is a\nglobally-unique identifier and is set only by the ACK service controller\nonce the controller has orchestrated the creation of the resource OR\nwhen it has verified that an \"adopted\" resource (a resource where the\nARN annotation was set by the Kubernetes user on the CR) exists and\nmatches the supplied CR's Spec field values.\nhttps://github.com/aws/aws-controllers-k8s/issues/270" + type: "string" + ownerAccountID: + description: "OwnerAccountID is the AWS Account ID of the account that owns the\nbackend AWS service API resource." + type: "string" + region: + description: "Region is the AWS region in which the resource exists or will exist." + type: "string" + required: + - "ownerAccountID" + - "region" + type: "object" + apiEndpoint: + description: "The URI of the API, of the form {api-id}.execute-api.{region}.amazonaws.com.\nThe stage name is typically appended to this URI to form a complete path\nto a deployed API stage." + type: "string" + apiGatewayManaged: + description: "Specifies whether an API is managed by API Gateway. You can't update or delete\na managed API by using API Gateway. A managed API can be deleted only through\nthe tooling or service that created it." + type: "boolean" + apiID: + description: "The API ID." + type: "string" + conditions: + description: "All CRs managed by ACK have a common `Status.Conditions` member that\ncontains a collection of `ackv1alpha1.Condition` objects that describe\nthe various terminal states of the CR and its backend AWS service API\nresource" + items: + description: "Condition is the common struct used by all CRDs managed by ACK service\ncontrollers to indicate terminal states of the CR and its backend AWS\nservice API resource" + properties: + lastTransitionTime: + description: "Last time the condition transitioned from one status to another." + format: "date-time" + type: "string" + message: + description: "A human readable message indicating details about the transition." + type: "string" + reason: + description: "The reason for the condition's last transition." + type: "string" + status: + description: "Status of the condition, one of True, False, Unknown." + type: "string" + type: + description: "Type is the type of the Condition" + type: "string" + required: + - "status" + - "type" + type: "object" + type: "array" + createdDate: + description: "The timestamp when the API was created." + format: "date-time" + type: "string" + importInfo: + description: "The validation information during API import. This may include particular\nproperties of your OpenAPI definition which are ignored during import. Supported\nonly for HTTP APIs." + items: + type: "string" + type: "array" + warnings: + description: "The warning messages reported when failonwarnings is turned on during API\nimport." + items: + type: "string" + type: "array" + type: "object" + type: "object" + served: true + storage: true + subresources: + status: {} diff --git a/tests/cmd/generate/crds/argocdexports.argoproj.io.yaml b/tests/cmd/generate/crds/argocdexports.argoproj.io.yaml new file mode 100644 index 0000000..665f591 --- /dev/null +++ b/tests/cmd/generate/crds/argocdexports.argoproj.io.yaml @@ -0,0 +1,183 @@ +apiVersion: "apiextensions.k8s.io/v1" +kind: "CustomResourceDefinition" +metadata: + annotations: + controller-gen.kubebuilder.io/version: "v0.18.0" + name: "argocdexports.argoproj.io" +spec: + group: "argoproj.io" + names: + kind: "ArgoCDExport" + listKind: "ArgoCDExportList" + plural: "argocdexports" + singular: "argocdexport" + scope: "Namespaced" + versions: + - name: "v1alpha1" + schema: + openAPIV3Schema: + description: "ArgoCDExport is the Schema for the argocdexports API" + properties: + apiVersion: + description: "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: "string" + kind: + description: "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: "string" + metadata: + type: "object" + spec: + description: "ArgoCDExportSpec defines the desired state of ArgoCDExport" + properties: + argocd: + description: "Argocd is the name of the ArgoCD instance to export." + type: "string" + image: + description: "Image is the container image to use for the export Job." + type: "string" + schedule: + description: "Schedule in Cron format, see https://en.wikipedia.org/wiki/Cron." + type: "string" + storage: + description: "Storage defines the storage configuration options." + properties: + backend: + description: "Backend defines the storage backend to use, must be \"local\" (the default), \"aws\", \"azure\" or \"gcp\"." + type: "string" + pvc: + description: "PVC is the desired characteristics for a PersistentVolumeClaim." + properties: + accessModes: + description: "accessModes contains the desired access modes the volume should have.\nMore info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1" + items: + type: "string" + type: "array" + x-kubernetes-list-type: "atomic" + dataSource: + description: "dataSource field can be used to specify either:\n* An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n* An existing PVC (PersistentVolumeClaim)\nIf the provisioner or an external controller can support the specified data source,\nit will create a new volume based on the contents of the specified data source.\nWhen the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\nand dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\nIf the namespace is specified, then dataSourceRef will not be copied to dataSource." + properties: + apiGroup: + description: "APIGroup is the group for the resource being referenced.\nIf APIGroup is not specified, the specified Kind must be in the core API group.\nFor any other third-party types, APIGroup is required." + type: "string" + kind: + description: "Kind is the type of resource being referenced" + type: "string" + name: + description: "Name is the name of resource being referenced" + type: "string" + required: + - "kind" + - "name" + type: "object" + x-kubernetes-map-type: "atomic" + dataSourceRef: + description: "dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\nvolume is desired. This may be any object from a non-empty API group (non\ncore object) or a PersistentVolumeClaim object.\nWhen this field is specified, volume binding will only succeed if the type of\nthe specified object matches some installed volume populator or dynamic\nprovisioner.\nThis field will replace the functionality of the dataSource field and as such\nif both fields are non-empty, they must have the same value. For backwards\ncompatibility, when namespace isn't specified in dataSourceRef,\nboth fields (dataSource and dataSourceRef) will be set to the same\nvalue automatically if one of them is empty and the other is non-empty.\nWhen namespace is specified in dataSourceRef,\ndataSource isn't set to the same value and must be empty.\nThere are three important differences between dataSource and dataSourceRef:\n* While dataSource only allows two specific types of objects, dataSourceRef\n allows any non-core object, as well as PersistentVolumeClaim objects.\n* While dataSource ignores disallowed values (dropping them), dataSourceRef\n preserves all values, and generates an error if a disallowed value is\n specified.\n* While dataSource only allows local objects, dataSourceRef allows objects\n in any namespaces.\n(Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n(Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled." + properties: + apiGroup: + description: "APIGroup is the group for the resource being referenced.\nIf APIGroup is not specified, the specified Kind must be in the core API group.\nFor any other third-party types, APIGroup is required." + type: "string" + kind: + description: "Kind is the type of resource being referenced" + type: "string" + name: + description: "Name is the name of resource being referenced" + type: "string" + namespace: + description: "Namespace is the namespace of resource being referenced\nNote that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n(Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled." + type: "string" + required: + - "kind" + - "name" + type: "object" + resources: + description: "resources represents the minimum resources the volume should have.\nIf RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\nthat are lower than previous value but must still be higher than capacity recorded in the\nstatus field of the claim.\nMore info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources" + properties: + limits: + additionalProperties: + anyOf: + - type: "integer" + - type: "string" + pattern: "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$" + x-kubernetes-int-or-string: true + description: "Limits describes the maximum amount of compute resources allowed.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/" + type: "object" + requests: + additionalProperties: + anyOf: + - type: "integer" + - type: "string" + pattern: "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$" + x-kubernetes-int-or-string: true + description: "Requests describes the minimum amount of compute resources required.\nIf Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\notherwise to an implementation-defined value. Requests cannot exceed Limits.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/" + type: "object" + type: "object" + selector: + description: "selector is a label query over volumes to consider for binding." + properties: + matchExpressions: + description: "matchExpressions is a list of label selector requirements. The requirements are ANDed." + items: + description: "A label selector requirement is a selector that contains values, a key, and an operator that\nrelates the key and values." + properties: + key: + description: "key is the label key that the selector applies to." + type: "string" + operator: + description: "operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist." + type: "string" + values: + description: "values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch." + items: + type: "string" + type: "array" + x-kubernetes-list-type: "atomic" + required: + - "key" + - "operator" + type: "object" + type: "array" + x-kubernetes-list-type: "atomic" + matchLabels: + additionalProperties: + type: "string" + description: "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\nmap is equivalent to an element of matchExpressions, whose key field is \"key\", the\noperator is \"In\", and the values array contains only \"value\". The requirements are ANDed." + type: "object" + type: "object" + x-kubernetes-map-type: "atomic" + storageClassName: + description: "storageClassName is the name of the StorageClass required by the claim.\nMore info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1" + type: "string" + volumeAttributesClassName: + description: "volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\nIf specified, the CSI driver will create or update the volume with the attributes defined\nin the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\nit can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\nwill be applied to the claim but it's not allowed to reset this field to empty string once it is set.\nIf unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\nwill be set by the persistentvolume controller if it exists.\nIf the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\nset to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\nexists.\nMore info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n(Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default)." + type: "string" + volumeMode: + description: "volumeMode defines what type of volume is required by the claim.\nValue of Filesystem is implied when not included in claim spec." + type: "string" + volumeName: + description: "volumeName is the binding reference to the PersistentVolume backing this claim." + type: "string" + type: "object" + secretName: + description: "SecretName is the name of a Secret with encryption key, credentials, etc." + type: "string" + type: "object" + version: + description: "Version is the tag/digest to use for the export Job container image." + type: "string" + required: + - "argocd" + type: "object" + status: + description: "ArgoCDExportStatus defines the observed state of ArgoCDExport" + properties: + phase: + description: "Phase is a simple, high-level summary of where the ArgoCDExport is in its lifecycle.\nThere are five possible phase values:\nPending: The ArgoCDExport has been accepted by the Kubernetes system, but one or more of the required resources have not been created.\nRunning: All of the containers for the ArgoCDExport are still running, or in the process of starting or restarting.\nSucceeded: All containers for the ArgoCDExport have terminated in success, and will not be restarted.\nFailed: At least one container has terminated in failure, either exited with non-zero status or was terminated by the system.\nUnknown: For some reason the state of the ArgoCDExport could not be obtained." + type: "string" + required: + - "phase" + type: "object" + type: "object" + served: true + storage: true + subresources: + status: {} diff --git a/tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml b/tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml new file mode 100644 index 0000000..e7a4aec --- /dev/null +++ b/tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml @@ -0,0 +1,146 @@ +apiVersion: "apiextensions.k8s.io/v1" +kind: "CustomResourceDefinition" +metadata: + annotations: + controller-gen.kubebuilder.io/version: "v0.16.2" + name: "authorizers.apigatewayv2.services.k8s.aws" +spec: + group: "apigatewayv2.services.k8s.aws" + names: + kind: "Authorizer" + listKind: "AuthorizerList" + plural: "authorizers" + singular: "authorizer" + scope: "Namespaced" + versions: + - name: "v1alpha1" + schema: + openAPIV3Schema: + description: "Authorizer is the Schema for the Authorizers API" + properties: + apiVersion: + description: "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: "string" + kind: + description: "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: "string" + metadata: + type: "object" + spec: + description: "AuthorizerSpec defines the desired state of Authorizer.\n\nRepresents an authorizer." + properties: + apiID: + description: "The API identifier." + type: "string" + apiRef: + description: "AWSResourceReferenceWrapper provides a wrapper around *AWSResourceReference\ntype to provide more user friendly syntax for references using 'from' field\nEx:\nAPIIDRef:\n\n\tfrom:\n\t name: my-api" + properties: + from: + description: "AWSResourceReference provides all the values necessary to reference another\nk8s resource for finding the identifier(Id/ARN/Name)" + properties: + name: + type: "string" + namespace: + type: "string" + type: "object" + type: "object" + authorizerCredentialsARN: + description: "Specifies the required credentials as an IAM role for API Gateway to invoke\nthe authorizer. To specify an IAM role for API Gateway to assume, use the\nrole's Amazon Resource Name (ARN). To use resource-based permissions on the\nLambda function, don't specify this parameter. Supported only for REQUEST\nauthorizers." + type: "string" + authorizerPayloadFormatVersion: + description: "Specifies the format of the payload sent to an HTTP API Lambda authorizer.\nRequired for HTTP API Lambda authorizers. Supported values are 1.0 and 2.0.\nTo learn more, see Working with AWS Lambda authorizers for HTTP APIs (https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html)." + type: "string" + authorizerResultTTLInSeconds: + description: "The time to live (TTL) for cached authorizer results, in seconds. If it equals\n0, authorization caching is disabled. If it is greater than 0, API Gateway\ncaches authorizer responses. The maximum value is 3600, or 1 hour. Supported\nonly for HTTP API Lambda authorizers." + format: "int64" + type: "integer" + authorizerType: + description: "The authorizer type. Specify REQUEST for a Lambda function using incoming\nrequest parameters. Specify JWT to use JSON Web Tokens (supported only for\nHTTP APIs)." + type: "string" + authorizerURI: + description: "The authorizer's Uniform Resource Identifier (URI). For REQUEST authorizers,\nthis must be a well-formed Lambda function URI, for example, arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:{account_id}:function:{lambda_function_name}/invocations.\nIn general, the URI has this form: arn:aws:apigateway:{region}:lambda:path/{service_api}\n, where {region} is the same as the region hosting the Lambda function, path\nindicates that the remaining substring in the URI should be treated as the\npath to the resource, including the initial /. For Lambda functions, this\nis usually of the form /2015-03-31/functions/[FunctionARN]/invocations. Supported\nonly for REQUEST authorizers." + type: "string" + enableSimpleResponses: + description: "Specifies whether a Lambda authorizer returns a response in a simple format.\nBy default, a Lambda authorizer must return an IAM policy. If enabled, the\nLambda authorizer can return a boolean value instead of an IAM policy. Supported\nonly for HTTP APIs. To learn more, see Working with AWS Lambda authorizers\nfor HTTP APIs (https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html)" + type: "boolean" + identitySource: + description: "The identity source for which authorization is requested.\n\nFor a REQUEST authorizer, this is optional. The value is a set of one or\nmore mapping expressions of the specified request parameters. The identity\nsource can be headers, query string parameters, stage variables, and context\nparameters. For example, if an Auth header and a Name query string parameter\nare defined as identity sources, this value is route.request.header.Auth,\nroute.request.querystring.Name for WebSocket APIs. For HTTP APIs, use selection\nexpressions prefixed with $, for example, $request.header.Auth, $request.querystring.Name.\nThese parameters are used to perform runtime validation for Lambda-based\nauthorizers by verifying all of the identity-related request parameters are\npresent in the request, not null, and non-empty. Only when this is true does\nthe authorizer invoke the authorizer Lambda function. Otherwise, it returns\na 401 Unauthorized response without calling the Lambda function. For HTTP\nAPIs, identity sources are also used as the cache key when caching is enabled.\nTo learn more, see Working with AWS Lambda authorizers for HTTP APIs (https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html).\n\nFor JWT, a single entry that specifies where to extract the JSON Web Token\n(JWT) from inbound requests. Currently only header-based and query parameter-based\nselections are supported, for example $request.header.Authorization." + items: + type: "string" + type: "array" + identityValidationExpression: + description: "This parameter is not used." + type: "string" + jwtConfiguration: + description: "Represents the configuration of a JWT authorizer. Required for the JWT authorizer\ntype. Supported only for HTTP APIs." + properties: + audience: + items: + type: "string" + type: "array" + issuer: + description: "A string representation of a URI with a length between [1-2048]." + type: "string" + type: "object" + name: + description: "The name of the authorizer." + type: "string" + required: + - "authorizerType" + - "identitySource" + - "name" + type: "object" + status: + description: "AuthorizerStatus defines the observed state of Authorizer" + properties: + ackResourceMetadata: + description: "All CRs managed by ACK have a common `Status.ACKResourceMetadata` member\nthat is used to contain resource sync state, account ownership,\nconstructed ARN for the resource" + properties: + arn: + description: "ARN is the Amazon Resource Name for the resource. This is a\nglobally-unique identifier and is set only by the ACK service controller\nonce the controller has orchestrated the creation of the resource OR\nwhen it has verified that an \"adopted\" resource (a resource where the\nARN annotation was set by the Kubernetes user on the CR) exists and\nmatches the supplied CR's Spec field values.\nhttps://github.com/aws/aws-controllers-k8s/issues/270" + type: "string" + ownerAccountID: + description: "OwnerAccountID is the AWS Account ID of the account that owns the\nbackend AWS service API resource." + type: "string" + region: + description: "Region is the AWS region in which the resource exists or will exist." + type: "string" + required: + - "ownerAccountID" + - "region" + type: "object" + authorizerID: + description: "The authorizer identifier." + type: "string" + conditions: + description: "All CRs managed by ACK have a common `Status.Conditions` member that\ncontains a collection of `ackv1alpha1.Condition` objects that describe\nthe various terminal states of the CR and its backend AWS service API\nresource" + items: + description: "Condition is the common struct used by all CRDs managed by ACK service\ncontrollers to indicate terminal states of the CR and its backend AWS\nservice API resource" + properties: + lastTransitionTime: + description: "Last time the condition transitioned from one status to another." + format: "date-time" + type: "string" + message: + description: "A human readable message indicating details about the transition." + type: "string" + reason: + description: "The reason for the condition's last transition." + type: "string" + status: + description: "Status of the condition, one of True, False, Unknown." + type: "string" + type: + description: "Type is the type of the Condition" + type: "string" + required: + - "status" + - "type" + type: "object" + type: "array" + type: "object" + type: "object" + served: true + storage: true + subresources: + status: {} diff --git a/tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml b/tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml new file mode 100644 index 0000000..b3d772d --- /dev/null +++ b/tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml @@ -0,0 +1,666 @@ +apiVersion: "apiextensions.k8s.io/v1" +kind: "CustomResourceDefinition" +metadata: + labels: + app.kubernetes.io/name: "postgres-operator" + name: "postgresqls.acid.zalan.do" +spec: + group: "acid.zalan.do" + names: + categories: + - "all" + kind: "postgresql" + listKind: "postgresqlList" + plural: "postgresqls" + shortNames: + - "pg" + singular: "postgresql" + scope: "Namespaced" + versions: + - additionalPrinterColumns: + - description: "Team responsible for Postgres cluster" + jsonPath: ".spec.teamId" + name: "Team" + type: "string" + - description: "PostgreSQL version" + jsonPath: ".spec.postgresql.version" + name: "Version" + type: "string" + - description: "Number of Pods per Postgres cluster" + jsonPath: ".spec.numberOfInstances" + name: "Pods" + type: "integer" + - description: "Size of the bound volume" + jsonPath: ".spec.volume.size" + name: "Volume" + type: "string" + - description: "Requested CPU for Postgres containers" + jsonPath: ".spec.resources.requests.cpu" + name: "CPU-Request" + type: "string" + - description: "Requested memory for Postgres containers" + jsonPath: ".spec.resources.requests.memory" + name: "Memory-Request" + type: "string" + - jsonPath: ".metadata.creationTimestamp" + name: "Age" + type: "date" + - description: "Current sync status of postgresql resource" + jsonPath: ".status.PostgresClusterStatus" + name: "Status" + type: "string" + name: "v1" + schema: + openAPIV3Schema: + properties: + apiVersion: + enum: + - "acid.zalan.do/v1" + type: "string" + kind: + enum: + - "postgresql" + type: "string" + spec: + properties: + additionalVolumes: + items: + properties: + isSubPathExpr: + type: "boolean" + mountPath: + type: "string" + name: + type: "string" + subPath: + type: "string" + targetContainers: + items: + type: "string" + nullable: true + type: "array" + volumeSource: + type: "object" + x-kubernetes-preserve-unknown-fields: true + required: + - "name" + - "mountPath" + - "volumeSource" + type: "object" + type: "array" + allowedSourceRanges: + items: + pattern: "^(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\/(\\d|[1-2]\\d|3[0-2])$" + type: "string" + nullable: true + type: "array" + clone: + properties: + cluster: + type: "string" + s3_access_key_id: + type: "string" + s3_endpoint: + type: "string" + s3_force_path_style: + type: "boolean" + s3_secret_access_key: + type: "string" + s3_wal_path: + type: "string" + timestamp: + pattern: "^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\\.[0-9]+)?(([+-]([01][0-9]|2[0-3]):[0-5][0-9]))$" + type: "string" + uid: + format: "uuid" + type: "string" + required: + - "cluster" + type: "object" + connectionPooler: + properties: + dockerImage: + type: "string" + maxDBConnections: + type: "integer" + mode: + enum: + - "session" + - "transaction" + type: "string" + numberOfInstances: + minimum: 1.0 + type: "integer" + resources: + properties: + limits: + properties: + cpu: + pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$" + type: "string" + memory: + pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$" + type: "string" + type: "object" + requests: + properties: + cpu: + pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$" + type: "string" + memory: + pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$" + type: "string" + type: "object" + type: "object" + schema: + type: "string" + user: + type: "string" + type: "object" + databases: + additionalProperties: + type: "string" + type: "object" + dockerImage: + type: "string" + enableConnectionPooler: + type: "boolean" + enableLogicalBackup: + type: "boolean" + enableMasterLoadBalancer: + type: "boolean" + enableMasterPoolerLoadBalancer: + type: "boolean" + enableReplicaConnectionPooler: + type: "boolean" + enableReplicaLoadBalancer: + type: "boolean" + enableReplicaPoolerLoadBalancer: + type: "boolean" + enableShmVolume: + type: "boolean" + env: + items: + type: "object" + x-kubernetes-preserve-unknown-fields: true + nullable: true + type: "array" + initContainers: + items: + type: "object" + x-kubernetes-preserve-unknown-fields: true + nullable: true + type: "array" + init_containers: + description: "deprecated" + items: + type: "object" + x-kubernetes-preserve-unknown-fields: true + nullable: true + type: "array" + logicalBackupRetention: + type: "string" + logicalBackupSchedule: + pattern: "^(\\d+|\\*)(/\\d+)?(\\s+(\\d+|\\*)(/\\d+)?){4}$" + type: "string" + maintenanceWindows: + items: + pattern: "^\\ *((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\\d):([0-5]?\\d)|(2[0-3]|[01]?\\d):([0-5]?\\d))-((2[0-3]|[01]?\\d):([0-5]?\\d)|(2[0-3]|[01]?\\d):([0-5]?\\d))\\ *$" + type: "string" + type: "array" + masterServiceAnnotations: + additionalProperties: + type: "string" + type: "object" + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: "string" + operator: + type: "string" + values: + items: + type: "string" + type: "array" + required: + - "key" + - "operator" + type: "object" + type: "array" + matchFields: + items: + properties: + key: + type: "string" + operator: + type: "string" + values: + items: + type: "string" + type: "array" + required: + - "key" + - "operator" + type: "object" + type: "array" + type: "object" + weight: + format: "int32" + type: "integer" + required: + - "preference" + - "weight" + type: "object" + type: "array" + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: "string" + operator: + type: "string" + values: + items: + type: "string" + type: "array" + required: + - "key" + - "operator" + type: "object" + type: "array" + matchFields: + items: + properties: + key: + type: "string" + operator: + type: "string" + values: + items: + type: "string" + type: "array" + required: + - "key" + - "operator" + type: "object" + type: "array" + type: "object" + type: "array" + required: + - "nodeSelectorTerms" + type: "object" + type: "object" + numberOfInstances: + minimum: 0.0 + type: "integer" + patroni: + properties: + failsafe_mode: + type: "boolean" + initdb: + additionalProperties: + type: "string" + type: "object" + loop_wait: + type: "integer" + maximum_lag_on_failover: + type: "integer" + pg_hba: + items: + type: "string" + type: "array" + retry_timeout: + type: "integer" + slots: + additionalProperties: + additionalProperties: + type: "string" + type: "object" + type: "object" + synchronous_mode: + type: "boolean" + synchronous_mode_strict: + type: "boolean" + synchronous_node_count: + type: "integer" + ttl: + type: "integer" + type: "object" + podAnnotations: + additionalProperties: + type: "string" + type: "object" + podPriorityClassName: + type: "string" + pod_priority_class_name: + description: "deprecated" + type: "string" + postgresql: + properties: + parameters: + additionalProperties: + type: "string" + type: "object" + version: + enum: + - "13" + - "14" + - "15" + - "16" + - "17" + type: "string" + required: + - "version" + type: "object" + preparedDatabases: + additionalProperties: + properties: + defaultUsers: + type: "boolean" + extensions: + additionalProperties: + type: "string" + type: "object" + schemas: + additionalProperties: + properties: + defaultRoles: + type: "boolean" + defaultUsers: + type: "boolean" + type: "object" + type: "object" + secretNamespace: + type: "string" + type: "object" + type: "object" + replicaLoadBalancer: + description: "deprecated" + type: "boolean" + replicaServiceAnnotations: + additionalProperties: + type: "string" + type: "object" + resources: + properties: + limits: + properties: + cpu: + pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$" + type: "string" + hugepages-1Gi: + pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$" + type: "string" + hugepages-2Mi: + pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$" + type: "string" + memory: + pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$" + type: "string" + type: "object" + requests: + properties: + cpu: + pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$" + type: "string" + hugepages-1Gi: + pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$" + type: "string" + hugepages-2Mi: + pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$" + type: "string" + memory: + pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$" + type: "string" + type: "object" + type: "object" + schedulerName: + type: "string" + serviceAnnotations: + additionalProperties: + type: "string" + type: "object" + sidecars: + items: + type: "object" + x-kubernetes-preserve-unknown-fields: true + nullable: true + type: "array" + spiloFSGroup: + type: "integer" + spiloRunAsGroup: + type: "integer" + spiloRunAsUser: + type: "integer" + standby: + oneOf: + - required: + - "s3_wal_path" + - required: + - "gs_wal_path" + - required: + - "standby_host" + properties: + gs_wal_path: + type: "string" + s3_wal_path: + type: "string" + standby_host: + type: "string" + standby_port: + type: "string" + type: "object" + streams: + items: + properties: + applicationId: + type: "string" + batchSize: + type: "integer" + cpu: + pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$" + type: "string" + database: + type: "string" + enableRecovery: + type: "boolean" + filter: + additionalProperties: + type: "string" + type: "object" + memory: + pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$" + type: "string" + tables: + additionalProperties: + properties: + eventType: + type: "string" + idColumn: + type: "string" + ignoreRecovery: + type: "boolean" + payloadColumn: + type: "string" + recoveryEventType: + type: "string" + required: + - "eventType" + type: "object" + type: "object" + required: + - "applicationId" + - "database" + - "tables" + type: "object" + type: "array" + teamId: + type: "string" + tls: + properties: + caFile: + type: "string" + caSecretName: + type: "string" + certificateFile: + type: "string" + privateKeyFile: + type: "string" + secretName: + type: "string" + required: + - "secretName" + type: "object" + tolerations: + items: + properties: + effect: + enum: + - "NoExecute" + - "NoSchedule" + - "PreferNoSchedule" + type: "string" + key: + type: "string" + operator: + enum: + - "Equal" + - "Exists" + type: "string" + tolerationSeconds: + type: "integer" + value: + type: "string" + type: "object" + type: "array" + useLoadBalancer: + description: "deprecated" + type: "boolean" + users: + additionalProperties: + items: + enum: + - "bypassrls" + - "BYPASSRLS" + - "nobypassrls" + - "NOBYPASSRLS" + - "createdb" + - "CREATEDB" + - "nocreatedb" + - "NOCREATEDB" + - "createrole" + - "CREATEROLE" + - "nocreaterole" + - "NOCREATEROLE" + - "inherit" + - "INHERIT" + - "noinherit" + - "NOINHERIT" + - "login" + - "LOGIN" + - "nologin" + - "NOLOGIN" + - "replication" + - "REPLICATION" + - "noreplication" + - "NOREPLICATION" + - "superuser" + - "SUPERUSER" + - "nosuperuser" + - "NOSUPERUSER" + type: "string" + nullable: true + type: "array" + type: "object" + usersIgnoringSecretRotation: + items: + type: "string" + nullable: true + type: "array" + usersWithInPlaceSecretRotation: + items: + type: "string" + nullable: true + type: "array" + usersWithSecretRotation: + items: + type: "string" + nullable: true + type: "array" + volume: + properties: + iops: + type: "integer" + isSubPathExpr: + type: "boolean" + selector: + properties: + matchExpressions: + items: + properties: + key: + type: "string" + operator: + enum: + - "DoesNotExist" + - "Exists" + - "In" + - "NotIn" + type: "string" + values: + items: + type: "string" + type: "array" + required: + - "key" + - "operator" + type: "object" + type: "array" + matchLabels: + type: "object" + x-kubernetes-preserve-unknown-fields: true + type: "object" + size: + pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$" + type: "string" + storageClass: + type: "string" + subPath: + type: "string" + throughput: + type: "integer" + required: + - "size" + type: "object" + required: + - "numberOfInstances" + - "teamId" + - "postgresql" + - "volume" + type: "object" + status: + additionalProperties: + type: "string" + type: "object" + required: + - "kind" + - "apiVersion" + - "spec" + type: "object" + served: true + storage: true + subresources: + status: {} diff --git a/tests/cmd/generate/from-file-with-auto.md b/tests/cmd/generate/from-file-with-auto.md new file mode 100644 index 0000000..8490311 --- /dev/null +++ b/tests/cmd/generate/from-file-with-auto.md @@ -0,0 +1,1137 @@ +``` +$ kopium --auto --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --auto --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use schemars::JsonSchema; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +/// ApiSpec defines the desired state of Api. +/// +/// Represents an API. +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, JsonSchema)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "API", plural = "apis")] +#[kube(namespaced)] +#[kube(status = "APIStatus")] +pub struct ApiSpec { + /// An API key selection expression. Supported only for WebSocket APIs. See API + /// Key Selection Expressions ( + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiKeySelectionExpression")] + pub api_key_selection_expression: Option, + /// Specifies how to interpret the base path of the API during import. Valid + /// values are ignore, prepend, and split. The default value is ignore. To learn + /// more, see Set the OpenAPI basePath Property ( + /// Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub basepath: Option, + /// The OpenAPI definition. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub body: Option, + /// A CORS configuration. Supported only for HTTP APIs. See Configuring CORS + /// ( + /// for more information. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "corsConfiguration")] + pub cors_configuration: Option, + /// This property is part of quick create. It specifies the credentials required + /// for the integration, if any. For a Lambda integration, three options are + /// available. To specify an IAM Role for API Gateway to assume, use the role's + /// Amazon Resource Name (ARN). To require that the caller's identity be passed + /// through from the request, specify arn:aws:iam::*:user/*. To use resource-based + /// permissions on supported AWS services, specify null. Currently, this property + /// is not used for HTTP integrations. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "credentialsARN")] + pub credentials_arn: Option, + /// The description of the API. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub description: Option, + /// Specifies whether clients can invoke your API by using the default execute-api + /// endpoint. By default, clients can invoke your API with the default + /// endpoint. To require that clients use a custom domain name to invoke your + /// API, disable the default endpoint. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableExecuteAPIEndpoint")] + pub disable_execute_api_endpoint: Option, + /// Avoid validating models when creating a deployment. Supported only for WebSocket + /// APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableSchemaValidation")] + pub disable_schema_validation: Option, + /// Specifies whether to rollback the API creation when a warning is encountered. + /// By default, API creation continues if a warning is encountered. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "failOnWarnings")] + pub fail_on_warnings: Option, + /// The name of the API. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + /// The API protocol. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "protocolType")] + pub protocol_type: Option, + /// This property is part of quick create. If you don't specify a routeKey, a + /// default route of $default is created. The $default route acts as a catch-all + /// for any request made to your API, for a particular stage. The $default route + /// key can't be modified. You can add routes after creating the API, and you + /// can update the route keys of additional routes. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeKey")] + pub route_key: Option, + /// The route selection expression for the API. For HTTP APIs, the routeSelectionExpression + /// must be ${request.method} ${request.path}. If not provided, this will be + /// the default for HTTP APIs. This property is required for WebSocket APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeSelectionExpression")] + pub route_selection_expression: Option, + /// The collection of tags. Each tag element is associated with a given resource. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tags: Option>, + /// This property is part of quick create. Quick create produces an API with + /// an integration, a default catch-all route, and a default stage which is configured + /// to automatically deploy changes. For HTTP integrations, specify a fully qualified + /// URL. For Lambda integrations, specify a function ARN. The type of the integration + /// will be HTTP_PROXY or AWS_PROXY, respectively. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub target: Option, + /// A version identifier for the API. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +/// A CORS configuration. Supported only for HTTP APIs. See Configuring CORS +/// ( +/// for more information. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct ApiSpecCorsConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowCredentials")] + pub allow_credentials: Option, + /// Represents a collection of allowed headers. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowHeaders")] + pub allow_headers: Option>, + /// Represents a collection of methods. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowMethods")] + pub allow_methods: Option>, + /// Represents a collection of origins. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowOrigins")] + pub allow_origins: Option>, + /// Represents a collection of allowed headers. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "exposeHeaders")] + pub expose_headers: Option>, + /// An integer with a value between -1 and 86400. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxAge")] + pub max_age: Option, +} + +/// APIStatus defines the observed state of API +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct ApiStatus { + /// All CRs managed by ACK have a common `Status.ACKResourceMetadata` member + /// that is used to contain resource sync state, account ownership, + /// constructed ARN for the resource + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + /// The URI of the API, of the form {api-id}.execute-api.{region}.amazonaws.com. + /// The stage name is typically appended to this URI to form a complete path + /// to a deployed API stage. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiEndpoint")] + pub api_endpoint: Option, + /// Specifies whether an API is managed by API Gateway. You can't update or delete + /// a managed API by using API Gateway. A managed API can be deleted only through + /// the tooling or service that created it. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGatewayManaged")] + pub api_gateway_managed: Option, + /// The API ID. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + /// All CRs managed by ACK have a common `Status.Conditions` member that + /// contains a collection of `ackv1alpha1.Condition` objects that describe + /// the various terminal states of the CR and its backend AWS service API + /// resource + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, + /// The timestamp when the API was created. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "createdDate")] + pub created_date: Option, + /// The validation information during API import. This may include particular + /// properties of your OpenAPI definition which are ignored during import. Supported + /// only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "importInfo")] + pub import_info: Option>, + /// The warning messages reported when failonwarnings is turned on during API + /// import. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub warnings: Option>, +} + +/// All CRs managed by ACK have a common `Status.ACKResourceMetadata` member +/// that is used to contain resource sync state, account ownership, +/// constructed ARN for the resource +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct ApiStatusAckResourceMetadata { + /// ARN is the Amazon Resource Name for the resource. This is a + /// globally-unique identifier and is set only by the ACK service controller + /// once the controller has orchestrated the creation of the resource OR + /// when it has verified that an "adopted" resource (a resource where the + /// ARN annotation was set by the Kubernetes user on the CR) exists and + /// matches the supplied CR's Spec field values. + /// + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + /// OwnerAccountID is the AWS Account ID of the account that owns the + /// backend AWS service API resource. + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + /// Region is the AWS region in which the resource exists or will exist. + pub region: String, +} + + +``` + +``` +$ kopium --auto --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --auto --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use schemars::JsonSchema; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::util::intstr::IntOrString; +} +use self::prelude::*; + +/// ArgoCDExportSpec defines the desired state of ArgoCDExport +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, JsonSchema)] +#[kube(group = "argoproj.io", version = "v1alpha1", kind = "ArgoCDExport", plural = "argocdexports")] +#[kube(namespaced)] +#[kube(status = "ArgoCDExportStatus")] +pub struct ArgoCdExportSpec { + /// Argocd is the name of the ArgoCD instance to export. + pub argocd: String, + /// Image is the container image to use for the export Job. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub image: Option, + /// Schedule in Cron format, see + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schedule: Option, + /// Storage defines the storage configuration options. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub storage: Option, + /// Version is the tag/digest to use for the export Job container image. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +/// Storage defines the storage configuration options. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct ArgoCdExportSpecStorage { + /// Backend defines the storage backend to use, must be "local" (the default), "aws", "azure" or "gcp". + #[serde(default, skip_serializing_if = "Option::is_none")] + pub backend: Option, + /// PVC is the desired characteristics for a PersistentVolumeClaim. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pvc: Option, + /// SecretName is the name of a Secret with encryption key, credentials, etc. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretName")] + pub secret_name: Option, +} + +/// PVC is the desired characteristics for a PersistentVolumeClaim. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct ArgoCdExportSpecStoragePvc { + /// accessModes contains the desired access modes the volume should have. + /// More info: + #[serde(default, skip_serializing_if = "Option::is_none", rename = "accessModes")] + pub access_modes: Option>, + /// dataSource field can be used to specify either: + /// * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + /// * An existing PVC (PersistentVolumeClaim) + /// If the provisioner or an external controller can support the specified data source, + /// it will create a new volume based on the contents of the specified data source. + /// When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + /// and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + /// If the namespace is specified, then dataSourceRef will not be copied to dataSource. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSource")] + pub data_source: Option, + /// dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + /// volume is desired. This may be any object from a non-empty API group (non + /// core object) or a PersistentVolumeClaim object. + /// When this field is specified, volume binding will only succeed if the type of + /// the specified object matches some installed volume populator or dynamic + /// provisioner. + /// This field will replace the functionality of the dataSource field and as such + /// if both fields are non-empty, they must have the same value. For backwards + /// compatibility, when namespace isn't specified in dataSourceRef, + /// both fields (dataSource and dataSourceRef) will be set to the same + /// value automatically if one of them is empty and the other is non-empty. + /// When namespace is specified in dataSourceRef, + /// dataSource isn't set to the same value and must be empty. + /// There are three important differences between dataSource and dataSourceRef: + /// * While dataSource only allows two specific types of objects, dataSourceRef + /// allows any non-core object, as well as PersistentVolumeClaim objects. + /// * While dataSource ignores disallowed values (dropping them), dataSourceRef + /// preserves all values, and generates an error if a disallowed value is + /// specified. + /// * While dataSource only allows local objects, dataSourceRef allows objects + /// in any namespaces. + /// (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + /// (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSourceRef")] + pub data_source_ref: Option, + /// resources represents the minimum resources the volume should have. + /// If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + /// that are lower than previous value but must still be higher than capacity recorded in the + /// status field of the claim. + /// More info: + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + /// selector is a label query over volumes to consider for binding. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + /// storageClassName is the name of the StorageClass required by the claim. + /// More info: + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClassName")] + pub storage_class_name: Option, + /// volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + /// If specified, the CSI driver will create or update the volume with the attributes defined + /// in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + /// it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + /// will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + /// If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + /// will be set by the persistentvolume controller if it exists. + /// If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + /// set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + /// exists. + /// More info: + /// (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeAttributesClassName")] + pub volume_attributes_class_name: Option, + /// volumeMode defines what type of volume is required by the claim. + /// Value of Filesystem is implied when not included in claim spec. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeMode")] + pub volume_mode: Option, + /// volumeName is the binding reference to the PersistentVolume backing this claim. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeName")] + pub volume_name: Option, +} + +/// dataSource field can be used to specify either: +/// * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) +/// * An existing PVC (PersistentVolumeClaim) +/// If the provisioner or an external controller can support the specified data source, +/// it will create a new volume based on the contents of the specified data source. +/// When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, +/// and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. +/// If the namespace is specified, then dataSourceRef will not be copied to dataSource. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct ArgoCdExportSpecStoragePvcDataSource { + /// APIGroup is the group for the resource being referenced. + /// If APIGroup is not specified, the specified Kind must be in the core API group. + /// For any other third-party types, APIGroup is required. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + /// Kind is the type of resource being referenced + pub kind: String, + /// Name is the name of resource being referenced + pub name: String, +} + +/// dataSourceRef specifies the object from which to populate the volume with data, if a non-empty +/// volume is desired. This may be any object from a non-empty API group (non +/// core object) or a PersistentVolumeClaim object. +/// When this field is specified, volume binding will only succeed if the type of +/// the specified object matches some installed volume populator or dynamic +/// provisioner. +/// This field will replace the functionality of the dataSource field and as such +/// if both fields are non-empty, they must have the same value. For backwards +/// compatibility, when namespace isn't specified in dataSourceRef, +/// both fields (dataSource and dataSourceRef) will be set to the same +/// value automatically if one of them is empty and the other is non-empty. +/// When namespace is specified in dataSourceRef, +/// dataSource isn't set to the same value and must be empty. +/// There are three important differences between dataSource and dataSourceRef: +/// * While dataSource only allows two specific types of objects, dataSourceRef +/// allows any non-core object, as well as PersistentVolumeClaim objects. +/// * While dataSource ignores disallowed values (dropping them), dataSourceRef +/// preserves all values, and generates an error if a disallowed value is +/// specified. +/// * While dataSource only allows local objects, dataSourceRef allows objects +/// in any namespaces. +/// (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. +/// (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct ArgoCdExportSpecStoragePvcDataSourceRef { + /// APIGroup is the group for the resource being referenced. + /// If APIGroup is not specified, the specified Kind must be in the core API group. + /// For any other third-party types, APIGroup is required. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + /// Kind is the type of resource being referenced + pub kind: String, + /// Name is the name of resource being referenced + pub name: String, + /// Namespace is the namespace of resource being referenced + /// Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + /// (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +/// resources represents the minimum resources the volume should have. +/// If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements +/// that are lower than previous value but must still be higher than capacity recorded in the +/// status field of the claim. +/// More info: +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct ArgoCdExportSpecStoragePvcResources { + /// Limits describes the maximum amount of compute resources allowed. + /// More info: + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option>, + /// Requests describes the minimum amount of compute resources required. + /// If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + /// otherwise to an implementation-defined value. Requests cannot exceed Limits. + /// More info: + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option>, +} + +/// selector is a label query over volumes to consider for binding. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct ArgoCdExportSpecStoragePvcSelector { + /// matchExpressions is a list of label selector requirements. The requirements are ANDed. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + /// matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + /// map is equivalent to an element of matchExpressions, whose key field is "key", the + /// operator is "In", and the values array contains only "value". The requirements are ANDed. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +/// A label selector requirement is a selector that contains values, a key, and an operator that +/// relates the key and values. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct ArgoCdExportSpecStoragePvcSelectorMatchExpressions { + /// key is the label key that the selector applies to. + pub key: String, + /// operator represents a key's relationship to a set of values. + /// Valid operators are In, NotIn, Exists and DoesNotExist. + pub operator: String, + /// values is an array of string values. If the operator is In or NotIn, + /// the values array must be non-empty. If the operator is Exists or DoesNotExist, + /// the values array must be empty. This array is replaced during a strategic + /// merge patch. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +/// ArgoCDExportStatus defines the observed state of ArgoCDExport +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct ArgoCdExportStatus { + /// Phase is a simple, high-level summary of where the ArgoCDExport is in its lifecycle. + /// There are five possible phase values: + /// Pending: The ArgoCDExport has been accepted by the Kubernetes system, but one or more of the required resources have not been created. + /// Running: All of the containers for the ArgoCDExport are still running, or in the process of starting or restarting. + /// Succeeded: All containers for the ArgoCDExport have terminated in success, and will not be restarted. + /// Failed: At least one container has terminated in failure, either exited with non-zero status or was terminated by the system. + /// Unknown: For some reason the state of the ArgoCDExport could not be obtained. + pub phase: String, +} + + +``` + +``` +$ kopium --auto --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --auto --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use schemars::JsonSchema; + pub use serde::{Serialize, Deserialize}; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +/// AuthorizerSpec defines the desired state of Authorizer. +/// +/// Represents an authorizer. +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, JsonSchema)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "Authorizer", plural = "authorizers")] +#[kube(namespaced)] +#[kube(status = "AuthorizerStatus")] +pub struct AuthorizerSpec { + /// The API identifier. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + /// AWSResourceReferenceWrapper provides a wrapper around *AWSResourceReference + /// type to provide more user friendly syntax for references using 'from' field + /// Ex: + /// APIIDRef: + /// + /// from: + /// name: my-api + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiRef")] + pub api_ref: Option, + /// Specifies the required credentials as an IAM role for API Gateway to invoke + /// the authorizer. To specify an IAM role for API Gateway to assume, use the + /// role's Amazon Resource Name (ARN). To use resource-based permissions on the + /// Lambda function, don't specify this parameter. Supported only for REQUEST + /// authorizers. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerCredentialsARN")] + pub authorizer_credentials_arn: Option, + /// Specifies the format of the payload sent to an HTTP API Lambda authorizer. + /// Required for HTTP API Lambda authorizers. Supported values are 1.0 and 2.0. + /// To learn more, see Working with AWS Lambda authorizers for HTTP APIs ( + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerPayloadFormatVersion")] + pub authorizer_payload_format_version: Option, + /// The time to live (TTL) for cached authorizer results, in seconds. If it equals + /// 0, authorization caching is disabled. If it is greater than 0, API Gateway + /// caches authorizer responses. The maximum value is 3600, or 1 hour. Supported + /// only for HTTP API Lambda authorizers. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerResultTTLInSeconds")] + pub authorizer_result_ttl_in_seconds: Option, + /// The authorizer type. Specify REQUEST for a Lambda function using incoming + /// request parameters. Specify JWT to use JSON Web Tokens (supported only for + /// HTTP APIs). + #[serde(rename = "authorizerType")] + pub authorizer_type: String, + /// The authorizer's Uniform Resource Identifier (URI). For REQUEST authorizers, + /// this must be a well-formed Lambda function URI, for example, arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:{account_id}:function:{lambda_function_name}/invocations. + /// In general, the URI has this form: arn:aws:apigateway:{region}:lambda:path/{service_api} + /// , where {region} is the same as the region hosting the Lambda function, path + /// indicates that the remaining substring in the URI should be treated as the + /// path to the resource, including the initial /. For Lambda functions, this + /// is usually of the form /2015-03-31/functions/[FunctionARN]/invocations. Supported + /// only for REQUEST authorizers. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerURI")] + pub authorizer_uri: Option, + /// Specifies whether a Lambda authorizer returns a response in a simple format. + /// By default, a Lambda authorizer must return an IAM policy. If enabled, the + /// Lambda authorizer can return a boolean value instead of an IAM policy. Supported + /// only for HTTP APIs. To learn more, see Working with AWS Lambda authorizers + /// for HTTP APIs ( + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableSimpleResponses")] + pub enable_simple_responses: Option, + /// The identity source for which authorization is requested. + /// + /// For a REQUEST authorizer, this is optional. The value is a set of one or + /// more mapping expressions of the specified request parameters. The identity + /// source can be headers, query string parameters, stage variables, and context + /// parameters. For example, if an Auth header and a Name query string parameter + /// are defined as identity sources, this value is route.request.header.Auth, + /// route.request.querystring.Name for WebSocket APIs. For HTTP APIs, use selection + /// expressions prefixed with $, for example, $request.header.Auth, $request.querystring.Name. + /// These parameters are used to perform runtime validation for Lambda-based + /// authorizers by verifying all of the identity-related request parameters are + /// present in the request, not null, and non-empty. Only when this is true does + /// the authorizer invoke the authorizer Lambda function. Otherwise, it returns + /// a 401 Unauthorized response without calling the Lambda function. For HTTP + /// APIs, identity sources are also used as the cache key when caching is enabled. + /// To learn more, see Working with AWS Lambda authorizers for HTTP APIs ( + /// + /// For JWT, a single entry that specifies where to extract the JSON Web Token + /// (JWT) from inbound requests. Currently only header-based and query parameter-based + /// selections are supported, for example $request.header.Authorization. + #[serde(rename = "identitySource")] + pub identity_source: Vec, + /// This parameter is not used. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "identityValidationExpression")] + pub identity_validation_expression: Option, + /// Represents the configuration of a JWT authorizer. Required for the JWT authorizer + /// type. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "jwtConfiguration")] + pub jwt_configuration: Option, + /// The name of the authorizer. + pub name: String, +} + +/// AWSResourceReferenceWrapper provides a wrapper around *AWSResourceReference +/// type to provide more user friendly syntax for references using 'from' field +/// Ex: +/// APIIDRef: +/// +/// from: +/// name: my-api +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct AuthorizerApiRef { + /// AWSResourceReference provides all the values necessary to reference another + /// k8s resource for finding the identifier(Id/ARN/Name) + #[serde(default, skip_serializing_if = "Option::is_none")] + pub from: Option, +} + +/// AWSResourceReference provides all the values necessary to reference another +/// k8s resource for finding the identifier(Id/ARN/Name) +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct AuthorizerApiRefFrom { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +/// Represents the configuration of a JWT authorizer. Required for the JWT authorizer +/// type. Supported only for HTTP APIs. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct AuthorizerJwtConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub audience: Option>, + /// A string representation of a URI with a length between [1-2048]. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub issuer: Option, +} + +/// AuthorizerStatus defines the observed state of Authorizer +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct AuthorizerStatus { + /// All CRs managed by ACK have a common `Status.ACKResourceMetadata` member + /// that is used to contain resource sync state, account ownership, + /// constructed ARN for the resource + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + /// The authorizer identifier. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerID")] + pub authorizer_id: Option, + /// All CRs managed by ACK have a common `Status.Conditions` member that + /// contains a collection of `ackv1alpha1.Condition` objects that describe + /// the various terminal states of the CR and its backend AWS service API + /// resource + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, +} + +/// All CRs managed by ACK have a common `Status.ACKResourceMetadata` member +/// that is used to contain resource sync state, account ownership, +/// constructed ARN for the resource +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct AuthorizerStatusAckResourceMetadata { + /// ARN is the Amazon Resource Name for the resource. This is a + /// globally-unique identifier and is set only by the ACK service controller + /// once the controller has orchestrated the creation of the resource OR + /// when it has verified that an "adopted" resource (a resource where the + /// ARN annotation was set by the Kubernetes user on the CR) exists and + /// matches the supplied CR's Spec field values. + /// + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + /// OwnerAccountID is the AWS Account ID of the account that owns the + /// backend AWS service API resource. + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + /// Region is the AWS region in which the resource exists or will exist. + pub region: String, +} + + +``` + +``` +$ kopium --auto --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --auto --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use schemars::JsonSchema; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, JsonSchema)] +#[kube(group = "acid.zalan.do", version = "v1", kind = "postgresql", plural = "postgresqls")] +#[kube(namespaced)] +pub struct PostgresqlSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "additionalVolumes")] + pub additional_volumes: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowedSourceRanges")] + pub allowed_source_ranges: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub clone: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "connectionPooler")] + pub connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub databases: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableConnectionPooler")] + pub enable_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableLogicalBackup")] + pub enable_logical_backup: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterLoadBalancer")] + pub enable_master_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterPoolerLoadBalancer")] + pub enable_master_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaConnectionPooler")] + pub enable_replica_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaLoadBalancer")] + pub enable_replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaPoolerLoadBalancer")] + pub enable_replica_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableShmVolume")] + pub enable_shm_volume: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub env: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "initContainers")] + pub init_containers: Option>>, + /// deprecated + #[serde(default, skip_serializing_if = "Option::is_none", rename = "init_containers")] + pub init_containers_x: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupRetention")] + pub logical_backup_retention: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupSchedule")] + pub logical_backup_schedule: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maintenanceWindows")] + pub maintenance_windows: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "masterServiceAnnotations")] + pub master_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "nodeAffinity")] + pub node_affinity: Option, + #[serde(rename = "numberOfInstances")] + pub number_of_instances: i64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub patroni: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podAnnotations")] + pub pod_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podPriorityClassName")] + pub pod_priority_class_name: Option, + /// deprecated + #[serde(default, skip_serializing_if = "Option::is_none", rename = "pod_priority_class_name")] + pub pod_priority_class_name_x: Option, + pub postgresql: PostgresqlSpecPostgresql, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preparedDatabases")] + pub prepared_databases: Option>, + /// deprecated + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaLoadBalancer")] + pub replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaServiceAnnotations")] + pub replica_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "schedulerName")] + pub scheduler_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "serviceAnnotations")] + pub service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub sidecars: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloFSGroup")] + pub spilo_fs_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsGroup")] + pub spilo_run_as_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsUser")] + pub spilo_run_as_user: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub streams: Option>, + #[serde(rename = "teamId")] + pub team_id: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tls: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tolerations: Option>, + /// deprecated + #[serde(default, skip_serializing_if = "Option::is_none", rename = "useLoadBalancer")] + pub use_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub users: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersIgnoringSecretRotation")] + pub users_ignoring_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithInPlaceSecretRotation")] + pub users_with_in_place_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithSecretRotation")] + pub users_with_secret_rotation: Option>, + pub volume: PostgresqlSpecVolume, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecAdditionalVolumes { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(rename = "mountPath")] + pub mount_path: String, + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "targetContainers")] + pub target_containers: Option>, + #[serde(rename = "volumeSource")] + pub volume_source: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecClone { + pub cluster: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_access_key_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_force_path_style: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_secret_access_key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub timestamp: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub uid: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecConnectionPooler { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxDBConnections")] + pub max_db_connections: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "numberOfInstances")] + pub number_of_instances: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schema: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub user: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub enum PostgresqlSpecConnectionPoolerMode { + #[serde(rename = "session")] + Session, + #[serde(rename = "transaction")] + Transaction, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecConnectionPoolerResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecConnectionPoolerResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecConnectionPoolerResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecNodeAffinity { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preferredDuringSchedulingIgnoredDuringExecution")] + pub preferred_during_scheduling_ignored_during_execution: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "requiredDuringSchedulingIgnoredDuringExecution")] + pub required_during_scheduling_ignored_during_execution: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecution { + pub preference: PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference, + pub weight: i32, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution { + #[serde(rename = "nodeSelectorTerms")] + pub node_selector_terms: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTerms { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecPatroni { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub failsafe_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub initdb: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub loop_wait: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub maximum_lag_on_failover: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pg_hba: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub retry_timeout: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub slots: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode_strict: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_node_count: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ttl: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecPostgresql { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub parameters: Option>, + pub version: PostgresqlSpecPostgresqlVersion, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub enum PostgresqlSpecPostgresqlVersion { + #[serde(rename = "13")] + r#_13, + #[serde(rename = "14")] + r#_14, + #[serde(rename = "15")] + r#_15, + #[serde(rename = "16")] + r#_16, + #[serde(rename = "17")] + r#_17, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecPreparedDatabases { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub extensions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schemas: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretNamespace")] + pub secret_namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecPreparedDatabasesSchemas { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultRoles")] + pub default_roles: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecStandby { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub gs_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_host: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_port: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecStreams { + #[serde(rename = "applicationId")] + pub application_id: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "batchSize")] + pub batch_size: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + pub database: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableRecovery")] + pub enable_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub filter: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, + pub tables: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecStreamsTables { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "eventType")] + pub event_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "idColumn")] + pub id_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ignoreRecovery")] + pub ignore_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "payloadColumn")] + pub payload_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "recoveryEventType")] + pub recovery_event_type: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecTls { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caFile")] + pub ca_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caSecretName")] + pub ca_secret_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "certificateFile")] + pub certificate_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "privateKeyFile")] + pub private_key_file: Option, + #[serde(rename = "secretName")] + pub secret_name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecTolerations { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub effect: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub operator: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "tolerationSeconds")] + pub toleration_seconds: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub value: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub enum PostgresqlSpecTolerationsEffect { + NoExecute, + NoSchedule, + PreferNoSchedule, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub enum PostgresqlSpecTolerationsOperator { + Equal, + Exists, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecVolume { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub iops: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + pub size: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClass")] + pub storage_class: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub throughput: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecVolumeSelector { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub struct PostgresqlSpecVolumeSelectorMatchExpressions { + pub key: String, + pub operator: PostgresqlSpecVolumeSelectorMatchExpressionsOperator, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] +pub enum PostgresqlSpecVolumeSelectorMatchExpressionsOperator { + DoesNotExist, + Exists, + In, + NotIn, +} + + +``` diff --git a/tests/cmd/generate/from-file-with-derive-default.md b/tests/cmd/generate/from-file-with-derive-default.md new file mode 100644 index 0000000..29535d0 --- /dev/null +++ b/tests/cmd/generate/from-file-with-derive-default.md @@ -0,0 +1,806 @@ +``` +$ kopium --derive=Default --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=Default --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, Default)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "API", plural = "apis")] +#[kube(namespaced)] +#[kube(status = "APIStatus")] +#[kube(schema = "disabled")] +#[kube(derive="Default")] +pub struct ApiSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiKeySelectionExpression")] + pub api_key_selection_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub basepath: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub body: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "corsConfiguration")] + pub cors_configuration: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "credentialsARN")] + pub credentials_arn: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub description: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableExecuteAPIEndpoint")] + pub disable_execute_api_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableSchemaValidation")] + pub disable_schema_validation: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "failOnWarnings")] + pub fail_on_warnings: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "protocolType")] + pub protocol_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeKey")] + pub route_key: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeSelectionExpression")] + pub route_selection_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tags: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub target: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct ApiSpecCorsConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowCredentials")] + pub allow_credentials: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowHeaders")] + pub allow_headers: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowMethods")] + pub allow_methods: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowOrigins")] + pub allow_origins: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "exposeHeaders")] + pub expose_headers: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxAge")] + pub max_age: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct ApiStatus { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiEndpoint")] + pub api_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGatewayManaged")] + pub api_gateway_managed: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "createdDate")] + pub created_date: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "importInfo")] + pub import_info: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub warnings: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct ApiStatusAckResourceMetadata { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + pub region: String, +} + + +``` + +``` +$ kopium --derive=Default --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=Default --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::util::intstr::IntOrString; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, Default)] +#[kube(group = "argoproj.io", version = "v1alpha1", kind = "ArgoCDExport", plural = "argocdexports")] +#[kube(namespaced)] +#[kube(status = "ArgoCDExportStatus")] +#[kube(schema = "disabled")] +#[kube(derive="Default")] +pub struct ArgoCdExportSpec { + pub argocd: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub image: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schedule: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub storage: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct ArgoCdExportSpecStorage { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub backend: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pvc: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretName")] + pub secret_name: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct ArgoCdExportSpecStoragePvc { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "accessModes")] + pub access_modes: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSource")] + pub data_source: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSourceRef")] + pub data_source_ref: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClassName")] + pub storage_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeAttributesClassName")] + pub volume_attributes_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeMode")] + pub volume_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeName")] + pub volume_name: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct ArgoCdExportSpecStoragePvcDataSource { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + pub kind: String, + pub name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct ArgoCdExportSpecStoragePvcDataSourceRef { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + pub kind: String, + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct ArgoCdExportSpecStoragePvcResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct ArgoCdExportSpecStoragePvcSelector { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct ArgoCdExportSpecStoragePvcSelectorMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct ArgoCdExportStatus { + pub phase: String, +} + + +``` + +``` +$ kopium --derive=Default --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=Default --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, Default)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "Authorizer", plural = "authorizers")] +#[kube(namespaced)] +#[kube(status = "AuthorizerStatus")] +#[kube(schema = "disabled")] +#[kube(derive="Default")] +pub struct AuthorizerSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiRef")] + pub api_ref: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerCredentialsARN")] + pub authorizer_credentials_arn: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerPayloadFormatVersion")] + pub authorizer_payload_format_version: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerResultTTLInSeconds")] + pub authorizer_result_ttl_in_seconds: Option, + #[serde(rename = "authorizerType")] + pub authorizer_type: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerURI")] + pub authorizer_uri: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableSimpleResponses")] + pub enable_simple_responses: Option, + #[serde(rename = "identitySource")] + pub identity_source: Vec, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "identityValidationExpression")] + pub identity_validation_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "jwtConfiguration")] + pub jwt_configuration: Option, + pub name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct AuthorizerApiRef { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub from: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct AuthorizerApiRefFrom { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct AuthorizerJwtConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub audience: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub issuer: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct AuthorizerStatus { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerID")] + pub authorizer_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct AuthorizerStatusAckResourceMetadata { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + pub region: String, +} + + +``` + +``` +$ kopium --derive=Default --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=Default --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, Default)] +#[kube(group = "acid.zalan.do", version = "v1", kind = "postgresql", plural = "postgresqls")] +#[kube(namespaced)] +#[kube(schema = "disabled")] +#[kube(derive="Default")] +pub struct PostgresqlSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "additionalVolumes")] + pub additional_volumes: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowedSourceRanges")] + pub allowed_source_ranges: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub clone: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "connectionPooler")] + pub connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub databases: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableConnectionPooler")] + pub enable_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableLogicalBackup")] + pub enable_logical_backup: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterLoadBalancer")] + pub enable_master_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterPoolerLoadBalancer")] + pub enable_master_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaConnectionPooler")] + pub enable_replica_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaLoadBalancer")] + pub enable_replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaPoolerLoadBalancer")] + pub enable_replica_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableShmVolume")] + pub enable_shm_volume: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub env: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "initContainers")] + pub init_containers: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "init_containers")] + pub init_containers_x: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupRetention")] + pub logical_backup_retention: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupSchedule")] + pub logical_backup_schedule: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maintenanceWindows")] + pub maintenance_windows: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "masterServiceAnnotations")] + pub master_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "nodeAffinity")] + pub node_affinity: Option, + #[serde(rename = "numberOfInstances")] + pub number_of_instances: i64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub patroni: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podAnnotations")] + pub pod_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podPriorityClassName")] + pub pod_priority_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "pod_priority_class_name")] + pub pod_priority_class_name_x: Option, + pub postgresql: PostgresqlSpecPostgresql, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preparedDatabases")] + pub prepared_databases: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaLoadBalancer")] + pub replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaServiceAnnotations")] + pub replica_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "schedulerName")] + pub scheduler_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "serviceAnnotations")] + pub service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub sidecars: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloFSGroup")] + pub spilo_fs_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsGroup")] + pub spilo_run_as_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsUser")] + pub spilo_run_as_user: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub streams: Option>, + #[serde(rename = "teamId")] + pub team_id: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tls: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tolerations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "useLoadBalancer")] + pub use_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub users: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersIgnoringSecretRotation")] + pub users_ignoring_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithInPlaceSecretRotation")] + pub users_with_in_place_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithSecretRotation")] + pub users_with_secret_rotation: Option>, + pub volume: PostgresqlSpecVolume, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecAdditionalVolumes { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(rename = "mountPath")] + pub mount_path: String, + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "targetContainers")] + pub target_containers: Option>, + #[serde(rename = "volumeSource")] + pub volume_source: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecClone { + pub cluster: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_access_key_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_force_path_style: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_secret_access_key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub timestamp: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub uid: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecConnectionPooler { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxDBConnections")] + pub max_db_connections: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "numberOfInstances")] + pub number_of_instances: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schema: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub user: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecConnectionPoolerMode { + #[serde(rename = "session")] + Session, + #[serde(rename = "transaction")] + Transaction, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecConnectionPoolerResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecConnectionPoolerResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecConnectionPoolerResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecNodeAffinity { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preferredDuringSchedulingIgnoredDuringExecution")] + pub preferred_during_scheduling_ignored_during_execution: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "requiredDuringSchedulingIgnoredDuringExecution")] + pub required_during_scheduling_ignored_during_execution: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecution { + pub preference: PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference, + pub weight: i32, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution { + #[serde(rename = "nodeSelectorTerms")] + pub node_selector_terms: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTerms { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecPatroni { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub failsafe_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub initdb: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub loop_wait: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub maximum_lag_on_failover: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pg_hba: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub retry_timeout: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub slots: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode_strict: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_node_count: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ttl: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecPostgresql { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub parameters: Option>, + pub version: PostgresqlSpecPostgresqlVersion, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecPostgresqlVersion { + #[serde(rename = "13")] + r#_13, + #[serde(rename = "14")] + r#_14, + #[serde(rename = "15")] + r#_15, + #[serde(rename = "16")] + r#_16, + #[serde(rename = "17")] + r#_17, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecPreparedDatabases { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub extensions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schemas: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretNamespace")] + pub secret_namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecPreparedDatabasesSchemas { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultRoles")] + pub default_roles: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecStandby { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub gs_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_host: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_port: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecStreams { + #[serde(rename = "applicationId")] + pub application_id: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "batchSize")] + pub batch_size: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + pub database: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableRecovery")] + pub enable_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub filter: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, + pub tables: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecStreamsTables { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "eventType")] + pub event_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "idColumn")] + pub id_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ignoreRecovery")] + pub ignore_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "payloadColumn")] + pub payload_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "recoveryEventType")] + pub recovery_event_type: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecTls { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caFile")] + pub ca_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caSecretName")] + pub ca_secret_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "certificateFile")] + pub certificate_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "privateKeyFile")] + pub private_key_file: Option, + #[serde(rename = "secretName")] + pub secret_name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecTolerations { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub effect: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub operator: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "tolerationSeconds")] + pub toleration_seconds: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub value: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecTolerationsEffect { + NoExecute, + NoSchedule, + PreferNoSchedule, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecTolerationsOperator { + Equal, + Exists, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecVolume { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub iops: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + pub size: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClass")] + pub storage_class: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub throughput: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecVolumeSelector { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +pub struct PostgresqlSpecVolumeSelectorMatchExpressions { + pub key: String, + pub operator: PostgresqlSpecVolumeSelectorMatchExpressionsOperator, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecVolumeSelectorMatchExpressionsOperator { + DoesNotExist, + Exists, + In, + NotIn, +} + + +``` diff --git a/tests/cmd/generate/from-file-with-derive-partialeq.md b/tests/cmd/generate/from-file-with-derive-partialeq.md new file mode 100644 index 0000000..0b05ea4 --- /dev/null +++ b/tests/cmd/generate/from-file-with-derive-partialeq.md @@ -0,0 +1,806 @@ +``` +$ kopium --derive=PartialEq --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=PartialEq --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, PartialEq)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "API", plural = "apis")] +#[kube(namespaced)] +#[kube(status = "APIStatus")] +#[kube(schema = "disabled")] +#[kube(derive="PartialEq")] +pub struct ApiSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiKeySelectionExpression")] + pub api_key_selection_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub basepath: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub body: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "corsConfiguration")] + pub cors_configuration: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "credentialsARN")] + pub credentials_arn: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub description: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableExecuteAPIEndpoint")] + pub disable_execute_api_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableSchemaValidation")] + pub disable_schema_validation: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "failOnWarnings")] + pub fail_on_warnings: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "protocolType")] + pub protocol_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeKey")] + pub route_key: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeSelectionExpression")] + pub route_selection_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tags: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub target: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ApiSpecCorsConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowCredentials")] + pub allow_credentials: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowHeaders")] + pub allow_headers: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowMethods")] + pub allow_methods: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowOrigins")] + pub allow_origins: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "exposeHeaders")] + pub expose_headers: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxAge")] + pub max_age: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ApiStatus { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiEndpoint")] + pub api_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGatewayManaged")] + pub api_gateway_managed: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "createdDate")] + pub created_date: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "importInfo")] + pub import_info: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub warnings: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ApiStatusAckResourceMetadata { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + pub region: String, +} + + +``` + +``` +$ kopium --derive=PartialEq --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=PartialEq --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::util::intstr::IntOrString; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, PartialEq)] +#[kube(group = "argoproj.io", version = "v1alpha1", kind = "ArgoCDExport", plural = "argocdexports")] +#[kube(namespaced)] +#[kube(status = "ArgoCDExportStatus")] +#[kube(schema = "disabled")] +#[kube(derive="PartialEq")] +pub struct ArgoCdExportSpec { + pub argocd: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub image: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schedule: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub storage: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ArgoCdExportSpecStorage { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub backend: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pvc: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretName")] + pub secret_name: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ArgoCdExportSpecStoragePvc { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "accessModes")] + pub access_modes: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSource")] + pub data_source: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSourceRef")] + pub data_source_ref: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClassName")] + pub storage_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeAttributesClassName")] + pub volume_attributes_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeMode")] + pub volume_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeName")] + pub volume_name: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ArgoCdExportSpecStoragePvcDataSource { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + pub kind: String, + pub name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ArgoCdExportSpecStoragePvcDataSourceRef { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + pub kind: String, + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ArgoCdExportSpecStoragePvcResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ArgoCdExportSpecStoragePvcSelector { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ArgoCdExportSpecStoragePvcSelectorMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct ArgoCdExportStatus { + pub phase: String, +} + + +``` + +``` +$ kopium --derive=PartialEq --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=PartialEq --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, PartialEq)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "Authorizer", plural = "authorizers")] +#[kube(namespaced)] +#[kube(status = "AuthorizerStatus")] +#[kube(schema = "disabled")] +#[kube(derive="PartialEq")] +pub struct AuthorizerSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiRef")] + pub api_ref: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerCredentialsARN")] + pub authorizer_credentials_arn: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerPayloadFormatVersion")] + pub authorizer_payload_format_version: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerResultTTLInSeconds")] + pub authorizer_result_ttl_in_seconds: Option, + #[serde(rename = "authorizerType")] + pub authorizer_type: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerURI")] + pub authorizer_uri: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableSimpleResponses")] + pub enable_simple_responses: Option, + #[serde(rename = "identitySource")] + pub identity_source: Vec, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "identityValidationExpression")] + pub identity_validation_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "jwtConfiguration")] + pub jwt_configuration: Option, + pub name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct AuthorizerApiRef { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub from: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct AuthorizerApiRefFrom { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct AuthorizerJwtConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub audience: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub issuer: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct AuthorizerStatus { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerID")] + pub authorizer_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct AuthorizerStatusAckResourceMetadata { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + pub region: String, +} + + +``` + +``` +$ kopium --derive=PartialEq --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=PartialEq --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, PartialEq)] +#[kube(group = "acid.zalan.do", version = "v1", kind = "postgresql", plural = "postgresqls")] +#[kube(namespaced)] +#[kube(schema = "disabled")] +#[kube(derive="PartialEq")] +pub struct PostgresqlSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "additionalVolumes")] + pub additional_volumes: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowedSourceRanges")] + pub allowed_source_ranges: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub clone: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "connectionPooler")] + pub connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub databases: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableConnectionPooler")] + pub enable_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableLogicalBackup")] + pub enable_logical_backup: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterLoadBalancer")] + pub enable_master_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterPoolerLoadBalancer")] + pub enable_master_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaConnectionPooler")] + pub enable_replica_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaLoadBalancer")] + pub enable_replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaPoolerLoadBalancer")] + pub enable_replica_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableShmVolume")] + pub enable_shm_volume: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub env: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "initContainers")] + pub init_containers: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "init_containers")] + pub init_containers_x: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupRetention")] + pub logical_backup_retention: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupSchedule")] + pub logical_backup_schedule: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maintenanceWindows")] + pub maintenance_windows: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "masterServiceAnnotations")] + pub master_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "nodeAffinity")] + pub node_affinity: Option, + #[serde(rename = "numberOfInstances")] + pub number_of_instances: i64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub patroni: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podAnnotations")] + pub pod_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podPriorityClassName")] + pub pod_priority_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "pod_priority_class_name")] + pub pod_priority_class_name_x: Option, + pub postgresql: PostgresqlSpecPostgresql, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preparedDatabases")] + pub prepared_databases: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaLoadBalancer")] + pub replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaServiceAnnotations")] + pub replica_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "schedulerName")] + pub scheduler_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "serviceAnnotations")] + pub service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub sidecars: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloFSGroup")] + pub spilo_fs_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsGroup")] + pub spilo_run_as_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsUser")] + pub spilo_run_as_user: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub streams: Option>, + #[serde(rename = "teamId")] + pub team_id: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tls: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tolerations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "useLoadBalancer")] + pub use_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub users: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersIgnoringSecretRotation")] + pub users_ignoring_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithInPlaceSecretRotation")] + pub users_with_in_place_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithSecretRotation")] + pub users_with_secret_rotation: Option>, + pub volume: PostgresqlSpecVolume, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecAdditionalVolumes { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(rename = "mountPath")] + pub mount_path: String, + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "targetContainers")] + pub target_containers: Option>, + #[serde(rename = "volumeSource")] + pub volume_source: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecClone { + pub cluster: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_access_key_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_force_path_style: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_secret_access_key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub timestamp: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub uid: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecConnectionPooler { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxDBConnections")] + pub max_db_connections: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "numberOfInstances")] + pub number_of_instances: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schema: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub user: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum PostgresqlSpecConnectionPoolerMode { + #[serde(rename = "session")] + Session, + #[serde(rename = "transaction")] + Transaction, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecConnectionPoolerResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecConnectionPoolerResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecConnectionPoolerResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecNodeAffinity { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preferredDuringSchedulingIgnoredDuringExecution")] + pub preferred_during_scheduling_ignored_during_execution: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "requiredDuringSchedulingIgnoredDuringExecution")] + pub required_during_scheduling_ignored_during_execution: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecution { + pub preference: PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference, + pub weight: i32, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution { + #[serde(rename = "nodeSelectorTerms")] + pub node_selector_terms: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTerms { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecPatroni { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub failsafe_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub initdb: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub loop_wait: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub maximum_lag_on_failover: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pg_hba: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub retry_timeout: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub slots: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode_strict: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_node_count: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ttl: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecPostgresql { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub parameters: Option>, + pub version: PostgresqlSpecPostgresqlVersion, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum PostgresqlSpecPostgresqlVersion { + #[serde(rename = "13")] + r#_13, + #[serde(rename = "14")] + r#_14, + #[serde(rename = "15")] + r#_15, + #[serde(rename = "16")] + r#_16, + #[serde(rename = "17")] + r#_17, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecPreparedDatabases { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub extensions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schemas: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretNamespace")] + pub secret_namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecPreparedDatabasesSchemas { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultRoles")] + pub default_roles: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecStandby { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub gs_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_host: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_port: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecStreams { + #[serde(rename = "applicationId")] + pub application_id: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "batchSize")] + pub batch_size: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + pub database: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableRecovery")] + pub enable_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub filter: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, + pub tables: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecStreamsTables { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "eventType")] + pub event_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "idColumn")] + pub id_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ignoreRecovery")] + pub ignore_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "payloadColumn")] + pub payload_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "recoveryEventType")] + pub recovery_event_type: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecTls { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caFile")] + pub ca_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caSecretName")] + pub ca_secret_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "certificateFile")] + pub certificate_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "privateKeyFile")] + pub private_key_file: Option, + #[serde(rename = "secretName")] + pub secret_name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecTolerations { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub effect: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub operator: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "tolerationSeconds")] + pub toleration_seconds: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub value: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum PostgresqlSpecTolerationsEffect { + NoExecute, + NoSchedule, + PreferNoSchedule, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum PostgresqlSpecTolerationsOperator { + Equal, + Exists, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecVolume { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub iops: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + pub size: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClass")] + pub storage_class: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub throughput: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecVolumeSelector { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecVolumeSelectorMatchExpressions { + pub key: String, + pub operator: PostgresqlSpecVolumeSelectorMatchExpressionsOperator, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum PostgresqlSpecVolumeSelectorMatchExpressionsOperator { + DoesNotExist, + Exists, + In, + NotIn, +} + + +``` diff --git a/tests/cmd/generate/from-file-with-docs.md b/tests/cmd/generate/from-file-with-docs.md new file mode 100644 index 0000000..b1c8c28 --- /dev/null +++ b/tests/cmd/generate/from-file-with-docs.md @@ -0,0 +1,1137 @@ +``` +$ kopium --docs --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --docs --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +/// ApiSpec defines the desired state of Api. +/// +/// Represents an API. +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "API", plural = "apis")] +#[kube(namespaced)] +#[kube(status = "APIStatus")] +#[kube(schema = "disabled")] +pub struct ApiSpec { + /// An API key selection expression. Supported only for WebSocket APIs. See API + /// Key Selection Expressions ( + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiKeySelectionExpression")] + pub api_key_selection_expression: Option, + /// Specifies how to interpret the base path of the API during import. Valid + /// values are ignore, prepend, and split. The default value is ignore. To learn + /// more, see Set the OpenAPI basePath Property ( + /// Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub basepath: Option, + /// The OpenAPI definition. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub body: Option, + /// A CORS configuration. Supported only for HTTP APIs. See Configuring CORS + /// ( + /// for more information. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "corsConfiguration")] + pub cors_configuration: Option, + /// This property is part of quick create. It specifies the credentials required + /// for the integration, if any. For a Lambda integration, three options are + /// available. To specify an IAM Role for API Gateway to assume, use the role's + /// Amazon Resource Name (ARN). To require that the caller's identity be passed + /// through from the request, specify arn:aws:iam::*:user/*. To use resource-based + /// permissions on supported AWS services, specify null. Currently, this property + /// is not used for HTTP integrations. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "credentialsARN")] + pub credentials_arn: Option, + /// The description of the API. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub description: Option, + /// Specifies whether clients can invoke your API by using the default execute-api + /// endpoint. By default, clients can invoke your API with the default + /// endpoint. To require that clients use a custom domain name to invoke your + /// API, disable the default endpoint. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableExecuteAPIEndpoint")] + pub disable_execute_api_endpoint: Option, + /// Avoid validating models when creating a deployment. Supported only for WebSocket + /// APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableSchemaValidation")] + pub disable_schema_validation: Option, + /// Specifies whether to rollback the API creation when a warning is encountered. + /// By default, API creation continues if a warning is encountered. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "failOnWarnings")] + pub fail_on_warnings: Option, + /// The name of the API. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + /// The API protocol. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "protocolType")] + pub protocol_type: Option, + /// This property is part of quick create. If you don't specify a routeKey, a + /// default route of $default is created. The $default route acts as a catch-all + /// for any request made to your API, for a particular stage. The $default route + /// key can't be modified. You can add routes after creating the API, and you + /// can update the route keys of additional routes. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeKey")] + pub route_key: Option, + /// The route selection expression for the API. For HTTP APIs, the routeSelectionExpression + /// must be ${request.method} ${request.path}. If not provided, this will be + /// the default for HTTP APIs. This property is required for WebSocket APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeSelectionExpression")] + pub route_selection_expression: Option, + /// The collection of tags. Each tag element is associated with a given resource. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tags: Option>, + /// This property is part of quick create. Quick create produces an API with + /// an integration, a default catch-all route, and a default stage which is configured + /// to automatically deploy changes. For HTTP integrations, specify a fully qualified + /// URL. For Lambda integrations, specify a function ARN. The type of the integration + /// will be HTTP_PROXY or AWS_PROXY, respectively. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub target: Option, + /// A version identifier for the API. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +/// A CORS configuration. Supported only for HTTP APIs. See Configuring CORS +/// ( +/// for more information. +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ApiSpecCorsConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowCredentials")] + pub allow_credentials: Option, + /// Represents a collection of allowed headers. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowHeaders")] + pub allow_headers: Option>, + /// Represents a collection of methods. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowMethods")] + pub allow_methods: Option>, + /// Represents a collection of origins. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowOrigins")] + pub allow_origins: Option>, + /// Represents a collection of allowed headers. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "exposeHeaders")] + pub expose_headers: Option>, + /// An integer with a value between -1 and 86400. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxAge")] + pub max_age: Option, +} + +/// APIStatus defines the observed state of API +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ApiStatus { + /// All CRs managed by ACK have a common `Status.ACKResourceMetadata` member + /// that is used to contain resource sync state, account ownership, + /// constructed ARN for the resource + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + /// The URI of the API, of the form {api-id}.execute-api.{region}.amazonaws.com. + /// The stage name is typically appended to this URI to form a complete path + /// to a deployed API stage. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiEndpoint")] + pub api_endpoint: Option, + /// Specifies whether an API is managed by API Gateway. You can't update or delete + /// a managed API by using API Gateway. A managed API can be deleted only through + /// the tooling or service that created it. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGatewayManaged")] + pub api_gateway_managed: Option, + /// The API ID. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + /// All CRs managed by ACK have a common `Status.Conditions` member that + /// contains a collection of `ackv1alpha1.Condition` objects that describe + /// the various terminal states of the CR and its backend AWS service API + /// resource + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, + /// The timestamp when the API was created. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "createdDate")] + pub created_date: Option, + /// The validation information during API import. This may include particular + /// properties of your OpenAPI definition which are ignored during import. Supported + /// only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "importInfo")] + pub import_info: Option>, + /// The warning messages reported when failonwarnings is turned on during API + /// import. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub warnings: Option>, +} + +/// All CRs managed by ACK have a common `Status.ACKResourceMetadata` member +/// that is used to contain resource sync state, account ownership, +/// constructed ARN for the resource +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ApiStatusAckResourceMetadata { + /// ARN is the Amazon Resource Name for the resource. This is a + /// globally-unique identifier and is set only by the ACK service controller + /// once the controller has orchestrated the creation of the resource OR + /// when it has verified that an "adopted" resource (a resource where the + /// ARN annotation was set by the Kubernetes user on the CR) exists and + /// matches the supplied CR's Spec field values. + /// + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + /// OwnerAccountID is the AWS Account ID of the account that owns the + /// backend AWS service API resource. + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + /// Region is the AWS region in which the resource exists or will exist. + pub region: String, +} + + +``` + +``` +$ kopium --docs --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --docs --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::util::intstr::IntOrString; +} +use self::prelude::*; + +/// ArgoCDExportSpec defines the desired state of ArgoCDExport +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug)] +#[kube(group = "argoproj.io", version = "v1alpha1", kind = "ArgoCDExport", plural = "argocdexports")] +#[kube(namespaced)] +#[kube(status = "ArgoCDExportStatus")] +#[kube(schema = "disabled")] +pub struct ArgoCdExportSpec { + /// Argocd is the name of the ArgoCD instance to export. + pub argocd: String, + /// Image is the container image to use for the export Job. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub image: Option, + /// Schedule in Cron format, see + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schedule: Option, + /// Storage defines the storage configuration options. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub storage: Option, + /// Version is the tag/digest to use for the export Job container image. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +/// Storage defines the storage configuration options. +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStorage { + /// Backend defines the storage backend to use, must be "local" (the default), "aws", "azure" or "gcp". + #[serde(default, skip_serializing_if = "Option::is_none")] + pub backend: Option, + /// PVC is the desired characteristics for a PersistentVolumeClaim. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pvc: Option, + /// SecretName is the name of a Secret with encryption key, credentials, etc. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretName")] + pub secret_name: Option, +} + +/// PVC is the desired characteristics for a PersistentVolumeClaim. +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvc { + /// accessModes contains the desired access modes the volume should have. + /// More info: + #[serde(default, skip_serializing_if = "Option::is_none", rename = "accessModes")] + pub access_modes: Option>, + /// dataSource field can be used to specify either: + /// * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + /// * An existing PVC (PersistentVolumeClaim) + /// If the provisioner or an external controller can support the specified data source, + /// it will create a new volume based on the contents of the specified data source. + /// When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + /// and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + /// If the namespace is specified, then dataSourceRef will not be copied to dataSource. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSource")] + pub data_source: Option, + /// dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + /// volume is desired. This may be any object from a non-empty API group (non + /// core object) or a PersistentVolumeClaim object. + /// When this field is specified, volume binding will only succeed if the type of + /// the specified object matches some installed volume populator or dynamic + /// provisioner. + /// This field will replace the functionality of the dataSource field and as such + /// if both fields are non-empty, they must have the same value. For backwards + /// compatibility, when namespace isn't specified in dataSourceRef, + /// both fields (dataSource and dataSourceRef) will be set to the same + /// value automatically if one of them is empty and the other is non-empty. + /// When namespace is specified in dataSourceRef, + /// dataSource isn't set to the same value and must be empty. + /// There are three important differences between dataSource and dataSourceRef: + /// * While dataSource only allows two specific types of objects, dataSourceRef + /// allows any non-core object, as well as PersistentVolumeClaim objects. + /// * While dataSource ignores disallowed values (dropping them), dataSourceRef + /// preserves all values, and generates an error if a disallowed value is + /// specified. + /// * While dataSource only allows local objects, dataSourceRef allows objects + /// in any namespaces. + /// (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + /// (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSourceRef")] + pub data_source_ref: Option, + /// resources represents the minimum resources the volume should have. + /// If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + /// that are lower than previous value but must still be higher than capacity recorded in the + /// status field of the claim. + /// More info: + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + /// selector is a label query over volumes to consider for binding. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + /// storageClassName is the name of the StorageClass required by the claim. + /// More info: + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClassName")] + pub storage_class_name: Option, + /// volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + /// If specified, the CSI driver will create or update the volume with the attributes defined + /// in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + /// it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + /// will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + /// If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + /// will be set by the persistentvolume controller if it exists. + /// If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + /// set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + /// exists. + /// More info: + /// (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeAttributesClassName")] + pub volume_attributes_class_name: Option, + /// volumeMode defines what type of volume is required by the claim. + /// Value of Filesystem is implied when not included in claim spec. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeMode")] + pub volume_mode: Option, + /// volumeName is the binding reference to the PersistentVolume backing this claim. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeName")] + pub volume_name: Option, +} + +/// dataSource field can be used to specify either: +/// * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) +/// * An existing PVC (PersistentVolumeClaim) +/// If the provisioner or an external controller can support the specified data source, +/// it will create a new volume based on the contents of the specified data source. +/// When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, +/// and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. +/// If the namespace is specified, then dataSourceRef will not be copied to dataSource. +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvcDataSource { + /// APIGroup is the group for the resource being referenced. + /// If APIGroup is not specified, the specified Kind must be in the core API group. + /// For any other third-party types, APIGroup is required. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + /// Kind is the type of resource being referenced + pub kind: String, + /// Name is the name of resource being referenced + pub name: String, +} + +/// dataSourceRef specifies the object from which to populate the volume with data, if a non-empty +/// volume is desired. This may be any object from a non-empty API group (non +/// core object) or a PersistentVolumeClaim object. +/// When this field is specified, volume binding will only succeed if the type of +/// the specified object matches some installed volume populator or dynamic +/// provisioner. +/// This field will replace the functionality of the dataSource field and as such +/// if both fields are non-empty, they must have the same value. For backwards +/// compatibility, when namespace isn't specified in dataSourceRef, +/// both fields (dataSource and dataSourceRef) will be set to the same +/// value automatically if one of them is empty and the other is non-empty. +/// When namespace is specified in dataSourceRef, +/// dataSource isn't set to the same value and must be empty. +/// There are three important differences between dataSource and dataSourceRef: +/// * While dataSource only allows two specific types of objects, dataSourceRef +/// allows any non-core object, as well as PersistentVolumeClaim objects. +/// * While dataSource ignores disallowed values (dropping them), dataSourceRef +/// preserves all values, and generates an error if a disallowed value is +/// specified. +/// * While dataSource only allows local objects, dataSourceRef allows objects +/// in any namespaces. +/// (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. +/// (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvcDataSourceRef { + /// APIGroup is the group for the resource being referenced. + /// If APIGroup is not specified, the specified Kind must be in the core API group. + /// For any other third-party types, APIGroup is required. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + /// Kind is the type of resource being referenced + pub kind: String, + /// Name is the name of resource being referenced + pub name: String, + /// Namespace is the namespace of resource being referenced + /// Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + /// (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +/// resources represents the minimum resources the volume should have. +/// If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements +/// that are lower than previous value but must still be higher than capacity recorded in the +/// status field of the claim. +/// More info: +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvcResources { + /// Limits describes the maximum amount of compute resources allowed. + /// More info: + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option>, + /// Requests describes the minimum amount of compute resources required. + /// If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + /// otherwise to an implementation-defined value. Requests cannot exceed Limits. + /// More info: + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option>, +} + +/// selector is a label query over volumes to consider for binding. +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvcSelector { + /// matchExpressions is a list of label selector requirements. The requirements are ANDed. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + /// matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + /// map is equivalent to an element of matchExpressions, whose key field is "key", the + /// operator is "In", and the values array contains only "value". The requirements are ANDed. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +/// A label selector requirement is a selector that contains values, a key, and an operator that +/// relates the key and values. +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvcSelectorMatchExpressions { + /// key is the label key that the selector applies to. + pub key: String, + /// operator represents a key's relationship to a set of values. + /// Valid operators are In, NotIn, Exists and DoesNotExist. + pub operator: String, + /// values is an array of string values. If the operator is In or NotIn, + /// the values array must be non-empty. If the operator is Exists or DoesNotExist, + /// the values array must be empty. This array is replaced during a strategic + /// merge patch. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +/// ArgoCDExportStatus defines the observed state of ArgoCDExport +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportStatus { + /// Phase is a simple, high-level summary of where the ArgoCDExport is in its lifecycle. + /// There are five possible phase values: + /// Pending: The ArgoCDExport has been accepted by the Kubernetes system, but one or more of the required resources have not been created. + /// Running: All of the containers for the ArgoCDExport are still running, or in the process of starting or restarting. + /// Succeeded: All containers for the ArgoCDExport have terminated in success, and will not be restarted. + /// Failed: At least one container has terminated in failure, either exited with non-zero status or was terminated by the system. + /// Unknown: For some reason the state of the ArgoCDExport could not be obtained. + pub phase: String, +} + + +``` + +``` +$ kopium --docs --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --docs --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +/// AuthorizerSpec defines the desired state of Authorizer. +/// +/// Represents an authorizer. +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "Authorizer", plural = "authorizers")] +#[kube(namespaced)] +#[kube(status = "AuthorizerStatus")] +#[kube(schema = "disabled")] +pub struct AuthorizerSpec { + /// The API identifier. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + /// AWSResourceReferenceWrapper provides a wrapper around *AWSResourceReference + /// type to provide more user friendly syntax for references using 'from' field + /// Ex: + /// APIIDRef: + /// + /// from: + /// name: my-api + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiRef")] + pub api_ref: Option, + /// Specifies the required credentials as an IAM role for API Gateway to invoke + /// the authorizer. To specify an IAM role for API Gateway to assume, use the + /// role's Amazon Resource Name (ARN). To use resource-based permissions on the + /// Lambda function, don't specify this parameter. Supported only for REQUEST + /// authorizers. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerCredentialsARN")] + pub authorizer_credentials_arn: Option, + /// Specifies the format of the payload sent to an HTTP API Lambda authorizer. + /// Required for HTTP API Lambda authorizers. Supported values are 1.0 and 2.0. + /// To learn more, see Working with AWS Lambda authorizers for HTTP APIs ( + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerPayloadFormatVersion")] + pub authorizer_payload_format_version: Option, + /// The time to live (TTL) for cached authorizer results, in seconds. If it equals + /// 0, authorization caching is disabled. If it is greater than 0, API Gateway + /// caches authorizer responses. The maximum value is 3600, or 1 hour. Supported + /// only for HTTP API Lambda authorizers. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerResultTTLInSeconds")] + pub authorizer_result_ttl_in_seconds: Option, + /// The authorizer type. Specify REQUEST for a Lambda function using incoming + /// request parameters. Specify JWT to use JSON Web Tokens (supported only for + /// HTTP APIs). + #[serde(rename = "authorizerType")] + pub authorizer_type: String, + /// The authorizer's Uniform Resource Identifier (URI). For REQUEST authorizers, + /// this must be a well-formed Lambda function URI, for example, arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:{account_id}:function:{lambda_function_name}/invocations. + /// In general, the URI has this form: arn:aws:apigateway:{region}:lambda:path/{service_api} + /// , where {region} is the same as the region hosting the Lambda function, path + /// indicates that the remaining substring in the URI should be treated as the + /// path to the resource, including the initial /. For Lambda functions, this + /// is usually of the form /2015-03-31/functions/[FunctionARN]/invocations. Supported + /// only for REQUEST authorizers. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerURI")] + pub authorizer_uri: Option, + /// Specifies whether a Lambda authorizer returns a response in a simple format. + /// By default, a Lambda authorizer must return an IAM policy. If enabled, the + /// Lambda authorizer can return a boolean value instead of an IAM policy. Supported + /// only for HTTP APIs. To learn more, see Working with AWS Lambda authorizers + /// for HTTP APIs ( + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableSimpleResponses")] + pub enable_simple_responses: Option, + /// The identity source for which authorization is requested. + /// + /// For a REQUEST authorizer, this is optional. The value is a set of one or + /// more mapping expressions of the specified request parameters. The identity + /// source can be headers, query string parameters, stage variables, and context + /// parameters. For example, if an Auth header and a Name query string parameter + /// are defined as identity sources, this value is route.request.header.Auth, + /// route.request.querystring.Name for WebSocket APIs. For HTTP APIs, use selection + /// expressions prefixed with $, for example, $request.header.Auth, $request.querystring.Name. + /// These parameters are used to perform runtime validation for Lambda-based + /// authorizers by verifying all of the identity-related request parameters are + /// present in the request, not null, and non-empty. Only when this is true does + /// the authorizer invoke the authorizer Lambda function. Otherwise, it returns + /// a 401 Unauthorized response without calling the Lambda function. For HTTP + /// APIs, identity sources are also used as the cache key when caching is enabled. + /// To learn more, see Working with AWS Lambda authorizers for HTTP APIs ( + /// + /// For JWT, a single entry that specifies where to extract the JSON Web Token + /// (JWT) from inbound requests. Currently only header-based and query parameter-based + /// selections are supported, for example $request.header.Authorization. + #[serde(rename = "identitySource")] + pub identity_source: Vec, + /// This parameter is not used. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "identityValidationExpression")] + pub identity_validation_expression: Option, + /// Represents the configuration of a JWT authorizer. Required for the JWT authorizer + /// type. Supported only for HTTP APIs. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "jwtConfiguration")] + pub jwt_configuration: Option, + /// The name of the authorizer. + pub name: String, +} + +/// AWSResourceReferenceWrapper provides a wrapper around *AWSResourceReference +/// type to provide more user friendly syntax for references using 'from' field +/// Ex: +/// APIIDRef: +/// +/// from: +/// name: my-api +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AuthorizerApiRef { + /// AWSResourceReference provides all the values necessary to reference another + /// k8s resource for finding the identifier(Id/ARN/Name) + #[serde(default, skip_serializing_if = "Option::is_none")] + pub from: Option, +} + +/// AWSResourceReference provides all the values necessary to reference another +/// k8s resource for finding the identifier(Id/ARN/Name) +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AuthorizerApiRefFrom { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +/// Represents the configuration of a JWT authorizer. Required for the JWT authorizer +/// type. Supported only for HTTP APIs. +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AuthorizerJwtConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub audience: Option>, + /// A string representation of a URI with a length between [1-2048]. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub issuer: Option, +} + +/// AuthorizerStatus defines the observed state of Authorizer +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AuthorizerStatus { + /// All CRs managed by ACK have a common `Status.ACKResourceMetadata` member + /// that is used to contain resource sync state, account ownership, + /// constructed ARN for the resource + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + /// The authorizer identifier. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerID")] + pub authorizer_id: Option, + /// All CRs managed by ACK have a common `Status.Conditions` member that + /// contains a collection of `ackv1alpha1.Condition` objects that describe + /// the various terminal states of the CR and its backend AWS service API + /// resource + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, +} + +/// All CRs managed by ACK have a common `Status.ACKResourceMetadata` member +/// that is used to contain resource sync state, account ownership, +/// constructed ARN for the resource +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AuthorizerStatusAckResourceMetadata { + /// ARN is the Amazon Resource Name for the resource. This is a + /// globally-unique identifier and is set only by the ACK service controller + /// once the controller has orchestrated the creation of the resource OR + /// when it has verified that an "adopted" resource (a resource where the + /// ARN annotation was set by the Kubernetes user on the CR) exists and + /// matches the supplied CR's Spec field values. + /// + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + /// OwnerAccountID is the AWS Account ID of the account that owns the + /// backend AWS service API resource. + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + /// Region is the AWS region in which the resource exists or will exist. + pub region: String, +} + + +``` + +``` +$ kopium --docs --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --docs --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug)] +#[kube(group = "acid.zalan.do", version = "v1", kind = "postgresql", plural = "postgresqls")] +#[kube(namespaced)] +#[kube(schema = "disabled")] +pub struct PostgresqlSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "additionalVolumes")] + pub additional_volumes: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowedSourceRanges")] + pub allowed_source_ranges: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub clone: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "connectionPooler")] + pub connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub databases: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableConnectionPooler")] + pub enable_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableLogicalBackup")] + pub enable_logical_backup: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterLoadBalancer")] + pub enable_master_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterPoolerLoadBalancer")] + pub enable_master_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaConnectionPooler")] + pub enable_replica_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaLoadBalancer")] + pub enable_replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaPoolerLoadBalancer")] + pub enable_replica_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableShmVolume")] + pub enable_shm_volume: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub env: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "initContainers")] + pub init_containers: Option>>, + /// deprecated + #[serde(default, skip_serializing_if = "Option::is_none", rename = "init_containers")] + pub init_containers_x: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupRetention")] + pub logical_backup_retention: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupSchedule")] + pub logical_backup_schedule: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maintenanceWindows")] + pub maintenance_windows: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "masterServiceAnnotations")] + pub master_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "nodeAffinity")] + pub node_affinity: Option, + #[serde(rename = "numberOfInstances")] + pub number_of_instances: i64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub patroni: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podAnnotations")] + pub pod_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podPriorityClassName")] + pub pod_priority_class_name: Option, + /// deprecated + #[serde(default, skip_serializing_if = "Option::is_none", rename = "pod_priority_class_name")] + pub pod_priority_class_name_x: Option, + pub postgresql: PostgresqlSpecPostgresql, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preparedDatabases")] + pub prepared_databases: Option>, + /// deprecated + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaLoadBalancer")] + pub replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaServiceAnnotations")] + pub replica_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "schedulerName")] + pub scheduler_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "serviceAnnotations")] + pub service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub sidecars: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloFSGroup")] + pub spilo_fs_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsGroup")] + pub spilo_run_as_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsUser")] + pub spilo_run_as_user: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub streams: Option>, + #[serde(rename = "teamId")] + pub team_id: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tls: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tolerations: Option>, + /// deprecated + #[serde(default, skip_serializing_if = "Option::is_none", rename = "useLoadBalancer")] + pub use_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub users: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersIgnoringSecretRotation")] + pub users_ignoring_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithInPlaceSecretRotation")] + pub users_with_in_place_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithSecretRotation")] + pub users_with_secret_rotation: Option>, + pub volume: PostgresqlSpecVolume, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecAdditionalVolumes { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(rename = "mountPath")] + pub mount_path: String, + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "targetContainers")] + pub target_containers: Option>, + #[serde(rename = "volumeSource")] + pub volume_source: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecClone { + pub cluster: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_access_key_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_force_path_style: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_secret_access_key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub timestamp: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub uid: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecConnectionPooler { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxDBConnections")] + pub max_db_connections: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "numberOfInstances")] + pub number_of_instances: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schema: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub user: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecConnectionPoolerMode { + #[serde(rename = "session")] + Session, + #[serde(rename = "transaction")] + Transaction, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecConnectionPoolerResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecConnectionPoolerResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecConnectionPoolerResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinity { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preferredDuringSchedulingIgnoredDuringExecution")] + pub preferred_during_scheduling_ignored_during_execution: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "requiredDuringSchedulingIgnoredDuringExecution")] + pub required_during_scheduling_ignored_during_execution: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecution { + pub preference: PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference, + pub weight: i32, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution { + #[serde(rename = "nodeSelectorTerms")] + pub node_selector_terms: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTerms { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecPatroni { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub failsafe_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub initdb: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub loop_wait: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub maximum_lag_on_failover: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pg_hba: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub retry_timeout: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub slots: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode_strict: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_node_count: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ttl: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecPostgresql { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub parameters: Option>, + pub version: PostgresqlSpecPostgresqlVersion, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecPostgresqlVersion { + #[serde(rename = "13")] + r#_13, + #[serde(rename = "14")] + r#_14, + #[serde(rename = "15")] + r#_15, + #[serde(rename = "16")] + r#_16, + #[serde(rename = "17")] + r#_17, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecPreparedDatabases { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub extensions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schemas: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretNamespace")] + pub secret_namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecPreparedDatabasesSchemas { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultRoles")] + pub default_roles: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecStandby { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub gs_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_host: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_port: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecStreams { + #[serde(rename = "applicationId")] + pub application_id: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "batchSize")] + pub batch_size: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + pub database: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableRecovery")] + pub enable_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub filter: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, + pub tables: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecStreamsTables { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "eventType")] + pub event_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "idColumn")] + pub id_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ignoreRecovery")] + pub ignore_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "payloadColumn")] + pub payload_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "recoveryEventType")] + pub recovery_event_type: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecTls { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caFile")] + pub ca_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caSecretName")] + pub ca_secret_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "certificateFile")] + pub certificate_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "privateKeyFile")] + pub private_key_file: Option, + #[serde(rename = "secretName")] + pub secret_name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecTolerations { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub effect: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub operator: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "tolerationSeconds")] + pub toleration_seconds: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub value: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecTolerationsEffect { + NoExecute, + NoSchedule, + PreferNoSchedule, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecTolerationsOperator { + Equal, + Exists, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecVolume { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub iops: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + pub size: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClass")] + pub storage_class: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub throughput: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecVolumeSelector { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecVolumeSelectorMatchExpressions { + pub key: String, + pub operator: PostgresqlSpecVolumeSelectorMatchExpressionsOperator, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecVolumeSelectorMatchExpressionsOperator { + DoesNotExist, + Exists, + In, + NotIn, +} + + +``` diff --git a/tests/cmd/generate/from-file-with-smart-derive-elision.md b/tests/cmd/generate/from-file-with-smart-derive-elision.md new file mode 100644 index 0000000..19dc7d5 --- /dev/null +++ b/tests/cmd/generate/from-file-with-smart-derive-elision.md @@ -0,0 +1,809 @@ +``` +$ kopium --derive=PartialEq --derive=Default --smart-derive-elision --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=PartialEq --derive=Default --smart-derive-elision --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "API", plural = "apis")] +#[kube(namespaced)] +#[kube(status = "APIStatus")] +#[kube(schema = "disabled")] +#[kube(derive="PartialEq")] +#[kube(derive="Default")] +pub struct ApiSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiKeySelectionExpression")] + pub api_key_selection_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub basepath: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub body: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "corsConfiguration")] + pub cors_configuration: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "credentialsARN")] + pub credentials_arn: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub description: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableExecuteAPIEndpoint")] + pub disable_execute_api_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableSchemaValidation")] + pub disable_schema_validation: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "failOnWarnings")] + pub fail_on_warnings: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "protocolType")] + pub protocol_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeKey")] + pub route_key: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeSelectionExpression")] + pub route_selection_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tags: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub target: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct ApiSpecCorsConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowCredentials")] + pub allow_credentials: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowHeaders")] + pub allow_headers: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowMethods")] + pub allow_methods: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowOrigins")] + pub allow_origins: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "exposeHeaders")] + pub expose_headers: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxAge")] + pub max_age: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct ApiStatus { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiEndpoint")] + pub api_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGatewayManaged")] + pub api_gateway_managed: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "createdDate")] + pub created_date: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "importInfo")] + pub import_info: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub warnings: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct ApiStatusAckResourceMetadata { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + pub region: String, +} + + +``` + +``` +$ kopium --derive=PartialEq --derive=Default --smart-derive-elision --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=PartialEq --derive=Default --smart-derive-elision --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::util::intstr::IntOrString; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +#[kube(group = "argoproj.io", version = "v1alpha1", kind = "ArgoCDExport", plural = "argocdexports")] +#[kube(namespaced)] +#[kube(status = "ArgoCDExportStatus")] +#[kube(schema = "disabled")] +#[kube(derive="PartialEq")] +#[kube(derive="Default")] +pub struct ArgoCdExportSpec { + pub argocd: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub image: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schedule: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub storage: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct ArgoCdExportSpecStorage { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub backend: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pvc: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretName")] + pub secret_name: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct ArgoCdExportSpecStoragePvc { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "accessModes")] + pub access_modes: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSource")] + pub data_source: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSourceRef")] + pub data_source_ref: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClassName")] + pub storage_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeAttributesClassName")] + pub volume_attributes_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeMode")] + pub volume_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeName")] + pub volume_name: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct ArgoCdExportSpecStoragePvcDataSource { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + pub kind: String, + pub name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct ArgoCdExportSpecStoragePvcDataSourceRef { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + pub kind: String, + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct ArgoCdExportSpecStoragePvcResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct ArgoCdExportSpecStoragePvcSelector { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct ArgoCdExportSpecStoragePvcSelectorMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct ArgoCdExportStatus { + pub phase: String, +} + + +``` + +``` +$ kopium --derive=PartialEq --derive=Default --smart-derive-elision --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=PartialEq --derive=Default --smart-derive-elision --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "Authorizer", plural = "authorizers")] +#[kube(namespaced)] +#[kube(status = "AuthorizerStatus")] +#[kube(schema = "disabled")] +#[kube(derive="PartialEq")] +#[kube(derive="Default")] +pub struct AuthorizerSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiRef")] + pub api_ref: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerCredentialsARN")] + pub authorizer_credentials_arn: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerPayloadFormatVersion")] + pub authorizer_payload_format_version: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerResultTTLInSeconds")] + pub authorizer_result_ttl_in_seconds: Option, + #[serde(rename = "authorizerType")] + pub authorizer_type: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerURI")] + pub authorizer_uri: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableSimpleResponses")] + pub enable_simple_responses: Option, + #[serde(rename = "identitySource")] + pub identity_source: Vec, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "identityValidationExpression")] + pub identity_validation_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "jwtConfiguration")] + pub jwt_configuration: Option, + pub name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct AuthorizerApiRef { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub from: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct AuthorizerApiRefFrom { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct AuthorizerJwtConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub audience: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub issuer: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct AuthorizerStatus { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerID")] + pub authorizer_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct AuthorizerStatusAckResourceMetadata { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + pub region: String, +} + + +``` + +``` +$ kopium --derive=PartialEq --derive=Default --smart-derive-elision --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --derive=PartialEq --derive=Default --smart-derive-elision --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, PartialEq)] +#[kube(group = "acid.zalan.do", version = "v1", kind = "postgresql", plural = "postgresqls")] +#[kube(namespaced)] +#[kube(schema = "disabled")] +#[kube(derive="PartialEq")] +pub struct PostgresqlSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "additionalVolumes")] + pub additional_volumes: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowedSourceRanges")] + pub allowed_source_ranges: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub clone: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "connectionPooler")] + pub connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub databases: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableConnectionPooler")] + pub enable_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableLogicalBackup")] + pub enable_logical_backup: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterLoadBalancer")] + pub enable_master_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterPoolerLoadBalancer")] + pub enable_master_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaConnectionPooler")] + pub enable_replica_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaLoadBalancer")] + pub enable_replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaPoolerLoadBalancer")] + pub enable_replica_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableShmVolume")] + pub enable_shm_volume: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub env: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "initContainers")] + pub init_containers: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "init_containers")] + pub init_containers_x: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupRetention")] + pub logical_backup_retention: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupSchedule")] + pub logical_backup_schedule: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maintenanceWindows")] + pub maintenance_windows: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "masterServiceAnnotations")] + pub master_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "nodeAffinity")] + pub node_affinity: Option, + #[serde(rename = "numberOfInstances")] + pub number_of_instances: i64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub patroni: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podAnnotations")] + pub pod_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podPriorityClassName")] + pub pod_priority_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "pod_priority_class_name")] + pub pod_priority_class_name_x: Option, + pub postgresql: PostgresqlSpecPostgresql, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preparedDatabases")] + pub prepared_databases: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaLoadBalancer")] + pub replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaServiceAnnotations")] + pub replica_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "schedulerName")] + pub scheduler_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "serviceAnnotations")] + pub service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub sidecars: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloFSGroup")] + pub spilo_fs_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsGroup")] + pub spilo_run_as_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsUser")] + pub spilo_run_as_user: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub streams: Option>, + #[serde(rename = "teamId")] + pub team_id: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tls: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tolerations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "useLoadBalancer")] + pub use_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub users: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersIgnoringSecretRotation")] + pub users_ignoring_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithInPlaceSecretRotation")] + pub users_with_in_place_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithSecretRotation")] + pub users_with_secret_rotation: Option>, + pub volume: PostgresqlSpecVolume, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecAdditionalVolumes { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(rename = "mountPath")] + pub mount_path: String, + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "targetContainers")] + pub target_containers: Option>, + #[serde(rename = "volumeSource")] + pub volume_source: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecClone { + pub cluster: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_access_key_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_force_path_style: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_secret_access_key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub timestamp: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub uid: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecConnectionPooler { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxDBConnections")] + pub max_db_connections: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "numberOfInstances")] + pub number_of_instances: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schema: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub user: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum PostgresqlSpecConnectionPoolerMode { + #[serde(rename = "session")] + Session, + #[serde(rename = "transaction")] + Transaction, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecConnectionPoolerResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecConnectionPoolerResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecConnectionPoolerResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecNodeAffinity { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preferredDuringSchedulingIgnoredDuringExecution")] + pub preferred_during_scheduling_ignored_during_execution: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "requiredDuringSchedulingIgnoredDuringExecution")] + pub required_during_scheduling_ignored_during_execution: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecution { + pub preference: PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference, + pub weight: i32, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution { + #[serde(rename = "nodeSelectorTerms")] + pub node_selector_terms: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTerms { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecPatroni { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub failsafe_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub initdb: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub loop_wait: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub maximum_lag_on_failover: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pg_hba: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub retry_timeout: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub slots: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode_strict: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_node_count: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ttl: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecPostgresql { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub parameters: Option>, + pub version: PostgresqlSpecPostgresqlVersion, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum PostgresqlSpecPostgresqlVersion { + #[serde(rename = "13")] + r#_13, + #[serde(rename = "14")] + r#_14, + #[serde(rename = "15")] + r#_15, + #[serde(rename = "16")] + r#_16, + #[serde(rename = "17")] + r#_17, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecPreparedDatabases { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub extensions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schemas: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretNamespace")] + pub secret_namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecPreparedDatabasesSchemas { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultRoles")] + pub default_roles: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecStandby { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub gs_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_host: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_port: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecStreams { + #[serde(rename = "applicationId")] + pub application_id: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "batchSize")] + pub batch_size: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + pub database: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableRecovery")] + pub enable_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub filter: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, + pub tables: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecStreamsTables { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "eventType")] + pub event_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "idColumn")] + pub id_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ignoreRecovery")] + pub ignore_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "payloadColumn")] + pub payload_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "recoveryEventType")] + pub recovery_event_type: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecTls { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caFile")] + pub ca_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caSecretName")] + pub ca_secret_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "certificateFile")] + pub certificate_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "privateKeyFile")] + pub private_key_file: Option, + #[serde(rename = "secretName")] + pub secret_name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecTolerations { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub effect: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub operator: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "tolerationSeconds")] + pub toleration_seconds: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub value: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum PostgresqlSpecTolerationsEffect { + NoExecute, + NoSchedule, + PreferNoSchedule, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum PostgresqlSpecTolerationsOperator { + Equal, + Exists, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecVolume { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub iops: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + pub size: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClass")] + pub storage_class: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub throughput: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +pub struct PostgresqlSpecVolumeSelector { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct PostgresqlSpecVolumeSelectorMatchExpressions { + pub key: String, + pub operator: PostgresqlSpecVolumeSelectorMatchExpressionsOperator, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum PostgresqlSpecVolumeSelectorMatchExpressionsOperator { + DoesNotExist, + Exists, + In, + NotIn, +} + + +``` diff --git a/tests/cmd/generate/from-file.md b/tests/cmd/generate/from-file.md new file mode 100644 index 0000000..93f737d --- /dev/null +++ b/tests/cmd/generate/from-file.md @@ -0,0 +1,802 @@ +``` +$ kopium --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --filename tests/cmd/generate/crds/apis.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "API", plural = "apis")] +#[kube(namespaced)] +#[kube(status = "APIStatus")] +#[kube(schema = "disabled")] +pub struct ApiSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiKeySelectionExpression")] + pub api_key_selection_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub basepath: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub body: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "corsConfiguration")] + pub cors_configuration: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "credentialsARN")] + pub credentials_arn: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub description: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableExecuteAPIEndpoint")] + pub disable_execute_api_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableSchemaValidation")] + pub disable_schema_validation: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "failOnWarnings")] + pub fail_on_warnings: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "protocolType")] + pub protocol_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeKey")] + pub route_key: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "routeSelectionExpression")] + pub route_selection_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tags: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub target: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ApiSpecCorsConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowCredentials")] + pub allow_credentials: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowHeaders")] + pub allow_headers: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowMethods")] + pub allow_methods: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowOrigins")] + pub allow_origins: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "exposeHeaders")] + pub expose_headers: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxAge")] + pub max_age: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ApiStatus { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiEndpoint")] + pub api_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGatewayManaged")] + pub api_gateway_managed: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "createdDate")] + pub created_date: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "importInfo")] + pub import_info: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub warnings: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ApiStatusAckResourceMetadata { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + pub region: String, +} + + +``` + +``` +$ kopium --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --filename tests/cmd/generate/crds/argocdexports.argoproj.io.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::util::intstr::IntOrString; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug)] +#[kube(group = "argoproj.io", version = "v1alpha1", kind = "ArgoCDExport", plural = "argocdexports")] +#[kube(namespaced)] +#[kube(status = "ArgoCDExportStatus")] +#[kube(schema = "disabled")] +pub struct ArgoCdExportSpec { + pub argocd: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub image: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schedule: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub storage: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStorage { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub backend: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pvc: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretName")] + pub secret_name: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvc { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "accessModes")] + pub access_modes: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSource")] + pub data_source: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dataSourceRef")] + pub data_source_ref: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClassName")] + pub storage_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeAttributesClassName")] + pub volume_attributes_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeMode")] + pub volume_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "volumeName")] + pub volume_name: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvcDataSource { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + pub kind: String, + pub name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvcDataSourceRef { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")] + pub api_group: Option, + pub kind: String, + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvcResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvcSelector { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportSpecStoragePvcSelectorMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArgoCdExportStatus { + pub phase: String, +} + + +``` + +``` +$ kopium --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --filename tests/cmd/generate/crds/authorizers.apigatewayv2.services.k8s.aws.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug)] +#[kube(group = "apigatewayv2.services.k8s.aws", version = "v1alpha1", kind = "Authorizer", plural = "authorizers")] +#[kube(namespaced)] +#[kube(status = "AuthorizerStatus")] +#[kube(schema = "disabled")] +pub struct AuthorizerSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiID")] + pub api_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiRef")] + pub api_ref: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerCredentialsARN")] + pub authorizer_credentials_arn: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerPayloadFormatVersion")] + pub authorizer_payload_format_version: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerResultTTLInSeconds")] + pub authorizer_result_ttl_in_seconds: Option, + #[serde(rename = "authorizerType")] + pub authorizer_type: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerURI")] + pub authorizer_uri: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableSimpleResponses")] + pub enable_simple_responses: Option, + #[serde(rename = "identitySource")] + pub identity_source: Vec, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "identityValidationExpression")] + pub identity_validation_expression: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "jwtConfiguration")] + pub jwt_configuration: Option, + pub name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AuthorizerApiRef { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub from: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AuthorizerApiRefFrom { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AuthorizerJwtConfiguration { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub audience: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub issuer: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AuthorizerStatus { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ackResourceMetadata")] + pub ack_resource_metadata: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "authorizerID")] + pub authorizer_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AuthorizerStatusAckResourceMetadata { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub arn: Option, + #[serde(rename = "ownerAccountID")] + pub owner_account_id: String, + pub region: String, +} + + +``` + +``` +$ kopium --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium --filename tests/cmd/generate/crds/postgresqls.acid.zalan.do.yaml +// kopium version: [..] + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug)] +#[kube(group = "acid.zalan.do", version = "v1", kind = "postgresql", plural = "postgresqls")] +#[kube(namespaced)] +#[kube(schema = "disabled")] +pub struct PostgresqlSpec { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "additionalVolumes")] + pub additional_volumes: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "allowedSourceRanges")] + pub allowed_source_ranges: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub clone: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "connectionPooler")] + pub connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub databases: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableConnectionPooler")] + pub enable_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableLogicalBackup")] + pub enable_logical_backup: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterLoadBalancer")] + pub enable_master_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableMasterPoolerLoadBalancer")] + pub enable_master_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaConnectionPooler")] + pub enable_replica_connection_pooler: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaLoadBalancer")] + pub enable_replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableReplicaPoolerLoadBalancer")] + pub enable_replica_pooler_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableShmVolume")] + pub enable_shm_volume: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub env: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "initContainers")] + pub init_containers: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "init_containers")] + pub init_containers_x: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupRetention")] + pub logical_backup_retention: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "logicalBackupSchedule")] + pub logical_backup_schedule: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maintenanceWindows")] + pub maintenance_windows: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "masterServiceAnnotations")] + pub master_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "nodeAffinity")] + pub node_affinity: Option, + #[serde(rename = "numberOfInstances")] + pub number_of_instances: i64, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub patroni: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podAnnotations")] + pub pod_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "podPriorityClassName")] + pub pod_priority_class_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "pod_priority_class_name")] + pub pod_priority_class_name_x: Option, + pub postgresql: PostgresqlSpecPostgresql, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preparedDatabases")] + pub prepared_databases: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaLoadBalancer")] + pub replica_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "replicaServiceAnnotations")] + pub replica_service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "schedulerName")] + pub scheduler_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "serviceAnnotations")] + pub service_annotations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub sidecars: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloFSGroup")] + pub spilo_fs_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsGroup")] + pub spilo_run_as_group: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "spiloRunAsUser")] + pub spilo_run_as_user: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub streams: Option>, + #[serde(rename = "teamId")] + pub team_id: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tls: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tolerations: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "useLoadBalancer")] + pub use_load_balancer: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub users: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersIgnoringSecretRotation")] + pub users_ignoring_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithInPlaceSecretRotation")] + pub users_with_in_place_secret_rotation: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "usersWithSecretRotation")] + pub users_with_secret_rotation: Option>, + pub volume: PostgresqlSpecVolume, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecAdditionalVolumes { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(rename = "mountPath")] + pub mount_path: String, + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "targetContainers")] + pub target_containers: Option>, + #[serde(rename = "volumeSource")] + pub volume_source: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecClone { + pub cluster: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_access_key_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_endpoint: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_force_path_style: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_secret_access_key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub timestamp: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub uid: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecConnectionPooler { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dockerImage")] + pub docker_image: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxDBConnections")] + pub max_db_connections: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "numberOfInstances")] + pub number_of_instances: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schema: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub user: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecConnectionPoolerMode { + #[serde(rename = "session")] + Session, + #[serde(rename = "transaction")] + Transaction, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecConnectionPoolerResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecConnectionPoolerResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecConnectionPoolerResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinity { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "preferredDuringSchedulingIgnoredDuringExecution")] + pub preferred_during_scheduling_ignored_during_execution: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "requiredDuringSchedulingIgnoredDuringExecution")] + pub required_during_scheduling_ignored_during_execution: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecution { + pub preference: PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference, + pub weight: i32, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreference { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityPreferredDuringSchedulingIgnoredDuringExecutionPreferenceMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution { + #[serde(rename = "nodeSelectorTerms")] + pub node_selector_terms: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTerms { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchFields")] + pub match_fields: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchExpressions { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecNodeAffinityRequiredDuringSchedulingIgnoredDuringExecutionNodeSelectorTermsMatchFields { + pub key: String, + pub operator: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecPatroni { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub failsafe_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub initdb: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub loop_wait: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub maximum_lag_on_failover: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pg_hba: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub retry_timeout: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub slots: Option>>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_mode_strict: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub synchronous_node_count: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ttl: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecPostgresql { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub parameters: Option>, + pub version: PostgresqlSpecPostgresqlVersion, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecPostgresqlVersion { + #[serde(rename = "13")] + r#_13, + #[serde(rename = "14")] + r#_14, + #[serde(rename = "15")] + r#_15, + #[serde(rename = "16")] + r#_16, + #[serde(rename = "17")] + r#_17, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecPreparedDatabases { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub extensions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub schemas: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretNamespace")] + pub secret_namespace: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecPreparedDatabasesSchemas { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultRoles")] + pub default_roles: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultUsers")] + pub default_users: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecResources { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limits: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub requests: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecResourcesLimits { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecResourcesRequests { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-1Gi")] + pub hugepages_1gi: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "hugepages-2Mi")] + pub hugepages_2mi: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecStandby { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub gs_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub s3_wal_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_host: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub standby_port: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecStreams { + #[serde(rename = "applicationId")] + pub application_id: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "batchSize")] + pub batch_size: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cpu: Option, + pub database: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "enableRecovery")] + pub enable_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub filter: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory: Option, + pub tables: BTreeMap, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecStreamsTables { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "eventType")] + pub event_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "idColumn")] + pub id_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ignoreRecovery")] + pub ignore_recovery: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "payloadColumn")] + pub payload_column: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "recoveryEventType")] + pub recovery_event_type: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecTls { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caFile")] + pub ca_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "caSecretName")] + pub ca_secret_name: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "certificateFile")] + pub certificate_file: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "privateKeyFile")] + pub private_key_file: Option, + #[serde(rename = "secretName")] + pub secret_name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecTolerations { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub effect: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub operator: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "tolerationSeconds")] + pub toleration_seconds: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub value: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecTolerationsEffect { + NoExecute, + NoSchedule, + PreferNoSchedule, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecTolerationsOperator { + Equal, + Exists, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecVolume { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub iops: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "isSubPathExpr")] + pub is_sub_path_expr: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, + pub size: String, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "storageClass")] + pub storage_class: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "subPath")] + pub sub_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub throughput: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecVolumeSelector { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct PostgresqlSpecVolumeSelectorMatchExpressions { + pub key: String, + pub operator: PostgresqlSpecVolumeSelectorMatchExpressionsOperator, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum PostgresqlSpecVolumeSelectorMatchExpressionsOperator { + DoesNotExist, + Exists, + In, + NotIn, +} + + +``` diff --git a/tests/cmd/help/help.md b/tests/cmd/help/help.md new file mode 100644 index 0000000..4de079c --- /dev/null +++ b/tests/cmd/help/help.md @@ -0,0 +1,103 @@ +``` +$ kopium --help +Kubernetes OPenapI UnMangler + +Usage: kopium [OPTIONS] [CRD] + +Arguments: + [CRD] + Give the name of the input CRD to use e.g. prometheusrules.monitoring.coreos.com + +Options: + -f, --filename + Point to the location of a CRD to use on disk + + --api-version + Use this CRD version if multiple versions are present + + --hide-prelude + Do not emit prelude + + --hide-kube + Do not derive CustomResource nor set kube-derive attributes + + If this is set, it makes any kube-derive specific options such as `--schema` unnecessary + + -d, --docs + Emit doc comments from descriptions + + -b, --builders + Emit builder derives via the typed_builder crate + + --schema + Schema mode to use for kube-derive + + The default is --schema=disabled and will compile without a schema, but the resulting crd cannot be applied into a cluster. + + --schema=manual requires the user to `impl JsonSchema for MyCrdSpec` elsewhere for the code to compile. Once this is done, the crd via `CustomResourceExt::crd()` can be applied into Kubernetes directly. + + --schema=derived implies `--derive JsonSchema`. The resulting schema will compile without external user action. The crd via `CustomResourceExt::crd()` can be applied into Kubernetes directly. + + [default: disabled] + [possible values: disabled, manual, derived] + + -D, --derive + Derive these additional traits on generated objects + + There are three different ways of specifying traits to derive: + + 1. A plain trait name will implement the trait for *all* objects generated from the custom resource definition: `--derive PartialEq` + + 2. Constraining the derivation to a singular struct or enum: `--derive IssuerAcmeSolversDns01CnameStrategy=PartialEq` + + 3. Constraining the derivation to only structs (@struct), enums (@enum) or *unit-only* enums (@enum:simple), meaning enums where no variants are tuple or structs: `--derive @struct=PartialEq`, `--derive @enum=PartialEq`, `--derive @enum:simple=PartialEq` + + See also: https://doc.rust-lang.org/reference/items/enumerations.html + + -A, --auto + Enable all automatation features + + This is a recommended, but early set of features that generates the most rust native code. + + It contains an unstable set of of features and may get expanded in the future. + + Setting --auto enables: --schema=derived --derive=JsonSchema --docs + + -e, --elide + Elide the following containers from the output + + This allows manual customization of structs from the output without having to remove it from the output first. Takes precise generated struct names. + + --relaxed + Relaxed interpretation + + This allows certain invalid openapi specs to be interpreted as arbitrary objects as used by argo workflows for example. the output first. + + --no-condition + Disable standardised Condition API + + By default, kopium detects Condition objects and uses a standard Condition API from k8s_openapi instead of generating a custom definition. + + --no-object-reference + Disable standardised ObjectReference API + + By default, kopium detects ObjectReference objects and uses a standard ObjectReference from k8s_openapi instead of generating a custom definition. + + --map-type + Type used to represent maps via additionalProperties + + [default: BTreeMap] + [possible values: BTreeMap, HashMap] + + --smart-derive-elision + Automatically removes #[derive(Default)] from structs that contain fields for which a default can not be automatically derived. + + This option only has an effect if `--derive Default` is set. + + -h, --help + Print help (see a summary with '-h') + + -V, --version + Print version + +``` \ No newline at end of file diff --git a/tests/trycmd_tests.rs b/tests/trycmd_tests.rs new file mode 100644 index 0000000..61e6095 --- /dev/null +++ b/tests/trycmd_tests.rs @@ -0,0 +1,6 @@ +#[test] +fn cli_tests() { + trycmd::TestCases::new() + .case("tests/cmd/generate/*.md") + .case("tests/cmd/help/*.md"); +}