From e07d44f88664e51e480a23146be3f76673556ac7 Mon Sep 17 00:00:00 2001 From: Techassi Date: Tue, 28 Apr 2026 08:58:35 +0200 Subject: [PATCH 1/6] feat: Support dynamic image repositories --- Cargo.lock | 51 ++++++++++----------- Cargo.nix | 61 ++++++++++++++------------ Cargo.toml | 2 +- crate-hashes.json | 18 ++++---- extra/crds.yaml | 34 +++++++++----- rust/operator-binary/src/controller.rs | 10 ++++- rust/operator-binary/src/main.rs | 5 ++- 7 files changed, 105 insertions(+), 76 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5e6f9be..5431129f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,7 +81,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -92,7 +92,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -898,7 +898,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1639,7 +1639,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1785,7 +1785,7 @@ dependencies = [ [[package]] name = "k8s-version" version = "0.1.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#96f42571ea185a3cd76fedde351fcabbeefcae16" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" dependencies = [ "darling", "regex", @@ -2189,7 +2189,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2671,7 +2671,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", - "itertools 0.13.0", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.117", @@ -3024,7 +3024,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3083,7 +3083,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3094,9 +3094,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.12" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "aws-lc-rs", "ring", @@ -3463,7 +3463,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3491,7 +3491,7 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stackable-certs" version = "0.4.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#96f42571ea185a3cd76fedde351fcabbeefcae16" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" dependencies = [ "const-oid", "ecdsa", @@ -3591,8 +3591,8 @@ dependencies = [ [[package]] name = "stackable-operator" -version = "0.110.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#96f42571ea185a3cd76fedde351fcabbeefcae16" +version = "0.111.0" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" dependencies = [ "base64", "clap", @@ -3633,7 +3633,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#96f42571ea185a3cd76fedde351fcabbeefcae16" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" dependencies = [ "darling", "proc-macro2", @@ -3644,7 +3644,7 @@ dependencies = [ [[package]] name = "stackable-shared" version = "0.1.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#96f42571ea185a3cd76fedde351fcabbeefcae16" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" dependencies = [ "jiff", "k8s-openapi", @@ -3661,7 +3661,7 @@ dependencies = [ [[package]] name = "stackable-telemetry" version = "0.6.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#96f42571ea185a3cd76fedde351fcabbeefcae16" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" dependencies = [ "axum", "clap", @@ -3684,9 +3684,10 @@ dependencies = [ [[package]] name = "stackable-versioned" -version = "0.9.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#96f42571ea185a3cd76fedde351fcabbeefcae16" +version = "0.10.0" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" dependencies = [ + "kube", "schemars", "serde", "serde_json", @@ -3697,8 +3698,8 @@ dependencies = [ [[package]] name = "stackable-versioned-macros" -version = "0.9.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#96f42571ea185a3cd76fedde351fcabbeefcae16" +version = "0.10.0" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" dependencies = [ "convert_case", "convert_case_extras", @@ -3716,7 +3717,7 @@ dependencies = [ [[package]] name = "stackable-webhook" version = "0.9.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#96f42571ea185a3cd76fedde351fcabbeefcae16" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" dependencies = [ "arc-swap", "async-trait", @@ -3868,7 +3869,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -4532,7 +4533,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] diff --git a/Cargo.nix b/Cargo.nix index e52f19e5..0994336f 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -316,7 +316,7 @@ rec { dependencies = [ { name = "windows-sys"; - packageId = "windows-sys 0.60.2"; + packageId = "windows-sys 0.61.2"; target = { target, features }: (target."windows" or false); features = [ "Win32_System_Console" "Win32_Foundation" ]; } @@ -341,7 +341,7 @@ rec { } { name = "windows-sys"; - packageId = "windows-sys 0.60.2"; + packageId = "windows-sys 0.61.2"; target = { target, features }: (target."windows" or false); features = [ "Win32_System_Console" "Win32_Foundation" ]; } @@ -2824,7 +2824,7 @@ rec { } { name = "windows-sys"; - packageId = "windows-sys 0.60.2"; + packageId = "windows-sys 0.61.2"; target = { target, features }: (target."windows" or false); features = [ "Win32_Foundation" "Win32_System_Diagnostics_Debug" ]; } @@ -5167,7 +5167,6 @@ rec { "default" = [ "use_std" ]; "use_std" = [ "use_alloc" "either/use_std" ]; }; - resolvedDefaultFeatures = [ "default" "use_alloc" "use_std" ]; }; "itertools 0.14.0" = rec { crateName = "itertools"; @@ -5278,7 +5277,7 @@ rec { } { name = "windows-sys"; - packageId = "windows-sys 0.60.2"; + packageId = "windows-sys 0.61.2"; optional = true; usesDefaultFeatures = false; target = { target, features }: (target."windows" or false); @@ -5712,7 +5711,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "96f42571ea185a3cd76fedde351fcabbeefcae16"; + rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; sha256 = "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2"; }; libName = "k8s_version"; @@ -7157,7 +7156,7 @@ rec { dependencies = [ { name = "windows-sys"; - packageId = "windows-sys 0.60.2"; + packageId = "windows-sys 0.61.2"; rename = "windows"; target = { target, features }: (target."windows" or false); features = [ "Win32_Foundation" "Win32_System_Console" "Win32_Storage_FileSystem" "Win32_Security" ]; @@ -8726,7 +8725,7 @@ rec { } { name = "itertools"; - packageId = "itertools 0.13.0"; + packageId = "itertools 0.14.0"; } { name = "proc-macro2"; @@ -10241,7 +10240,7 @@ rec { } { name = "windows-sys"; - packageId = "windows-sys 0.60.2"; + packageId = "windows-sys 0.61.2"; target = { target, features }: (target."windows" or false); features = [ "Win32_Foundation" "Win32_Networking_WinSock" ]; } @@ -10513,7 +10512,7 @@ rec { } { name = "windows-sys"; - packageId = "windows-sys 0.60.2"; + packageId = "windows-sys 0.61.2"; usesDefaultFeatures = false; target = { target, features }: (target."windows" or false); features = [ "Win32_Foundation" "Win32_Security_Cryptography" ]; @@ -10551,9 +10550,9 @@ rec { }; "rustls-webpki" = rec { crateName = "rustls-webpki"; - version = "0.103.12"; + version = "0.103.13"; edition = "2021"; - sha256 = "01nxzkfd1l96jzp04svc7iznlkarzx3wb9p63a0i17rc4y2vnyc2"; + sha256 = "0vkm7z9pnxz5qz66p2kmyy2pwx0g4jnsbqk5xzfhs4czcjl2ki31"; libName = "webpki"; dependencies = [ { @@ -11659,7 +11658,7 @@ rec { } { name = "windows-sys"; - packageId = "windows-sys 0.60.2"; + packageId = "windows-sys 0.61.2"; target = { target, features }: (target."windows" or false); features = [ "Win32_Foundation" "Win32_Networking_WinSock" "Win32_System_IO" "Win32_System_Threading" "Win32_System_WindowsProgramming" ]; } @@ -11745,7 +11744,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "96f42571ea185a3cd76fedde351fcabbeefcae16"; + rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; sha256 = "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2"; }; libName = "stackable_certs"; @@ -12153,12 +12152,12 @@ rec { }; "stackable-operator" = rec { crateName = "stackable-operator"; - version = "0.110.1"; + version = "0.111.0"; edition = "2024"; workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "96f42571ea185a3cd76fedde351fcabbeefcae16"; + rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; sha256 = "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2"; }; libName = "stackable_operator"; @@ -12338,7 +12337,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "96f42571ea185a3cd76fedde351fcabbeefcae16"; + rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; sha256 = "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2"; }; procMacro = true; @@ -12373,7 +12372,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "96f42571ea185a3cd76fedde351fcabbeefcae16"; + rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; sha256 = "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2"; }; libName = "stackable_shared"; @@ -12454,7 +12453,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "96f42571ea185a3cd76fedde351fcabbeefcae16"; + rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; sha256 = "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2"; }; libName = "stackable_telemetry"; @@ -12559,12 +12558,12 @@ rec { }; "stackable-versioned" = rec { crateName = "stackable-versioned"; - version = "0.9.0"; + version = "0.10.0"; edition = "2024"; workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "96f42571ea185a3cd76fedde351fcabbeefcae16"; + rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; sha256 = "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2"; }; libName = "stackable_versioned"; @@ -12572,6 +12571,12 @@ rec { "Stackable GmbH " ]; dependencies = [ + { + name = "kube"; + packageId = "kube"; + usesDefaultFeatures = false; + features = [ "client" "jsonpatch" "runtime" "derive" "admission" "rustls-tls" "ring" ]; + } { name = "schemars"; packageId = "schemars"; @@ -12603,12 +12608,12 @@ rec { }; "stackable-versioned-macros" = rec { crateName = "stackable-versioned-macros"; - version = "0.9.0"; + version = "0.10.0"; edition = "2024"; workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "96f42571ea185a3cd76fedde351fcabbeefcae16"; + rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; sha256 = "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2"; }; procMacro = true; @@ -12676,7 +12681,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "96f42571ea185a3cd76fedde351fcabbeefcae16"; + rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; sha256 = "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2"; }; libName = "stackable_webhook"; @@ -13124,7 +13129,7 @@ rec { } { name = "windows-sys"; - packageId = "windows-sys 0.60.2"; + packageId = "windows-sys 0.61.2"; target = { target, features }: (target."windows" or false); features = [ "Win32_Storage_FileSystem" "Win32_Foundation" ]; } @@ -15828,7 +15833,7 @@ rec { dependencies = [ { name = "windows-sys"; - packageId = "windows-sys 0.60.2"; + packageId = "windows-sys 0.61.2"; target = { target, features }: (target."windows" or false); features = [ "Win32_Foundation" "Win32_Storage_FileSystem" "Win32_System_Console" "Win32_System_SystemInformation" ]; } @@ -17691,7 +17696,7 @@ rec { "Win32_Web" = [ "Win32" ]; "Win32_Web_InternetExplorer" = [ "Win32_Web" ]; }; - resolvedDefaultFeatures = [ "Win32" "Win32_Foundation" "Win32_Networking" "Win32_Networking_WinSock" "Win32_Security" "Win32_Security_Cryptography" "Win32_Storage" "Win32_Storage_FileSystem" "Win32_System" "Win32_System_Console" "Win32_System_Diagnostics" "Win32_System_Diagnostics_Debug" "Win32_System_IO" "Win32_System_SystemInformation" "Win32_System_Threading" "Win32_System_Time" "Win32_System_WindowsProgramming" "default" ]; + resolvedDefaultFeatures = [ "Win32" "Win32_Foundation" "Win32_Networking" "Win32_Networking_WinSock" "Win32_System" "Win32_System_IO" "default" ]; }; "windows-sys 0.61.2" = rec { crateName = "windows-sys"; @@ -17953,7 +17958,7 @@ rec { "Win32_Web" = [ "Win32" ]; "Win32_Web_InternetExplorer" = [ "Win32_Web" ]; }; - resolvedDefaultFeatures = [ "Wdk" "Wdk_Foundation" "Wdk_Storage" "Wdk_Storage_FileSystem" "Wdk_System" "Wdk_System_IO" "Win32" "Win32_Foundation" "Win32_Networking" "Win32_Networking_WinSock" "Win32_Security" "Win32_Security_Authentication" "Win32_Security_Authentication_Identity" "Win32_Security_Credentials" "Win32_Security_Cryptography" "Win32_Storage" "Win32_Storage_FileSystem" "Win32_System" "Win32_System_Console" "Win32_System_IO" "Win32_System_LibraryLoader" "Win32_System_Memory" "Win32_System_Pipes" "Win32_System_SystemInformation" "Win32_System_SystemServices" "Win32_System_Threading" "Win32_System_WindowsProgramming" "default" ]; + resolvedDefaultFeatures = [ "Wdk" "Wdk_Foundation" "Wdk_Storage" "Wdk_Storage_FileSystem" "Wdk_System" "Wdk_System_IO" "Win32" "Win32_Foundation" "Win32_Networking" "Win32_Networking_WinSock" "Win32_Security" "Win32_Security_Authentication" "Win32_Security_Authentication_Identity" "Win32_Security_Credentials" "Win32_Security_Cryptography" "Win32_Storage" "Win32_Storage_FileSystem" "Win32_System" "Win32_System_Console" "Win32_System_Diagnostics" "Win32_System_Diagnostics_Debug" "Win32_System_IO" "Win32_System_LibraryLoader" "Win32_System_Memory" "Win32_System_Pipes" "Win32_System_SystemInformation" "Win32_System_SystemServices" "Win32_System_Threading" "Win32_System_Time" "Win32_System_WindowsProgramming" "default" ]; }; "windows-targets 0.42.2" = rec { crateName = "windows-targets"; diff --git a/Cargo.toml b/Cargo.toml index 63e8d549..360d0ed6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/stackabletech/opa-operator" [workspace.dependencies] product-config = { git = "https://github.com/stackabletech/product-config.git", tag = "0.8.0" } -stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.110.1", features = ["webhook"] } +stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.111.0", features = ["webhook"] } krb5 = { git = "https://github.com/stackabletech/krb5-rs.git", tag = "v0.1.0" } anyhow = "1.0" diff --git a/crate-hashes.json b/crate-hashes.json index ea584b7f..91609075 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,14 +1,14 @@ { "git+https://github.com/stackabletech/krb5-rs.git?tag=v0.1.0#krb5-sys@0.1.0": "148zr0q04163hpirkrff5q7cbxqgwzzxh0091zr4g23x7l64jh39", "git+https://github.com/stackabletech/krb5-rs.git?tag=v0.1.0#krb5@0.1.0": "148zr0q04163hpirkrff5q7cbxqgwzzxh0091zr4g23x7l64jh39", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#k8s-version@0.1.3": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#stackable-certs@0.4.0": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#stackable-operator-derive@0.3.1": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#stackable-operator@0.110.1": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#stackable-shared@0.1.0": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#stackable-telemetry@0.6.3": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#stackable-versioned-macros@0.9.0": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#stackable-versioned@0.9.0": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.110.1#stackable-webhook@0.9.1": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#k8s-version@0.1.3": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-certs@0.4.0": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-operator-derive@0.3.1": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-operator@0.111.0": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-shared@0.1.0": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-telemetry@0.6.3": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-versioned-macros@0.10.0": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-versioned@0.10.0": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-webhook@0.9.1": "1fgc7i8rhq1nl9m4s69sbfiywy2jx4narpynvm3g54vd5yd4c6m2", "git+https://github.com/stackabletech/product-config.git?tag=0.8.0#product-config@0.8.0": "1dz70kapm2wdqcr7ndyjji0lhsl98bsq95gnb2lw487wf6yr7987" } \ No newline at end of file diff --git a/extra/crds.yaml b/extra/crds.yaml index 7362b2e5..e1d8a67e 100644 --- a/extra/crds.yaml +++ b/extra/crds.yaml @@ -550,8 +550,9 @@ spec: properties: custom: description: |- - Overwrite the docker image. - Specify the full docker image name, e.g. `oci.stackable.tech/sdp/superset:1.4.1-stackable2.1.0` + Provide a custom container image. + + Specify the full container image name, e.g. `oci.example.tech/namespace/superset:1.4.1-my-tag` type: string productVersion: description: Version of the product, e.g. `1.4.1`. @@ -578,14 +579,20 @@ spec: nullable: true type: array repo: - description: Name of the docker repo, e.g. `oci.stackable.tech/sdp` + description: |- + The repository on the container image registry where the container image is located, e.g. + `oci.example.com/namespace`. + + If not specified, the operator will use the image registry provided via the operator + environment options. nullable: true type: string stackableVersion: description: |- Stackable version of the product, e.g. `23.4`, `23.4.1` or `0.0.0-dev`. - If not specified, the operator will use its own version, e.g. `23.4.1`. - When using a nightly operator or a pr version, it will use the nightly `0.0.0-dev` image. + + If not specified, the operator will use its own version, e.g. `23.4.1`. When using a nightly + operator or a PR version, it will use the nightly `0.0.0-dev` image. nullable: true type: string type: object @@ -2384,8 +2391,9 @@ spec: properties: custom: description: |- - Overwrite the docker image. - Specify the full docker image name, e.g. `oci.stackable.tech/sdp/superset:1.4.1-stackable2.1.0` + Provide a custom container image. + + Specify the full container image name, e.g. `oci.example.tech/namespace/superset:1.4.1-my-tag` type: string productVersion: description: Version of the product, e.g. `1.4.1`. @@ -2412,14 +2420,20 @@ spec: nullable: true type: array repo: - description: Name of the docker repo, e.g. `oci.stackable.tech/sdp` + description: |- + The repository on the container image registry where the container image is located, e.g. + `oci.example.com/namespace`. + + If not specified, the operator will use the image registry provided via the operator + environment options. nullable: true type: string stackableVersion: description: |- Stackable version of the product, e.g. `23.4`, `23.4.1` or `0.0.0-dev`. - If not specified, the operator will use its own version, e.g. `23.4.1`. - When using a nightly operator or a pr version, it will use the nightly `0.0.0-dev` image. + + If not specified, the operator will use its own version, e.g. `23.4.1`. When using a nightly + operator or a PR version, it will use the nightly `0.0.0-dev` image. nullable: true type: string type: object diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index 73a2ecd8..52ba3a04 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -23,6 +23,7 @@ use stackable_operator::{ volume::{SecretOperatorVolumeSourceBuilder, VolumeBuilder}, }, }, + cli::OperatorEnvironmentOptions, cluster_resources::{ClusterResourceApplyStrategy, ClusterResources}, commons::{ product_image_selection::{self, ResolvedProductImage}, @@ -112,7 +113,7 @@ const USER_INFO_FETCHER_KERBEROS_DIR: &str = "/stackable/kerberos"; const TLS_VOLUME_NAME: &str = "tls"; const TLS_STORE_DIR: &str = "/stackable/tls"; -const DOCKER_IMAGE_BASE_NAME: &str = "opa"; +const CONTAINER_IMAGE_BASE_NAME: &str = "opa"; const CONSOLE_LOG_LEVEL_ENV: &str = "CONSOLE_LOG_LEVEL"; const FILE_LOG_LEVEL_ENV: &str = "FILE_LOG_LEVEL"; @@ -161,6 +162,7 @@ pub struct Ctx { pub opa_bundle_builder_image: String, pub user_info_fetcher_image: String, pub cluster_info: KubernetesClusterInfo, + pub operator_environment: OperatorEnvironmentOptions, } #[derive(Snafu, Debug, EnumDiscriminants)] @@ -449,7 +451,11 @@ pub async fn reconcile_opa( let resolved_product_image = opa .spec .image - .resolve(DOCKER_IMAGE_BASE_NAME, crate::built_info::PKG_VERSION) + .resolve( + CONTAINER_IMAGE_BASE_NAME, + &ctx.operator_environment.image_repository, + crate::built_info::PKG_VERSION, + ) .context(ResolveProductImageSnafu)?; let opa_role = OpaRole::Server; diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index dc4bf2c5..5cb9491d 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -9,7 +9,7 @@ use futures::{FutureExt, StreamExt, TryFutureExt}; use product_config::ProductConfigManager; use stackable_operator::{ YamlSchema, - cli::{Command, RunArguments}, + cli::{Command, OperatorEnvironmentOptions, RunArguments}, client::{self, Client}, eos::EndOfSupportChecker, k8s_openapi::api::{ @@ -151,6 +151,7 @@ async fn main() -> anyhow::Result<()> { operator_image.clone(), operator_image, kubernetes_cluster_info, + operator_environment, sigterm_watcher.handle(), ) .map(anyhow::Ok); @@ -177,6 +178,7 @@ async fn create_controller( opa_bundle_builder_image: String, user_info_fetcher_image: String, cluster_info: KubernetesClusterInfo, + operator_environment: OperatorEnvironmentOptions, shutdown_signal: F, ) where F: Future + Send + Sync + 'static, @@ -208,6 +210,7 @@ async fn create_controller( product_config, opa_bundle_builder_image, user_info_fetcher_image, + operator_environment, cluster_info, }), ) From 1989381dc1664f127ad9d01b132a419a15a1179e Mon Sep 17 00:00:00 2001 From: Techassi Date: Tue, 28 Apr 2026 09:29:07 +0200 Subject: [PATCH 2/6] test: Add placeholder values to satify roundtrip tests --- rust/operator-binary/src/crd/mod.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index 9788f0c6..51a4a229 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -454,3 +454,22 @@ impl HasStatusCondition for v1alpha2::OpaCluster { } } } + +#[cfg(test)] +mod tests { + use stackable_operator::versioned::test_utils::RoundtripTestData; + + use super::{v1alpha1, v1alpha2}; + + impl RoundtripTestData for v1alpha1::OpaClusterSpec { + fn roundtrip_test_data() -> Vec { + vec![] + } + } + + impl RoundtripTestData for v1alpha2::OpaClusterSpec { + fn roundtrip_test_data() -> Vec { + vec![] + } + } +} From ff73c3ec0fc8b03581d5d36050a8a6fd191196a6 Mon Sep 17 00:00:00 2001 From: Techassi Date: Tue, 28 Apr 2026 09:34:41 +0200 Subject: [PATCH 3/6] refactor: Remove create_controller function --- rust/operator-binary/src/main.rs | 149 +++++++++++++------------------ 1 file changed, 62 insertions(+), 87 deletions(-) diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index 5cb9491d..280498d9 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -1,23 +1,22 @@ // TODO: Look into how to properly resolve `clippy::result_large_err`. // This will need changes in our and upstream error types. #![allow(clippy::result_large_err)] -use std::{future::Future, sync::Arc}; +use std::sync::Arc; use anyhow::anyhow; use clap::Parser; use futures::{FutureExt, StreamExt, TryFutureExt}; -use product_config::ProductConfigManager; use stackable_operator::{ YamlSchema, - cli::{Command, OperatorEnvironmentOptions, RunArguments}, - client::{self, Client}, + cli::{Command, RunArguments}, + client, eos::EndOfSupportChecker, k8s_openapi::api::{ apps::v1::DaemonSet, core::v1::{ConfigMap, Service}, }, kube::{ - Api, CustomResourceExt as _, + CustomResourceExt as _, core::DeserializeGuard, runtime::{ Controller, @@ -26,13 +25,9 @@ use stackable_operator::{ }, }, logging::controller::report_controller_reconciled, - namespace::WatchNamespace, shared::yaml::SerializeOptions, telemetry::Tracing, - utils::{ - cluster_info::KubernetesClusterInfo, - signal::{self, SignalWatcher}, - }, + utils::signal::{self, SignalWatcher}, }; use crate::{ @@ -144,17 +139,63 @@ async fn main() -> anyhow::Result<()> { .run(sigterm_watcher.handle()) .map_err(|err| anyhow!(err).context("failed to run webhook server")); - let controller = create_controller( - client.clone(), - product_config, - watch_namespace, - operator_image.clone(), - operator_image, - kubernetes_cluster_info, - operator_environment, - sigterm_watcher.handle(), - ) - .map(anyhow::Ok); + let event_recorder = Arc::new(Recorder::new( + client.as_kube_client(), + Reporter { + controller: OPA_FULL_CONTROLLER_NAME.to_string(), + instance: None, + }, + )); + + let controller = Controller::new( + watch_namespace.get_api::>(&client), + watcher::Config::default(), + ); + + let controller = controller + .owns( + watch_namespace.get_api::>(&client), + watcher::Config::default(), + ) + .owns( + watch_namespace.get_api::>(&client), + watcher::Config::default(), + ) + .owns( + watch_namespace.get_api::>(&client), + watcher::Config::default(), + ) + .graceful_shutdown_on(sigterm_watcher.handle()) + .run( + controller::reconcile_opa, + controller::error_policy, + Arc::new(controller::Ctx { + client: client.clone(), + product_config, + opa_bundle_builder_image: operator_image.clone(), + user_info_fetcher_image: operator_image, + operator_environment, + cluster_info: kubernetes_cluster_info, + }), + ) + // We can let the reporting happen in the background + .for_each_concurrent( + 16, // concurrency limit + |result| { + // The event_recorder needs to be shared across all invocations, so that + // events are correctly aggregated + let event_recorder = event_recorder.clone(); + async move { + report_controller_reconciled( + &event_recorder, + OPA_FULL_CONTROLLER_NAME, + &result, + ) + .await; + } + }, + ) + .map(anyhow::Ok); let delayed_controller = async { signal::crd_established(&client, v1alpha2::OpaCluster::crd_name(), None).await?; @@ -167,69 +208,3 @@ async fn main() -> anyhow::Result<()> { Ok(()) } - -/// This creates an instance of a [`Controller`] which waits for incoming events and reconciles them. -/// -/// This is an async method and the returned future needs to be consumed to make progress. -async fn create_controller( - client: Client, - product_config: ProductConfigManager, - watch_namespace: WatchNamespace, - opa_bundle_builder_image: String, - user_info_fetcher_image: String, - cluster_info: KubernetesClusterInfo, - operator_environment: OperatorEnvironmentOptions, - shutdown_signal: F, -) where - F: Future + Send + Sync + 'static, -{ - let opa_api: Api> = watch_namespace.get_api(&client); - let daemonsets_api: Api> = watch_namespace.get_api(&client); - let configmaps_api: Api> = watch_namespace.get_api(&client); - let services_api: Api> = watch_namespace.get_api(&client); - - let controller = Controller::new(opa_api, watcher::Config::default()) - .owns(daemonsets_api, watcher::Config::default()) - .owns(configmaps_api, watcher::Config::default()) - .owns(services_api, watcher::Config::default()); - - let event_recorder = Arc::new(Recorder::new( - client.as_kube_client(), - Reporter { - controller: OPA_FULL_CONTROLLER_NAME.to_string(), - instance: None, - }, - )); - controller - .graceful_shutdown_on(shutdown_signal) - .run( - controller::reconcile_opa, - controller::error_policy, - Arc::new(controller::Ctx { - client: client.clone(), - product_config, - opa_bundle_builder_image, - user_info_fetcher_image, - operator_environment, - cluster_info, - }), - ) - // We can let the reporting happen in the background - .for_each_concurrent( - 16, // concurrency limit - |result| { - // The event_recorder needs to be shared across all invocations, so that - // events are correctly aggregated - let event_recorder = event_recorder.clone(); - async move { - report_controller_reconciled( - &event_recorder, - OPA_FULL_CONTROLLER_NAME, - &result, - ) - .await; - } - }, - ) - .await; -} From 02f2b0a5b03ccacce7c00a5661e1e44b8a97c566 Mon Sep 17 00:00:00 2001 From: Techassi Date: Tue, 28 Apr 2026 12:44:32 +0200 Subject: [PATCH 4/6] chore: Add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67ef19b6..c06a4df2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. ### Added +- BREAKING: Add required CLI argument and env var to set the image repository used to construct final product image names: `IMAGE_REPOSITORY` (`--image-repository`), eg. `oci.example.org/my/namespace` ([#830]). - Support `configOverrides` for `config.json` ([#818]). ### Changed @@ -18,6 +19,7 @@ All notable changes to this project will be documented in this file. [#818]: https://github.com/stackabletech/opa-operator/pull/818 [#819]: https://github.com/stackabletech/opa-operator/pull/819 [#820]: https://github.com/stackabletech/opa-operator/pull/820 +[#830]: https://github.com/stackabletech/opa-operator/pull/830 ## [26.3.0] - 2026-03-16 From 2dfa5fac57cfd5bb3cda202142b2fe969085ae11 Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Wed, 29 Apr 2026 12:35:26 +0200 Subject: [PATCH 5/6] test: Add CRD roundtrip test data --- rust/operator-binary/src/crd/mod.rs | 210 +++++++++++++++++++++++++++- 1 file changed, 208 insertions(+), 2 deletions(-) diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index 51a4a229..ec7ade94 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -457,19 +457,225 @@ impl HasStatusCondition for v1alpha2::OpaCluster { #[cfg(test)] mod tests { + use indoc::formatdoc; use stackable_operator::versioned::test_utils::RoundtripTestData; use super::{v1alpha1, v1alpha2}; impl RoundtripTestData for v1alpha1::OpaClusterSpec { fn roundtrip_test_data() -> Vec { - vec![] + let user_info_fetcher_sections = vec![ + r#" + userInfo: + backend: + experimentalXfscAas: + hostname: aas.default.svc.cluster.local + port: 5000 + "#, + r#" + userInfo: + backend: + experimentalActiveDirectory: + ldapServer: sble-addc.sble.test + baseDistinguishedName: DC=sble,DC=test + customAttributeMappings: + country: c + kerberosSecretClassName: kerberos-ad + tls: + verification: + server: + caCert: + secretClass: tls-ad + cache: + entryTimeToLive: 60s + "#, + r#" + userInfo: + backend: + keycloak: + hostname: keycloak.default.svc.cluster.local + port: 8443 + tls: + verification: + server: + caCert: + secretClass: keycloak-tls + clientCredentialsSecret: user-info-fetcher-client-credentials + adminRealm: my-dataspace + userRealm: my-dataspace + "#, + r#" + userInfo: + backend: + experimentalOpenLdap: + hostname: test-openldap.default.svc.cluster.local + port: 1636 + searchBase: ou=users,dc=example,dc=org + bindCredentials: + secretClass: ldap-bind-test + groupsSearchBase: ou=groups,dc=example,dc=org + customAttributeMappings: + hdir: homeDirectory + displayName: cn + surname: sn + tls: + verification: + server: + caCert: + secretClass: ldap-tls-test + cache: + entryTimeToLive: 60s + "#, + r#" + userInfo: + backend: + # Note the experimentalEntra vs entra here! + experimentalEntra: + tenantId: 00000000-0000-0000-0000-000000000000 + clientCredentialsSecret: user-info-fetcher-client-credentials + "#, + ]; + user_info_fetcher_sections + .into_iter() + .map(test_opa_cluster_yaml) + .map(|yaml| { + println!("{}", &yaml); + stackable_operator::utils::yaml_from_str_singleton_map(&yaml) + .expect("Failed to parse OpaClusterSpec YAML") + }) + .collect() } } impl RoundtripTestData for v1alpha2::OpaClusterSpec { fn roundtrip_test_data() -> Vec { - vec![] + let user_info_fetcher_sections = vec![ + r#" + userInfo: + backend: + experimentalXfscAas: + hostname: aas.default.svc.cluster.local + port: 5000 + "#, + r#" + userInfo: + backend: + experimentalActiveDirectory: + ldapServer: sble-addc.sble.test + baseDistinguishedName: DC=sble,DC=test + customAttributeMappings: + country: c + kerberosSecretClassName: kerberos-ad + tls: + verification: + server: + caCert: + secretClass: tls-ad + cache: + entryTimeToLive: 60s + "#, + r#" + userInfo: + backend: + keycloak: + hostname: keycloak.default.svc.cluster.local + port: 8443 + tls: + verification: + server: + caCert: + secretClass: keycloak-tls + clientCredentialsSecret: user-info-fetcher-client-credentials + adminRealm: my-dataspace + userRealm: my-dataspace + "#, + r#" + userInfo: + backend: + experimentalOpenLdap: + hostname: test-openldap.default.svc.cluster.local + port: 1636 + searchBase: ou=users,dc=example,dc=org + bindCredentials: + secretClass: ldap-bind-test + groupsSearchBase: ou=groups,dc=example,dc=org + customAttributeMappings: + hdir: homeDirectory + displayName: cn + surname: sn + tls: + verification: + server: + caCert: + secretClass: ldap-tls-test + cache: + entryTimeToLive: 60s + "#, + r#" + userInfo: + backend: + # Note the experimentalEntra vs entra here! + entra: + tenantId: 00000000-0000-0000-0000-000000000000 + clientCredentialsSecret: user-info-fetcher-client-credentials + "#, + ]; + user_info_fetcher_sections + .into_iter() + .map(test_opa_cluster_yaml) + .map(|yaml| { + println!("{}", &yaml); + stackable_operator::utils::yaml_from_str_singleton_map(&yaml) + .expect("Failed to parse OpaClusterSpec YAML") + }) + .collect() + } + } + + fn test_opa_cluster_yaml(user_info_fetcher_section: &str) -> String { + formatdoc! { + r#" + image: + productVersion: 1.2.3 + pullPolicy: IfNotPresent + clusterOperation: + stopped: false + reconciliationPaused: false + clusterConfig: + tls: + serverSecretClass: my-tls + vectorAggregatorConfigMapName: vector-aggregator-discovery + {user_info_fetcher_section} + servers: + config: + logging: + enableVectorAgent: true + configOverrides: + config.json: + jsonMergePatch: + bundles: + stackable: + polling: + min_delay_seconds: 3 + max_delay_seconds: 7 + default_decision: test/hello + envOverrides: + SERVER_ROLE_LEVEL_ENV_VAR: SERVER_ROLE_LEVEL_ENV_VAR + roleGroups: + default: + configOverrides: + config.json: + jsonMergePatch: + bundles: + stackable: + polling: + max_delay_seconds: 5 + labels: + rolegroup: default + envOverrides: + SERVER_ROLE_GROUP_LEVEL_ENV_VAR: SERVER_ROLE_GROUP_LEVEL_ENV_VAR + replicas: 1 + "# } } } From e91a3f2fb2ea3f9ddf338be272b475c9096cc769 Mon Sep 17 00:00:00 2001 From: Techassi Date: Wed, 29 Apr 2026 13:36:38 +0200 Subject: [PATCH 6/6] chore: Apply suggestion Co-authored-by: Sebastian Bernauer --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c06a4df2..c1b6eeeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to this project will be documented in this file. ### Changed -- Bump `stackable-operator` to 0.110.1 and `snafu` to 0.9 ([#818]). +- Bump `stackable-operator` to 0.111.0 and `snafu` to 0.9 ([#818], [#830]). - Set `maxSurge=1` and `maxUnavailable=0` on the OPA DaemonSet rolling update strategy to eliminate availability gaps during rolling updates ([#819]). - Document Helm deployed RBAC permissions and remove unnecessary permissions ([#820]).