diff --git a/CHANGELOG.md b/CHANGELOG.md index 064d5e1..6c4db55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - Support objectOverrides using `.spec.objectOverrides` on the `Listener`. See [objectOverrides concepts page](https://docs.stackable.tech/home/nightly/concepts/overrides/#object-overrides) for details ([#364]). +- Support serviceOverrides using `.spec.serviceOverrides` on the `ListenerClass` ([#365]). ### Changed @@ -20,6 +21,7 @@ All notable changes to this project will be documented in this file. [#360]: https://github.com/stackabletech/listener-operator/pull/360 [#363]: https://github.com/stackabletech/listener-operator/pull/363 [#364]: https://github.com/stackabletech/listener-operator/pull/364 +[#365]: https://github.com/stackabletech/listener-operator/pull/365 ## [25.11.0] - 2025-11-07 diff --git a/Cargo.lock b/Cargo.lock index a95a12e..d4148d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1375,7 +1375,7 @@ dependencies = [ [[package]] name = "k8s-version" version = "0.1.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#402911782469fd689308f3e57c38ad249dec83f3" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#99ceb14e2466a8928b0075ad21c4aafeb54dcfe0" dependencies = [ "darling 0.23.0", "regex", @@ -2582,8 +2582,8 @@ dependencies = [ [[package]] name = "stackable-operator" -version = "0.102.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#402911782469fd689308f3e57c38ad249dec83f3" +version = "0.104.0" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#99ceb14e2466a8928b0075ad21c4aafeb54dcfe0" dependencies = [ "chrono", "clap", @@ -2621,7 +2621,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#402911782469fd689308f3e57c38ad249dec83f3" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#99ceb14e2466a8928b0075ad21c4aafeb54dcfe0" dependencies = [ "darling 0.23.0", "proc-macro2", @@ -2632,7 +2632,7 @@ dependencies = [ [[package]] name = "stackable-shared" version = "0.0.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#402911782469fd689308f3e57c38ad249dec83f3" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#99ceb14e2466a8928b0075ad21c4aafeb54dcfe0" dependencies = [ "chrono", "k8s-openapi", @@ -2649,7 +2649,7 @@ dependencies = [ [[package]] name = "stackable-telemetry" version = "0.6.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#402911782469fd689308f3e57c38ad249dec83f3" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#99ceb14e2466a8928b0075ad21c4aafeb54dcfe0" dependencies = [ "axum", "clap", @@ -2673,7 +2673,7 @@ dependencies = [ [[package]] name = "stackable-versioned" version = "0.8.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#402911782469fd689308f3e57c38ad249dec83f3" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#99ceb14e2466a8928b0075ad21c4aafeb54dcfe0" dependencies = [ "schemars", "serde", @@ -2686,7 +2686,7 @@ dependencies = [ [[package]] name = "stackable-versioned-macros" version = "0.8.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#402911782469fd689308f3e57c38ad249dec83f3" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#99ceb14e2466a8928b0075ad21c4aafeb54dcfe0" dependencies = [ "convert_case", "darling 0.23.0", diff --git a/Cargo.nix b/Cargo.nix index b900d65..43e8bf8 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -4301,8 +4301,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "402911782469fd689308f3e57c38ad249dec83f3"; - sha256 = "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy"; + rev = "99ceb14e2466a8928b0075ad21c4aafeb54dcfe0"; + sha256 = "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh"; }; libName = "k8s_version"; authors = [ @@ -8549,13 +8549,13 @@ rec { }; "stackable-operator" = rec { crateName = "stackable-operator"; - version = "0.102.0"; + version = "0.104.0"; edition = "2024"; workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "402911782469fd689308f3e57c38ad249dec83f3"; - sha256 = "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy"; + rev = "99ceb14e2466a8928b0075ad21c4aafeb54dcfe0"; + sha256 = "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh"; }; libName = "stackable_operator"; authors = [ @@ -8723,8 +8723,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "402911782469fd689308f3e57c38ad249dec83f3"; - sha256 = "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy"; + rev = "99ceb14e2466a8928b0075ad21c4aafeb54dcfe0"; + sha256 = "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh"; }; procMacro = true; libName = "stackable_operator_derive"; @@ -8758,8 +8758,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "402911782469fd689308f3e57c38ad249dec83f3"; - sha256 = "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy"; + rev = "99ceb14e2466a8928b0075ad21c4aafeb54dcfe0"; + sha256 = "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh"; }; libName = "stackable_shared"; authors = [ @@ -8840,8 +8840,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "402911782469fd689308f3e57c38ad249dec83f3"; - sha256 = "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy"; + rev = "99ceb14e2466a8928b0075ad21c4aafeb54dcfe0"; + sha256 = "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh"; }; libName = "stackable_telemetry"; authors = [ @@ -8950,8 +8950,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "402911782469fd689308f3e57c38ad249dec83f3"; - sha256 = "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy"; + rev = "99ceb14e2466a8928b0075ad21c4aafeb54dcfe0"; + sha256 = "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh"; }; libName = "stackable_versioned"; authors = [ @@ -8994,8 +8994,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "402911782469fd689308f3e57c38ad249dec83f3"; - sha256 = "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy"; + rev = "99ceb14e2466a8928b0075ad21c4aafeb54dcfe0"; + sha256 = "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh"; }; procMacro = true; libName = "stackable_versioned_macros"; diff --git a/Cargo.toml b/Cargo.toml index 039df3e..e057e9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" repository = "https://github.com/stackabletech/listener-operator" [workspace.dependencies] -stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.102.0", features = ["telemetry", "versioned"] } +stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.104.0", features = ["telemetry", "versioned"] } anyhow = "1.0" built = { version = "0.8", features = ["chrono", "git2"] } diff --git a/crate-hashes.json b/crate-hashes.json index 68215a4..3934aee 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -4,12 +4,12 @@ "git+https://github.com/stackabletech/kube-rs?branch=2.0.1-fix-schema-hoisting#kube-derive@2.0.1": "1a7bcl0w1jg71jc4iml0vjp8dpzy71mhxl012grxcy2xp5i6xvgf", "git+https://github.com/stackabletech/kube-rs?branch=2.0.1-fix-schema-hoisting#kube-runtime@2.0.1": "1a7bcl0w1jg71jc4iml0vjp8dpzy71mhxl012grxcy2xp5i6xvgf", "git+https://github.com/stackabletech/kube-rs?branch=2.0.1-fix-schema-hoisting#kube@2.0.1": "1a7bcl0w1jg71jc4iml0vjp8dpzy71mhxl012grxcy2xp5i6xvgf", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#k8s-version@0.1.3": "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#stackable-operator-derive@0.3.1": "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#stackable-operator@0.102.0": "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#stackable-shared@0.0.3": "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#stackable-telemetry@0.6.1": "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#stackable-versioned-macros@0.8.3": "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.102.0#stackable-versioned@0.8.3": "16j834cchvq6psb4lm5fjz6nm04cg3aqhsffyls20y617ky7whpy", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#k8s-version@0.1.3": "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#stackable-operator-derive@0.3.1": "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#stackable-operator@0.104.0": "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#stackable-shared@0.0.3": "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#stackable-telemetry@0.6.1": "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#stackable-versioned-macros@0.8.3": "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.104.0#stackable-versioned@0.8.3": "07cdivnyvrfrznqqm0hqsbvmbng00scv22p39a3wdgfanamjpjsh", "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/helm/listener-operator/crds/crds.yaml b/deploy/helm/listener-operator/crds/crds.yaml index bb58242..fe96eb0 100644 --- a/deploy/helm/listener-operator/crds/crds.yaml +++ b/deploy/helm/listener-operator/crds/crds.yaml @@ -91,6 +91,20 @@ spec: - Local nullable: true type: string + serviceOverrides: + default: + apiVersion: v1 + kind: Service + metadata: {} + description: |- + In the `serviceOverrides` property you can define a + [Service](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#service-v1-core) + to override any property that can be set on a Kubernetes Service. + + This mechanism is similar to the `podOverrides`, which are documented in the + [Pod overrides documentation](https://docs.stackable.tech/home/nightly/concepts/overrides#pod-overrides). + type: object + x-kubernetes-preserve-unknown-fields: true serviceType: description: The method used to access the services. enum: diff --git a/rust/operator-binary/src/listener_controller.rs b/rust/operator-binary/src/listener_controller.rs index 38dd1d3..9d1a4f6 100644 --- a/rust/operator-binary/src/listener_controller.rs +++ b/rust/operator-binary/src/listener_controller.rs @@ -17,6 +17,7 @@ use stackable_operator::{ crd::listener, iter::TryFromIterator, k8s_openapi::{ + DeepMerge, api::core::v1::{Endpoints, Node, PersistentVolume, Service, ServicePort, ServiceSpec}, apimachinery::pkg::apis::meta::v1::LabelSelector, }, @@ -348,7 +349,7 @@ pub async fn reconcile( } }; - let svc = Service { + let mut svc = Service { metadata: ObjectMetaBuilder::new() .namespace(ns) .name(&svc_name) @@ -402,6 +403,12 @@ pub async fn reconcile( }), ..Default::default() }; + + // The overrides need to come last! + svc.merge_from(listener_class.spec.service_overrides.clone()); + // Prevent accidental further modification by removing mutability + let svc = svc; + let svc_ref = ObjectRef::from_obj(&svc); let svc = cluster_resources .add(&ctx.client, svc) diff --git a/tests/templates/kuttl/overrides/00-patch-ns.yaml.j2 b/tests/templates/kuttl/overrides/00-patch-ns.yaml.j2 new file mode 100644 index 0000000..67185ac --- /dev/null +++ b/tests/templates/kuttl/overrides/00-patch-ns.yaml.j2 @@ -0,0 +1,9 @@ +{% if test_scenario['values']['openshift'] == 'true' %} +# see https://github.com/stackabletech/issues/issues/566 +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: kubectl patch namespace $NAMESPACE -p '{"metadata":{"labels":{"pod-security.kubernetes.io/enforce":"privileged"}}}' + timeout: 120 +{% endif %} diff --git a/tests/templates/kuttl/overrides/05-create-listenerclass.yaml b/tests/templates/kuttl/overrides/05-create-listenerclass.yaml new file mode 100644 index 0000000..48c97ba --- /dev/null +++ b/tests/templates/kuttl/overrides/05-create-listenerclass.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: envsubst '$NAMESPACE' < 05_listenerclass.yaml | kubectl apply -n $NAMESPACE -f - diff --git a/tests/templates/kuttl/overrides/05_listenerclass.yaml.j2 b/tests/templates/kuttl/overrides/05_listenerclass.yaml.j2 new file mode 100644 index 0000000..fba0b55 --- /dev/null +++ b/tests/templates/kuttl/overrides/05_listenerclass.yaml.j2 @@ -0,0 +1,17 @@ +--- +apiVersion: listeners.stackable.tech/v1alpha1 +kind: ListenerClass +metadata: + name: listener-operator-test-overrides-$NAMESPACE +spec: + serviceType: ClusterIP + serviceAnnotations: + deprecated: was here + winner: deprecated + serviceOverrides: + metadata: + annotations: + serviceOverrides: was here + winner: serviceOverrides + spec: + sessionAffinity: ClientIP diff --git a/tests/templates/kuttl/overrides/10-assert.yaml.j2 b/tests/templates/kuttl/overrides/10-assert.yaml.j2 new file mode 100644 index 0000000..77276fb --- /dev/null +++ b/tests/templates/kuttl/overrides/10-assert.yaml.j2 @@ -0,0 +1,21 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: listener + annotations: + deprecated: was here + serviceOverrides: was here + listener: was here + winner: listener +spec: + type: ClusterIP + ports: + - name: http + port: 80 + + # Set by ListenerClass.spec.serviceOverrides + sessionAffinity: ClientIP + + # Set by Listener.spec.objectOverrides + internalTrafficPolicy: Local diff --git a/tests/templates/kuttl/overrides/10-create-listener.yaml b/tests/templates/kuttl/overrides/10-create-listener.yaml new file mode 100644 index 0000000..3dd4317 --- /dev/null +++ b/tests/templates/kuttl/overrides/10-create-listener.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: envsubst '$NAMESPACE' < 10_listener.yaml | kubectl apply -n $NAMESPACE -f - diff --git a/tests/templates/kuttl/overrides/10_listener.yaml b/tests/templates/kuttl/overrides/10_listener.yaml new file mode 100644 index 0000000..8fea1c0 --- /dev/null +++ b/tests/templates/kuttl/overrides/10_listener.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: listeners.stackable.tech/v1alpha1 +kind: Listener +metadata: + name: listener +spec: + className: listener-operator-test-overrides-$NAMESPACE + ports: + - name: http + port: 80 + objectOverrides: + - apiVersion: v1 + kind: Service + metadata: + name: listener + namespace: $NAMESPACE + annotations: + listener: was here + winner: listener + spec: + internalTrafficPolicy: Local diff --git a/tests/test-definition.yaml b/tests/test-definition.yaml index 4f28a83..fbfd17e 100644 --- a/tests/test-definition.yaml +++ b/tests/test-definition.yaml @@ -23,6 +23,8 @@ tests: dimensions: - openshift - loadbalancer-allocatenodeports + - name: overrides + dimensions: [] suites: - name: nightly - name: openshift