From ae4ca69e4ee6f75bd4624bfbf5091ed8df64bb51 Mon Sep 17 00:00:00 2001 From: Techassi Date: Mon, 18 Nov 2024 16:16:28 +0100 Subject: [PATCH 1/6] Update CHANGELOG.md from release 24.11.0 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf9255a4..aed35e0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [24.11.0] - 2024-11-18 + ### Added - Support OpenID Connect authentication ([#660]). From a7476780975d6063aafcca6155578b3f3536f5e1 Mon Sep 17 00:00:00 2001 From: Stacky McStackface <95074132+stackable-bot@users.noreply.github.com> Date: Mon, 18 Nov 2024 22:47:53 +0100 Subject: [PATCH 2/6] chore: Generated commit to update templated files since the last template run up to stackabletech/operator-templating@fd40109c1bd66c79fa74bf67a5b5bff1e3a96ce8 (#713) Reference-to: stackabletech/operator-templating@fd40109 (Add make render-doc command) --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index ef882b6a..e103d0db 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,9 @@ SHELL=/usr/bin/env bash -euo pipefail render-readme: scripts/render_readme.sh +render-docs: + scripts/docs_templating.sh + ## Docker related targets docker-build: docker build --force-rm --build-arg VERSION=${VERSION} -t "${DOCKER_REPO}/${ORGANIZATION}/${OPERATOR_NAME}:${VERSION}-${ARCH}" -f docker/Dockerfile . From 5f9de588bfa038b011f585c8245ec6d3f271aa18 Mon Sep 17 00:00:00 2001 From: Nick <10092581+NickLarsenNZ@users.noreply.github.com> Date: Wed, 20 Nov 2024 20:16:25 +1300 Subject: [PATCH 3/6] chore(getting_started): replace templating instructions with make (#714) --- .../examples/getting_started/getting_started.sh | 13 +------------ .../examples/getting_started/getting_started.sh.j2 | 13 +------------ 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/docs/modules/nifi/examples/getting_started/getting_started.sh b/docs/modules/nifi/examples/getting_started/getting_started.sh index a422a6e4..427513e2 100755 --- a/docs/modules/nifi/examples/getting_started/getting_started.sh +++ b/docs/modules/nifi/examples/getting_started/getting_started.sh @@ -2,18 +2,7 @@ set -euo pipefail # DO NOT EDIT THE SCRIPT -# Instead, update the j2 template, and regenerate it for dev: -# cat < Date: Mon, 25 Nov 2024 11:03:45 +0100 Subject: [PATCH 4/6] fix: Construction of OIDC endpoint when rootPath has no trailing slash (#718) * refactor: Move oidc config creation to oidc.rs * Use new op-rs * nix files * changelog * Revert "nix files" This reverts commit 739d417478fe61246a77f59c9885a59c6ca621ef. * new op-rs version * changelog * use op-rs 0.82.0 * remove uneeded error * Add patch option * nixfiles * Apply suggestions from code review Co-authored-by: Techassi * fix compilation * calculation -> construction * Rename fn to add_oidc_config_to_properties * Update rust/operator-binary/src/security/oidc.rs Co-authored-by: Techassi * Rename NoOidcTlsVerificationNotSupported -> SkippingTlsVerificationNotSupported --------- Co-authored-by: Techassi --- CHANGELOG.md | 2 + Cargo.lock | 95 ++++++++- Cargo.nix | 245 +++++++++++++++++++++- Cargo.toml | 4 +- crate-hashes.json | 6 +- rust/operator-binary/Cargo.toml | 3 + rust/operator-binary/src/config.rs | 76 +------ rust/operator-binary/src/security/oidc.rs | 164 +++++++++++++-- 8 files changed, 498 insertions(+), 97 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aed35e0c..ef8c5c9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ All notable changes to this project will be documented in this file. - Switch from `flow.xml.gz` to `flow.json.gz` to allow seamless upgrades to version 2.0 ([#675]). - Failing to parse one `NifiCluster`/`AuthenticationClass` should no longer cause the whole operator to stop functioning ([#662]). - NiFi will now use the JDK trust store when an OIDC provider uses WebPKI as CA ([#686], [#698]). +- Fix OIDC endpoint construction in case the `rootPath` does not have a trailing slash ([#718]). ### Removed @@ -50,6 +51,7 @@ All notable changes to this project will be documented in this file. [#698]: https://github.com/stackabletech/nifi-operator/pull/698 [#702]: https://github.com/stackabletech/nifi-operator/pull/702 [#708]: https://github.com/stackabletech/nifi-operator/pull/708 +[#718]: https://github.com/stackabletech/nifi-operator/pull/718 ## [24.7.0] - 2024-07-24 diff --git a/Cargo.lock b/Cargo.lock index de175734..a026a399 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -720,6 +720,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.31" @@ -1630,6 +1636,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.89" @@ -1747,6 +1762,12 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + [[package]] name = "ring" version = "0.17.8" @@ -1762,12 +1783,51 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rstest" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2c585be59b6b5dd66a9d2084aa1d8bd52fbdb806eafdeffb52791147862035" +dependencies = [ + "futures 0.3.31", + "futures-timer", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825ea780781b15345a146be27eaefb05085e337e869bff01b4306a4fd4a9ad5a" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn 2.0.82", + "unicode-ident", +] + [[package]] name = "rustc-demangle" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustls" version = "0.23.15" @@ -2138,6 +2198,7 @@ dependencies = [ "pin-project", "product-config", "rand", + "rstest", "semver", "serde", "serde_json", @@ -2152,8 +2213,8 @@ dependencies = [ [[package]] name = "stackable-operator" -version = "0.80.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.80.0#6fbe32300b60f95e0baa2ab0ff2daf961b06531c" +version = "0.82.0" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.82.0#415bbd031bd52e9c0c5392060235030e9930b46b" dependencies = [ "chrono", "clap", @@ -2191,7 +2252,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.80.0#6fbe32300b60f95e0baa2ab0ff2daf961b06531c" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.82.0#415bbd031bd52e9c0c5392060235030e9930b46b" dependencies = [ "darling", "proc-macro2", @@ -2202,7 +2263,7 @@ dependencies = [ [[package]] name = "stackable-shared" version = "0.0.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.80.0#6fbe32300b60f95e0baa2ab0ff2daf961b06531c" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.82.0#415bbd031bd52e9c0c5392060235030e9930b46b" dependencies = [ "kube", "semver", @@ -2436,6 +2497,23 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.5.1" @@ -2874,6 +2952,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + [[package]] name = "xml-rs" version = "0.8.22" diff --git a/Cargo.nix b/Cargo.nix index 7392c79c..6b740996 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -2004,6 +2004,21 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "std" ]; }; + "futures-timer" = rec { + crateName = "futures-timer"; + version = "3.0.3"; + edition = "2018"; + sha256 = "094vw8k37djpbwv74bwf2qb7n6v6ghif4myss6smd6hgyajb127j"; + libName = "futures_timer"; + authors = [ + "Alex Crichton " + ]; + features = { + "gloo-timers" = [ "dep:gloo-timers" ]; + "send_wrapper" = [ "dep:send_wrapper" ]; + "wasm-bindgen" = [ "gloo-timers" "send_wrapper" ]; + }; + }; "futures-util" = rec { crateName = "futures-util"; version = "0.3.31"; @@ -5031,6 +5046,23 @@ rec { }; resolvedDefaultFeatures = [ "simd" "std" ]; }; + "proc-macro-crate" = rec { + crateName = "proc-macro-crate"; + version = "3.2.0"; + edition = "2021"; + sha256 = "0yzsqnavb3lmrcsmbrdjfrky9vcbl46v59xi9avn0796rb3likwf"; + libName = "proc_macro_crate"; + authors = [ + "Bastian Köcher " + ]; + dependencies = [ + { + name = "toml_edit"; + packageId = "toml_edit"; + } + ]; + + }; "proc-macro2" = rec { crateName = "proc-macro2"; version = "1.0.89"; @@ -5424,6 +5456,20 @@ rec { }; resolvedDefaultFeatures = [ "default" "std" "unicode" "unicode-age" "unicode-bool" "unicode-case" "unicode-gencat" "unicode-perl" "unicode-script" "unicode-segment" ]; }; + "relative-path" = rec { + crateName = "relative-path"; + version = "1.9.3"; + edition = "2021"; + sha256 = "1limlh8fzwi21g0473fqzd6fln9iqkwvzp3816bxi31pkilz6fds"; + libName = "relative_path"; + authors = [ + "John-John Tedro " + ]; + features = { + "serde" = [ "dep:serde" ]; + }; + resolvedDefaultFeatures = [ "default" ]; + }; "ring" = rec { crateName = "ring"; version = "0.17.8"; @@ -5489,6 +5535,105 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "default" "dev_urandom_fallback" ]; }; + "rstest" = rec { + crateName = "rstest"; + version = "0.23.0"; + edition = "2021"; + sha256 = "0d90hr3i2yajzgpzvsh6p2yjzmcb3nm8884xdbb5sswvwmdmhb0a"; + authors = [ + "Michele d'Amico " + ]; + dependencies = [ + { + name = "futures"; + packageId = "futures 0.3.31"; + optional = true; + } + { + name = "futures-timer"; + packageId = "futures-timer"; + optional = true; + } + { + name = "rstest_macros"; + packageId = "rstest_macros"; + usesDefaultFeatures = false; + } + ]; + buildDependencies = [ + { + name = "rustc_version"; + packageId = "rustc_version"; + } + ]; + features = { + "async-timeout" = [ "dep:futures" "dep:futures-timer" "rstest_macros/async-timeout" ]; + "crate-name" = [ "rstest_macros/crate-name" ]; + "default" = [ "async-timeout" "crate-name" ]; + }; + resolvedDefaultFeatures = [ "async-timeout" "crate-name" "default" ]; + }; + "rstest_macros" = rec { + crateName = "rstest_macros"; + version = "0.23.0"; + edition = "2021"; + sha256 = "0nmdm7a4ysihnh0zz6w6gqrmw205zfp7xqkb2id3858vg20afpl2"; + procMacro = true; + authors = [ + "Michele d'Amico " + ]; + dependencies = [ + { + name = "cfg-if"; + packageId = "cfg-if"; + } + { + name = "glob"; + packageId = "glob"; + } + { + name = "proc-macro-crate"; + packageId = "proc-macro-crate"; + optional = true; + } + { + name = "proc-macro2"; + packageId = "proc-macro2"; + } + { + name = "quote"; + packageId = "quote"; + } + { + name = "regex"; + packageId = "regex"; + } + { + name = "relative-path"; + packageId = "relative-path"; + } + { + name = "syn"; + packageId = "syn 2.0.82"; + features = [ "full" "parsing" "extra-traits" "visit" "visit-mut" ]; + } + { + name = "unicode-ident"; + packageId = "unicode-ident"; + } + ]; + buildDependencies = [ + { + name = "rustc_version"; + packageId = "rustc_version"; + } + ]; + features = { + "crate-name" = [ "dep:proc-macro-crate" ]; + "default" = [ "async-timeout" "crate-name" ]; + }; + resolvedDefaultFeatures = [ "async-timeout" "crate-name" ]; + }; "rustc-demangle" = rec { crateName = "rustc-demangle"; version = "0.1.24"; @@ -5504,6 +5649,19 @@ rec { "rustc-dep-of-std" = [ "core" "compiler_builtins" ]; }; }; + "rustc_version" = rec { + crateName = "rustc_version"; + version = "0.4.1"; + edition = "2018"; + sha256 = "14lvdsmr5si5qbqzrajgb6vfn69k0sfygrvfvr2mps26xwi3mjyg"; + dependencies = [ + { + name = "semver"; + packageId = "semver"; + } + ]; + + }; "rustls" = rec { crateName = "rustls"; version = "0.23.15"; @@ -6671,17 +6829,23 @@ rec { features = [ "chrono" "git2" ]; } ]; + devDependencies = [ + { + name = "rstest"; + packageId = "rstest"; + } + ]; }; "stackable-operator" = rec { crateName = "stackable-operator"; - version = "0.80.0"; + version = "0.82.0"; edition = "2021"; workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "6fbe32300b60f95e0baa2ab0ff2daf961b06531c"; - sha256 = "16jrq3wdwz63210jgmqbx3snrr15wxw6l1smqhzv7b7jpq8qvya3"; + rev = "415bbd031bd52e9c0c5392060235030e9930b46b"; + sha256 = "0phasjwb64rxgn5hs8vks92icmx9255bd5v9dms280clrfpcg4hy"; }; libName = "stackable_operator"; authors = [ @@ -6838,8 +7002,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "6fbe32300b60f95e0baa2ab0ff2daf961b06531c"; - sha256 = "16jrq3wdwz63210jgmqbx3snrr15wxw6l1smqhzv7b7jpq8qvya3"; + rev = "415bbd031bd52e9c0c5392060235030e9930b46b"; + sha256 = "0phasjwb64rxgn5hs8vks92icmx9255bd5v9dms280clrfpcg4hy"; }; procMacro = true; libName = "stackable_operator_derive"; @@ -6873,8 +7037,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "6fbe32300b60f95e0baa2ab0ff2daf961b06531c"; - sha256 = "16jrq3wdwz63210jgmqbx3snrr15wxw6l1smqhzv7b7jpq8qvya3"; + rev = "415bbd031bd52e9c0c5392060235030e9930b46b"; + sha256 = "0phasjwb64rxgn5hs8vks92icmx9255bd5v9dms280clrfpcg4hy"; }; libName = "stackable_shared"; authors = [ @@ -7624,6 +7788,51 @@ rec { }; resolvedDefaultFeatures = [ "codec" "default" "io" "slab" "time" ]; }; + "toml_datetime" = rec { + crateName = "toml_datetime"; + version = "0.6.8"; + edition = "2021"; + sha256 = "0hgv7v9g35d7y9r2afic58jvlwnf73vgd1mz2k8gihlgrf73bmqd"; + authors = [ + "Alex Crichton " + ]; + features = { + "serde" = [ "dep:serde" ]; + }; + }; + "toml_edit" = rec { + crateName = "toml_edit"; + version = "0.22.22"; + edition = "2021"; + sha256 = "1xf7sxfzmnc45f75x302qrn5aph52vc8w226v59yhrm211i8vr2a"; + authors = [ + "Andronik Ordian " + "Ed Page " + ]; + dependencies = [ + { + name = "indexmap"; + packageId = "indexmap"; + features = [ "std" ]; + } + { + name = "toml_datetime"; + packageId = "toml_datetime"; + } + { + name = "winnow"; + packageId = "winnow"; + optional = true; + } + ]; + features = { + "default" = [ "parse" "display" ]; + "parse" = [ "dep:winnow" ]; + "perf" = [ "dep:kstring" ]; + "serde" = [ "dep:serde" "toml_datetime/serde" "dep:serde_spanned" ]; + }; + resolvedDefaultFeatures = [ "default" "display" "parse" ]; + }; "tower" = rec { crateName = "tower"; version = "0.5.1"; @@ -9425,6 +9634,28 @@ rec { ]; }; + "winnow" = rec { + crateName = "winnow"; + version = "0.6.20"; + edition = "2021"; + sha256 = "16y4i8z9vh8hazjxg5mvmq0c5i35wlk8rxi5gkq6cn5vlb0zxh9n"; + dependencies = [ + { + name = "memchr"; + packageId = "memchr"; + optional = true; + usesDefaultFeatures = false; + } + ]; + features = { + "debug" = [ "std" "dep:anstream" "dep:anstyle" "dep:is-terminal" "dep:terminal_size" ]; + "default" = [ "std" ]; + "simd" = [ "dep:memchr" ]; + "std" = [ "alloc" "memchr?/std" ]; + "unstable-doc" = [ "alloc" "std" "simd" "unstable-recover" ]; + }; + resolvedDefaultFeatures = [ "alloc" "default" "std" ]; + }; "xml-rs" = rec { crateName = "xml-rs"; version = "0.8.22"; diff --git a/Cargo.toml b/Cargo.toml index e3180d09..1d3be928 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,12 +19,13 @@ indoc = "2.0" pin-project = "1.1" product-config = { git = "https://github.com/stackabletech/product-config.git", tag = "0.7.0" } rand = "0.8" +rstest = "0.23" semver = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.9" snafu = "0.8" -stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.80.0" } +stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.82.0" } strum = { version = "0.26", features = ["derive"] } tokio = { version = "1.40", features = ["full"] } tracing = "0.1" @@ -33,3 +34,4 @@ xml-rs = "0.8" # [patch."https://github.com/stackabletech/operator-rs.git"] # stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } +# stackable-operator = { path = "../operator-rs/crates/stackable-operator" } diff --git a/crate-hashes.json b/crate-hashes.json index 562fb18b..0ca37e6e 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,6 +1,6 @@ { - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.80.0#stackable-operator-derive@0.3.1": "16jrq3wdwz63210jgmqbx3snrr15wxw6l1smqhzv7b7jpq8qvya3", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.80.0#stackable-operator@0.80.0": "16jrq3wdwz63210jgmqbx3snrr15wxw6l1smqhzv7b7jpq8qvya3", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.80.0#stackable-shared@0.0.1": "16jrq3wdwz63210jgmqbx3snrr15wxw6l1smqhzv7b7jpq8qvya3", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.82.0#stackable-operator-derive@0.3.1": "0phasjwb64rxgn5hs8vks92icmx9255bd5v9dms280clrfpcg4hy", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.82.0#stackable-operator@0.82.0": "0phasjwb64rxgn5hs8vks92icmx9255bd5v9dms280clrfpcg4hy", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.82.0#stackable-shared@0.0.1": "0phasjwb64rxgn5hs8vks92icmx9255bd5v9dms280clrfpcg4hy", "git+https://github.com/stackabletech/product-config.git?tag=0.7.0#product-config@0.7.0": "0gjsm80g6r75pm3824dcyiz4ysq1ka4c1if6k1mjm9cnd5ym0gny" } \ No newline at end of file diff --git a/rust/operator-binary/Cargo.toml b/rust/operator-binary/Cargo.toml index d0d074e1..53c1782b 100644 --- a/rust/operator-binary/Cargo.toml +++ b/rust/operator-binary/Cargo.toml @@ -29,5 +29,8 @@ tokio.workspace = true tracing.workspace = true url.workspace = true +[dev-dependencies] +rstest.workspace = true + [build-dependencies] built.workspace = true diff --git a/rust/operator-binary/src/config.rs b/rust/operator-binary/src/config.rs index b0487f83..a5f0c716 100644 --- a/rust/operator-binary/src/config.rs +++ b/rust/operator-binary/src/config.rs @@ -10,11 +10,7 @@ use stackable_nifi_crd::{ PROTOCOL_PORT, }; use stackable_operator::{ - commons::{ - authentication::oidc::{AuthenticationProvider, DEFAULT_OIDC_WELLKNOWN_PATH}, - resources::Resources, - tls_verification::{CaCert, TlsServerVerification, TlsVerification}, - }, + commons::resources::Resources, memory::{BinaryMultiple, MemoryQuantity}, product_config_utils::{ transform_all_roles_to_config, validate_all_roles_and_groups_config, @@ -26,8 +22,11 @@ use strum::{Display, EnumIter}; use crate::{ operations::graceful_shutdown::graceful_shutdown_config_properties, - security::authentication::{ - NifiAuthenticationConfig, STACKABLE_SERVER_TLS_DIR, STACKABLE_TLS_STORE_PASSWORD, + security::{ + authentication::{ + NifiAuthenticationConfig, STACKABLE_SERVER_TLS_DIR, STACKABLE_TLS_STORE_PASSWORD, + }, + oidc::{self, add_oidc_config_to_properties}, }, }; @@ -92,16 +91,8 @@ pub enum Error { repo: NifiRepository, }, - #[snafu(display("invalid OIDC endpoint URL"))] - InvalidOidcEndpoint { - source: stackable_operator::commons::authentication::oidc::Error, - }, - - #[snafu(display("failed to build the OIDC wellkown path"))] - InvalidOidcWellknownPath { source: url::ParseError }, - - #[snafu(display("Nifi doesn't support skipping the OIDC TLS verification"))] - NoOidcTlsVerificationNotSupported {}, + #[snafu(display("failed to generate OIDC config"))] + GenerateOidcConfig { source: oidc::Error }, } /// Create the NiFi bootstrap.conf @@ -593,55 +584,10 @@ pub fn build_nifi_properties( "true".to_string(), ); - // OIDC config if let NifiAuthenticationConfig::Oidc { provider, oidc, .. } = auth_config { - let endpoint_url = provider - .endpoint_url() - .context(InvalidOidcEndpointSnafu)? - .join(DEFAULT_OIDC_WELLKNOWN_PATH) - .context(InvalidOidcWellknownPathSnafu)?; - properties.insert( - "nifi.security.user.oidc.discovery.url".to_string(), - endpoint_url.to_string(), - ); - let (oidc_client_id_env, oidc_client_secret_env) = - AuthenticationProvider::client_credentials_env_names( - &oidc.client_credentials_secret_ref, - ); - properties.insert( - "nifi.security.user.oidc.client.id".to_string(), - format!("${{env:{oidc_client_id_env}}}").to_string(), - ); - properties.insert( - "nifi.security.user.oidc.client.secret".to_string(), - format!("${{env:{oidc_client_secret_env}}}").to_string(), - ); - let scopes = provider.scopes.join(","); - properties.insert( - "nifi.security.user.oidc.additional.scopes".to_string(), - scopes.to_string(), - ); - properties.insert( - "nifi.security.user.oidc.claim.identifying.user".to_string(), - provider.principal_claim.to_string(), - ); - - if let Some(tls) = &provider.tls.tls { - let truststore_strategy = match tls.verification { - TlsVerification::None {} => NoOidcTlsVerificationNotSupportedSnafu.fail()?, - TlsVerification::Server(TlsServerVerification { - ca_cert: CaCert::SecretClass(_), - }) => "NIFI", // The cert get's added to the stackable truststore - TlsVerification::Server(TlsServerVerification { - ca_cert: CaCert::WebPki {}, - }) => "JDK", // The cert needs to be in the system truststore - }; - properties.insert( - "nifi.security.user.oidc.truststore.strategy".to_owned(), - truststore_strategy.to_owned(), - ); - } - } + add_oidc_config_to_properties(provider, oidc, &mut properties) + .context(GenerateOidcConfigSnafu)?; + }; // cluster node properties (only configure for cluster nodes) properties.insert("nifi.cluster.is.node".to_string(), "true".to_string()); diff --git a/rust/operator-binary/src/security/oidc.rs b/rust/operator-binary/src/security/oidc.rs index 227d2877..b01f100f 100644 --- a/rust/operator-binary/src/security/oidc.rs +++ b/rust/operator-binary/src/security/oidc.rs @@ -1,11 +1,17 @@ -use std::collections::{BTreeMap, HashSet}; +use std::collections::BTreeMap; use rand::{distributions::Alphanumeric, Rng}; use snafu::{OptionExt, ResultExt, Snafu}; use stackable_nifi_crd::NifiCluster; use stackable_operator::{ - builder::meta::ObjectMetaBuilder, client::Client, k8s_openapi::api::core::v1::Secret, - kube::ResourceExt, + builder::meta::ObjectMetaBuilder, + client::Client, + commons::{ + authentication::oidc::{self, AuthenticationProvider, ClientAuthenticationOptions}, + tls_verification::{CaCert, TlsServerVerification, TlsVerification}, + }, + k8s_openapi::api::core::v1::Secret, + kube::{runtime::reflector::ObjectRef, ResourceExt}, }; use super::authentication::STACKABLE_ADMIN_USERNAME; @@ -25,15 +31,22 @@ pub enum Error { }, #[snafu(display( - "found existing secret [{}/{}], but key {} is missing", - name, - namespace, - STACKABLE_OIDC_ADMIN_PASSWORD_KEY + "found existing admin password secret {secret:?}, but the key {STACKABLE_OIDC_ADMIN_PASSWORD_KEY} is missing", ))] - OidcAdminPasswordKeyMissing { name: String, namespace: String }, + MissingAdminPasswordKey { secret: ObjectRef }, + + #[snafu(display("invalid well-known OIDC configuration URL"))] + InvalidWellKnownConfigUrl { + source: stackable_operator::commons::authentication::oidc::Error, + }, + + #[snafu(display("Nifi doesn't support skipping the OIDC TLS verification"))] + SkippingTlsVerificationNotSupported {}, } -/// Generate a secret containing the password for the admin user that can access the API. This admin user is the same as for SingleUser authentication. +/// Generate a secret containing the password for the admin user that can access the API. +/// +/// This admin user is the same as for SingleUser authentication. pub(crate) async fn check_or_generate_oidc_admin_password( client: &Client, nifi: &NifiCluster, @@ -46,17 +59,17 @@ pub(crate) async fn check_or_generate_oidc_admin_password( .context(OidcAdminPasswordSecretSnafu)? { Some(secret) => { - let keys = secret + let admin_password_present = secret .data - .unwrap_or_default() - .into_keys() - .collect::>(); - if keys.contains(STACKABLE_OIDC_ADMIN_PASSWORD_KEY) { + .iter() + .flat_map(|data| data.keys()) + .any(|key| key == STACKABLE_OIDC_ADMIN_PASSWORD_KEY); + + if admin_password_present { Ok(false) } else { - OidcAdminPasswordKeyMissingSnafu { - name: build_oidc_admin_password_secret_name(nifi), - namespace, + MissingAdminPasswordKeySnafu { + secret: ObjectRef::from_obj(&secret), } .fail()? } @@ -92,3 +105,120 @@ pub(crate) async fn check_or_generate_oidc_admin_password( pub fn build_oidc_admin_password_secret_name(nifi: &NifiCluster) -> String { format!("{}-oidc-admin-password", nifi.name_any()) } + +/// Adds all the required configuration properties to enable OIDC authentication. +pub fn add_oidc_config_to_properties( + provider: &oidc::AuthenticationProvider, + client_auth_options: &ClientAuthenticationOptions, + properties: &mut BTreeMap, +) -> Result<(), Error> { + let well_known_url = provider + .well_known_config_url() + .context(InvalidWellKnownConfigUrlSnafu)?; + + properties.insert( + "nifi.security.user.oidc.discovery.url".to_string(), + well_known_url.to_string(), + ); + let (oidc_client_id_env, oidc_client_secret_env) = + AuthenticationProvider::client_credentials_env_names( + &client_auth_options.client_credentials_secret_ref, + ); + properties.insert( + "nifi.security.user.oidc.client.id".to_string(), + format!("${{env:{oidc_client_id_env}}}").to_string(), + ); + properties.insert( + "nifi.security.user.oidc.client.secret".to_string(), + format!("${{env:{oidc_client_secret_env}}}").to_string(), + ); + let scopes = provider.scopes.join(","); + properties.insert( + "nifi.security.user.oidc.additional.scopes".to_string(), + scopes.to_string(), + ); + properties.insert( + "nifi.security.user.oidc.claim.identifying.user".to_string(), + provider.principal_claim.to_string(), + ); + + if let Some(tls) = &provider.tls.tls { + let truststore_strategy = match tls.verification { + TlsVerification::None {} => SkippingTlsVerificationNotSupportedSnafu.fail()?, + TlsVerification::Server(TlsServerVerification { + ca_cert: CaCert::SecretClass(_), + }) => "NIFI", // The cert get's added to the stackable truststore + TlsVerification::Server(TlsServerVerification { + ca_cert: CaCert::WebPki {}, + }) => "JDK", // The cert needs to be in the system truststore + }; + properties.insert( + "nifi.security.user.oidc.truststore.strategy".to_owned(), + truststore_strategy.to_owned(), + ); + } + + Ok(()) +} + +#[cfg(test)] +mod tests { + use rstest::rstest; + use stackable_operator::commons::tls_verification::{Tls, TlsClientDetails}; + + use super::*; + + #[rstest] + #[case("/realms/sdp")] + #[case("/realms/sdp/")] + #[case("/realms/sdp/////")] + fn test_add_oidc_config(#[case] root_path: String) { + let mut properties = BTreeMap::new(); + let provider = oidc::AuthenticationProvider::new( + "keycloak.mycorp.org".to_owned().try_into().unwrap(), + Some(443), + root_path, + TlsClientDetails { + tls: Some(Tls { + verification: TlsVerification::Server(TlsServerVerification { + ca_cert: CaCert::WebPki {}, + }), + }), + }, + "preferred_username".to_owned(), + vec!["openid".to_owned()], + None, + ); + let oidc = ClientAuthenticationOptions { + client_credentials_secret_ref: "nifi-keycloak-client".to_owned(), + extra_scopes: vec![], + product_specific_fields: (), + }; + + add_oidc_config_to_properties(&provider, &oidc, &mut properties) + .expect("OIDC config adding failed"); + + assert_eq!( + properties.get("nifi.security.user.oidc.additional.scopes"), + Some(&"openid".to_owned()) + ); + assert_eq!( + properties.get("nifi.security.user.oidc.claim.identifying.user"), + Some(&"preferred_username".to_owned()) + ); + assert_eq!( + properties.get("nifi.security.user.oidc.discovery.url"), + Some( + &"https://keycloak.mycorp.org/realms/sdp/.well-known/openid-configuration" + .to_owned() + ) + ); + assert_eq!( + properties.get("nifi.security.user.oidc.truststore.strategy"), + Some(&"JDK".to_owned()) + ); + + assert!(properties.contains_key("nifi.security.user.oidc.client.id")); + assert!(properties.contains_key("nifi.security.user.oidc.client.secret")); + } +} From 29c3573bababe49ca3ba49eb34f613f7defcbd4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Liebau?= Date: Mon, 25 Nov 2024 16:15:46 +0100 Subject: [PATCH 5/6] Use patched version of op-rs that hopefully addresses SUP-148. (#717) * Use patched version of op-rs that hopefully addresses SUP-148. * Updated cargo.lock to include new commits in op-rs pr (should be no significant changes, pretty much just comments and tests). * Update revision of PR branch. * Update revision of PR branch. * Update to use released version of operator-rs and add Changelog entry. * Change test condition to look for 'succeeded' instead of 'ready', as ready only becomes 1 for a brief moment and apparently kuttl can miss that.. * Run pre-commit --------- Co-authored-by: Siegfried Weber --- CHANGELOG.md | 2 ++ tests/templates/kuttl/oidc/12_nifi.yaml.j2 | 2 +- tests/templates/kuttl/oidc/20-assert.yaml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef8c5c9d..22ea5218 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ All notable changes to this project will be documented in this file. - Failing to parse one `NifiCluster`/`AuthenticationClass` should no longer cause the whole operator to stop functioning ([#662]). - NiFi will now use the JDK trust store when an OIDC provider uses WebPKI as CA ([#686], [#698]). - Fix OIDC endpoint construction in case the `rootPath` does not have a trailing slash ([#718]). +- BREAKING: Use distinct ServiceAccounts for the Stacklets, so that multiple Stacklets can be deployed in one namespace. Existing Stacklets will use the newly created ServiceAccounts after restart ([#717]). ### Removed @@ -51,6 +52,7 @@ All notable changes to this project will be documented in this file. [#698]: https://github.com/stackabletech/nifi-operator/pull/698 [#702]: https://github.com/stackabletech/nifi-operator/pull/702 [#708]: https://github.com/stackabletech/nifi-operator/pull/708 +[#717]: https://github.com/stackabletech/nifi-operator/pull/717 [#718]: https://github.com/stackabletech/nifi-operator/pull/718 ## [24.7.0] - 2024-07-24 diff --git a/tests/templates/kuttl/oidc/12_nifi.yaml.j2 b/tests/templates/kuttl/oidc/12_nifi.yaml.j2 index 957bbbf1..764ab8bf 100644 --- a/tests/templates/kuttl/oidc/12_nifi.yaml.j2 +++ b/tests/templates/kuttl/oidc/12_nifi.yaml.j2 @@ -30,7 +30,7 @@ spec: clusterConfig: authentication: - authenticationClass: nifi-oidc-auth-class-$NAMESPACE - oidc: + oidc: clientCredentialsSecret: nifi-oidc-client sensitiveProperties: keySecret: nifi-sensitive-property-key diff --git a/tests/templates/kuttl/oidc/20-assert.yaml b/tests/templates/kuttl/oidc/20-assert.yaml index ce21f771..47c18ad2 100644 --- a/tests/templates/kuttl/oidc/20-assert.yaml +++ b/tests/templates/kuttl/oidc/20-assert.yaml @@ -8,4 +8,4 @@ kind: Job metadata: name: oidc-login-test status: - ready: 1 # wait for the test job to start before streaming its logs in the next test step + succeeded: 1 # wait for the test job to start before streaming its logs in the next test step From ed0a86975b0a4d1623bbf1cb118b3e8bfe7c0be5 Mon Sep 17 00:00:00 2001 From: Siegfried Weber Date: Tue, 26 Nov 2024 17:27:10 +0100 Subject: [PATCH 6/6] Update changelog --- CHANGELOG.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22ea5218..bb0203a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Fixed + +- Fix OIDC endpoint construction in case the `rootPath` does not have a trailing slash ([#718]). +- BREAKING: Use distinct ServiceAccounts for the Stacklets, so that multiple Stacklets can be + deployed in one namespace. Existing Stacklets will use the newly created ServiceAccounts after + restart ([#717]). + +[#717]: https://github.com/stackabletech/nifi-operator/pull/717 +[#718]: https://github.com/stackabletech/nifi-operator/pull/718 + ## [24.11.0] - 2024-11-18 ### Added @@ -30,8 +40,6 @@ All notable changes to this project will be documented in this file. - Switch from `flow.xml.gz` to `flow.json.gz` to allow seamless upgrades to version 2.0 ([#675]). - Failing to parse one `NifiCluster`/`AuthenticationClass` should no longer cause the whole operator to stop functioning ([#662]). - NiFi will now use the JDK trust store when an OIDC provider uses WebPKI as CA ([#686], [#698]). -- Fix OIDC endpoint construction in case the `rootPath` does not have a trailing slash ([#718]). -- BREAKING: Use distinct ServiceAccounts for the Stacklets, so that multiple Stacklets can be deployed in one namespace. Existing Stacklets will use the newly created ServiceAccounts after restart ([#717]). ### Removed @@ -52,8 +60,6 @@ All notable changes to this project will be documented in this file. [#698]: https://github.com/stackabletech/nifi-operator/pull/698 [#702]: https://github.com/stackabletech/nifi-operator/pull/702 [#708]: https://github.com/stackabletech/nifi-operator/pull/708 -[#717]: https://github.com/stackabletech/nifi-operator/pull/717 -[#718]: https://github.com/stackabletech/nifi-operator/pull/718 ## [24.7.0] - 2024-07-24