diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e88aef0..14036ca2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,12 @@ More information can be found in the [Superset database documentation](https://docs.stackable.tech/home/nightly/superset/usage-guide/database-connections) for details ([#722]). - Internal operator refactoring: introduce dereference() and validate() steps in the reconciler ([#731]). - test: Bump vector-aggregator to 0.55.0, replace /graphql call with gRPC call ([#735]). +- Removed the product-config based configuration validation. Config and environment overrides are + now merged directly from the CRD into the validated cluster (including the formerly + properties.yaml-provided `ROW_LIMIT` and `SUPERSET_WEBSERVER_TIMEOUT` recommended values), the + Flask config writer is consumed from `stackable-operator` (`v2::flask_config_writer`), and the + `product-config` crate dependency is dropped. The `--product-config` CLI flag and + `PRODUCT_CONFIG` env var are now no-ops ([#738]). [#717]: https://github.com/stackabletech/superset-operator/pull/717 [#719]: https://github.com/stackabletech/superset-operator/pull/719 @@ -33,6 +39,7 @@ [#726]: https://github.com/stackabletech/superset-operator/pull/726 [#731]: https://github.com/stackabletech/superset-operator/pull/731 [#735]: https://github.com/stackabletech/superset-operator/pull/735 +[#738]: https://github.com/stackabletech/superset-operator/pull/738 ## [26.3.0] - 2026-03-16 diff --git a/Cargo.lock b/Cargo.lock index 9b4c258d..7a936d4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1481,6 +1481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f300e415e2134745ef75f04562dd0145405c2f7fd92065db029ac4b16b57fe90" dependencies = [ "jsonptr", + "schemars", "serde", "serde_json", "thiserror 1.0.69", @@ -1525,11 +1526,11 @@ dependencies = [ [[package]] name = "k8s-version" version = "0.1.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "darling", "regex", - "snafu 0.9.0", + "snafu 0.9.1", ] [[package]] @@ -1850,9 +1851,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "opentelemetry" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0" +checksum = "b0142c63252a9e054e68a4c61a5778f7b14f576274d593f8ce883d191a099682" dependencies = [ "futures-core", "futures-sink", @@ -1864,9 +1865,9 @@ dependencies = [ [[package]] name = "opentelemetry-appender-tracing" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef6a1ac5ca3accf562b8c306fa8483c85f4390f768185ab775f242f7fe8fdcc2" +checksum = "2c0080f0dc1d7c786f467cd85a4e395fcab11ee852004f39a29a18ab7c25d837" dependencies = [ "opentelemetry", "tracing", @@ -1876,9 +1877,9 @@ dependencies = [ [[package]] name = "opentelemetry-http" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" +checksum = "5683015d09e2df236ef005b17f6f196f0d5f6313c4fa43a7b6a53b52776e4331" dependencies = [ "async-trait", "bytes", @@ -1889,9 +1890,9 @@ dependencies = [ [[package]] name = "opentelemetry-otlp" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f69cd6acbb9af919df949cd1ec9e5e7fdc2ef15d234b6b795aaa525cc02f71f" +checksum = "9966929966d17620d7c316c643ba62631826e10021409357772d5eea84f62c35" dependencies = [ "http", "opentelemetry", @@ -1903,14 +1904,14 @@ dependencies = [ "thiserror 2.0.18", "tokio", "tonic", - "tracing", + "tonic-types", ] [[package]] name = "opentelemetry-proto" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f" +checksum = "56d658ba1faf63f7b9c492cfbe6e0ec365440a16132d3270c1065f7b33f1b638" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -1921,21 +1922,22 @@ dependencies = [ [[package]] name = "opentelemetry-semantic-conventions" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e62e29dfe041afb8ed2a6c9737ab57db4907285d999ef8ad3a59092a36bdc846" +checksum = "6ca2f98a0437b427b4b08f19f1caa3c44db885a202bc12cfea13d6c702243d68" [[package]] name = "opentelemetry_sdk" -version = "0.31.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd" +checksum = "9b59f80e1ac4d5ff7a2db8fb6c80badb7f0f3f858211fba08dd9aaec750894f9" dependencies = [ "futures-channel", "futures-executor", "futures-util", "opentelemetry", "percent-encoding", + "portable-atomic", "rand 0.9.4", "thiserror 2.0.18", "tokio", @@ -2218,6 +2220,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "prost-types" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +dependencies = [ + "prost", +] + [[package]] name = "quote" version = "1.0.45" @@ -2357,9 +2368,9 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "reqwest" -version = "0.12.28" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ "base64", "bytes", @@ -2375,9 +2386,6 @@ dependencies = [ "log", "percent-encoding", "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", "sync_wrapper", "tokio", "tower", @@ -2820,11 +2828,11 @@ dependencies = [ [[package]] name = "snafu" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1d4bced6a69f90b2056c03dcff2c4737f98d6fb9e0853493996e1d253ca29c6" +checksum = "d1a012328be2e3f5d5f6f3218147ca02588cea4cb865e876849ab6debcf36522" dependencies = [ - "snafu-derive 0.9.0", + "snafu-derive 0.9.1", ] [[package]] @@ -2852,9 +2860,9 @@ dependencies = [ [[package]] name = "snafu-derive" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54254b8531cafa275c5e096f62d48c81435d1015405a91198ddb11e967301d40" +checksum = "5f103c50866b8743da9429b8a581d81a27c2d3a9c4ac7df8f8571c1dd7896eda" dependencies = [ "heck", "proc-macro2", @@ -2897,7 +2905,7 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stackable-certs" version = "0.4.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "const-oid", "ecdsa", @@ -2909,7 +2917,7 @@ dependencies = [ "rsa", "sha2", "signature", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-shared", "tokio", "tokio-rustls", @@ -2921,7 +2929,7 @@ dependencies = [ [[package]] name = "stackable-operator" version = "0.111.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "base64", "clap", @@ -2933,6 +2941,7 @@ dependencies = [ "futures 0.3.32", "http", "indexmap", + "java-properties", "jiff", "json-patch", "k8s-openapi", @@ -2945,7 +2954,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-operator-derive", "stackable-shared", "stackable-telemetry", @@ -2957,12 +2966,14 @@ dependencies = [ "tracing-appender", "tracing-subscriber", "url", + "uuid", + "xml", ] [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "darling", "proc-macro2", @@ -2972,8 +2983,8 @@ dependencies = [ [[package]] name = "stackable-shared" -version = "0.1.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +version = "0.1.1" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "jiff", "k8s-openapi", @@ -2982,7 +2993,7 @@ dependencies = [ "semver", "serde", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "strum", "time", ] @@ -2998,12 +3009,11 @@ dependencies = [ "fnv", "futures 0.3.32", "indoc", - "product-config", "rstest", "serde", "serde_json", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-operator", "strum", "tokio", @@ -3012,8 +3022,8 @@ dependencies = [ [[package]] name = "stackable-telemetry" -version = "0.6.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +version = "0.6.4" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "axum", "clap", @@ -3024,7 +3034,7 @@ dependencies = [ "opentelemetry-semantic-conventions", "opentelemetry_sdk", "pin-project", - "snafu 0.9.0", + "snafu 0.9.1", "strum", "tokio", "tower", @@ -3037,21 +3047,21 @@ dependencies = [ [[package]] name = "stackable-versioned" version = "0.10.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "kube", "schemars", "serde", "serde_json", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-versioned-macros", ] [[package]] name = "stackable-versioned-macros" version = "0.10.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "convert_case", "convert_case_extras", @@ -3069,7 +3079,7 @@ dependencies = [ [[package]] name = "stackable-webhook" version = "0.9.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "arc-swap", "async-trait", @@ -3085,7 +3095,7 @@ dependencies = [ "rand 0.9.4", "serde", "serde_json", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-certs", "stackable-shared", "stackable-telemetry", @@ -3421,6 +3431,17 @@ dependencies = [ "tonic", ] +[[package]] +name = "tonic-types" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a875a902255423d34c1f20838ab374126db8eb41625b7947a1d54113b0b7399" +dependencies = [ + "prost", + "prost-types", + "tonic", +] + [[package]] name = "tower" version = "0.5.3" @@ -3532,9 +3553,9 @@ dependencies = [ [[package]] name = "tracing-opentelemetry" -version = "0.32.1" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac28f2d093c6c477eaa76b23525478f38de514fa9aeb1285738d4b97a9552fc" +checksum = "adbc64cba7137545b8044cb1fe9814f7aacf3c6b5f9b45be8bb5db538befdb26" dependencies = [ "js-sys", "opentelemetry", @@ -3650,6 +3671,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.1" @@ -3945,9 +3976,9 @@ dependencies = [ [[package]] name = "xml" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8aa498d22c9bbaf482329839bc5620c46be275a19a812e9a22a2b07529a642a" +checksum = "636f85e5ca6488e96401b61eb7de54f4e44755c988af0f52cf90230c312a1a89" [[package]] name = "yoke" diff --git a/Cargo.nix b/Cargo.nix index d77e5e01..421ad43c 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -4714,6 +4714,11 @@ rec { name = "jsonptr"; packageId = "jsonptr"; } + { + name = "schemars"; + packageId = "schemars"; + optional = true; + } { name = "serde"; packageId = "serde"; @@ -4729,6 +4734,10 @@ rec { } ]; devDependencies = [ + { + name = "schemars"; + packageId = "schemars"; + } { name = "serde_json"; packageId = "serde_json"; @@ -4740,7 +4749,7 @@ rec { "schemars" = [ "dep:schemars" ]; "utoipa" = [ "dep:utoipa" ]; }; - resolvedDefaultFeatures = [ "default" "diff" ]; + resolvedDefaultFeatures = [ "default" "diff" "schemars" ]; }; "jsonpath-rust" = rec { crateName = "jsonpath-rust"; @@ -4866,8 +4875,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "k8s_version"; @@ -4886,7 +4895,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } ]; features = { @@ -6067,9 +6076,9 @@ rec { }; "opentelemetry" = rec { crateName = "opentelemetry"; - version = "0.31.0"; + version = "0.32.0"; edition = "2021"; - sha256 = "18629xsj4rsyiby9aj511q6wcw6s9m09gx3ymw1yjcvix1mcsjxq"; + sha256 = "10ln14d1jgc8rvw97mblc9blzcgpg1bimim4d170b7ia4mijq55h"; dependencies = [ { name = "futures-core"; @@ -6106,24 +6115,24 @@ rec { ]; features = { "default" = [ "trace" "metrics" "logs" "internal-logs" "futures" ]; + "experimental_metrics_bound_instruments" = [ "metrics" ]; "futures" = [ "futures-core" "futures-sink" "pin-project-lite" ]; "futures-core" = [ "dep:futures-core" ]; "futures-sink" = [ "dep:futures-sink" ]; "internal-logs" = [ "tracing" ]; "pin-project-lite" = [ "dep:pin-project-lite" ]; - "spec_unstable_logs_enabled" = [ "logs" ]; "testing" = [ "trace" ]; "thiserror" = [ "dep:thiserror" ]; "trace" = [ "futures" "thiserror" ]; "tracing" = [ "dep:tracing" ]; }; - resolvedDefaultFeatures = [ "default" "futures" "futures-core" "futures-sink" "internal-logs" "logs" "metrics" "pin-project-lite" "spec_unstable_logs_enabled" "thiserror" "trace" "tracing" ]; + resolvedDefaultFeatures = [ "default" "futures" "futures-core" "futures-sink" "internal-logs" "logs" "metrics" "pin-project-lite" "thiserror" "trace" "tracing" ]; }; "opentelemetry-appender-tracing" = rec { crateName = "opentelemetry-appender-tracing"; - version = "0.31.1"; + version = "0.32.0"; edition = "2021"; - sha256 = "1hnwizzgfhpjfnvml638yy846py8hf2gl1n3p1igbk1srb2ilspg"; + sha256 = "0dyq4myan64sl8wly02jx0gb3jjz7575mn3w8rpphz0xvkq8001c"; libName = "opentelemetry_appender_tracing"; dependencies = [ { @@ -6166,18 +6175,15 @@ rec { ]; features = { "experimental_metadata_attributes" = [ "dep:tracing-log" ]; - "experimental_use_tracing_span_context" = [ "tracing-opentelemetry" ]; "log" = [ "dep:log" ]; - "spec_unstable_logs_enabled" = [ "opentelemetry/spec_unstable_logs_enabled" ]; - "tracing-opentelemetry" = [ "dep:tracing-opentelemetry" ]; }; resolvedDefaultFeatures = [ "default" ]; }; "opentelemetry-http" = rec { crateName = "opentelemetry-http"; - version = "0.31.0"; + version = "0.32.0"; edition = "2021"; - sha256 = "0pc5nw1ds8v8w0nvyall39m92v8m1xl1p3vwvxk6nkhrffdd19np"; + sha256 = "0ca3drvm4fx5nskl7yn42dimy3bg35ppzc85y1p27pz215fh30sn"; libName = "opentelemetry_http"; dependencies = [ { @@ -6213,16 +6219,16 @@ rec { "internal-logs" = [ "opentelemetry/internal-logs" ]; "reqwest" = [ "dep:reqwest" ]; "reqwest-blocking" = [ "dep:reqwest" "reqwest/blocking" ]; - "reqwest-rustls" = [ "dep:reqwest" "reqwest/rustls-tls-native-roots" ]; - "reqwest-rustls-webpki-roots" = [ "dep:reqwest" "reqwest/rustls-tls-webpki-roots" ]; + "reqwest-rustls" = [ "dep:reqwest" "reqwest/default-tls" ]; + "reqwest-rustls-webpki-roots" = [ "dep:reqwest" "reqwest/default-tls" "reqwest/webpki-roots" ]; }; - resolvedDefaultFeatures = [ "internal-logs" "reqwest" "reqwest-blocking" ]; + resolvedDefaultFeatures = [ "reqwest" "reqwest-blocking" ]; }; "opentelemetry-otlp" = rec { crateName = "opentelemetry-otlp"; - version = "0.31.1"; + version = "0.32.0"; edition = "2021"; - sha256 = "07zp0b62b9dajnvvcd6j2ppw5zg7wp4ixka9z6fr3bxrrdmcss8z"; + sha256 = "0d9cys2flpidfxbr6h1103hjc633cax47ihnqgbj0xnicscr4rlr"; libName = "opentelemetry_otlp"; dependencies = [ { @@ -6283,10 +6289,9 @@ rec { usesDefaultFeatures = false; } { - name = "tracing"; - packageId = "tracing"; + name = "tonic-types"; + packageId = "tonic-types"; optional = true; - usesDefaultFeatures = false; } ]; devDependencies = [ @@ -6311,16 +6316,19 @@ rec { ]; features = { "default" = [ "http-proto" "reqwest-blocking-client" "trace" "metrics" "logs" "internal-logs" ]; + "experimental-grpc-retry" = [ "grpc-tonic" "opentelemetry_sdk/experimental_async_runtime" "opentelemetry_sdk/rt-tokio" ]; + "experimental-http-retry" = [ "opentelemetry_sdk/experimental_async_runtime" "opentelemetry_sdk/rt-tokio" "tokio" "httpdate" ]; "flate2" = [ "dep:flate2" ]; - "grpc-tonic" = [ "tonic" "prost" "http" "tokio" "opentelemetry-proto/gen-tonic" ]; + "grpc-tonic" = [ "tonic" "tonic-types" "prost" "http" "tokio" "opentelemetry-proto/gen-tonic" ]; "gzip-http" = [ "flate2" ]; "gzip-tonic" = [ "tonic/gzip" ]; "http" = [ "dep:http" ]; "http-json" = [ "serde_json" "prost" "opentelemetry-http" "opentelemetry-proto/gen-tonic-messages" "opentelemetry-proto/with-serde" "http" "trace" "metrics" ]; "http-proto" = [ "prost" "opentelemetry-http" "opentelemetry-proto/gen-tonic-messages" "http" "trace" "metrics" ]; + "httpdate" = [ "dep:httpdate" ]; "hyper-client" = [ "opentelemetry-http/hyper" ]; "integration-testing" = [ "tonic" "prost" "tokio/full" "trace" "logs" ]; - "internal-logs" = [ "tracing" "opentelemetry_sdk/internal-logs" "opentelemetry-http/internal-logs" ]; + "internal-logs" = [ "opentelemetry_sdk/internal-logs" "opentelemetry/internal-logs" ]; "logs" = [ "opentelemetry/logs" "opentelemetry_sdk/logs" "opentelemetry-proto/logs" ]; "metrics" = [ "opentelemetry/metrics" "opentelemetry_sdk/metrics" "opentelemetry-proto/metrics" ]; "opentelemetry-http" = [ "dep:opentelemetry-http" ]; @@ -6333,27 +6341,27 @@ rec { "serde" = [ "dep:serde" ]; "serde_json" = [ "dep:serde_json" ]; "serialize" = [ "serde" "serde_json" ]; - "tls" = [ "tonic/tls-ring" ]; + "tls" = [ "tls-ring" ]; "tls-aws-lc" = [ "tonic/tls-aws-lc" ]; "tls-provider-agnostic" = [ "tonic/_tls-any" ]; "tls-ring" = [ "tonic/tls-ring" ]; - "tls-roots" = [ "tls" "tonic/tls-native-roots" ]; - "tls-webpki-roots" = [ "tls" "tonic/tls-webpki-roots" ]; + "tls-roots" = [ "tonic/tls-native-roots" ]; + "tls-webpki-roots" = [ "tonic/tls-webpki-roots" ]; "tokio" = [ "dep:tokio" ]; "tonic" = [ "dep:tonic" ]; + "tonic-types" = [ "dep:tonic-types" ]; "trace" = [ "opentelemetry/trace" "opentelemetry_sdk/trace" "opentelemetry-proto/trace" ]; - "tracing" = [ "dep:tracing" ]; "zstd" = [ "dep:zstd" ]; "zstd-http" = [ "zstd" ]; "zstd-tonic" = [ "tonic/zstd" ]; }; - resolvedDefaultFeatures = [ "default" "grpc-tonic" "gzip-tonic" "http" "http-proto" "internal-logs" "logs" "metrics" "opentelemetry-http" "prost" "reqwest" "reqwest-blocking-client" "tokio" "tonic" "trace" "tracing" ]; + resolvedDefaultFeatures = [ "default" "grpc-tonic" "gzip-tonic" "http" "http-proto" "internal-logs" "logs" "metrics" "opentelemetry-http" "prost" "reqwest" "reqwest-blocking-client" "tokio" "tonic" "tonic-types" "trace" ]; }; "opentelemetry-proto" = rec { crateName = "opentelemetry-proto"; - version = "0.31.0"; + version = "0.32.0"; edition = "2021"; - sha256 = "03xkjsjrsm7zkkx5gascqd9bg2z20wymm06l16cyxsp5dpq5s5x7"; + sha256 = "0f5ny4rpnpq6q5q34b8k2q548rf31rpbxkwjqjwzfqxg3yx5imjn"; libName = "opentelemetry_proto"; dependencies = [ { @@ -6397,30 +6405,29 @@ rec { "const-hex" = [ "dep:const-hex" ]; "default" = [ "full" ]; "full" = [ "gen-tonic" "trace" "logs" "metrics" "zpages" "with-serde" "internal-logs" ]; - "gen-tonic" = [ "gen-tonic-messages" "tonic/channel" ]; - "gen-tonic-messages" = [ "tonic" "tonic-prost" "prost" ]; + "gen-tonic" = [ "gen-tonic-messages" "tonic" "tonic-prost" "tonic/channel" ]; + "gen-tonic-messages" = [ "prost" ]; "internal-logs" = [ "opentelemetry/internal-logs" ]; "logs" = [ "opentelemetry/logs" "opentelemetry_sdk/logs" ]; "metrics" = [ "opentelemetry/metrics" "opentelemetry_sdk/metrics" ]; "prost" = [ "dep:prost" ]; "schemars" = [ "dep:schemars" ]; "serde" = [ "dep:serde" ]; - "serde_json" = [ "dep:serde_json" ]; "testing" = [ "opentelemetry/testing" ]; "tonic" = [ "dep:tonic" ]; "tonic-prost" = [ "dep:tonic-prost" ]; "trace" = [ "opentelemetry/trace" "opentelemetry_sdk/trace" ]; "with-schemars" = [ "schemars" ]; - "with-serde" = [ "serde" "const-hex" "base64" "serde_json" ]; + "with-serde" = [ "serde" "const-hex" "base64" ]; "zpages" = [ "trace" ]; }; resolvedDefaultFeatures = [ "gen-tonic" "gen-tonic-messages" "logs" "metrics" "prost" "tonic" "tonic-prost" "trace" ]; }; "opentelemetry-semantic-conventions" = rec { crateName = "opentelemetry-semantic-conventions"; - version = "0.31.0"; + version = "0.32.0"; edition = "2021"; - sha256 = "0in8plv2l2ar7anzi7lrbll0fjfvaymkg5vc5bnvibs1w3gjjbp6"; + sha256 = "0s1x4h1cgmhkxb7i5g02la2vhkf4lg5g26cgn2s2gd1p0j5gk8kc"; libName = "opentelemetry_semantic_conventions"; features = { }; @@ -6428,9 +6435,9 @@ rec { }; "opentelemetry_sdk" = rec { crateName = "opentelemetry_sdk"; - version = "0.31.0"; + version = "0.32.1"; edition = "2021"; - sha256 = "1gbjsggdxfpjbanjvaxa3nq32vfa37i3v13dvx4gsxhrk7sy8jp1"; + sha256 = "1ycl11syranrinhgn4c2hlzhyzyvpa06ryxq5mxgzmf4387ghncv"; dependencies = [ { name = "futures-channel"; @@ -6456,6 +6463,13 @@ rec { packageId = "percent-encoding"; optional = true; } + { + name = "portable-atomic"; + packageId = "portable-atomic"; + usesDefaultFeatures = false; + target = { target, features }: (!("64" == target."has_atomic" or null)); + features = [ "fallback" ]; + } { name = "rand"; packageId = "rand 0.9.4"; @@ -6480,10 +6494,18 @@ rec { optional = true; } ]; + devDependencies = [ + { + name = "tokio"; + packageId = "tokio"; + usesDefaultFeatures = false; + features = [ "macros" "rt-multi-thread" ]; + } + ]; features = { "default" = [ "trace" "metrics" "logs" "internal-logs" ]; "experimental_logs_batch_log_processor_with_async_runtime" = [ "logs" "experimental_async_runtime" ]; - "experimental_logs_concurrent_log_processor" = [ "logs" ]; + "experimental_metrics_bound_instruments" = [ "metrics" "opentelemetry/experimental_metrics_bound_instruments" ]; "experimental_metrics_custom_reader" = [ "metrics" ]; "experimental_metrics_disable_name_validation" = [ "metrics" ]; "experimental_metrics_periodicreader_with_async_runtime" = [ "metrics" "experimental_async_runtime" ]; @@ -6500,15 +6522,14 @@ rec { "rt-tokio-current-thread" = [ "tokio/rt" "tokio/time" "tokio-stream" "experimental_async_runtime" ]; "serde" = [ "dep:serde" ]; "serde_json" = [ "dep:serde_json" ]; - "spec_unstable_logs_enabled" = [ "logs" "opentelemetry/spec_unstable_logs_enabled" ]; "spec_unstable_metrics_views" = [ "metrics" ]; - "testing" = [ "opentelemetry/testing" "trace" "metrics" "logs" "rt-tokio" "rt-tokio-current-thread" "tokio/macros" "tokio/rt-multi-thread" ]; + "testing" = [ "opentelemetry/testing" "trace" "metrics" "logs" "tokio/sync" ]; "tokio" = [ "dep:tokio" ]; "tokio-stream" = [ "dep:tokio-stream" ]; "trace" = [ "opentelemetry/trace" "rand" "percent-encoding" ]; "url" = [ "dep:url" ]; }; - resolvedDefaultFeatures = [ "default" "experimental_async_runtime" "internal-logs" "logs" "metrics" "percent-encoding" "rand" "rt-tokio" "spec_unstable_logs_enabled" "tokio" "tokio-stream" "trace" ]; + resolvedDefaultFeatures = [ "default" "experimental_async_runtime" "internal-logs" "logs" "metrics" "percent-encoding" "rand" "rt-tokio" "tokio" "tokio-stream" "trace" ]; }; "ordered-float" = rec { crateName = "ordered-float"; @@ -7017,7 +7038,7 @@ rec { "default" = [ "fallback" ]; "serde" = [ "dep:serde" ]; }; - resolvedDefaultFeatures = [ "require-cas" ]; + resolvedDefaultFeatures = [ "fallback" "require-cas" ]; }; "portable-atomic-util" = rec { crateName = "portable-atomic-util"; @@ -7285,6 +7306,34 @@ rec { ]; }; + "prost-types" = rec { + crateName = "prost-types"; + version = "0.14.3"; + edition = "2021"; + sha256 = "1mrxrciryfgi6a0vmrgyj3g27r9hdhlgwkq71cgv3icbvg5w94c9"; + libName = "prost_types"; + authors = [ + "Dan Burkert " + "Lucio Franco " + "Casper Meijn " + "Tokio Contributors " + ]; + dependencies = [ + { + name = "prost"; + packageId = "prost"; + usesDefaultFeatures = false; + features = [ "derive" ]; + } + ]; + features = { + "arbitrary" = [ "dep:arbitrary" ]; + "chrono" = [ "dep:chrono" ]; + "default" = [ "std" ]; + "std" = [ "prost/std" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; "quote" = rec { crateName = "quote"; version = "1.0.45"; @@ -7714,9 +7763,9 @@ rec { }; "reqwest" = rec { crateName = "reqwest"; - version = "0.12.28"; + version = "0.13.4"; edition = "2021"; - sha256 = "0iqidijghgqbzl3bjg5hb4zmigwa4r612bgi0yiq0c90b6jkrpgd"; + sha256 = "1hy1plns9krbh3h1dy2sdjygsfkdcnxm6pbxdi0ya9b5vq8mi711"; authors = [ "Sean McArthur " ]; @@ -7733,7 +7782,7 @@ rec { name = "futures-channel"; packageId = "futures-channel"; optional = true; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "futures-core"; @@ -7753,62 +7802,44 @@ rec { { name = "http-body"; packageId = "http-body"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "http-body-util"; packageId = "http-body-util"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "hyper"; packageId = "hyper"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "http1" "client" ]; } { name = "hyper-util"; packageId = "hyper-util"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "http1" "client" "client-legacy" "client-proxy" "tokio" ]; } { name = "js-sys"; packageId = "js-sys"; - target = { target, features }: ("wasm32" == target."arch" or null); + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); } { name = "log"; packageId = "log"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "percent-encoding"; packageId = "percent-encoding"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "pin-project-lite"; packageId = "pin-project-lite"; - target = { target, features }: (!("wasm32" == target."arch" or null)); - } - { - name = "serde"; - packageId = "serde"; - } - { - name = "serde_json"; - packageId = "serde_json"; - optional = true; - } - { - name = "serde_json"; - packageId = "serde_json"; - target = { target, features }: ("wasm32" == target."arch" or null); - } - { - name = "serde_urlencoded"; - packageId = "serde_urlencoded"; + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "sync_wrapper"; @@ -7819,27 +7850,27 @@ rec { name = "tokio"; packageId = "tokio"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "net" "time" ]; } { name = "tower"; packageId = "tower"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "retry" "timeout" "util" ]; } { name = "tower-http"; packageId = "tower-http"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "follow-redirect" ]; } { name = "tower-service"; packageId = "tower-service"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "url"; @@ -7848,17 +7879,17 @@ rec { { name = "wasm-bindgen"; packageId = "wasm-bindgen"; - target = { target, features }: ("wasm32" == target."arch" or null); + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); } { name = "wasm-bindgen-futures"; packageId = "wasm-bindgen-futures"; - target = { target, features }: ("wasm32" == target."arch" or null); + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); } { name = "web-sys"; packageId = "web-sys"; - target = { target, features }: ("wasm32" == target."arch" or null); + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); features = [ "AbortController" "AbortSignal" "Headers" "Request" "RequestInit" "RequestMode" "Response" "Window" "FormData" "Blob" "BlobPropertyBag" "ServiceWorkerGlobalScope" "RequestCredentials" "File" "ReadableStream" "RequestCache" ]; } ]; @@ -7867,33 +7898,27 @@ rec { name = "futures-util"; packageId = "futures-util"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "std" "alloc" ]; } { name = "hyper"; packageId = "hyper"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "http1" "http2" "client" "server" ]; } { name = "hyper-util"; packageId = "hyper-util"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "http1" "http2" "client" "client-legacy" "server-auto" "server-graceful" "tokio" ]; } - { - name = "serde"; - packageId = "serde"; - target = { target, features }: (!("wasm32" == target."arch" or null)); - features = [ "derive" ]; - } { name = "tokio"; packageId = "tokio"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "macros" "rt-multi-thread" ]; } { @@ -7905,40 +7930,37 @@ rec { { name = "wasm-bindgen"; packageId = "wasm-bindgen"; - target = { target, features }: ("wasm32" == target."arch" or null); + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); features = [ "serde-serialize" ]; } ]; features = { + "__native-tls" = [ "dep:hyper-tls" "dep:native-tls-crate" "__tls" "dep:tokio-native-tls" ]; + "__native-tls-alpn" = [ "native-tls-crate?/alpn" "hyper-tls?/alpn" ]; "__rustls" = [ "dep:hyper-rustls" "dep:tokio-rustls" "dep:rustls" "__tls" ]; - "__rustls-ring" = [ "hyper-rustls?/ring" "tokio-rustls?/ring" "rustls?/ring" "quinn?/ring" ]; + "__rustls-aws-lc-rs" = [ "hyper-rustls?/aws-lc-rs" "tokio-rustls?/aws-lc-rs" "rustls?/aws-lc-rs" "quinn?/rustls-aws-lc-rs" ]; "__tls" = [ "dep:rustls-pki-types" "tokio/io-util" ]; "blocking" = [ "dep:futures-channel" "futures-channel?/sink" "dep:futures-util" "futures-util?/io" "futures-util?/sink" "tokio/sync" ]; "brotli" = [ "tower-http/decompression-br" ]; "charset" = [ "dep:encoding_rs" "dep:mime" ]; "cookies" = [ "dep:cookie_crate" "dep:cookie_store" ]; "default" = [ "default-tls" "charset" "http2" "system-proxy" ]; - "default-tls" = [ "dep:hyper-tls" "dep:native-tls-crate" "__tls" "dep:tokio-native-tls" ]; + "default-tls" = [ "rustls" ]; "deflate" = [ "tower-http/decompression-deflate" ]; + "form" = [ "dep:serde" "dep:serde_urlencoded" ]; "gzip" = [ "tower-http/decompression-gzip" ]; - "h2" = [ "dep:h2" ]; "hickory-dns" = [ "dep:hickory-resolver" "dep:once_cell" ]; - "http2" = [ "h2" "hyper/http2" "hyper-util/http2" "hyper-rustls?/http2" ]; - "http3" = [ "rustls-tls-manual-roots" "dep:h3" "dep:h3-quinn" "dep:quinn" "tokio/macros" ]; - "json" = [ "dep:serde_json" ]; - "macos-system-configuration" = [ "system-proxy" ]; + "http2" = [ "dep:h2" "hyper/http2" "hyper-util/http2" "hyper-rustls?/http2" ]; + "http3" = [ "rustls" "dep:h3" "dep:h3-quinn" "dep:quinn" "tokio/macros" ]; + "json" = [ "dep:serde" "dep:serde_json" ]; "multipart" = [ "dep:mime_guess" "dep:futures-util" ]; - "native-tls" = [ "default-tls" ]; - "native-tls-alpn" = [ "native-tls" "native-tls-crate?/alpn" "hyper-tls?/alpn" ]; - "native-tls-vendored" = [ "native-tls" "native-tls-crate?/vendored" ]; - "rustls-tls" = [ "rustls-tls-webpki-roots" ]; - "rustls-tls-manual-roots" = [ "rustls-tls-manual-roots-no-provider" "__rustls-ring" ]; - "rustls-tls-manual-roots-no-provider" = [ "__rustls" ]; - "rustls-tls-native-roots" = [ "rustls-tls-native-roots-no-provider" "__rustls-ring" ]; - "rustls-tls-native-roots-no-provider" = [ "dep:rustls-native-certs" "hyper-rustls?/native-tokio" "__rustls" ]; - "rustls-tls-no-provider" = [ "rustls-tls-manual-roots-no-provider" ]; - "rustls-tls-webpki-roots" = [ "rustls-tls-webpki-roots-no-provider" "__rustls-ring" ]; - "rustls-tls-webpki-roots-no-provider" = [ "dep:webpki-roots" "hyper-rustls?/webpki-tokio" "__rustls" ]; + "native-tls" = [ "__native-tls" "__native-tls-alpn" ]; + "native-tls-no-alpn" = [ "__native-tls" ]; + "native-tls-vendored" = [ "__native-tls" "native-tls-crate?/vendored" "__native-tls-alpn" ]; + "native-tls-vendored-no-alpn" = [ "__native-tls" "native-tls-crate?/vendored" ]; + "query" = [ "dep:serde" "dep:serde_urlencoded" ]; + "rustls" = [ "__rustls-aws-lc-rs" "dep:rustls-platform-verifier" "__rustls" ]; + "rustls-no-provider" = [ "dep:rustls-platform-verifier" "__rustls" ]; "stream" = [ "tokio/fs" "dep:futures-util" "dep:tokio-util" "dep:wasm-streams" ]; "system-proxy" = [ "hyper-util/client-proxy-system" ]; "zstd" = [ "tower-http/decompression-zstd" ]; @@ -9312,29 +9334,25 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "default" "rust_1_61" "rust_1_65" "std" ]; }; - "snafu 0.9.0" = rec { + "snafu 0.9.1" = rec { crateName = "snafu"; - version = "0.9.0"; + version = "0.9.1"; edition = "2018"; - sha256 = "1ii9r99x5qcn754m624yzgb9hzvkqkrcygf0aqh0pyb9dbnvrm6i"; + sha256 = "08k5yfydxdlshivfhrdq9km8qn02r93q28gkyvazbqz2icr1586i"; authors = [ "Jake Goulding " ]; dependencies = [ { name = "snafu-derive"; - packageId = "snafu-derive 0.9.0"; + packageId = "snafu-derive 0.9.1"; } ]; features = { - "backtrace" = [ "dep:backtrace" ]; - "backtraces-impl-backtrace-crate" = [ "backtrace" ]; + "backtraces-impl-backtrace-crate" = [ "dep:backtrace" ]; "default" = [ "std" "rust_1_81" ]; - "futures" = [ "futures-core-crate" "pin-project" ]; - "futures-core-crate" = [ "dep:futures-core-crate" ]; - "futures-crate" = [ "dep:futures-crate" ]; - "internal-dev-dependencies" = [ "futures-crate" ]; - "pin-project" = [ "dep:pin-project" ]; + "futures" = [ "dep:futures-core" "dep:pin-project" ]; + "internal-dev-dependencies" = [ "dep:futures" ]; "std" = [ "alloc" ]; "unstable-provider-api" = [ "snafu-derive/unstable-provider-api" ]; }; @@ -9402,11 +9420,11 @@ rec { }; resolvedDefaultFeatures = [ "rust_1_61" ]; }; - "snafu-derive 0.9.0" = rec { + "snafu-derive 0.9.1" = rec { crateName = "snafu-derive"; - version = "0.9.0"; + version = "0.9.1"; edition = "2018"; - sha256 = "0h0x61kyj4fvilcr2nj02l85shw1ika64vq9brf2gyna662ln9al"; + sha256 = "1nkfi7bis72pz3w7vb64m79w49qsv20sbf19jkd471vbhr83q42z"; procMacro = true; libName = "snafu_derive"; authors = [ @@ -9432,7 +9450,7 @@ rec { name = "syn"; packageId = "syn 2.0.117"; usesDefaultFeatures = false; - features = [ "clone-impls" "derive" "full" "parsing" "printing" "proc-macro" ]; + features = [ "clone-impls" "derive" "full" "parsing" "printing" "proc-macro" "visit-mut" ]; } ]; features = { @@ -9540,8 +9558,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_certs"; @@ -9600,7 +9618,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-shared"; @@ -9643,8 +9661,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_operator"; @@ -9695,6 +9713,10 @@ rec { name = "indexmap"; packageId = "indexmap"; } + { + name = "java-properties"; + packageId = "java-properties"; + } { name = "jiff"; packageId = "jiff"; @@ -9702,6 +9724,7 @@ rec { { name = "json-patch"; packageId = "json-patch"; + features = [ "schemars" ]; } { name = "k8s-openapi"; @@ -9751,7 +9774,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-operator-derive"; @@ -9805,12 +9828,21 @@ rec { packageId = "url"; features = [ "serde" ]; } + { + name = "uuid"; + packageId = "uuid"; + } + { + name = "xml"; + packageId = "xml"; + } ]; features = { "certs" = [ "dep:stackable-certs" ]; + "client-feature-gates" = [ "dep:winnow" ]; "crds" = [ "dep:stackable-versioned" ]; "default" = [ "crds" ]; - "full" = [ "crds" "certs" "time" "webhook" "kube-ws" ]; + "full" = [ "client-feature-gates" "crds" "certs" "time" "webhook" "kube-ws" ]; "kube-ws" = [ "kube/ws" ]; "time" = [ "stackable-shared/time" ]; "webhook" = [ "dep:stackable-webhook" ]; @@ -9823,8 +9855,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; procMacro = true; @@ -9854,12 +9886,12 @@ rec { }; "stackable-shared" = rec { crateName = "stackable-shared"; - version = "0.1.0"; + version = "0.1.1"; edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_shared"; @@ -9904,7 +9936,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "strum"; @@ -9974,10 +10006,6 @@ rec { name = "indoc"; packageId = "indoc"; } - { - name = "product-config"; - packageId = "product-config"; - } { name = "serde"; packageId = "serde"; @@ -9989,7 +10017,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-operator"; @@ -10041,12 +10069,12 @@ rec { }; "stackable-telemetry" = rec { crateName = "stackable-telemetry"; - version = "0.6.3"; + version = "0.6.4"; edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_telemetry"; @@ -10090,7 +10118,7 @@ rec { { name = "opentelemetry_sdk"; packageId = "opentelemetry_sdk"; - features = [ "rt-tokio" "logs" "rt-tokio" "spec_unstable_logs_enabled" ]; + features = [ "rt-tokio" "logs" "rt-tokio" ]; } { name = "pin-project"; @@ -10098,7 +10126,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "strum"; @@ -10155,8 +10183,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_versioned"; @@ -10190,7 +10218,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-versioned-macros"; @@ -10205,8 +10233,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; procMacro = true; @@ -10273,8 +10301,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_webhook"; @@ -10347,7 +10375,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-certs"; @@ -11438,6 +11466,33 @@ rec { } ]; + }; + "tonic-types" = rec { + crateName = "tonic-types"; + version = "0.14.5"; + edition = "2021"; + sha256 = "16bk1cxi2m0xgaabf98nnj7dn9j16ymkh27jq4s3shjm4a85m1ra"; + libName = "tonic_types"; + authors = [ + "Lucio Franco " + "Rafael Lemos " + ]; + dependencies = [ + { + name = "prost"; + packageId = "prost"; + } + { + name = "prost-types"; + packageId = "prost-types"; + } + { + name = "tonic"; + packageId = "tonic"; + usesDefaultFeatures = false; + } + ]; + }; "tower" = rec { crateName = "tower"; @@ -11894,9 +11949,9 @@ rec { }; "tracing-opentelemetry" = rec { crateName = "tracing-opentelemetry"; - version = "0.32.1"; + version = "0.33.0"; edition = "2021"; - sha256 = "1z2jjmxbkm1qawlb3bm99x8xwf4g8wjkbcknm9z4fv1w14nqzhhs"; + sha256 = "09nvxy5m7nxmifz4b6szdcyczapp2jcgxcac0jw4ax8klz5n9g5d"; libName = "tracing_opentelemetry"; dependencies = [ { @@ -12298,6 +12353,66 @@ rec { }; resolvedDefaultFeatures = [ "default" ]; }; + "uuid" = rec { + crateName = "uuid"; + version = "1.23.2"; + edition = "2021"; + sha256 = "1xy942s4z0bi8p3441wvd4ry3hx6ry1c7s6fgrr38462xqybhn6j"; + authors = [ + "Ashley Mannix" + "Dylan DPC" + "Hunar Roop Kahlon" + ]; + dependencies = [ + { + name = "js-sys"; + packageId = "js-sys"; + optional = true; + usesDefaultFeatures = false; + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)) && (builtins.elem "atomics" targetFeatures)); + } + { + name = "wasm-bindgen"; + packageId = "wasm-bindgen"; + optional = true; + usesDefaultFeatures = false; + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); + } + ]; + devDependencies = [ + { + name = "wasm-bindgen"; + packageId = "wasm-bindgen"; + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); + } + ]; + features = { + "arbitrary" = [ "dep:arbitrary" ]; + "atomic" = [ "dep:atomic" ]; + "borsh" = [ "dep:borsh" "dep:borsh-derive" ]; + "bytemuck" = [ "dep:bytemuck" ]; + "default" = [ "std" ]; + "fast-rng" = [ "rng" "dep:rand" ]; + "js" = [ "dep:wasm-bindgen" "dep:js-sys" ]; + "md5" = [ "dep:md-5" ]; + "rng" = [ "dep:getrandom" ]; + "rng-getrandom" = [ "rng" "dep:getrandom" "uuid-rng-internal-lib" "uuid-rng-internal-lib/getrandom" ]; + "rng-rand" = [ "rng" "dep:rand" "uuid-rng-internal-lib" "uuid-rng-internal-lib/rand" ]; + "serde" = [ "dep:serde_core" ]; + "sha1" = [ "dep:sha1_smol" ]; + "slog" = [ "dep:slog" ]; + "std" = [ "wasm-bindgen?/std" "js-sys?/std" ]; + "uuid-rng-internal-lib" = [ "dep:uuid-rng-internal-lib" ]; + "v1" = [ "atomic" ]; + "v3" = [ "md5" ]; + "v4" = [ "rng" ]; + "v5" = [ "sha1" ]; + "v6" = [ "atomic" ]; + "v7" = [ "rng" ]; + "zerocopy" = [ "dep:zerocopy" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; "valuable" = rec { crateName = "valuable"; version = "0.1.1"; @@ -13956,9 +14071,9 @@ rec { }; "xml" = rec { crateName = "xml"; - version = "1.2.1"; + version = "1.3.0"; edition = "2021"; - sha256 = "0ak4k990faralbli5a0rb8kvwihccb2rp0r94d4azfy94a6lkamq"; + sha256 = "128s58qhq8whrx90zbw8r5algr7lakgbf7mn05jfk234rbjqavv3"; authors = [ "Vladimir Matveev " "Kornel (https://github.com/kornelski)" diff --git a/Cargo.toml b/Cargo.toml index ff9518a7..35091154 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ edition = "2021" repository = "https://github.com/stackabletech/superset-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.111.1", features = ["webhook"] } anyhow = "1.0" @@ -29,6 +28,7 @@ strum = { version = "0.28", features = ["derive"] } tokio = { version = "1.40", features = ["full"] } tracing = "0.1" -[patch."https://github.com/stackabletech/operator-rs"] +[patch."https://github.com/stackabletech/operator-rs.git"] +stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "smooth-operator" } # 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 86f2b840..5b0037c5 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,12 +1,12 @@ { - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#k8s-version@0.1.3": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-certs@0.4.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-operator-derive@0.3.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-operator@0.111.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-shared@0.1.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-telemetry@0.6.3": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-versioned-macros@0.10.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-versioned@0.10.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-webhook@0.9.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#k8s-version@0.1.3": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-certs@0.4.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator-derive@0.3.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator@0.111.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-shared@0.1.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-telemetry@0.6.4": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned-macros@0.10.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned@0.10.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-webhook@0.9.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", "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/deploy/config-spec/properties.yaml b/deploy/config-spec/properties.yaml index e063e334..9bd8c3b2 100644 --- a/deploy/config-spec/properties.yaml +++ b/deploy/config-spec/properties.yaml @@ -2,45 +2,4 @@ version: 0.1.0 spec: units: [] -properties: - - property: &rowLimit - propertyNames: - - name: "ROW_LIMIT" - kind: - type: "file" - file: "superset_config.py" - datatype: - type: "integer" - defaultValues: - - fromVersion: "0.0.0" - value: "50000" - recommendedValues: - - fromVersion: "0.0.0" - value: "50000" - roles: - - name: "node" - required: false - asOfVersion: "0.0.0" - description: "Row limit when requesting chart data. Corresponds to ROW_LIMIT" - - property: &webserverTimeout - propertyNames: - - name: "SUPERSET_WEBSERVER_TIMEOUT" - kind: - type: "file" - file: "superset_config.py" - datatype: - type: "integer" - defaultValues: - - fromVersion: "0.0.0" - value: "60" # 1 min - recommendedValues: - # The default timeout of Superset is 60s which is way to low when querying "big data" systems. - # Especially Trino queries often take longer. - # see [the Superset docs](https://superset.apache.org/docs/frequently-asked-questions#why-are-my-queries-timing-out). - - fromVersion: "0.0.0" - value: "300" # 5 min - roles: - - name: "node" - required: true - asOfVersion: "0.0.0" - description: "Maximum number of seconds a Superset request can take before timing out. This settings effect the maximum duration a query to an underlying datasource can take. If you get timeout errors before your query returns the result you can need to increase this timeout. Corresponds to SUPERSET_WEBSERVER_TIMEOUT" +properties: [] diff --git a/deploy/helm/superset-operator/configs/properties.yaml b/deploy/helm/superset-operator/configs/properties.yaml index e063e334..9bd8c3b2 100644 --- a/deploy/helm/superset-operator/configs/properties.yaml +++ b/deploy/helm/superset-operator/configs/properties.yaml @@ -2,45 +2,4 @@ version: 0.1.0 spec: units: [] -properties: - - property: &rowLimit - propertyNames: - - name: "ROW_LIMIT" - kind: - type: "file" - file: "superset_config.py" - datatype: - type: "integer" - defaultValues: - - fromVersion: "0.0.0" - value: "50000" - recommendedValues: - - fromVersion: "0.0.0" - value: "50000" - roles: - - name: "node" - required: false - asOfVersion: "0.0.0" - description: "Row limit when requesting chart data. Corresponds to ROW_LIMIT" - - property: &webserverTimeout - propertyNames: - - name: "SUPERSET_WEBSERVER_TIMEOUT" - kind: - type: "file" - file: "superset_config.py" - datatype: - type: "integer" - defaultValues: - - fromVersion: "0.0.0" - value: "60" # 1 min - recommendedValues: - # The default timeout of Superset is 60s which is way to low when querying "big data" systems. - # Especially Trino queries often take longer. - # see [the Superset docs](https://superset.apache.org/docs/frequently-asked-questions#why-are-my-queries-timing-out). - - fromVersion: "0.0.0" - value: "300" # 5 min - roles: - - name: "node" - required: true - asOfVersion: "0.0.0" - description: "Maximum number of seconds a Superset request can take before timing out. This settings effect the maximum duration a query to an underlying datasource can take. If you get timeout errors before your query returns the result you can need to increase this timeout. Corresponds to SUPERSET_WEBSERVER_TIMEOUT" +properties: [] diff --git a/docs/modules/superset/pages/reference/commandline-parameters.adoc b/docs/modules/superset/pages/reference/commandline-parameters.adoc index 964229aa..6402afcd 100644 --- a/docs/modules/superset/pages/reference/commandline-parameters.adoc +++ b/docs/modules/superset/pages/reference/commandline-parameters.adoc @@ -2,19 +2,6 @@ This operator accepts the following command line parameters: -== product-config - -*Default value*: `/etc/stackable/superset-operator/config-spec/properties.yaml` - -*Required*: false - -*Multiple values:* false - -[source] ----- -stackable-superset-operator run --product-config /foo/bar/properties.yaml ----- - == watch-namespace *Default value*: All namespaces diff --git a/docs/modules/superset/pages/reference/environment-variables.adoc b/docs/modules/superset/pages/reference/environment-variables.adoc index 7f46bf8f..d07fcd84 100644 --- a/docs/modules/superset/pages/reference/environment-variables.adoc +++ b/docs/modules/superset/pages/reference/environment-variables.adoc @@ -33,32 +33,6 @@ docker run \ oci.stackable.tech/sdp/superset-operator:0.0.0-dev ---- -== PRODUCT_CONFIG - -*Default value*: `/etc/stackable/superset-operator/config-spec/properties.yaml` - -*Required*: false - -*Multiple values*: false - -[source] ----- -export PRODUCT_CONFIG=/foo/bar/properties.yaml -stackable-superset-operator run ----- - -or via docker: - ----- -docker run \ - --name superset-operator \ - --network host \ - --env KUBECONFIG=/home/stackable/.kube/config \ - --env PRODUCT_CONFIG=/my/product/config.yaml \ - --mount type=bind,source="$HOME/.kube/config",target="/home/stackable/.kube/config" \ - oci.stackable.tech/sdp/superset-operator:0.0.0-dev ----- - == WATCH_NAMESPACE *Default value*: All namespaces diff --git a/extra/crds.yaml b/extra/crds.yaml index 5add8d90..51d8f4a0 100644 --- a/extra/crds.yaml +++ b/extra/crds.yaml @@ -335,6 +335,7 @@ spec: properties: superset_config.py: additionalProperties: + nullable: true type: string description: |- Flat key-value overrides for `*.properties`, Hadoop XML, etc. @@ -712,6 +713,7 @@ spec: properties: superset_config.py: additionalProperties: + nullable: true type: string description: |- Flat key-value overrides for `*.properties`, Hadoop XML, etc. @@ -1470,6 +1472,7 @@ spec: properties: superset_config.py: additionalProperties: + nullable: true type: string description: |- Flat key-value overrides for `*.properties`, Hadoop XML, etc. @@ -1847,6 +1850,7 @@ spec: properties: superset_config.py: additionalProperties: + nullable: true type: string description: |- Flat key-value overrides for `*.properties`, Hadoop XML, etc. @@ -2213,6 +2217,7 @@ spec: properties: superset_config.py: additionalProperties: + nullable: true type: string description: |- Flat key-value overrides for `*.properties`, Hadoop XML, etc. @@ -2590,6 +2595,7 @@ spec: properties: superset_config.py: additionalProperties: + nullable: true type: string description: |- Flat key-value overrides for `*.properties`, Hadoop XML, etc. diff --git a/rust/operator-binary/Cargo.toml b/rust/operator-binary/Cargo.toml index bfd455e9..f0ee44a5 100644 --- a/rust/operator-binary/Cargo.toml +++ b/rust/operator-binary/Cargo.toml @@ -9,7 +9,6 @@ repository.workspace = true publish = false [dependencies] -product-config.workspace = true stackable-operator.workspace = true anyhow.workspace = true diff --git a/rust/operator-binary/src/config/mod.rs b/rust/operator-binary/src/config/mod.rs index c09ab723..667a0c22 100644 --- a/rust/operator-binary/src/config/mod.rs +++ b/rust/operator-binary/src/config/mod.rs @@ -1,3 +1,4 @@ pub mod commands; pub mod product_logging; pub mod superset; +pub mod superset_config; diff --git a/rust/operator-binary/src/config/superset_config.rs b/rust/operator-binary/src/config/superset_config.rs new file mode 100644 index 00000000..8404d748 --- /dev/null +++ b/rust/operator-binary/src/config/superset_config.rs @@ -0,0 +1,94 @@ +//! Builds the `superset_config.py` configuration file from the resolved +//! authentication/OPA config plus the per-rolegroup config-file properties. + +use std::{collections::BTreeMap, io::Write}; + +use snafu::{ResultExt, Snafu}; +use stackable_operator::v2::flask_config_writer; + +use super::superset::{self, PYTHON_IMPORTS, add_superset_config, append_celery_connection_config}; +use crate::{ + authorization::opa::{OPA_IMPORTS, SupersetOpaConfigResolved}, + crd::{ + SupersetConfigOptions, authentication::SupersetClientAuthenticationDetailsResolved, + v1alpha1::SupersetCluster, + }, +}; + +/// Marks arbitrary Python code to prepend verbatim to the generated file. +const CONFIG_OVERRIDE_FILE_HEADER_KEY: &str = "FILE_HEADER"; +/// Marks arbitrary Python code to append verbatim to the generated file. +const CONFIG_OVERRIDE_FILE_FOOTER_KEY: &str = "FILE_FOOTER"; + +#[derive(Snafu, Debug)] +pub enum Error { + #[snafu(display("failed to add Superset config settings"))] + AddSupersetConfig { source: superset::Error }, + + #[snafu(display("failed to write the superset config file"))] + WriteConfigFile { + source: flask_config_writer::FlaskAppConfigWriterError, + }, + + #[snafu(display("failed to write the header/footer to the superset config file"))] + WriteHeaderFooter { source: std::io::Error }, +} + +/// Renders the `superset_config.py` contents: operator defaults (derived from the +/// resolved authentication/OPA config) with the per-rolegroup config-file properties +/// applied last, wrapped by the optional `FILE_HEADER`/`FILE_FOOTER` Python blocks. +pub fn build( + superset: &SupersetCluster, + authentication_config: &SupersetClientAuthenticationDetailsResolved, + superset_opa_config: &Option, + config_file_properties: &BTreeMap, +) -> Result { + let mut config_properties = BTreeMap::new(); + let mut imports = PYTHON_IMPORTS.to_vec(); + // TODO: this is true per default for versions 3.0.0 and up. + // We deactivate it here to keep existing functionality. + // However this is a security issue and should be configured properly + // Issue: https://github.com/stackabletech/superset-operator/issues/416 + config_properties.insert("TALISMAN_ENABLED".to_string(), "False".to_string()); + + add_superset_config(&mut config_properties, superset, authentication_config) + .context(AddSupersetConfigSnafu)?; + + // Adding opa configuration properties to config_properties. + // This will be injected as key/value pair in superset_config.py + if let Some(opa_config) = superset_opa_config { + // If opa role mapping is configured, insert CustomOpaSecurityManager import + imports.extend(OPA_IMPORTS); + + config_properties.extend(opa_config.as_config()); + } + + // The order here should be kept in order to preserve overrides. + // No properties should be added after this extend. + config_properties.extend(config_file_properties.clone()); + + let mut config_file = Vec::new(); + + // By removing the keys from `config_properties`, we avoid pasting the Python code into a Python variable as well + // (which would be bad) + if let Some(header) = config_properties.remove(CONFIG_OVERRIDE_FILE_HEADER_KEY) { + writeln!(config_file, "{header}").context(WriteHeaderFooterSnafu)?; + } + let temp_file_footer = config_properties.remove(CONFIG_OVERRIDE_FILE_FOOTER_KEY); + + flask_config_writer::write::( + &mut config_file, + config_properties.iter(), + &imports, + ) + .context(WriteConfigFileSnafu)?; + + // We have to add a python class (no key) and cannot use the superset::config machinery. + append_celery_connection_config(&mut config_file, superset); + + if let Some(footer) = temp_file_footer { + writeln!(config_file, "{footer}").context(WriteHeaderFooterSnafu)?; + } + + Ok(String::from_utf8(config_file).expect("the Flask config writer only emits valid UTF-8")) +} diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index 0918caff..83fc87c5 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -1,10 +1,10 @@ //! Ensures that `Pod`s are configured and running for each [`SupersetCluster`] +pub(crate) mod build; pub mod dereference; pub mod validate; use std::sync::Arc; use const_format::concatcp; -use product_config::ProductConfigManager; use snafu::{ResultExt, Snafu}; use stackable_operator::{ cli::OperatorEnvironmentOptions, @@ -34,7 +34,6 @@ use crate::{ operations::pdb::add_pdbs, resources::{ build_recommended_labels, - configmap::build_rolegroup_config_map, deployment::{build_beat_rolegroup_deployment, build_worker_rolegroup_deployment}, listener::build_group_listener, service::{build_node_rolegroup_headless_service, build_node_rolegroup_metrics_service}, @@ -49,7 +48,6 @@ pub const CONTAINER_IMAGE_BASE_NAME: &str = "superset"; pub struct Ctx { pub client: stackable_operator::client::Client, - pub product_config: ProductConfigManager, pub operator_environment: OperatorEnvironmentOptions, } @@ -160,7 +158,7 @@ pub enum Error { #[snafu(display("failed to build configmap"))] BuildConfigMap { - source: crate::resources::configmap::Error, + source: crate::controller::build::config_map::Error, }, #[snafu(display("failed to create SECRET_KEY secret"))] @@ -202,7 +200,6 @@ pub async fn reconcile_superset( superset, dereferenced, &ctx.operator_environment.image_repository, - &ctx.product_config, ) .context(ValidateSnafu)?; let resolved_product_image = &validated.image; @@ -253,14 +250,13 @@ pub async fn reconcile_superset( for (superset_role, rolegroup_configs) in validated.role_groups.iter() { for (rolegroup_name, validated_rolegroup) in rolegroup_configs.iter() { let rolegroup = superset.rolegroup_ref(superset_role, rolegroup_name); - let rolegroup_config = &validated_rolegroup.product_config_properties; let config = &validated_rolegroup.merged_config; - let rg_configmap = build_rolegroup_config_map( + let rg_configmap = build::config_map::build_rolegroup_config_map( superset, resolved_product_image, &rolegroup, - rolegroup_config, + &validated_rolegroup.config_file_properties, auth_config, superset_opa_config, &config.logging, @@ -303,7 +299,8 @@ pub async fn reconcile_superset( resolved_product_image, superset_role, &rolegroup, - rolegroup_config, + &validated_rolegroup.config_file_properties, + &validated_rolegroup.env_overrides, auth_config, &rbac_sa.name_any(), config, @@ -328,7 +325,7 @@ pub async fn reconcile_superset( resolved_product_image, superset_role, &rolegroup, - rolegroup_config, + &validated_rolegroup.env_overrides, &rbac_sa.name_any(), config, ) @@ -352,7 +349,7 @@ pub async fn reconcile_superset( resolved_product_image, superset_role, &rolegroup, - rolegroup_config, + &validated_rolegroup.env_overrides, &rbac_sa.name_any(), config, ) diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs new file mode 100644 index 00000000..895c044f --- /dev/null +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -0,0 +1,106 @@ +use std::collections::BTreeMap; + +use snafu::{ResultExt, Snafu}; +use stackable_operator::{ + builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder}, + commons::product_image_selection::ResolvedProductImage, + k8s_openapi::api::core::v1::ConfigMap, + product_logging::spec::Logging, + role_utils::RoleGroupRef, +}; + +use crate::{ + authorization::opa::SupersetOpaConfigResolved, + config::{product_logging::extend_config_map_with_log_config, superset_config}, + controller::SUPERSET_CONTROLLER_NAME, + crd::{ + SUPERSET_CONFIG_FILENAME, + authentication::SupersetClientAuthenticationDetailsResolved, + v1alpha1::{Container, SupersetCluster}, + }, + resources::build_recommended_labels, +}; + +#[derive(Snafu, Debug)] +pub enum Error { + #[snafu(display("object is missing metadata to build owner reference"))] + ObjectMissingMetadataForOwnerRef { + source: stackable_operator::builder::meta::Error, + }, + + #[snafu(display("failed to build superset_config.py for {rolegroup}"))] + BuildSupersetConfig { + source: superset_config::Error, + rolegroup: RoleGroupRef, + }, + + #[snafu(display("failed to build Metadata"))] + BuildMetadata { + source: stackable_operator::builder::meta::Error, + }, + + #[snafu(display("failed to build ConfigMap for {rolegroup}"))] + BuildRoleGroupConfig { + source: stackable_operator::builder::configmap::Error, + rolegroup: RoleGroupRef, + }, +} + +type Result = std::result::Result; + +/// The rolegroup [`ConfigMap`] configures the rolegroup based on the configuration given by the administrator +#[allow(clippy::too_many_arguments)] +pub fn build_rolegroup_config_map( + superset: &SupersetCluster, + resolved_product_image: &ResolvedProductImage, + rolegroup: &RoleGroupRef, + config_file_properties: &BTreeMap, + authentication_config: &SupersetClientAuthenticationDetailsResolved, + superset_opa_config: &Option, + logging: &Logging, +) -> Result { + let config_file = superset_config::build( + superset, + authentication_config, + superset_opa_config, + config_file_properties, + ) + .with_context(|_| BuildSupersetConfigSnafu { + rolegroup: rolegroup.clone(), + })?; + + let mut cm_builder = ConfigMapBuilder::new(); + + cm_builder + .metadata( + ObjectMetaBuilder::new() + .name_and_namespace(superset) + .name(rolegroup.object_name()) + .ownerreference_from_resource(superset, None, Some(true)) + .context(ObjectMissingMetadataForOwnerRefSnafu)? + .with_recommended_labels(&build_recommended_labels( + superset, + SUPERSET_CONTROLLER_NAME, + &resolved_product_image.app_version_label_value, + &rolegroup.role, + &rolegroup.role_group, + )) + .context(BuildMetadataSnafu)? + .build(), + ) + .add_data(SUPERSET_CONFIG_FILENAME, config_file); + + extend_config_map_with_log_config( + rolegroup, + logging, + &Container::Superset, + &Container::Vector, + &mut cm_builder, + ); + + cm_builder + .build() + .with_context(|_| BuildRoleGroupConfigSnafu { + rolegroup: rolegroup.clone(), + }) +} diff --git a/rust/operator-binary/src/controller/build/mod.rs b/rust/operator-binary/src/controller/build/mod.rs new file mode 100644 index 00000000..7cebb446 --- /dev/null +++ b/rust/operator-binary/src/controller/build/mod.rs @@ -0,0 +1,3 @@ +//! Builders that assemble Kubernetes resources for superset rolegroups. + +pub mod config_map; diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index 9beb9a82..e5768ec0 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -3,19 +3,11 @@ //! Synchronously validates inputs that don't require a Kubernetes client. Produces //! [`ValidatedSupersetCluster`], consumed by the rest of `reconcile_superset`. -use std::{ - collections::{BTreeMap, HashMap}, - str::FromStr, -}; +use std::collections::{BTreeMap, HashMap}; -use product_config::{ProductConfigManager, types::PropertyNameKind}; use snafu::{ResultExt, Snafu}; use stackable_operator::{ commons::product_image_selection::{self, ResolvedProductImage}, - product_config_utils::{ - ValidatedRoleConfigByPropertyKind, transform_all_roles_to_config, - validate_all_roles_and_groups_config, - }, role_utils::GenericRoleConfig, }; use strum::IntoEnumIterator; @@ -25,7 +17,7 @@ use crate::{ built_info::PKG_VERSION, controller::{CONTAINER_IMAGE_BASE_NAME, dereference::DereferencedObjects}, crd::{ - SUPERSET_CONFIG_FILENAME, SupersetRole, + SupersetConfigOptions, SupersetRole, SupersetRoleType, authentication::SupersetClientAuthenticationDetailsResolved, v1alpha1::{SupersetCluster, SupersetConfig}, }, @@ -38,24 +30,8 @@ pub enum Error { source: product_image_selection::Error, }, - #[snafu(display("failed to generate product config"))] - GenerateProductConfig { - source: stackable_operator::product_config_utils::Error, - }, - - #[snafu(display("invalid product config"))] - InvalidProductConfig { - source: stackable_operator::product_config_utils::Error, - }, - #[snafu(display("failed to resolve and merge config for role and role group"))] FailedToResolveConfig { source: crate::crd::Error }, - - #[snafu(display("failed to parse Superset role [{role}]"))] - ParseRole { - source: strum::ParseError, - role: String, - }, } /// Per-role configuration extracted during validation. @@ -66,17 +42,25 @@ pub struct ValidatedRoleConfig { pub group_listener_name: Option, } -/// Per-rolegroup configuration: the merged CRD config plus the product-config properties. +/// Per-rolegroup configuration: the merged CRD config plus the assembled property maps. #[derive(Clone, Debug)] pub struct ValidatedRoleGroupConfig { pub merged_config: SupersetConfig, - pub product_config_properties: HashMap>, + // DESIGN DECISION: this is the COMPLETE superset_config.py key/value map (operator + // recommended values + config-derived values + user configOverrides), not just the + // user overrides. Superset differs from airflow/kafka here: the old product-config + // path injected role-scoped recommended values (ROW_LIMIT, SUPERSET_WEBSERVER_TIMEOUT + // from properties.yaml) and config-derived values (compute_files), and the + // statefulset reads SUPERSET_WEBSERVER_TIMEOUT back out of this map. Alternative: + // store only the user overrides and re-derive the rest at each consumer — rejected, + // it would duplicate the precedence logic and break the statefulset's read-back. + pub config_file_properties: BTreeMap, + pub env_overrides: BTreeMap, } -/// The validated cluster: proves that product-config validation and config merging -/// succeeded for every role and role group before any Kubernetes resources are created. -/// Carries the dereferenced external objects so downstream code has a single "ready to use" -/// view of the cluster. +/// The validated cluster: proves that config merging succeeded for every role and role group +/// before any Kubernetes resources are created. Carries the dereferenced external objects so +/// downstream code has a single "ready to use" view of the cluster. pub struct ValidatedSupersetCluster { pub image: ResolvedProductImage, pub role_groups: HashMap>, @@ -89,7 +73,6 @@ pub fn validate_cluster( superset: &SupersetCluster, dereferenced: DereferencedObjects, image_repository: &str, - product_config_manager: &ProductConfigManager, ) -> Result { let DereferencedObjects { authentication_config, @@ -102,71 +85,53 @@ pub fn validate_cluster( .resolve(CONTAINER_IMAGE_BASE_NAME, image_repository, PKG_VERSION) .context(ResolveProductImageSnafu)?; - let mut roles = HashMap::new(); - for role in SupersetRole::iter() { - if let Some(resolved_role) = superset.get_role(&role) { - roles.insert( - role.to_string(), - ( - vec![ - PropertyNameKind::Env, - PropertyNameKind::File(SUPERSET_CONFIG_FILENAME.into()), - ], - resolved_role.clone(), - ), - ); - } - } - - let role_config = transform_all_roles_to_config(superset, &roles); - let validated_role_config: ValidatedRoleConfigByPropertyKind = - validate_all_roles_and_groups_config( - &resolved_product_image.product_version, - &role_config.context(GenerateProductConfigSnafu)?, - product_config_manager, - false, - false, - ) - .context(InvalidProductConfigSnafu)?; - let mut role_groups = HashMap::new(); let mut role_configs = HashMap::new(); - for (role_name, rolegroup_configs) in validated_role_config.iter() { - let superset_role = SupersetRole::from_str(role_name).context(ParseRoleSnafu { - role: role_name.to_string(), - })?; + for role in SupersetRole::iter() { + let Some(resolved_role) = superset.get_role(&role) else { + continue; + }; role_configs.insert( - superset_role.clone(), + role.clone(), ValidatedRoleConfig { - pdb: superset.generic_role_config(&superset_role).map( + pdb: superset.generic_role_config(&role).map( |GenericRoleConfig { pod_disruption_budget, }| pod_disruption_budget, ), - listener_class: superset_role.listener_class_name(superset), - group_listener_name: superset.group_listener_name(&superset_role), + listener_class: role.listener_class_name(superset), + group_listener_name: superset.group_listener_name(&role), }, ); let mut group_configs = BTreeMap::new(); - for (rolegroup_name, rolegroup_config) in rolegroup_configs.iter() { - let rolegroup_ref = superset.rolegroup_ref(&superset_role, rolegroup_name); + for rolegroup_name in resolved_role.role_groups.keys() { + let rolegroup_ref = superset.rolegroup_ref(&role, rolegroup_name); let merged_config = superset - .merged_config(&superset_role, &rolegroup_ref) + .merged_config(&role, &rolegroup_ref) .context(FailedToResolveConfigSnafu)?; + let (config_file_properties, env_overrides) = collect_role_group_config( + superset, + &role, + resolved_role, + rolegroup_name, + &merged_config, + ); + group_configs.insert( rolegroup_name.clone(), ValidatedRoleGroupConfig { merged_config, - product_config_properties: rolegroup_config.clone(), + config_file_properties, + env_overrides, }, ); } - role_groups.insert(superset_role, group_configs); + role_groups.insert(role, group_configs); } Ok(ValidatedSupersetCluster { @@ -177,3 +142,114 @@ pub fn validate_cluster( opa_config, }) } + +// DESIGN DECISION: the per-rolegroup file map and env map are assembled here, in +// validation, reproducing the old product-config precedence exactly: +// user configOverrides > config-derived values > operator recommended values. +// Alternative: a generic with_validated_config-style merge. The upstream +// stackable_operator::v2::role_utils::with_validated_config is published on the +// smooth-operator branch but not consumed by any operator yet; trino-operator uses +// its own vendored, deliberately simplified variant (framework::role_utils) because +// its JavaCommonConfig cannot implement Merge. Neither variant covers the +// recommended-value injection and the statefulset's file read-back that superset +// needs, so the merge is assembled explicitly here. +fn collect_role_group_config( + superset: &SupersetCluster, + role: &SupersetRole, + resolved_role: &SupersetRoleType, + rolegroup_name: &str, + merged_config: &SupersetConfig, +) -> (BTreeMap, BTreeMap) { + // --- config_file_properties (superset_config.py key/value map) --- + + let mut config_file_properties: BTreeMap = BTreeMap::new(); + + // Step 1: Operator recommended values — Node role only, matching the old + // properties.yaml role-scoping (worker/beat never received these). + if *role == SupersetRole::Node { + // Operator recommended values, formerly injected by product-config from + // deploy/config-spec/properties.yaml (role-scoped to the node role). + // ROW_LIMIT: row limit when requesting chart data. + // SUPERSET_WEBSERVER_TIMEOUT: the default timeout of Superset is 60s which is way + // too low when querying "big data" systems. Especially Trino queries often take + // longer. See https://superset.apache.org/docs/frequently-asked-questions#why-are-my-queries-timing-out + config_file_properties.insert( + SupersetConfigOptions::RowLimit.to_string(), + "50000".to_string(), + ); + config_file_properties.insert( + SupersetConfigOptions::SupersetWebserverTimeout.to_string(), + "300".to_string(), + ); + } + + // Step 2: Config-derived values (all roles) — mirror old compute_files logic. + // row_limit and webserver_timeout are Option<_> on the validated SupersetConfig; + // when set by the user they override the recommended values above. + if let Some(v) = merged_config.row_limit { + config_file_properties.insert(SupersetConfigOptions::RowLimit.to_string(), v.to_string()); + } + if let Some(v) = merged_config.webserver_timeout { + config_file_properties.insert( + SupersetConfigOptions::SupersetWebserverTimeout.to_string(), + v.to_string(), + ); + } + + // Step 3: User configOverrides — role level first, then rolegroup extends on top + // (rolegroup wins). None values in the v2 map are dropped (deletion semantics). + let role_overrides: BTreeMap> = resolved_role + .config + .config_overrides + .superset_config_py + .as_ref() + .map(|o| o.overrides.clone()) + .unwrap_or_default(); + let rg_overrides: BTreeMap> = resolved_role + .role_groups + .get(rolegroup_name) + .and_then(|rg| rg.config.config_overrides.superset_config_py.as_ref()) + .map(|o| o.overrides.clone()) + .unwrap_or_default(); + let mut merged_overrides = role_overrides; + merged_overrides.extend(rg_overrides); + config_file_properties.extend( + merged_overrides + .into_iter() + .filter_map(|(k, v)| v.map(|v| (k, v))), + ); + + // --- env_overrides --- + + // DESIGN DECISION: the MAPBOX secret property is injected first (moved here from + // crd Configuration::compute_env), then user envOverrides (role then rolegroup) + // extend on top so a user-set key wins — the same precedence product-config used. + // Alternative: inject after user overrides (operator wins) — rejected to preserve + // the previous precedence. + let mut env_overrides: BTreeMap = BTreeMap::new(); + + if let Some(mapbox_secret) = &superset.spec.cluster_config.mapbox_secret { + env_overrides.insert( + SupersetConfig::MAPBOX_SECRET_PROPERTY.to_string(), + mapbox_secret.clone(), + ); + } + + env_overrides.extend( + resolved_role + .config + .env_overrides + .iter() + .map(|(k, v)| (k.clone(), v.clone())), + ); + if let Some(rg) = resolved_role.role_groups.get(rolegroup_name) { + env_overrides.extend( + rg.config + .env_overrides + .iter() + .map(|(k, v)| (k.clone(), v.clone())), + ); + } + + (config_file_properties, env_overrides) +} diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index a1e780c5..b6944e6d 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -1,6 +1,3 @@ -use std::collections::BTreeMap; - -use product_config::flask_app_config_writer::{FlaskAppConfigOptions, PythonType}; use serde::{Deserialize, Serialize}; use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ @@ -19,17 +16,19 @@ use stackable_operator::{ fragment::{self, Fragment, ValidationError}, merge::Merge, }, - config_overrides::{KeyValueConfigOverrides, KeyValueOverridesProvider}, deep_merger::ObjectOverrides, k8s_openapi::apimachinery::pkg::api::resource::Quantity, kube::{CustomResource, ResourceExt, runtime::reflector::ObjectRef}, memory::{BinaryMultiple, MemoryQuantity}, - product_config_utils::{self, Configuration}, product_logging::{self, spec::Logging}, role_utils::{GenericRoleConfig, Role, RoleGroupRef}, schemars::{self, JsonSchema}, shared::time::Duration, status::condition::{ClusterCondition, HasStatusCondition}, + v2::{ + config_overrides::KeyValueConfigOverrides, + flask_config_writer::{FlaskAppConfigOptions, PythonType}, + }, versioned::versioned, }; use strum::{Display, EnumIter, EnumString, IntoEnumIterator}; @@ -192,6 +191,8 @@ pub mod versioned { #[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct SupersetConfigOverrides { + // Uses the v2 KeyValueConfigOverrides (Merge-capable, nullable values) to match + // trino/hdfs/airflow/kafka. Resolution happens in controller/validate.rs. #[serde( default, rename = "superset_config.py", @@ -372,18 +373,7 @@ impl Default for v1alpha1::SupersetRoleConfig { } } -impl KeyValueOverridesProvider for v1alpha1::SupersetConfigOverrides { - fn get_key_value_overrides(&self, file: &str) -> BTreeMap> { - match file { - SUPERSET_CONFIG_FILENAME => self - .superset_config_py - .as_ref() - .map(KeyValueConfigOverrides::as_product_config_overrides) - .unwrap_or_default(), - _ => BTreeMap::new(), - } - } -} +// KeyValueOverridesProvider impl removed — override resolution moved to controller/validate.rs::collect_role_group_config. #[derive( Clone, @@ -428,24 +418,6 @@ impl SupersetRole { } } -impl SupersetConfigOptions { - /// Mapping from `SupersetConfigOptions` to the values set in `SupersetConfigFragment`. - /// `None` is returned if either the according option is not set or is not exposed in the - /// `SupersetConfig`. - fn config_type_to_string( - &self, - superset_config: &v1alpha1::SupersetConfigFragment, - ) -> Option { - match self { - SupersetConfigOptions::RowLimit => superset_config.row_limit.map(|v| v.to_string()), - SupersetConfigOptions::SupersetWebserverTimeout => { - superset_config.webserver_timeout.map(|v| v.to_string()) - } - _ => None, - } - } -} - impl FlaskAppConfigOptions for SupersetConfigOptions { fn python_type(&self) -> PythonType { match self { @@ -556,51 +528,8 @@ impl v1alpha1::SupersetConfig { } } -impl Configuration for v1alpha1::SupersetConfigFragment { - type Configurable = v1alpha1::SupersetCluster; - - fn compute_env( - &self, - cluster: &Self::Configurable, - _role_name: &str, - ) -> Result>, product_config_utils::Error> { - let mut result = BTreeMap::new(); - if let Some(msec) = &cluster.spec.cluster_config.mapbox_secret { - result.insert( - v1alpha1::SupersetConfig::MAPBOX_SECRET_PROPERTY.to_string(), - Some(msec.clone()), - ); - } - Ok(result) - } - - fn compute_cli( - &self, - _cluster: &Self::Configurable, - _role_name: &str, - ) -> Result>, product_config_utils::Error> { - Ok(BTreeMap::new()) - } - - fn compute_files( - &self, - _cluster: &Self::Configurable, - _role_name: &str, - file: &str, - ) -> Result>, product_config_utils::Error> { - let mut result = BTreeMap::new(); - - if file == SUPERSET_CONFIG_FILENAME { - for option in SupersetConfigOptions::iter() { - if let Some(value) = option.config_type_to_string(self) { - result.insert(option.to_string(), Some(value)); - } - } - } - - Ok(result) - } -} +// Configuration::compute_env (mapbox secret injection) moved to controller/validate.rs::collect_role_group_config. +// Configuration::compute_files (row_limit / webserver_timeout derivation) moved to controller/validate.rs::collect_role_group_config. impl HasStatusCondition for v1alpha1::SupersetCluster { fn conditions(&self) -> Vec { diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index 6709b422..ea04f865 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -78,9 +78,9 @@ async fn main() -> anyhow::Result<()> { Command::Run(RunArguments { operator_environment, watch_namespace, - product_config, maintenance, common, + .. }) => { // NOTE (@NickLarsenNZ): Before stackable-telemetry was used: // - The console log level was set by `SUPERSET_OPERATOR_LOG`, and is now `CONSOLE_LOG` (when using Tracing::pre_configured). @@ -125,11 +125,6 @@ async fn main() -> anyhow::Result<()> { .run(sigterm_watcher.handle()) .map_err(|err| anyhow!(err).context("failed to run webhook server")); - let product_config = product_config.load(&[ - "deploy/config-spec/properties.yaml", - "/etc/stackable/superset-operator/config-spec/properties.yaml", - ])?; - let superset_event_recorder = Arc::new(Recorder::new( client.as_kube_client(), Reporter { @@ -188,7 +183,6 @@ async fn main() -> anyhow::Result<()> { Arc::new(controller::Ctx { client: client.clone(), operator_environment: operator_environment.clone(), - product_config, }), ) // We can let the reporting happen in the background diff --git a/rust/operator-binary/src/resources/configmap.rs b/rust/operator-binary/src/resources/configmap.rs deleted file mode 100644 index 5f3e4b20..00000000 --- a/rust/operator-binary/src/resources/configmap.rs +++ /dev/null @@ -1,171 +0,0 @@ -use std::{ - collections::{BTreeMap, HashMap}, - io::Write, -}; - -use product_config::{ - flask_app_config_writer::{self}, - types::PropertyNameKind, -}; -use snafu::{ResultExt, Snafu}; -use stackable_operator::{ - builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder}, - commons::product_image_selection::ResolvedProductImage, - k8s_openapi::api::core::v1::ConfigMap, - product_config_utils::{CONFIG_OVERRIDE_FILE_FOOTER_KEY, CONFIG_OVERRIDE_FILE_HEADER_KEY}, - product_logging::spec::Logging, - role_utils::RoleGroupRef, -}; - -use crate::{ - authorization::opa::{OPA_IMPORTS, SupersetOpaConfigResolved}, - config::{self, product_logging::extend_config_map_with_log_config, superset::PYTHON_IMPORTS}, - controller::SUPERSET_CONTROLLER_NAME, - crd::{ - SUPERSET_CONFIG_FILENAME, SupersetConfigOptions, - authentication::SupersetClientAuthenticationDetailsResolved, - v1alpha1::{Container, SupersetCluster}, - }, - resources::build_recommended_labels, -}; - -#[derive(Snafu, Debug)] -pub enum Error { - #[snafu(display("object is missing metadata to build owner reference"))] - ObjectMissingMetadataForOwnerRef { - source: stackable_operator::builder::meta::Error, - }, - - #[snafu(display("failed to add Superset config settings"))] - AddSupersetConfig { source: config::superset::Error }, - - #[snafu(display( - "failed to write to String (Vec to be precise) containing superset config" - ))] - WriteToConfigFileString { source: std::io::Error }, - - #[snafu(display("failed to build Metadata"))] - BuildMetadata { - source: stackable_operator::builder::meta::Error, - }, - - #[snafu(display("failed to build config file for {rolegroup}"))] - BuildRoleGroupConfigFile { - source: flask_app_config_writer::FlaskAppConfigWriterError, - rolegroup: RoleGroupRef, - }, - - #[snafu(display("failed to build ConfigMap for {rolegroup}"))] - BuildRoleGroupConfig { - source: stackable_operator::builder::configmap::Error, - rolegroup: RoleGroupRef, - }, -} - -type Result = std::result::Result; - -/// The rolegroup [`ConfigMap`] configures the rolegroup based on the configuration given by the administrator -#[allow(clippy::too_many_arguments)] -pub fn build_rolegroup_config_map( - superset: &SupersetCluster, - resolved_product_image: &ResolvedProductImage, - rolegroup: &RoleGroupRef, - rolegroup_config: &HashMap>, - authentication_config: &SupersetClientAuthenticationDetailsResolved, - superset_opa_config: &Option, - logging: &Logging, -) -> Result { - let mut config_properties = BTreeMap::new(); - let mut imports = PYTHON_IMPORTS.to_vec(); - // TODO: this is true per default for versions 3.0.0 and up. - // We deactivate it here to keep existing functionality. - // However this is a security issue and should be configured properly - // Issue: https://github.com/stackabletech/superset-operator/issues/416 - config_properties.insert("TALISMAN_ENABLED".to_string(), "False".to_string()); - - config::superset::add_superset_config(&mut config_properties, superset, authentication_config) - .context(AddSupersetConfigSnafu)?; - - // Adding opa configuration properties to config_properties. - // This will be injected as key/value pair in superset_config.py - if let Some(opa_config) = superset_opa_config { - // If opa role mapping is configured, insert CustomOpaSecurityManager import - imports.extend(OPA_IMPORTS); - - config_properties.extend(opa_config.as_config()); - } - - // The order here should be kept in order to preserve overrides. - // No properties should be added after this extend. - config_properties.extend( - rolegroup_config - .get(&PropertyNameKind::File( - SUPERSET_CONFIG_FILENAME.to_string(), - )) - .cloned() - .unwrap_or_default(), - ); - - let mut config_file = Vec::new(); - - // By removing the keys from `config_properties`, we avoid pasting the Python code into a Python variable as well - // (which would be bad) - if let Some(header) = config_properties.remove(CONFIG_OVERRIDE_FILE_HEADER_KEY) { - writeln!(config_file, "{header}").context(WriteToConfigFileStringSnafu)?; - } - let temp_file_footer = config_properties.remove(CONFIG_OVERRIDE_FILE_FOOTER_KEY); - - flask_app_config_writer::write::( - &mut config_file, - config_properties.iter(), - &imports, - ) - .with_context(|_| BuildRoleGroupConfigFileSnafu { - rolegroup: rolegroup.clone(), - })?; - - // We have to add a python class (no key) and cannot use the superset::config machinery. - config::superset::append_celery_connection_config(&mut config_file, superset); - - if let Some(footer) = temp_file_footer { - writeln!(config_file, "{footer}").context(WriteToConfigFileStringSnafu)?; - } - - let mut cm_builder = ConfigMapBuilder::new(); - - cm_builder - .metadata( - ObjectMetaBuilder::new() - .name_and_namespace(superset) - .name(rolegroup.object_name()) - .ownerreference_from_resource(superset, None, Some(true)) - .context(ObjectMissingMetadataForOwnerRefSnafu)? - .with_recommended_labels(&build_recommended_labels( - superset, - SUPERSET_CONTROLLER_NAME, - &resolved_product_image.app_version_label_value, - &rolegroup.role, - &rolegroup.role_group, - )) - .context(BuildMetadataSnafu)? - .build(), - ) - .add_data( - SUPERSET_CONFIG_FILENAME, - String::from_utf8(config_file).unwrap(), - ); - - extend_config_map_with_log_config( - rolegroup, - logging, - &Container::Superset, - &Container::Vector, - &mut cm_builder, - ); - - cm_builder - .build() - .with_context(|_| BuildRoleGroupConfigSnafu { - rolegroup: rolegroup.clone(), - }) -} diff --git a/rust/operator-binary/src/resources/deployment.rs b/rust/operator-binary/src/resources/deployment.rs index 55fc209b..210a1de7 100644 --- a/rust/operator-binary/src/resources/deployment.rs +++ b/rust/operator-binary/src/resources/deployment.rs @@ -1,7 +1,6 @@ -use std::collections::{BTreeMap, HashMap}; +use std::collections::BTreeMap; use indoc::formatdoc; -use product_config::types::PropertyNameKind; use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ builder::{ @@ -34,8 +33,7 @@ use crate::{ controller::SUPERSET_CONTROLLER_NAME, crd::{ APP_NAME, APP_PORT, METRICS_PORT, METRICS_PORT_NAME, PYTHONPATH, STACKABLE_CONFIG_DIR, - STACKABLE_LOG_CONFIG_DIR, STACKABLE_LOG_DIR, SUPERSET_CONFIG_FILENAME, - SupersetConfigOptions, SupersetRole, + STACKABLE_LOG_CONFIG_DIR, STACKABLE_LOG_DIR, SupersetRole, v1alpha1::{Container, SupersetCluster, SupersetConfig}, }, operations::graceful_shutdown::add_graceful_shutdown_config, @@ -80,14 +78,6 @@ pub enum Error { source: stackable_operator::builder::meta::Error, }, - #[snafu(display( - "failed to get the {SUPERSET_CONFIG_FILENAME} file from node or product config" - ))] - MissingSupersetConfigInNodeConfig, - - #[snafu(display("failed to get {timeout} from {SUPERSET_CONFIG_FILENAME} file. It should be set in the product config or by user input", timeout = SupersetConfigOptions::SupersetWebserverTimeout))] - MissingWebServerTimeoutInSupersetConfig, - #[snafu(display("failed to configure logging"))] ConfigureLogging { source: product_logging::framework::LoggingError, @@ -112,7 +102,7 @@ pub fn build_worker_rolegroup_deployment( resolved_product_image: &ResolvedProductImage, superset_role: &SupersetRole, rolegroup_ref: &RoleGroupRef, - node_config: &HashMap>, + env_overrides: &BTreeMap, sa_name: &str, merged_config: &SupersetConfig, ) -> Result { @@ -173,11 +163,7 @@ pub fn build_worker_rolegroup_deployment( celery_broker_connection_details.add_to_container(&mut superset_cb); } - for (name, value) in node_config - .get(&PropertyNameKind::Env) - .cloned() - .unwrap_or_default() - { + for (name, value) in env_overrides.clone() { if name == SupersetConfig::MAPBOX_SECRET_PROPERTY { superset_cb.add_env_var_from_secret( "MAPBOX_API_KEY", @@ -373,7 +359,7 @@ pub fn build_beat_rolegroup_deployment( resolved_product_image: &ResolvedProductImage, superset_role: &SupersetRole, rolegroup_ref: &RoleGroupRef, - node_config: &HashMap>, + env_overrides: &BTreeMap, sa_name: &str, merged_config: &SupersetConfig, ) -> Result { @@ -434,11 +420,7 @@ pub fn build_beat_rolegroup_deployment( celery_broker_connection_details.add_to_container(&mut superset_cb); } - for (name, value) in node_config - .get(&PropertyNameKind::Env) - .cloned() - .unwrap_or_default() - { + for (name, value) in env_overrides.clone() { if name == SupersetConfig::MAPBOX_SECRET_PROPERTY { superset_cb.add_env_var_from_secret( "MAPBOX_API_KEY", diff --git a/rust/operator-binary/src/resources/mod.rs b/rust/operator-binary/src/resources/mod.rs index 3e94d08e..72719347 100644 --- a/rust/operator-binary/src/resources/mod.rs +++ b/rust/operator-binary/src/resources/mod.rs @@ -24,7 +24,6 @@ use crate::{ v1alpha1::SupersetCluster, }; -pub mod configmap; pub mod deployment; pub mod listener; pub mod rbac; diff --git a/rust/operator-binary/src/resources/statefulset.rs b/rust/operator-binary/src/resources/statefulset.rs index 751c5d87..6d061b43 100644 --- a/rust/operator-binary/src/resources/statefulset.rs +++ b/rust/operator-binary/src/resources/statefulset.rs @@ -1,7 +1,6 @@ -use std::collections::{BTreeMap, BTreeSet, HashMap}; +use std::collections::{BTreeMap, BTreeSet}; use indoc::formatdoc; -use product_config::types::PropertyNameKind; use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ builder::{ @@ -92,11 +91,6 @@ pub enum Error { source: stackable_operator::builder::meta::Error, }, - #[snafu(display( - "failed to get the {SUPERSET_CONFIG_FILENAME} file from node or product config" - ))] - MissingSupersetConfigInNodeConfig, - #[snafu(display("failed to get {timeout} from {SUPERSET_CONFIG_FILENAME} file. It should be set in the product config or by user input", timeout = SupersetConfigOptions::SupersetWebserverTimeout))] MissingWebServerTimeoutInSupersetConfig, @@ -140,7 +134,8 @@ pub fn build_server_rolegroup_statefulset( resolved_product_image: &ResolvedProductImage, superset_role: &SupersetRole, rolegroup_ref: &RoleGroupRef, - node_config: &HashMap>, + config_file_properties: &BTreeMap, + env_overrides: &BTreeMap, authentication_config: &SupersetClientAuthenticationDetailsResolved, sa_name: &str, merged_config: &SupersetConfig, @@ -212,11 +207,7 @@ pub fn build_server_rolegroup_statefulset( celery_broker_connection_details.add_to_container(&mut superset_cb); } - for (name, value) in node_config - .get(&PropertyNameKind::Env) - .cloned() - .unwrap_or_default() - { + for (name, value) in env_overrides.clone() { if name == SupersetConfig::MAPBOX_SECRET_PROPERTY { superset_cb.add_env_var_from_secret( "MAPBOX_API_KEY", @@ -237,11 +228,7 @@ pub fn build_server_rolegroup_statefulset( add_authentication_volumes_and_volume_mounts(authentication_config, &mut superset_cb, pb)?; - let webserver_timeout = node_config - .get(&PropertyNameKind::File( - SUPERSET_CONFIG_FILENAME.to_string(), - )) - .context(MissingSupersetConfigInNodeConfigSnafu)? + let webserver_timeout = config_file_properties .get(&SupersetConfigOptions::SupersetWebserverTimeout.to_string()) .context(MissingWebServerTimeoutInSupersetConfigSnafu)?;