From 6c9c18fc495680563396481be09566b488082335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teo=20Klestrup=20R=C3=B6ijezon?= Date: Thu, 4 Aug 2022 16:40:02 +0200 Subject: [PATCH 01/42] Migrate kafka-operator to use lb-operator for exposing brokers This is far from final (for example, we'd need to expose a configurable LoadBalancerClass, for example), but I wanted to see whether lb-op would be a good fit for this operator first. --- .../kafka-operator/templates/roles-kafka.yaml | 8 +- rust/operator/src/kafka_controller.rs | 86 ++++++++----------- rust/operator/src/lib.rs | 24 +----- rust/operator/src/pod_svc_controller.rs | 83 ------------------ 4 files changed, 39 insertions(+), 162 deletions(-) delete mode 100644 rust/operator/src/pod_svc_controller.rs diff --git a/deploy/helm/kafka-operator/templates/roles-kafka.yaml b/deploy/helm/kafka-operator/templates/roles-kafka.yaml index b8e445ba..d1497b4f 100644 --- a/deploy/helm/kafka-operator/templates/roles-kafka.yaml +++ b/deploy/helm/kafka-operator/templates/roles-kafka.yaml @@ -2,10 +2,4 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ include "operator.fullname" . }}-kafka-broker-clusterrole -rules: - - apiGroups: - - "" - resources: - - services - verbs: - - get +rules: [] diff --git a/rust/operator/src/kafka_controller.rs b/rust/operator/src/kafka_controller.rs index d41b7207..d3768009 100644 --- a/rust/operator/src/kafka_controller.rs +++ b/rust/operator/src/kafka_controller.rs @@ -19,16 +19,20 @@ use stackable_operator::{ api::{ apps::v1::{StatefulSet, StatefulSetSpec}, core::v1::{ - ConfigMap, ConfigMapKeySelector, ConfigMapVolumeSource, EmptyDirVolumeSource, - EnvVar, EnvVarSource, ExecAction, ObjectFieldSelector, PodSpec, Probe, + ConfigMap, ConfigMapKeySelector, ConfigMapVolumeSource, EnvVar, EnvVarSource, + EphemeralVolumeSource, ExecAction, PersistentVolumeClaimSpec, + PersistentVolumeClaimTemplate, PodSpec, Probe, ResourceRequirements, SecurityContext, Service, ServiceAccount, ServicePort, ServiceSpec, Volume, }, rbac::v1::{ClusterRole, RoleBinding, RoleRef, Subject}, }, - apimachinery::pkg::apis::meta::v1::LabelSelector, + apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::LabelSelector}, Resource, }, - kube::runtime::{controller::Action, reflector::ObjectRef}, + kube::{ + core::ObjectMeta, + runtime::{controller::Action, reflector::ObjectRef}, + }, labels::{role_group_selector_labels, role_selector_labels}, logging::controller::ReconcilerError, product_config::{ @@ -41,7 +45,6 @@ use strum::{EnumDiscriminants, IntoStaticStr}; use crate::{ discovery::{self, build_discovery_configmaps}, - pod_svc_controller, utils::{self, ObjectRefExt}, ControllerConfig, }; @@ -492,33 +495,6 @@ fn build_broker_rolegroup_statefulset( .context(KafkaVersionParseFailureSnafu)?; let image = format!("docker.stackable.tech/stackable/kafka:{}", image_version); - let container_get_svc = ContainerBuilder::new("get-svc") - .image("docker.stackable.tech/stackable/tools:0.2.0-stackable0.3.0") - .command(vec!["bash".to_string()]) - .args(vec![ - "-euo".to_string(), - "pipefail".to_string(), - "-c".to_string(), - [ - "kubectl get service \"$POD_NAME\" -o jsonpath='{.spec.ports[0].nodePort}'", - "tee /stackable/tmp/nodeport", - ] - .join(" | "), - ]) - .add_env_vars(vec![EnvVar { - name: "POD_NAME".to_string(), - value_from: Some(EnvVarSource { - field_ref: Some(ObjectFieldSelector { - api_version: Some("v1".to_string()), - field_path: "metadata.name".to_string(), - }), - ..EnvVarSource::default() - }), - ..EnvVar::default() - }]) - .add_volume_mount("tmp", "/stackable/tmp") - .build(); - // For most storage classes the mounts will belong to the root user and not be writeable to // other users. // Since kafka runs as the user stackable inside of the container the data directory needs to be @@ -583,18 +559,6 @@ fn build_broker_rolegroup_statefulset( ..EnvVar::default() }); - env.push(EnvVar { - name: "NODE".to_string(), - value_from: Some(EnvVarSource { - field_ref: Some(ObjectFieldSelector { - api_version: Some("v1".to_string()), - field_path: "status.hostIP".to_string(), - }), - ..EnvVarSource::default() - }), - ..EnvVar::default() - }); - // add env var for log4j if set if kafka.spec.log4j.is_some() { env.push(EnvVar { @@ -609,7 +573,7 @@ fn build_broker_rolegroup_statefulset( let jvm_args = format!("-javaagent:/stackable/jmx/jmx_prometheus_javaagent-0.16.1.jar={}:/stackable/jmx/broker.yaml", METRICS_PORT); let zookeeper_override = "--override \"zookeeper.connect=$ZOOKEEPER\""; let advertised_listeners_override = - "--override \"advertised.listeners=PLAINTEXT://$NODE:$(cat /stackable/tmp/nodeport)\""; + "--override \"advertised.listeners=PLAINTEXT://$(cat /stackable/lb/default-address/address):$(cat /stackable/lb/default-address/ports/kafka)\""; let opa_url_override = opa_connect_string.map_or("".to_string(), |opa| { format!("--override \"opa.authorizer.url={}\"", opa) }); @@ -634,7 +598,7 @@ fn build_broker_rolegroup_statefulset( .add_container_port("metrics", METRICS_PORT.into()) .add_volume_mount(LOG_DIRS_VOLUME_NAME, "/stackable/data") .add_volume_mount("config", "/stackable/config") - .add_volume_mount("tmp", "/stackable/tmp") + .add_volume_mount("lb", "/stackable/lb") .resources(resources) .build(); @@ -670,10 +634,8 @@ fn build_broker_rolegroup_statefulset( &rolegroup_ref.role, &rolegroup_ref.role_group, ) - .with_label(pod_svc_controller::LABEL_ENABLE, "true") }) .add_init_container(container_chown) - .add_init_container(container_get_svc) .add_container(container_kafka) .add_container(container_kcat_prober) .add_volume(Volume { @@ -685,8 +647,32 @@ fn build_broker_rolegroup_statefulset( ..Volume::default() }) .add_volume(Volume { - name: "tmp".to_string(), - empty_dir: Some(EmptyDirVolumeSource::default()), + name: "lb".to_string(), + ephemeral: Some(EphemeralVolumeSource { + volume_claim_template: Some(PersistentVolumeClaimTemplate { + metadata: Some(ObjectMeta { + annotations: Some( + [( + "lb.stackable.tech/lb-class".to_string(), + "nodeport".to_string(), + )] + .into(), + ), + ..Default::default() + }), + spec: PersistentVolumeClaimSpec { + access_modes: Some(vec!["ReadWriteMany".to_string()]), + resources: Some(ResourceRequirements { + requests: Some( + [("storage".to_string(), Quantity("1".to_string()))].into(), + ), + ..Default::default() + }), + storage_class_name: Some("lb.stackable.tech".to_string()), + ..Default::default() + }, + }), + }), ..Volume::default() }) .build_template(); diff --git a/rust/operator/src/lib.rs b/rust/operator/src/lib.rs index 98660b2f..f5eb8fb3 100644 --- a/rust/operator/src/lib.rs +++ b/rust/operator/src/lib.rs @@ -1,6 +1,5 @@ mod discovery; mod kafka_controller; -mod pod_svc_controller; mod utils; use std::sync::Arc; @@ -12,7 +11,7 @@ use stackable_operator::{ client::Client, k8s_openapi::api::{ apps::v1::StatefulSet, - core::v1::{ConfigMap, Pod, Service, ServiceAccount}, + core::v1::{ConfigMap, Service, ServiceAccount}, rbac::v1::RoleBinding, }, kube::{api::ListParams, runtime::Controller}, @@ -65,24 +64,5 @@ pub async fn create_controller( report_controller_reconciled(&client, "kafkacluster.kafka.stackable.tech", &res); }); - let pod_svc_controller = Controller::new( - namespace.get_api::(&client), - ListParams::default().labels(&format!("{}=true", pod_svc_controller::LABEL_ENABLE)), - ) - .owns(namespace.get_api::(&client), ListParams::default()) - .shutdown_on_signal() - .run( - pod_svc_controller::reconcile_pod, - pod_svc_controller::error_policy, - Arc::new(pod_svc_controller::Ctx { - client: client.clone(), - }), - ) - .map(|res| { - report_controller_reconciled(&client, "pod-service.kafka.stackable.tech", &res); - }); - - futures::stream::select(kafka_controller, pod_svc_controller) - .collect::<()>() - .await; + kafka_controller.collect::<()>().await; } diff --git a/rust/operator/src/pod_svc_controller.rs b/rust/operator/src/pod_svc_controller.rs deleted file mode 100644 index 8431405b..00000000 --- a/rust/operator/src/pod_svc_controller.rs +++ /dev/null @@ -1,83 +0,0 @@ -use snafu::{OptionExt, ResultExt, Snafu}; -use stackable_kafka_crd::APP_PORT; -use stackable_operator::{ - k8s_openapi::{ - api::core::v1::{Pod, Service, ServicePort, ServiceSpec}, - apimachinery::pkg::apis::meta::v1::OwnerReference, - }, - kube::{core::ObjectMeta, runtime::controller::Action}, - logging::controller::ReconcilerError, -}; -use std::{sync::Arc, time::Duration}; -use strum::{EnumDiscriminants, IntoStaticStr}; - -pub const LABEL_ENABLE: &str = "kafka.stackable.tech/pod-service"; -const LABEL_STS_POD_NAME: &str = "statefulset.kubernetes.io/pod-name"; - -const FIELD_MANAGER_SCOPE: &str = "pod-service"; - -pub struct Ctx { - pub client: stackable_operator::client::Client, -} - -#[derive(Snafu, Debug, EnumDiscriminants)] -#[strum_discriminants(derive(IntoStaticStr))] -#[allow(clippy::enum_variant_names)] -pub enum Error { - #[snafu(display("object has no name"))] - ObjectHasNoName, - #[snafu(display("object has no UID"))] - ObjectHasNoUid, - #[snafu(display("failed to apply Service for Pod"))] - ApplyServiceFailed { - source: stackable_operator::error::Error, - }, -} -type Result = std::result::Result; - -impl ReconcilerError for Error { - fn category(&self) -> &'static str { - ErrorDiscriminants::from(self).into() - } -} - -pub async fn reconcile_pod(pod: Arc, ctx: Arc) -> Result { - tracing::info!("Starting reconcile"); - let name = pod.metadata.name.clone().context(ObjectHasNoNameSnafu)?; - let svc = Service { - metadata: ObjectMeta { - namespace: pod.metadata.namespace.clone(), - name: pod.metadata.name.clone(), - owner_references: Some(vec![OwnerReference { - api_version: "v1".to_string(), - kind: "Pod".to_string(), - name: name.clone(), - uid: pod.metadata.uid.clone().context(ObjectHasNoUidSnafu)?, - ..OwnerReference::default() - }]), - ..ObjectMeta::default() - }, - spec: Some(ServiceSpec { - type_: Some("NodePort".to_string()), - external_traffic_policy: Some("Local".to_string()), - ports: Some(vec![ServicePort { - name: Some("kafka".to_string()), - port: APP_PORT.into(), - ..ServicePort::default() - }]), - selector: Some([(LABEL_STS_POD_NAME.to_string(), name)].into()), - publish_not_ready_addresses: Some(true), - ..ServiceSpec::default() - }), - ..Service::default() - }; - ctx.client - .apply_patch(FIELD_MANAGER_SCOPE, &svc, &svc) - .await - .context(ApplyServiceFailedSnafu)?; - Ok(Action::await_change()) -} - -pub fn error_policy(_error: &Error, _ctx: Arc) -> Action { - Action::requeue(Duration::from_secs(5)) -} From ae8ed3a2b0e615de728baea0ed0aa09e9c4050ec Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Mon, 29 Aug 2022 12:35:30 +0200 Subject: [PATCH 02/42] regenerated charts --- deploy/manifests/roles-kafka.yaml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/deploy/manifests/roles-kafka.yaml b/deploy/manifests/roles-kafka.yaml index 8c6cafbe..669b7940 100644 --- a/deploy/manifests/roles-kafka.yaml +++ b/deploy/manifests/roles-kafka.yaml @@ -3,10 +3,4 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: kafka-operator-kafka-broker-clusterrole -rules: - - apiGroups: - - "" - resources: - - services - verbs: - - get +rules: [] From f57097b4bcf6605689f397d29f3f9e1a96504138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teo=20Klestrup=20R=C3=B6ijezon?= Date: Thu, 8 Sep 2022 16:28:29 +0200 Subject: [PATCH 03/42] Update for lb-operator -> listener-operator rebrand --- rust/operator/src/kafka_controller.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/operator/src/kafka_controller.rs b/rust/operator/src/kafka_controller.rs index d3768009..120c8318 100644 --- a/rust/operator/src/kafka_controller.rs +++ b/rust/operator/src/kafka_controller.rs @@ -573,7 +573,7 @@ fn build_broker_rolegroup_statefulset( let jvm_args = format!("-javaagent:/stackable/jmx/jmx_prometheus_javaagent-0.16.1.jar={}:/stackable/jmx/broker.yaml", METRICS_PORT); let zookeeper_override = "--override \"zookeeper.connect=$ZOOKEEPER\""; let advertised_listeners_override = - "--override \"advertised.listeners=PLAINTEXT://$(cat /stackable/lb/default-address/address):$(cat /stackable/lb/default-address/ports/kafka)\""; + "--override \"advertised.listeners=PLAINTEXT://$(cat /stackable/listener/default-address/address):$(cat /stackable/listener/default-address/ports/kafka)\""; let opa_url_override = opa_connect_string.map_or("".to_string(), |opa| { format!("--override \"opa.authorizer.url={}\"", opa) }); @@ -598,7 +598,7 @@ fn build_broker_rolegroup_statefulset( .add_container_port("metrics", METRICS_PORT.into()) .add_volume_mount(LOG_DIRS_VOLUME_NAME, "/stackable/data") .add_volume_mount("config", "/stackable/config") - .add_volume_mount("lb", "/stackable/lb") + .add_volume_mount("listener", "/stackable/listener") .resources(resources) .build(); @@ -647,13 +647,13 @@ fn build_broker_rolegroup_statefulset( ..Volume::default() }) .add_volume(Volume { - name: "lb".to_string(), + name: "listener".to_string(), ephemeral: Some(EphemeralVolumeSource { volume_claim_template: Some(PersistentVolumeClaimTemplate { metadata: Some(ObjectMeta { annotations: Some( [( - "lb.stackable.tech/lb-class".to_string(), + "listeners.stackable.tech/listener-class".to_string(), "nodeport".to_string(), )] .into(), @@ -668,7 +668,7 @@ fn build_broker_rolegroup_statefulset( ), ..Default::default() }), - storage_class_name: Some("lb.stackable.tech".to_string()), + storage_class_name: Some("listener.stackable.tech".to_string()), ..Default::default() }, }), From 3a72373057e886bb337aeb5100204373d1ce53d4 Mon Sep 17 00:00:00 2001 From: Siegfried Weber Date: Tue, 25 Oct 2022 12:55:24 +0200 Subject: [PATCH 04/42] Use ListenerOperatorVolumeSourceBuilder --- Cargo.lock | 4 +-- Cargo.toml | 3 ++ rust/operator/src/kafka_controller.rs | 42 +++++++-------------------- 3 files changed, 16 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f589758d..e950b58a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1712,7 +1712,7 @@ dependencies = [ [[package]] name = "stackable-operator" version = "0.26.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=0.26.0#420ff75a5d6f689ccd74e0a84127836e28d4dc05" +source = "git+https://github.com//stackabletech/operator-rs.git?branch=listener-volume-builder#b8968914e57f2404b00748c3670bbff25032b9b3" dependencies = [ "chrono", "clap", @@ -1746,7 +1746,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.26.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=0.26.0#420ff75a5d6f689ccd74e0a84127836e28d4dc05" +source = "git+https://github.com//stackabletech/operator-rs.git?branch=listener-volume-builder#b8968914e57f2404b00748c3670bbff25032b9b3" dependencies = [ "darling", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index 98190375..be2d5b18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,3 +2,6 @@ members = [ "rust/crd", "rust/operator", "rust/operator-binary" ] + +[patch."https://github.com/stackabletech/operator-rs.git"] +stackable-operator = { git = "https://github.com//stackabletech/operator-rs.git", branch = "listener-volume-builder" } diff --git a/rust/operator/src/kafka_controller.rs b/rust/operator/src/kafka_controller.rs index 18ac9849..839ca721 100644 --- a/rust/operator/src/kafka_controller.rs +++ b/rust/operator/src/kafka_controller.rs @@ -11,8 +11,9 @@ use stackable_kafka_crd::{ }; use stackable_operator::{ builder::{ - ConfigMapBuilder, ContainerBuilder, ObjectMetaBuilder, PodBuilder, - SecretOperatorVolumeSourceBuilder, SecurityContextBuilder, VolumeBuilder, + ConfigMapBuilder, ContainerBuilder, ListenerOperatorVolumeSourceBuilder, ListenerReference, + ObjectMetaBuilder, PodBuilder, SecretOperatorVolumeSourceBuilder, SecurityContextBuilder, + VolumeBuilder, }, cluster_resources::ClusterResources, commons::{ @@ -26,17 +27,15 @@ use stackable_operator::{ apps::v1::{StatefulSet, StatefulSetSpec}, core::v1::{ ConfigMap, ConfigMapKeySelector, ConfigMapVolumeSource, ContainerPort, EnvVar, - EnvVarSource, EphemeralVolumeSource, ExecAction, ObjectFieldSelector, - PersistentVolumeClaimSpec, PersistentVolumeClaimTemplate, PodSpec, Probe, + EnvVarSource, ExecAction, ObjectFieldSelector, PodSpec, Probe, ResourceRequirements, Service, ServiceAccount, ServicePort, ServiceSpec, Volume, }, rbac::v1::{RoleBinding, RoleRef, Subject}, }, - apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::LabelSelector}, + apimachinery::pkg::apis::meta::v1::LabelSelector, }, kube::{ api::DynamicObject, - core::ObjectMeta, runtime::{controller::Action, reflector::ObjectRef}, Resource, }, @@ -822,31 +821,12 @@ fn build_broker_rolegroup_statefulset( }) .add_volume(Volume { name: "listener".to_string(), - ephemeral: Some(EphemeralVolumeSource { - volume_claim_template: Some(PersistentVolumeClaimTemplate { - metadata: Some(ObjectMeta { - annotations: Some( - [( - "listeners.stackable.tech/listener-class".to_string(), - "nodeport".to_string(), - )] - .into(), - ), - ..Default::default() - }), - spec: PersistentVolumeClaimSpec { - access_modes: Some(vec!["ReadWriteMany".to_string()]), - resources: Some(ResourceRequirements { - requests: Some( - [("storage".to_string(), Quantity("1".to_string()))].into(), - ), - ..Default::default() - }), - storage_class_name: Some("listeners.stackable.tech".to_string()), - ..Default::default() - }, - }), - }), + ephemeral: Some( + ListenerOperatorVolumeSourceBuilder::new(&ListenerReference::ListenerClass( + "nodeport".into(), + )) + .build(), + ), ..Volume::default() }) .build_template(); From f35b23bd0989739122d142451a4933369eaab568 Mon Sep 17 00:00:00 2001 From: Siegfried Weber Date: Wed, 26 Oct 2022 13:12:43 +0200 Subject: [PATCH 05/42] Use shortcut for creating the listener volume --- Cargo.lock | 4 ++-- rust/operator/src/kafka_controller.rs | 16 +++------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e950b58a..28341cfb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1712,7 +1712,7 @@ dependencies = [ [[package]] name = "stackable-operator" version = "0.26.0" -source = "git+https://github.com//stackabletech/operator-rs.git?branch=listener-volume-builder#b8968914e57f2404b00748c3670bbff25032b9b3" +source = "git+https://github.com//stackabletech/operator-rs.git?branch=listener-volume-builder#2d8553b555d4601799525cd0e5d0a1332629e8af" dependencies = [ "chrono", "clap", @@ -1746,7 +1746,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.26.0" -source = "git+https://github.com//stackabletech/operator-rs.git?branch=listener-volume-builder#b8968914e57f2404b00748c3670bbff25032b9b3" +source = "git+https://github.com//stackabletech/operator-rs.git?branch=listener-volume-builder#2d8553b555d4601799525cd0e5d0a1332629e8af" dependencies = [ "darling", "proc-macro2", diff --git a/rust/operator/src/kafka_controller.rs b/rust/operator/src/kafka_controller.rs index 839ca721..f26e5478 100644 --- a/rust/operator/src/kafka_controller.rs +++ b/rust/operator/src/kafka_controller.rs @@ -11,9 +11,8 @@ use stackable_kafka_crd::{ }; use stackable_operator::{ builder::{ - ConfigMapBuilder, ContainerBuilder, ListenerOperatorVolumeSourceBuilder, ListenerReference, - ObjectMetaBuilder, PodBuilder, SecretOperatorVolumeSourceBuilder, SecurityContextBuilder, - VolumeBuilder, + ConfigMapBuilder, ContainerBuilder, ObjectMetaBuilder, PodBuilder, + SecretOperatorVolumeSourceBuilder, SecurityContextBuilder, VolumeBuilder, }, cluster_resources::ClusterResources, commons::{ @@ -819,16 +818,7 @@ fn build_broker_rolegroup_statefulset( }), ..Volume::default() }) - .add_volume(Volume { - name: "listener".to_string(), - ephemeral: Some( - ListenerOperatorVolumeSourceBuilder::new(&ListenerReference::ListenerClass( - "nodeport".into(), - )) - .build(), - ), - ..Volume::default() - }) + .add_listener_volume_by_listener_class("listener", "nodeport") .build_template(); let pod_template_spec = pod_template.spec.get_or_insert_with(PodSpec::default); // Don't run kcat pod as PID 1, to ensure that default signal handlers apply From 0b70333f2b85e513ff3e8695d742cc952cd3d05b Mon Sep 17 00:00:00 2001 From: Siegfried Weber Date: Wed, 26 Oct 2022 13:30:24 +0200 Subject: [PATCH 06/42] Allow git source for operator-rs temporarily --- deny.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deny.toml b/deny.toml index e22644fd..a90b3364 100644 --- a/deny.toml +++ b/deny.toml @@ -52,6 +52,9 @@ license-files = [ [sources] unknown-registry = "deny" unknown-git = "deny" +allow-git = [ + "https://github.com//stackabletech/operator-rs", +] [sources.allow-org] github = ["stackabletech"] From e9d768aac8cf08d13947221b3e0edeecd42e267a Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Wed, 1 Mar 2023 17:06:51 +0100 Subject: [PATCH 07/42] Rename node_cmd -> node_address_cmd --- rust/crd/src/listener.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rust/crd/src/listener.rs b/rust/crd/src/listener.rs index 81cd8da7..a7e05539 100644 --- a/rust/crd/src/listener.rs +++ b/rust/crd/src/listener.rs @@ -105,7 +105,7 @@ pub fn get_kafka_listener_config( }); advertised_listeners.push(KafkaListener { name: KafkaListenerName::ClientAuth, - host: node_cmd(STACKABLE_LISTENER_DIR), + host: node_address_cmd(STACKABLE_LISTENER_DIR), port: node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), }); listener_security_protocol_map @@ -119,7 +119,7 @@ pub fn get_kafka_listener_config( }); advertised_listeners.push(KafkaListener { name: KafkaListenerName::Client, - host: node_cmd(STACKABLE_LISTENER_DIR), + host: node_address_cmd(STACKABLE_LISTENER_DIR), port: node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), }); listener_security_protocol_map @@ -133,7 +133,7 @@ pub fn get_kafka_listener_config( }); advertised_listeners.push(KafkaListener { name: KafkaListenerName::Client, - host: node_cmd(STACKABLE_LISTENER_DIR), + host: node_address_cmd(STACKABLE_LISTENER_DIR), port: node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), }); listener_security_protocol_map @@ -179,7 +179,7 @@ pub fn get_kafka_listener_config( }) } -fn node_cmd(directory: &str) -> String { +fn node_address_cmd(directory: &str) -> String { format!("$(cat {directory}/default-address/address)") } @@ -261,7 +261,7 @@ mod tests { format!( "{name}://{host}:{port},{internal_name}://{internal_host}:{internal_port}", name = KafkaListenerName::ClientAuth, - host = node_cmd(STACKABLE_LISTENER_DIR), + host = node_address_cmd(STACKABLE_LISTENER_DIR), port = node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), internal_name = KafkaListenerName::Internal, internal_host = pod_fqdn(&kafka, object_name).unwrap(), @@ -321,7 +321,7 @@ mod tests { format!( "{name}://{host}:{port},{internal_name}://{internal_host}:{internal_port}", name = KafkaListenerName::Client, - host = node_cmd(STACKABLE_LISTENER_DIR), + host = node_address_cmd(STACKABLE_LISTENER_DIR), port = node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), internal_name = KafkaListenerName::Internal, internal_host = pod_fqdn(&kafka, object_name).unwrap(), @@ -383,7 +383,7 @@ mod tests { format!( "{name}://{host}:{port},{internal_name}://{internal_host}:{internal_port}", name = KafkaListenerName::Client, - host = node_cmd(STACKABLE_LISTENER_DIR), + host = node_address_cmd(STACKABLE_LISTENER_DIR), port = node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), internal_name = KafkaListenerName::Internal, internal_host = pod_fqdn(&kafka, object_name).unwrap(), From 006b1225206b3ddfff343aae86c0622c9bb4b110 Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Wed, 1 Mar 2023 17:21:31 +0100 Subject: [PATCH 08/42] Remove operator-rs entry in deny.toml --- deny.toml | 3 --- test.yaml | 43 +++++++++++++++++++++++++++++++++++++++++++ test2.yaml | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 test.yaml create mode 100644 test2.yaml diff --git a/deny.toml b/deny.toml index a90b3364..e22644fd 100644 --- a/deny.toml +++ b/deny.toml @@ -52,9 +52,6 @@ license-files = [ [sources] unknown-registry = "deny" unknown-git = "deny" -allow-git = [ - "https://github.com//stackabletech/operator-rs", -] [sources.allow-org] github = ["stackabletech"] diff --git a/test.yaml b/test.yaml new file mode 100644 index 00000000..e7205e4a --- /dev/null +++ b/test.yaml @@ -0,0 +1,43 @@ +--- +apiVersion: listeners.stackable.tech/v1alpha1 +kind: ListenerClass +metadata: + name: public +spec: + serviceType: NodePort +--- +apiVersion: listeners.stackable.tech/v1alpha1 +kind: ListenerClass +metadata: + name: public-lb +spec: + serviceType: LoadBalancer +--- +apiVersion: v1 +kind: Pod +metadata: + name: example-public-pod +spec: + volumes: + - name: listener + ephemeral: + volumeClaimTemplate: + metadata: + annotations: + listeners.stackable.tech/listener-class: public + spec: + storageClassName: listeners.stackable.tech + accessModes: + - ReadWriteMany + resources: + requests: + storage: "1" + containers: + - name: nginx + image: nginx + ports: + - name: http + containerPort: 80 + volumeMounts: + - name: listener + mountPath: /listener diff --git a/test2.yaml b/test2.yaml new file mode 100644 index 00000000..9f4204cf --- /dev/null +++ b/test2.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: zookeeper.stackable.tech/v1alpha1 +kind: ZookeeperCluster +metadata: + name: simple-zk +spec: + image: + productVersion: 3.8.0 + stackableVersion: "23.1" + servers: + roleGroups: + default: + replicas: 1 +--- +apiVersion: zookeeper.stackable.tech/v1alpha1 +kind: ZookeeperZnode +metadata: + name: simple-kafka-znode +spec: + clusterRef: + name: simple-zk +--- +apiVersion: kafka.stackable.tech/v1alpha1 +kind: KafkaCluster +metadata: + name: simple-kafka +spec: + image: + productVersion: 3.3.1 + stackableVersion: "23.4.0-rc2" + clusterConfig: + zookeeperConfigMapName: simple-kafka-znode + brokers: + roleGroups: + default: + replicas: 3 From 3167720149a23cd5cd14bc2445472cc6a2f59cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Thu, 5 Sep 2024 15:58:39 +0200 Subject: [PATCH 09/42] Make listenerclass configurable --- Cargo.lock | 2 -- Cargo.nix | 14 ++------------ Cargo.toml | 3 ++- crate-hashes.json | 2 -- deploy/helm/kafka-operator/crds/crds.yaml | 6 ++++++ rust/crd/src/lib.rs | 4 ++++ rust/operator-binary/src/kafka_controller.rs | 6 +++++- 7 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1354698a..914ae6b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2160,7 +2160,6 @@ dependencies = [ [[package]] name = "stackable-operator" version = "0.74.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.74.0#c77a5423b66bc1667b63af7d8bec00de88a5303f" dependencies = [ "chrono", "clap", @@ -2196,7 +2195,6 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.74.0#c77a5423b66bc1667b63af7d8bec00de88a5303f" dependencies = [ "darling", "proc-macro2", diff --git a/Cargo.nix b/Cargo.nix index 922fac35..8a35ea6d 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -6688,12 +6688,7 @@ rec { crateName = "stackable-operator"; version = "0.74.0"; edition = "2021"; - workspace_member = null; - src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "c77a5423b66bc1667b63af7d8bec00de88a5303f"; - sha256 = "1g1a0v98wlcb36ibwv1nv75g3b3s1mjmaps443fc2w2maam94lya"; - }; + src = lib.cleanSourceWith { filter = sourceFilter; src = ../operator-rs/crates/stackable-operator; }; libName = "stackable_operator"; authors = [ "Stackable GmbH " @@ -6838,12 +6833,7 @@ rec { crateName = "stackable-operator-derive"; version = "0.3.1"; edition = "2021"; - workspace_member = null; - src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "c77a5423b66bc1667b63af7d8bec00de88a5303f"; - sha256 = "1g1a0v98wlcb36ibwv1nv75g3b3s1mjmaps443fc2w2maam94lya"; - }; + src = lib.cleanSourceWith { filter = sourceFilter; src = ../operator-rs/crates/stackable-operator-derive; }; procMacro = true; libName = "stackable_operator_derive"; authors = [ diff --git a/Cargo.toml b/Cargo.toml index 1fd2fd58..8a0b6901 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,5 +27,6 @@ strum = { version = "0.26", features = ["derive"] } tokio = { version = "1.39", features = ["full"] } tracing = "0.1" -# [patch."https://github.com/stackabletech/operator-rs.git"] +[patch."https://github.com/stackabletech/operator-rs.git"] +stackable-operator = { path = "../operator-rs/crates/stackable-operator" } # stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } diff --git a/crate-hashes.json b/crate-hashes.json index 8725a492..46c186b3 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,5 +1,3 @@ { - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.74.0#stackable-operator-derive@0.3.1": "1g1a0v98wlcb36ibwv1nv75g3b3s1mjmaps443fc2w2maam94lya", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.74.0#stackable-operator@0.74.0": "1g1a0v98wlcb36ibwv1nv75g3b3s1mjmaps443fc2w2maam94lya", "git+https://github.com/stackabletech/product-config.git?tag=0.7.0#product-config@0.7.0": "0gjsm80g6r75pm3824dcyiz4ysq1ka4c1if6k1mjm9cnd5ym0gny" } \ No newline at end of file diff --git a/deploy/helm/kafka-operator/crds/crds.yaml b/deploy/helm/kafka-operator/crds/crds.yaml index b8e7e981..dc6c7ff5 100644 --- a/deploy/helm/kafka-operator/crds/crds.yaml +++ b/deploy/helm/kafka-operator/crds/crds.yaml @@ -75,6 +75,9 @@ spec: description: Time period Pods have to gracefully shut down, e.g. `30m`, `1h` or `2d`. Consult the operator documentation for details. nullable: true type: string + listenerClass: + nullable: true + type: string logging: default: containers: {} @@ -342,6 +345,9 @@ spec: description: Time period Pods have to gracefully shut down, e.g. `30m`, `1h` or `2d`. Consult the operator documentation for details. nullable: true type: string + listenerClass: + nullable: true + type: string logging: default: containers: {} diff --git a/rust/crd/src/lib.rs b/rust/crd/src/lib.rs index f498fe84..1a8e2213 100644 --- a/rust/crd/src/lib.rs +++ b/rust/crd/src/lib.rs @@ -405,6 +405,9 @@ pub struct KafkaConfig { /// Time period Pods have to gracefully shut down, e.g. `30m`, `1h` or `2d`. Consult the operator documentation for details. #[fragment_attrs(serde(default))] pub graceful_shutdown_timeout: Option, + + #[fragment_attrs(serde(default))] + pub listener_class: String, } impl KafkaConfig { @@ -430,6 +433,7 @@ impl KafkaConfig { }, affinity: get_affinity(cluster_name, role), graceful_shutdown_timeout: Some(DEFAULT_BROKER_GRACEFUL_SHUTDOWN_TIMEOUT), + listener_class: Some("cluster-internal".to_string()), } } } diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index ab8d26db..69af086c 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -952,7 +952,11 @@ fn build_broker_rolegroup_statefulset( }), ..Volume::default() }) - .add_listener_volume_by_listener_class("listener", "external-unstable", &Labels::new()) + .add_listener_volume_by_listener_class( + "listener", + &merged_config.listener_class, + &Labels::new(), + ) .context(AddListenerVolumeSnafu)? .add_empty_dir_volume( "log", From f357a0648060e494c99f30324916a04537551755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Thu, 5 Sep 2024 16:08:09 +0200 Subject: [PATCH 10/42] Use operator-rs from git --- Cargo.lock | 2 ++ Cargo.nix | 14 ++++++++++++-- Cargo.toml | 4 ++-- crate-hashes.json | 2 ++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 914ae6b1..76efedbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2160,6 +2160,7 @@ dependencies = [ [[package]] name = "stackable-operator" version = "0.74.0" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=main#2cf690bfa6c244862d7866da95620ccaab4ab17a" dependencies = [ "chrono", "clap", @@ -2195,6 +2196,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=main#2cf690bfa6c244862d7866da95620ccaab4ab17a" dependencies = [ "darling", "proc-macro2", diff --git a/Cargo.nix b/Cargo.nix index 8a35ea6d..7d59dfec 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -6688,7 +6688,12 @@ rec { crateName = "stackable-operator"; version = "0.74.0"; edition = "2021"; - src = lib.cleanSourceWith { filter = sourceFilter; src = ../operator-rs/crates/stackable-operator; }; + workspace_member = null; + src = pkgs.fetchgit { + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "2cf690bfa6c244862d7866da95620ccaab4ab17a"; + sha256 = "14djdp8br3r5xxy0rjsxjr57ssvjqwj3km70z824ryzachjm9d11"; + }; libName = "stackable_operator"; authors = [ "Stackable GmbH " @@ -6833,7 +6838,12 @@ rec { crateName = "stackable-operator-derive"; version = "0.3.1"; edition = "2021"; - src = lib.cleanSourceWith { filter = sourceFilter; src = ../operator-rs/crates/stackable-operator-derive; }; + workspace_member = null; + src = pkgs.fetchgit { + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "2cf690bfa6c244862d7866da95620ccaab4ab17a"; + sha256 = "14djdp8br3r5xxy0rjsxjr57ssvjqwj3km70z824ryzachjm9d11"; + }; procMacro = true; libName = "stackable_operator_derive"; authors = [ diff --git a/Cargo.toml b/Cargo.toml index 8a0b6901..27a1fb74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,5 +28,5 @@ tokio = { version = "1.39", features = ["full"] } tracing = "0.1" [patch."https://github.com/stackabletech/operator-rs.git"] -stackable-operator = { path = "../operator-rs/crates/stackable-operator" } -# stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } +# stackable-operator = { path = "../operator-rs/crates/stackable-operator" } +stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } diff --git a/crate-hashes.json b/crate-hashes.json index 46c186b3..638c54d0 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,3 +1,5 @@ { + "git+https://github.com/stackabletech//operator-rs.git?branch=main#stackable-operator-derive@0.3.1": "14djdp8br3r5xxy0rjsxjr57ssvjqwj3km70z824ryzachjm9d11", + "git+https://github.com/stackabletech//operator-rs.git?branch=main#stackable-operator@0.74.0": "14djdp8br3r5xxy0rjsxjr57ssvjqwj3km70z824ryzachjm9d11", "git+https://github.com/stackabletech/product-config.git?tag=0.7.0#product-config@0.7.0": "0gjsm80g6r75pm3824dcyiz4ysq1ka4c1if6k1mjm9cnd5ym0gny" } \ No newline at end of file From f93d9ab4723867184ad4af2bd4f1a9fa7669e84d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Fri, 6 Sep 2024 16:05:41 +0200 Subject: [PATCH 11/42] Use listener secret scope --- Cargo.lock | 4 ++-- Cargo.nix | 8 ++++---- Cargo.toml | 3 ++- crate-hashes.json | 4 ++-- rust/crd/src/lib.rs | 1 + rust/crd/src/security.rs | 4 ++-- rust/operator-binary/src/kafka_controller.rs | 8 ++++---- 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76efedbc..12dc387c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2160,7 +2160,7 @@ dependencies = [ [[package]] name = "stackable-operator" version = "0.74.0" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=main#2cf690bfa6c244862d7866da95620ccaab4ab17a" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feature/secret-listener-volume#674b9b96ab3c2fa96ce7f1d45bf8ffa40bf56fd8" dependencies = [ "chrono", "clap", @@ -2196,7 +2196,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=main#2cf690bfa6c244862d7866da95620ccaab4ab17a" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feature/secret-listener-volume#674b9b96ab3c2fa96ce7f1d45bf8ffa40bf56fd8" dependencies = [ "darling", "proc-macro2", diff --git a/Cargo.nix b/Cargo.nix index 7d59dfec..3c6a9fdb 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -6691,8 +6691,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "2cf690bfa6c244862d7866da95620ccaab4ab17a"; - sha256 = "14djdp8br3r5xxy0rjsxjr57ssvjqwj3km70z824ryzachjm9d11"; + rev = "674b9b96ab3c2fa96ce7f1d45bf8ffa40bf56fd8"; + sha256 = "0ip976m371qc0dc81y499maw29bpw9rp676xm99gbk1i2djrkkyc"; }; libName = "stackable_operator"; authors = [ @@ -6841,8 +6841,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "2cf690bfa6c244862d7866da95620ccaab4ab17a"; - sha256 = "14djdp8br3r5xxy0rjsxjr57ssvjqwj3km70z824ryzachjm9d11"; + rev = "674b9b96ab3c2fa96ce7f1d45bf8ffa40bf56fd8"; + sha256 = "0ip976m371qc0dc81y499maw29bpw9rp676xm99gbk1i2djrkkyc"; }; procMacro = true; libName = "stackable_operator_derive"; diff --git a/Cargo.toml b/Cargo.toml index 27a1fb74..1a465619 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,4 +29,5 @@ tracing = "0.1" [patch."https://github.com/stackabletech/operator-rs.git"] # stackable-operator = { path = "../operator-rs/crates/stackable-operator" } -stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } +# stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } +stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "feature/secret-listener-volume" } diff --git a/crate-hashes.json b/crate-hashes.json index 638c54d0..6216dfd8 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,5 +1,5 @@ { - "git+https://github.com/stackabletech//operator-rs.git?branch=main#stackable-operator-derive@0.3.1": "14djdp8br3r5xxy0rjsxjr57ssvjqwj3km70z824ryzachjm9d11", - "git+https://github.com/stackabletech//operator-rs.git?branch=main#stackable-operator@0.74.0": "14djdp8br3r5xxy0rjsxjr57ssvjqwj3km70z824ryzachjm9d11", + "git+https://github.com/stackabletech//operator-rs.git?branch=feature%2Fsecret-listener-volume#stackable-operator-derive@0.3.1": "0ip976m371qc0dc81y499maw29bpw9rp676xm99gbk1i2djrkkyc", + "git+https://github.com/stackabletech//operator-rs.git?branch=feature%2Fsecret-listener-volume#stackable-operator@0.74.0": "0ip976m371qc0dc81y499maw29bpw9rp676xm99gbk1i2djrkkyc", "git+https://github.com/stackabletech/product-config.git?tag=0.7.0#product-config@0.7.0": "0gjsm80g6r75pm3824dcyiz4ysq1ka4c1if6k1mjm9cnd5ym0gny" } \ No newline at end of file diff --git a/rust/crd/src/lib.rs b/rust/crd/src/lib.rs index 1a8e2213..c25a2ff2 100644 --- a/rust/crd/src/lib.rs +++ b/rust/crd/src/lib.rs @@ -52,6 +52,7 @@ pub const KAFKA_HEAP_OPTS: &str = "KAFKA_HEAP_OPTS"; // server_properties pub const LOG_DIRS_VOLUME_NAME: &str = "log-dirs"; // directories +pub const LISTENER_VOLUME_NAME: &str = "listener"; pub const STACKABLE_LISTENER_DIR: &str = "/stackable/listener"; pub const STACKABLE_DATA_DIR: &str = "/stackable/data"; pub const STACKABLE_CONFIG_DIR: &str = "/stackable/config"; diff --git a/rust/crd/src/security.rs b/rust/crd/src/security.rs index 83aadfea..184d124e 100644 --- a/rust/crd/src/security.rs +++ b/rust/crd/src/security.rs @@ -23,12 +23,12 @@ use stackable_operator::{ utils::COMMON_BASH_TRAP_FUNCTIONS, }; -use crate::STACKABLE_LOG_DIR; use crate::{ authentication::{self, ResolvedAuthenticationClasses}, listener::{self, KafkaListenerConfig}, tls, KafkaCluster, SERVER_PROPERTIES_FILE, STACKABLE_CONFIG_DIR, }; +use crate::{LISTENER_VOLUME_NAME, STACKABLE_LOG_DIR}; #[derive(Snafu, Debug)] pub enum Error { @@ -455,7 +455,7 @@ impl<'a> KafkaTlsSecurity<'a> { .ephemeral( SecretOperatorVolumeSourceBuilder::new(secret_class_name) .with_pod_scope() - .with_node_scope() + .with_listener_volume_scope(LISTENER_VOLUME_NAME) .with_service_scope(kafka_bootstrap_service_name) .with_format(SecretFormat::TlsPkcs12) .build() diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index 69af086c..2f1c1691 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -14,8 +14,8 @@ use snafu::{OptionExt, ResultExt, Snafu}; use stackable_kafka_crd::{ listener::get_kafka_listener_config, security::KafkaTlsSecurity, Container, KafkaCluster, KafkaClusterStatus, KafkaConfig, KafkaRole, APP_NAME, DOCKER_IMAGE_BASE_NAME, - JVM_SECURITY_PROPERTIES_FILE, KAFKA_HEAP_OPTS, LOG_DIRS_VOLUME_NAME, METRICS_PORT, - METRICS_PORT_NAME, OPERATOR_NAME, SERVER_PROPERTIES_FILE, STACKABLE_CONFIG_DIR, + JVM_SECURITY_PROPERTIES_FILE, KAFKA_HEAP_OPTS, LISTENER_VOLUME_NAME, LOG_DIRS_VOLUME_NAME, + METRICS_PORT, METRICS_PORT_NAME, OPERATOR_NAME, SERVER_PROPERTIES_FILE, STACKABLE_CONFIG_DIR, STACKABLE_DATA_DIR, STACKABLE_LISTENER_DIR, STACKABLE_LOG_CONFIG_DIR, STACKABLE_LOG_DIR, }; use stackable_operator::{ @@ -871,7 +871,7 @@ fn build_broker_rolegroup_statefulset( .add_container_ports(container_ports(kafka_security)) .add_volume_mount(LOG_DIRS_VOLUME_NAME, STACKABLE_DATA_DIR) .add_volume_mount("config", STACKABLE_CONFIG_DIR) - .add_volume_mount("listener", STACKABLE_LISTENER_DIR) + .add_volume_mount(LISTENER_VOLUME_NAME, STACKABLE_LISTENER_DIR) .add_volume_mount("log-config", STACKABLE_LOG_CONFIG_DIR) .add_volume_mount("log", STACKABLE_LOG_DIR) .resources(merged_config.resources.clone().into()); @@ -953,7 +953,7 @@ fn build_broker_rolegroup_statefulset( ..Volume::default() }) .add_listener_volume_by_listener_class( - "listener", + LISTENER_VOLUME_NAME, &merged_config.listener_class, &Labels::new(), ) From cab56ff0b0792115358db698edd49e96602258d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Fri, 6 Sep 2024 18:00:03 +0200 Subject: [PATCH 12/42] Use listener for bootstrap and discovery --- .../helm/kafka-operator/templates/roles.yaml | 10 ++ rust/crd/src/lib.rs | 20 +++- rust/crd/src/listener.rs | 44 ++++++--- rust/crd/src/security.rs | 12 +-- rust/operator-binary/src/discovery.rs | 96 ++++++------------- rust/operator-binary/src/kafka_controller.rs | 95 +++++++++++------- rust/operator-binary/src/main.rs | 5 + 7 files changed, 158 insertions(+), 124 deletions(-) diff --git a/deploy/helm/kafka-operator/templates/roles.yaml b/deploy/helm/kafka-operator/templates/roles.yaml index aa366505..c686bda8 100644 --- a/deploy/helm/kafka-operator/templates/roles.yaml +++ b/deploy/helm/kafka-operator/templates/roles.yaml @@ -113,6 +113,16 @@ rules: - get - list - watch + - apiGroups: + - listeners.stackable.tech + resources: + - listeners + verbs: + - get + - list + - watch + - patch + - create - apiGroups: - rbac.authorization.k8s.io resources: diff --git a/rust/crd/src/lib.rs b/rust/crd/src/lib.rs index c25a2ff2..f0299fef 100644 --- a/rust/crd/src/lib.rs +++ b/rust/crd/src/lib.rs @@ -52,8 +52,10 @@ pub const KAFKA_HEAP_OPTS: &str = "KAFKA_HEAP_OPTS"; // server_properties pub const LOG_DIRS_VOLUME_NAME: &str = "log-dirs"; // directories -pub const LISTENER_VOLUME_NAME: &str = "listener"; -pub const STACKABLE_LISTENER_DIR: &str = "/stackable/listener"; +pub const LISTENER_BROKER_VOLUME_NAME: &str = "listener-broker"; +pub const LISTENER_BOOTSTRAP_VOLUME_NAME: &str = "listener-bootstrap"; +pub const STACKABLE_LISTENER_BROKER_DIR: &str = "/stackable/listener-broker"; +pub const STACKABLE_LISTENER_BOOTSTRAP_DIR: &str = "/stackable/listener-bootstrap"; pub const STACKABLE_DATA_DIR: &str = "/stackable/data"; pub const STACKABLE_CONFIG_DIR: &str = "/stackable/config"; pub const STACKABLE_LOG_CONFIG_DIR: &str = "/stackable/log_config"; @@ -160,6 +162,15 @@ pub struct KafkaClusterConfig { /// here. When using the [Stackable operator for Apache ZooKeeper](DOCS_BASE_URL_PLACEHOLDER/zookeeper/) /// to deploy a ZooKeeper cluster, this will simply be the name of your ZookeeperCluster resource. pub zookeeper_config_map_name: String, + + #[serde(default = "KafkaClusterConfig::default_bootstrap_listener_class")] + pub bootstrap_listener_class: String, +} + +impl KafkaClusterConfig { + fn default_bootstrap_listener_class() -> String { + "cluster-internal".to_string() + } } impl KafkaCluster { @@ -407,8 +418,7 @@ pub struct KafkaConfig { #[fragment_attrs(serde(default))] pub graceful_shutdown_timeout: Option, - #[fragment_attrs(serde(default))] - pub listener_class: String, + pub broker_listener_class: String, } impl KafkaConfig { @@ -434,7 +444,7 @@ impl KafkaConfig { }, affinity: get_affinity(cluster_name, role), graceful_shutdown_timeout: Some(DEFAULT_BROKER_GRACEFUL_SHUTDOWN_TIMEOUT), - listener_class: Some("cluster-internal".to_string()), + broker_listener_class: Some("cluster-internal".to_string()), } } } diff --git a/rust/crd/src/listener.rs b/rust/crd/src/listener.rs index 40ba1b99..761c18ae 100644 --- a/rust/crd/src/listener.rs +++ b/rust/crd/src/listener.rs @@ -1,4 +1,4 @@ -use crate::{KafkaCluster, STACKABLE_LISTENER_DIR}; +use crate::{KafkaCluster, STACKABLE_LISTENER_BROKER_DIR}; use crate::security::KafkaTlsSecurity; use snafu::{OptionExt, Snafu}; @@ -105,8 +105,11 @@ pub fn get_kafka_listener_config( }); advertised_listeners.push(KafkaListener { name: KafkaListenerName::ClientAuth, - host: node_address_cmd(STACKABLE_LISTENER_DIR), - port: node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), + host: node_address_cmd(STACKABLE_LISTENER_BROKER_DIR), + port: node_port_cmd( + STACKABLE_LISTENER_BROKER_DIR, + kafka_security.client_port_name(), + ), }); listener_security_protocol_map .insert(KafkaListenerName::ClientAuth, KafkaListenerProtocol::Ssl); @@ -119,8 +122,11 @@ pub fn get_kafka_listener_config( }); advertised_listeners.push(KafkaListener { name: KafkaListenerName::Client, - host: node_address_cmd(STACKABLE_LISTENER_DIR), - port: node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), + host: node_address_cmd(STACKABLE_LISTENER_BROKER_DIR), + port: node_port_cmd( + STACKABLE_LISTENER_BROKER_DIR, + kafka_security.client_port_name(), + ), }); listener_security_protocol_map .insert(KafkaListenerName::Client, KafkaListenerProtocol::Ssl); @@ -133,8 +139,11 @@ pub fn get_kafka_listener_config( }); advertised_listeners.push(KafkaListener { name: KafkaListenerName::Client, - host: node_address_cmd(STACKABLE_LISTENER_DIR), - port: node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), + host: node_address_cmd(STACKABLE_LISTENER_BROKER_DIR), + port: node_port_cmd( + STACKABLE_LISTENER_BROKER_DIR, + kafka_security.client_port_name(), + ), }); listener_security_protocol_map .insert(KafkaListenerName::Client, KafkaListenerProtocol::Plaintext); @@ -263,8 +272,11 @@ mod tests { format!( "{name}://{host}:{port},{internal_name}://{internal_host}:{internal_port}", name = KafkaListenerName::ClientAuth, - host = node_address_cmd(STACKABLE_LISTENER_DIR), - port = node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), + host = node_address_cmd(STACKABLE_LISTENER_BROKER_DIR), + port = node_port_cmd( + STACKABLE_LISTENER_BROKER_DIR, + kafka_security.client_port_name() + ), internal_name = KafkaListenerName::Internal, internal_host = pod_fqdn(&kafka, object_name).unwrap(), internal_port = kafka_security.internal_port(), @@ -323,8 +335,11 @@ mod tests { format!( "{name}://{host}:{port},{internal_name}://{internal_host}:{internal_port}", name = KafkaListenerName::Client, - host = node_address_cmd(STACKABLE_LISTENER_DIR), - port = node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), + host = node_address_cmd(STACKABLE_LISTENER_BROKER_DIR), + port = node_port_cmd( + STACKABLE_LISTENER_BROKER_DIR, + kafka_security.client_port_name() + ), internal_name = KafkaListenerName::Internal, internal_host = pod_fqdn(&kafka, object_name).unwrap(), internal_port = kafka_security.internal_port(), @@ -385,8 +400,11 @@ mod tests { format!( "{name}://{host}:{port},{internal_name}://{internal_host}:{internal_port}", name = KafkaListenerName::Client, - host = node_address_cmd(STACKABLE_LISTENER_DIR), - port = node_port_cmd(STACKABLE_LISTENER_DIR, kafka_security.client_port_name()), + host = node_address_cmd(STACKABLE_LISTENER_BROKER_DIR), + port = node_port_cmd( + STACKABLE_LISTENER_BROKER_DIR, + kafka_security.client_port_name() + ), internal_name = KafkaListenerName::Internal, internal_host = pod_fqdn(&kafka, object_name).unwrap(), internal_port = kafka_security.internal_port(), diff --git a/rust/crd/src/security.rs b/rust/crd/src/security.rs index 184d124e..40a556d4 100644 --- a/rust/crd/src/security.rs +++ b/rust/crd/src/security.rs @@ -26,9 +26,10 @@ use stackable_operator::{ use crate::{ authentication::{self, ResolvedAuthenticationClasses}, listener::{self, KafkaListenerConfig}, - tls, KafkaCluster, SERVER_PROPERTIES_FILE, STACKABLE_CONFIG_DIR, + tls, KafkaCluster, LISTENER_BOOTSTRAP_VOLUME_NAME, SERVER_PROPERTIES_FILE, + STACKABLE_CONFIG_DIR, }; -use crate::{LISTENER_VOLUME_NAME, STACKABLE_LOG_DIR}; +use crate::{LISTENER_BROKER_VOLUME_NAME, STACKABLE_LOG_DIR}; #[derive(Snafu, Debug)] pub enum Error { @@ -282,7 +283,6 @@ impl<'a> KafkaTlsSecurity<'a> { ); // Keystores fore the kafka container pod_builder.add_volume(Self::create_tls_keystore_volume( - &self.kafka.bootstrap_service_name(), Self::STACKABLE_TLS_KEYSTORE_SERVER_DIR_NAME, tls_server_secret_class, )?); @@ -294,7 +294,6 @@ impl<'a> KafkaTlsSecurity<'a> { if let Some(tls_internal_secret_class) = self.tls_internal_secret_class() { pod_builder.add_volume(Self::create_tls_keystore_volume( - &self.kafka.bootstrap_service_name(), Self::STACKABLE_TLS_KEYSTORE_INTERNAL_DIR_NAME, tls_internal_secret_class, )?); @@ -447,7 +446,6 @@ impl<'a> KafkaTlsSecurity<'a> { /// Creates ephemeral volumes to mount the `SecretClass` into the Pods as keystores fn create_tls_keystore_volume( - kafka_bootstrap_service_name: &str, volume_name: &str, secret_class_name: &str, ) -> Result { @@ -455,8 +453,8 @@ impl<'a> KafkaTlsSecurity<'a> { .ephemeral( SecretOperatorVolumeSourceBuilder::new(secret_class_name) .with_pod_scope() - .with_listener_volume_scope(LISTENER_VOLUME_NAME) - .with_service_scope(kafka_bootstrap_service_name) + .with_listener_volume_scope(LISTENER_BROKER_VOLUME_NAME) + .with_listener_volume_scope(LISTENER_BOOTSTRAP_VOLUME_NAME) .with_format(SecretFormat::TlsPkcs12) .build() .context(SecretVolumeBuildSnafu)?, diff --git a/rust/operator-binary/src/discovery.rs b/rust/operator-binary/src/discovery.rs index a61b45a3..f6e2fd15 100644 --- a/rust/operator-binary/src/discovery.rs +++ b/rust/operator-binary/src/discovery.rs @@ -5,11 +5,11 @@ use snafu::{OptionExt, ResultExt, Snafu}; use stackable_kafka_crd::{security::KafkaTlsSecurity, KafkaCluster, KafkaRole}; use stackable_operator::{ builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder}, - commons::product_image_selection::ResolvedProductImage, - k8s_openapi::api::core::v1::{ConfigMap, Endpoints, Service, ServicePort}, + commons::{listener::Listener, product_image_selection::ResolvedProductImage}, + k8s_openapi::api::core::v1::{ConfigMap, Service}, kube::{runtime::reflector::ObjectRef, Resource, ResourceExt}, }; -use std::{collections::BTreeSet, num::TryFromIntError}; +use std::num::TryFromIntError; #[derive(Snafu, Debug)] pub enum Error { @@ -56,9 +56,8 @@ pub async fn build_discovery_configmaps( kafka: &KafkaCluster, owner: &impl Resource, resolved_product_image: &ResolvedProductImage, - client: &stackable_operator::client::Client, kafka_security: &KafkaTlsSecurity<'_>, - svc: &Service, + listener: &Listener, ) -> Result, Error> { let name = owner.name_unchecked(); let port_name = kafka_security.client_port_name(); @@ -68,14 +67,17 @@ pub async fn build_discovery_configmaps( owner, resolved_product_image, &name, - service_hosts(svc, port_name)?, + listener_hosts(listener, port_name)?, )?, + // backwards compat: nodeport service is now the same as the main service, access type + // is determined by the listenerclass. + // do we want to deprecate/remove this? build_discovery_configmap( kafka, owner, resolved_product_image, - &format!("{}-nodeport", name), - nodeport_hosts(client, svc, port_name).await?, + &format!("{name}-nodeport"), + listener_hosts(listener, port_name)?, )?, ]) } @@ -121,64 +123,26 @@ fn build_discovery_configmap( .context(BuildConfigMapSnafu) } -fn find_named_svc_port<'a>(svc: &'a Service, port_name: &str) -> Option<&'a ServicePort> { - svc.spec - .as_ref()? - .ports - .as_ref()? - .iter() - .find(|port| port.name.as_deref() == Some(port_name)) -} - -/// Lists the [`Service`]'s FQDN (fully qualified domain name) -fn service_hosts( - svc: &Service, - port_name: &str, -) -> Result, Error> { - let svc_fqdn = format!( - "{}.{}.svc.cluster.local", - svc.metadata.name.as_deref().context(NoNameSnafu)?, - svc.metadata - .namespace - .as_deref() - .context(NoNamespaceSnafu)? - ); - let svc_port = find_named_svc_port(svc, port_name).context(NoServicePortSnafu { port_name })?; - Ok([( - svc_fqdn, - svc_port.port.try_into().context(InvalidNodePortSnafu)?, - )]) -} - -/// Lists all nodes currently hosting Pods participating in the [`Service`] -async fn nodeport_hosts( - client: &stackable_operator::client::Client, - svc: &Service, +fn listener_hosts( + listener: &Listener, port_name: &str, ) -> Result, Error> { - let svc_port = find_named_svc_port(svc, port_name).context(NoServicePortSnafu { port_name })?; - let node_port = svc_port.node_port.context(NoNodePortSnafu { port_name })?; - let endpoints = client - .get::( - svc.metadata.name.as_deref().context(NoNameSnafu)?, - svc.metadata - .namespace - .as_deref() - .context(NoNamespaceSnafu)?, - ) - .await - .with_context(|_| FindEndpointsSnafu { - svc: ObjectRef::from_obj(svc), - })?; - let nodes = endpoints - .subsets - .into_iter() - .flatten() - .flat_map(|subset| subset.addresses) - .flatten() - .flat_map(|addr| addr.node_name); - let addrs = nodes - .map(|node| Ok((node, node_port.try_into().context(InvalidNodePortSnafu)?))) - .collect::, _>>()?; - Ok(addrs) + listener + .status + .as_ref() + .and_then(|s| s.ingress_addresses.as_deref()) + .unwrap_or_default() + .iter() + .map(|x| { + Ok(( + x.address.clone(), + x.ports + .get(port_name) + .copied() + .context(NoServicePortSnafu { port_name })? + .try_into() + .context(InvalidNodePortSnafu)?, + )) + }) + .collect::, _>>() } diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index 2f1c1691..dfa17716 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -14,23 +14,31 @@ use snafu::{OptionExt, ResultExt, Snafu}; use stackable_kafka_crd::{ listener::get_kafka_listener_config, security::KafkaTlsSecurity, Container, KafkaCluster, KafkaClusterStatus, KafkaConfig, KafkaRole, APP_NAME, DOCKER_IMAGE_BASE_NAME, - JVM_SECURITY_PROPERTIES_FILE, KAFKA_HEAP_OPTS, LISTENER_VOLUME_NAME, LOG_DIRS_VOLUME_NAME, - METRICS_PORT, METRICS_PORT_NAME, OPERATOR_NAME, SERVER_PROPERTIES_FILE, STACKABLE_CONFIG_DIR, - STACKABLE_DATA_DIR, STACKABLE_LISTENER_DIR, STACKABLE_LOG_CONFIG_DIR, STACKABLE_LOG_DIR, + JVM_SECURITY_PROPERTIES_FILE, KAFKA_HEAP_OPTS, LISTENER_BOOTSTRAP_VOLUME_NAME, + LISTENER_BROKER_VOLUME_NAME, LOG_DIRS_VOLUME_NAME, METRICS_PORT, METRICS_PORT_NAME, + OPERATOR_NAME, SERVER_PROPERTIES_FILE, STACKABLE_CONFIG_DIR, STACKABLE_DATA_DIR, + STACKABLE_LISTENER_BOOTSTRAP_DIR, STACKABLE_LISTENER_BROKER_DIR, STACKABLE_LOG_CONFIG_DIR, + STACKABLE_LOG_DIR, }; use stackable_operator::{ builder::{ configmap::ConfigMapBuilder, meta::ObjectMetaBuilder, pod::{ - container::ContainerBuilder, resources::ResourceRequirementsBuilder, - security::PodSecurityContextBuilder, PodBuilder, + container::ContainerBuilder, + resources::ResourceRequirementsBuilder, + security::PodSecurityContextBuilder, + volume::{ListenerOperatorVolumeSourceBuilder, ListenerReference}, + PodBuilder, }, }, cluster_resources::{ClusterResourceApplyStrategy, ClusterResources}, commons::{ - authentication::AuthenticationClass, opa::OpaApiVersion, - product_image_selection::ResolvedProductImage, rbac::build_rbac_resources, + authentication::AuthenticationClass, + listener::{Listener, ListenerPort, ListenerSpec}, + opa::OpaApiVersion, + product_image_selection::ResolvedProductImage, + rbac::build_rbac_resources, }, k8s_openapi::{ api::{ @@ -443,11 +451,11 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< None }; - let broker_role_service = - build_bootstrap_service(&kafka, &resolved_product_image, &kafka_security)?; + let bootstrap_listener = + build_bootstrap_listener(&kafka, &resolved_product_image, &kafka_security)?; - let broker_role_service = cluster_resources - .add(client, broker_role_service) + let bootstrap_listener = cluster_resources + .add(client, bootstrap_listener) .await .context(ApplyRoleServiceSnafu)?; @@ -545,9 +553,8 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< &kafka, &*kafka, &resolved_product_image, - client, &kafka_security, - &broker_role_service, + &bootstrap_listener, ) .await .context(BuildDiscoveryConfigSnafu)? @@ -568,10 +575,11 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< ), }; - cluster_resources - .delete_orphaned_resources(client) - .await - .context(DeleteOrphansSnafu)?; + // FIXME: https://github.com/stackabletech/operator-rs/issues/861 + // cluster_resources + // .delete_orphaned_resources(client) + // .await + // .context(DeleteOrphansSnafu)?; client .apply_patch_status(OPERATOR_NAME, &*kafka, &status) @@ -583,13 +591,13 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< /// Kafka clients will use the load-balanced bootstrap service to get a list of broker addresses and will use those to /// transmit data to the correct broker. -pub fn build_bootstrap_service( +pub fn build_bootstrap_listener( kafka: &KafkaCluster, resolved_product_image: &ResolvedProductImage, kafka_security: &KafkaTlsSecurity, -) -> Result { +) -> Result { let role_name = KafkaRole::Broker.to_string(); - Ok(Service { + Ok(Listener { metadata: ObjectMetaBuilder::new() .name_and_namespace(kafka) .name(kafka.bootstrap_service_name()) @@ -604,16 +612,21 @@ pub fn build_bootstrap_service( )) .context(MetadataBuildSnafu)? .build(), - spec: Some(ServiceSpec { - ports: Some(service_ports(kafka_security)), - selector: Some( - Labels::role_selector(kafka, APP_NAME, &role_name) - .context(LabelBuildSnafu)? - .into(), + spec: ListenerSpec { + class_name: Some(kafka.spec.cluster_config.bootstrap_listener_class.clone()), + ports: Some( + // TODO:; produce ListenerPorts natively + service_ports(kafka_security) + .into_iter() + .map(|port| ListenerPort { + name: port.name.unwrap_or_default(), + port: port.port, + protocol: port.protocol, + }) + .collect(), ), - type_: Some("NodePort".to_string()), - ..ServiceSpec::default() - }), + ..ListenerSpec::default() + }, status: None, }) } @@ -787,7 +800,18 @@ fn build_broker_rolegroup_statefulset( .add_volume_and_volume_mounts(&mut pod_builder, &mut cb_kcat_prober, &mut cb_kafka) .context(AddVolumesAndVolumeMountsSnafu)?; - let pvcs = merged_config.resources.storage.build_pvcs(); + let mut pvcs = merged_config.resources.storage.build_pvcs(); + + // main broker listener is an ephemeral PVC instead + pvcs.push( + ListenerOperatorVolumeSourceBuilder::new( + // FIXME: error handling + &ListenerReference::ListenerName(kafka.name_unchecked()), + &Labels::new(), + ) + .and_then(|builder| builder.build_pvc(LISTENER_BOOTSTRAP_VOLUME_NAME)) + .unwrap(), + ); let mut env = broker_config .get(&PropertyNameKind::Env) @@ -871,7 +895,11 @@ fn build_broker_rolegroup_statefulset( .add_container_ports(container_ports(kafka_security)) .add_volume_mount(LOG_DIRS_VOLUME_NAME, STACKABLE_DATA_DIR) .add_volume_mount("config", STACKABLE_CONFIG_DIR) - .add_volume_mount(LISTENER_VOLUME_NAME, STACKABLE_LISTENER_DIR) + .add_volume_mount( + LISTENER_BOOTSTRAP_VOLUME_NAME, + STACKABLE_LISTENER_BOOTSTRAP_DIR, + ) + .add_volume_mount(LISTENER_BROKER_VOLUME_NAME, STACKABLE_LISTENER_BROKER_DIR) .add_volume_mount("log-config", STACKABLE_LOG_CONFIG_DIR) .add_volume_mount("log", STACKABLE_LOG_DIR) .resources(merged_config.resources.clone().into()); @@ -952,9 +980,10 @@ fn build_broker_rolegroup_statefulset( }), ..Volume::default() }) + // bootstrap volume is a persistent volume template instead, to keep addresses persistent .add_listener_volume_by_listener_class( - LISTENER_VOLUME_NAME, - &merged_config.listener_class, + LISTENER_BROKER_VOLUME_NAME, + &merged_config.broker_listener_class, &Labels::new(), ) .context(AddListenerVolumeSnafu)? diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index 785109ec..2865c626 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -7,6 +7,7 @@ use stackable_kafka_crd::{KafkaCluster, APP_NAME, OPERATOR_NAME}; use stackable_operator::{ cli::{Command, ProductOperatorRun}, client::{self, Client}, + commons::listener::Listener, k8s_openapi::api::{ apps::v1::StatefulSet, core::v1::{ConfigMap, Service, ServiceAccount}, @@ -106,6 +107,10 @@ pub async fn create_controller( namespace.get_api::(&client), watcher::Config::default(), ) + .owns( + namespace.get_api::(&client), + watcher::Config::default(), + ) .owns( namespace.get_api::(&client), watcher::Config::default(), From acb686ee0ecd6b8658d0f663ec2fe34e82b958d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Mon, 9 Sep 2024 16:06:33 +0200 Subject: [PATCH 13/42] Separate out kcat secret management now that it is the only PEM user --- rust/crd/src/security.rs | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/rust/crd/src/security.rs b/rust/crd/src/security.rs index 40a556d4..7d8973d3 100644 --- a/rust/crd/src/security.rs +++ b/rust/crd/src/security.rs @@ -98,8 +98,8 @@ impl<'a> KafkaTlsSecurity<'a> { const INTER_SSL_CLIENT_AUTH: &'static str = "listener.name.internal.ssl.client.auth"; // directories // for kcat container - const STACKABLE_TLS_CERT_SERVER_DIR: &'static str = "/stackable/tls_cert_server_mount"; - const STACKABLE_TLS_CERT_SERVER_DIR_NAME: &'static str = "tls-cert-server-mount"; + const STACKABLE_TLS_CERT_KCAT_DIR: &'static str = "/stackable/tls_cert_kcat"; + const STACKABLE_TLS_CERT_KCAT_DIR_NAME: &'static str = "tls-cert-kcat"; // kafka container const STACKABLE_TLS_KEYSTORE_SERVER_DIR: &'static str = "/stackable/tls_keystore_server"; const STACKABLE_TLS_KEYSTORE_SERVER_DIR_NAME: &'static str = "tls-keystore-server"; @@ -218,12 +218,12 @@ impl<'a> KafkaTlsSecurity<'a> { args.push("-b".to_string()); args.push(format!("localhost:{}", port)); args.extend(Self::kcat_client_auth_ssl( - Self::STACKABLE_TLS_CERT_SERVER_DIR, + Self::STACKABLE_TLS_CERT_KCAT_DIR, )); } else if self.tls_server_secret_class().is_some() { args.push("-b".to_string()); args.push(format!("localhost:{}", port)); - args.extend(Self::kcat_client_ssl(Self::STACKABLE_TLS_CERT_SERVER_DIR)); + args.extend(Self::kcat_client_ssl(Self::STACKABLE_TLS_CERT_KCAT_DIR)); } else { args.push("-b".to_string()); args.push(format!("localhost:{}", port)); @@ -272,14 +272,13 @@ impl<'a> KafkaTlsSecurity<'a> { // add tls (server or client authentication volumes) if required if let Some(tls_server_secret_class) = self.get_tls_secret_class() { // We have to mount tls pem files for kcat (the mount can be used directly) - pod_builder.add_volume(Self::create_tls_volume( - &self.kafka.bootstrap_service_name(), - Self::STACKABLE_TLS_CERT_SERVER_DIR_NAME, + pod_builder.add_volume(Self::create_kcat_tls_volume( + Self::STACKABLE_TLS_CERT_KCAT_DIR_NAME, tls_server_secret_class, )?); cb_kcat_prober.add_volume_mount( - Self::STACKABLE_TLS_CERT_SERVER_DIR_NAME, - Self::STACKABLE_TLS_CERT_SERVER_DIR, + Self::STACKABLE_TLS_CERT_KCAT_DIR_NAME, + Self::STACKABLE_TLS_CERT_KCAT_DIR, ); // Keystores fore the kafka container pod_builder.add_volume(Self::create_tls_keystore_volume( @@ -426,18 +425,13 @@ impl<'a> KafkaTlsSecurity<'a> { .or(self.server_secret_class.as_ref()) } - /// Creates ephemeral volumes to mount the `SecretClass` into the Pods - fn create_tls_volume( - kafka_bootstrap_service_name: &str, - volume_name: &str, - secret_class_name: &str, - ) -> Result { + /// Creates ephemeral volumes to mount the `SecretClass` into the Pods for kcat client + fn create_kcat_tls_volume(volume_name: &str, secret_class_name: &str) -> Result { Ok(VolumeBuilder::new(volume_name) .ephemeral( SecretOperatorVolumeSourceBuilder::new(secret_class_name) .with_pod_scope() - .with_node_scope() - .with_service_scope(kafka_bootstrap_service_name) + .with_format(SecretFormat::TlsPem) .build() .context(SecretVolumeBuildSnafu)?, ) From c91a0416159b8c5a53f2d0cd3f0015274f082344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Mon, 9 Sep 2024 16:17:40 +0200 Subject: [PATCH 14/42] Remove unused KafkaTlsSecurity::kafka --- rust/crd/src/listener.rs | 3 --- rust/crd/src/security.rs | 10 +++------- rust/operator-binary/src/discovery.rs | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/rust/crd/src/listener.rs b/rust/crd/src/listener.rs index 761c18ae..18b36c4b 100644 --- a/rust/crd/src/listener.rs +++ b/rust/crd/src/listener.rs @@ -240,7 +240,6 @@ mod tests { "#; let kafka: KafkaCluster = serde_yaml::from_str(kafka_cluster).expect("illegal test input"); let kafka_security = KafkaTlsSecurity::new( - &kafka, ResolvedAuthenticationClasses::new(vec![AuthenticationClass { metadata: ObjectMetaBuilder::new().name("auth-class").build(), spec: AuthenticationClassSpec { @@ -310,7 +309,6 @@ mod tests { "#; let kafka: KafkaCluster = serde_yaml::from_str(input).expect("illegal test input"); let kafka_security = KafkaTlsSecurity::new( - &kafka, ResolvedAuthenticationClasses::new(vec![]), "tls".to_string(), Some("tls".to_string()), @@ -375,7 +373,6 @@ mod tests { "#; let kafka: KafkaCluster = serde_yaml::from_str(input).expect("illegal test input"); let kafka_security = KafkaTlsSecurity::new( - &kafka, ResolvedAuthenticationClasses::new(vec![]), "".to_string(), None, diff --git a/rust/crd/src/security.rs b/rust/crd/src/security.rs index 7d8973d3..e65263ef 100644 --- a/rust/crd/src/security.rs +++ b/rust/crd/src/security.rs @@ -43,14 +43,13 @@ pub enum Error { } /// Helper struct combining TLS settings for server and internal with the resolved AuthenticationClasses -pub struct KafkaTlsSecurity<'a> { - kafka: &'a KafkaCluster, +pub struct KafkaTlsSecurity { resolved_authentication_classes: ResolvedAuthenticationClasses, internal_secret_class: String, server_secret_class: Option, } -impl<'a> KafkaTlsSecurity<'a> { +impl KafkaTlsSecurity { // ports pub const CLIENT_PORT_NAME: &'static str = "kafka"; pub const CLIENT_PORT: u16 = 9092; @@ -108,13 +107,11 @@ impl<'a> KafkaTlsSecurity<'a> { #[cfg(test)] pub fn new( - kafka: &'a KafkaCluster, resolved_authentication_classes: ResolvedAuthenticationClasses, internal_secret_class: String, server_secret_class: Option, ) -> Self { Self { - kafka, resolved_authentication_classes, internal_secret_class, server_secret_class, @@ -125,10 +122,9 @@ impl<'a> KafkaTlsSecurity<'a> { /// all provided `AuthenticationClass` references. pub async fn new_from_kafka_cluster( client: &Client, - kafka: &'a KafkaCluster, + kafka: &KafkaCluster, ) -> Result { Ok(KafkaTlsSecurity { - kafka, resolved_authentication_classes: ResolvedAuthenticationClasses::from_references( client, &kafka.spec.cluster_config.authentication, diff --git a/rust/operator-binary/src/discovery.rs b/rust/operator-binary/src/discovery.rs index f6e2fd15..991b3c02 100644 --- a/rust/operator-binary/src/discovery.rs +++ b/rust/operator-binary/src/discovery.rs @@ -56,7 +56,7 @@ pub async fn build_discovery_configmaps( kafka: &KafkaCluster, owner: &impl Resource, resolved_product_image: &ResolvedProductImage, - kafka_security: &KafkaTlsSecurity<'_>, + kafka_security: &KafkaTlsSecurity, listener: &Listener, ) -> Result, Error> { let name = owner.name_unchecked(); From d960573dc536f07816f6a8908c6e618b81785baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Mon, 9 Sep 2024 16:18:02 +0200 Subject: [PATCH 15/42] Regenerate CRD --- deploy/helm/kafka-operator/crds/crds.yaml | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/deploy/helm/kafka-operator/crds/crds.yaml b/deploy/helm/kafka-operator/crds/crds.yaml index dc6c7ff5..91ee2873 100644 --- a/deploy/helm/kafka-operator/crds/crds.yaml +++ b/deploy/helm/kafka-operator/crds/crds.yaml @@ -66,16 +66,12 @@ spec: nullable: true type: object x-kubernetes-preserve-unknown-fields: true - required: - - nodeAffinity - - podAffinity - - podAntiAffinity type: object - gracefulShutdownTimeout: - description: Time period Pods have to gracefully shut down, e.g. `30m`, `1h` or `2d`. Consult the operator documentation for details. + brokerListenerClass: nullable: true type: string - listenerClass: + gracefulShutdownTimeout: + description: Time period Pods have to gracefully shut down, e.g. `30m`, `1h` or `2d`. Consult the operator documentation for details. nullable: true type: string logging: @@ -336,16 +332,12 @@ spec: nullable: true type: object x-kubernetes-preserve-unknown-fields: true - required: - - nodeAffinity - - podAffinity - - podAntiAffinity type: object - gracefulShutdownTimeout: - description: Time period Pods have to gracefully shut down, e.g. `30m`, `1h` or `2d`. Consult the operator documentation for details. + brokerListenerClass: nullable: true type: string - listenerClass: + gracefulShutdownTimeout: + description: Time period Pods have to gracefully shut down, e.g. `30m`, `1h` or `2d`. Consult the operator documentation for details. nullable: true type: string logging: @@ -588,6 +580,9 @@ spec: - configMapName type: object type: object + bootstrapListenerClass: + default: cluster-internal + type: string tls: default: internalSecretClass: tls From 25cca0e32524fac523899c30a9e8b08dc53d1e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Mon, 9 Sep 2024 16:19:29 +0200 Subject: [PATCH 16/42] Switch to main op-rs https://github.com/stackabletech/operator-rs/pull/858 was merged --- Cargo.lock | 4 ++-- Cargo.nix | 8 ++++---- Cargo.toml | 3 +-- crate-hashes.json | 4 ++-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12dc387c..dc4bd22c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2160,7 +2160,7 @@ dependencies = [ [[package]] name = "stackable-operator" version = "0.74.0" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feature/secret-listener-volume#674b9b96ab3c2fa96ce7f1d45bf8ffa40bf56fd8" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=main#04f3b11719725e144c50f14f0c430191ca26aea0" dependencies = [ "chrono", "clap", @@ -2196,7 +2196,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feature/secret-listener-volume#674b9b96ab3c2fa96ce7f1d45bf8ffa40bf56fd8" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=main#04f3b11719725e144c50f14f0c430191ca26aea0" dependencies = [ "darling", "proc-macro2", diff --git a/Cargo.nix b/Cargo.nix index 3c6a9fdb..eefee269 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -6691,8 +6691,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "674b9b96ab3c2fa96ce7f1d45bf8ffa40bf56fd8"; - sha256 = "0ip976m371qc0dc81y499maw29bpw9rp676xm99gbk1i2djrkkyc"; + rev = "04f3b11719725e144c50f14f0c430191ca26aea0"; + sha256 = "0xz4hyca5pyjabwryngq74q1qq7cnhfjrn0b84nc78nv7lynw5g0"; }; libName = "stackable_operator"; authors = [ @@ -6841,8 +6841,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "674b9b96ab3c2fa96ce7f1d45bf8ffa40bf56fd8"; - sha256 = "0ip976m371qc0dc81y499maw29bpw9rp676xm99gbk1i2djrkkyc"; + rev = "04f3b11719725e144c50f14f0c430191ca26aea0"; + sha256 = "0xz4hyca5pyjabwryngq74q1qq7cnhfjrn0b84nc78nv7lynw5g0"; }; procMacro = true; libName = "stackable_operator_derive"; diff --git a/Cargo.toml b/Cargo.toml index 1a465619..27a1fb74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,5 +29,4 @@ tracing = "0.1" [patch."https://github.com/stackabletech/operator-rs.git"] # stackable-operator = { path = "../operator-rs/crates/stackable-operator" } -# stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } -stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "feature/secret-listener-volume" } +stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } diff --git a/crate-hashes.json b/crate-hashes.json index 6216dfd8..739c5e1f 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,5 +1,5 @@ { - "git+https://github.com/stackabletech//operator-rs.git?branch=feature%2Fsecret-listener-volume#stackable-operator-derive@0.3.1": "0ip976m371qc0dc81y499maw29bpw9rp676xm99gbk1i2djrkkyc", - "git+https://github.com/stackabletech//operator-rs.git?branch=feature%2Fsecret-listener-volume#stackable-operator@0.74.0": "0ip976m371qc0dc81y499maw29bpw9rp676xm99gbk1i2djrkkyc", + "git+https://github.com/stackabletech//operator-rs.git?branch=main#stackable-operator-derive@0.3.1": "0xz4hyca5pyjabwryngq74q1qq7cnhfjrn0b84nc78nv7lynw5g0", + "git+https://github.com/stackabletech//operator-rs.git?branch=main#stackable-operator@0.74.0": "0xz4hyca5pyjabwryngq74q1qq7cnhfjrn0b84nc78nv7lynw5g0", "git+https://github.com/stackabletech/product-config.git?tag=0.7.0#product-config@0.7.0": "0gjsm80g6r75pm3824dcyiz4ysq1ka4c1if6k1mjm9cnd5ym0gny" } \ No newline at end of file From c3018bc8a462b9c7b202358a089d53da68feef14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 11 Sep 2024 12:49:35 +0200 Subject: [PATCH 17/42] Switch to per-rolegroup bootstrap listeners --- rust/crd/src/lib.rs | 15 +++----- rust/operator-binary/src/discovery.rs | 27 +++++++------- rust/operator-binary/src/kafka_controller.rs | 38 ++++++++++++-------- 3 files changed, 43 insertions(+), 37 deletions(-) diff --git a/rust/crd/src/lib.rs b/rust/crd/src/lib.rs index f0299fef..5561268c 100644 --- a/rust/crd/src/lib.rs +++ b/rust/crd/src/lib.rs @@ -162,22 +162,13 @@ pub struct KafkaClusterConfig { /// here. When using the [Stackable operator for Apache ZooKeeper](DOCS_BASE_URL_PLACEHOLDER/zookeeper/) /// to deploy a ZooKeeper cluster, this will simply be the name of your ZookeeperCluster resource. pub zookeeper_config_map_name: String, - - #[serde(default = "KafkaClusterConfig::default_bootstrap_listener_class")] - pub bootstrap_listener_class: String, -} - -impl KafkaClusterConfig { - fn default_bootstrap_listener_class() -> String { - "cluster-internal".to_string() - } } impl KafkaCluster { /// The name of the load-balanced Kubernetes Service providing the bootstrap address. Kafka clients will use this /// to get a list of broker addresses and will use those to transmit data to the correct broker. - pub fn bootstrap_service_name(&self) -> String { - self.name_any() + pub fn bootstrap_service_name(&self, rolegroup: &RoleGroupRef) -> String { + format!("{}-bootstrap", rolegroup.object_name()) } /// Metadata about a broker rolegroup @@ -418,6 +409,7 @@ pub struct KafkaConfig { #[fragment_attrs(serde(default))] pub graceful_shutdown_timeout: Option, + pub bootstrap_listener_class: String, pub broker_listener_class: String, } @@ -444,6 +436,7 @@ impl KafkaConfig { }, affinity: get_affinity(cluster_name, role), graceful_shutdown_timeout: Some(DEFAULT_BROKER_GRACEFUL_SHUTDOWN_TIMEOUT), + bootstrap_listener_class: Some("cluster-internal".to_string()), broker_listener_class: Some("cluster-internal".to_string()), } } diff --git a/rust/operator-binary/src/discovery.rs b/rust/operator-binary/src/discovery.rs index 991b3c02..564a171e 100644 --- a/rust/operator-binary/src/discovery.rs +++ b/rust/operator-binary/src/discovery.rs @@ -57,7 +57,7 @@ pub async fn build_discovery_configmaps( owner: &impl Resource, resolved_product_image: &ResolvedProductImage, kafka_security: &KafkaTlsSecurity, - listener: &Listener, + listeners: &[Listener], ) -> Result, Error> { let name = owner.name_unchecked(); let port_name = kafka_security.client_port_name(); @@ -67,7 +67,7 @@ pub async fn build_discovery_configmaps( owner, resolved_product_image, &name, - listener_hosts(listener, port_name)?, + listener_hosts(listeners, port_name)?, )?, // backwards compat: nodeport service is now the same as the main service, access type // is determined by the listenerclass. @@ -77,7 +77,7 @@ pub async fn build_discovery_configmaps( owner, resolved_product_image, &format!("{name}-nodeport"), - listener_hosts(listener, port_name)?, + listener_hosts(listeners, port_name)?, )?, ]) } @@ -124,19 +124,22 @@ fn build_discovery_configmap( } fn listener_hosts( - listener: &Listener, + listeners: &[Listener], port_name: &str, ) -> Result, Error> { - listener - .status - .as_ref() - .and_then(|s| s.ingress_addresses.as_deref()) - .unwrap_or_default() + listeners .iter() - .map(|x| { + .flat_map(|listener| { + listener + .status + .as_ref() + .and_then(|s| s.ingress_addresses.as_deref()) + }) + .flatten() + .map(|addr| { Ok(( - x.address.clone(), - x.ports + addr.address.clone(), + addr.ports .get(port_name) .copied() .context(NoServicePortSnafu { port_name })? diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index dfa17716..afe458b5 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -451,14 +451,6 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< None }; - let bootstrap_listener = - build_bootstrap_listener(&kafka, &resolved_product_image, &kafka_security)?; - - let bootstrap_listener = cluster_resources - .add(client, bootstrap_listener) - .await - .context(ApplyRoleServiceSnafu)?; - let vector_aggregator_address = resolve_vector_aggregator_address(&kafka, client) .await .context(ResolveVectorAggregatorAddressSnafu)?; @@ -483,6 +475,8 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< .await .context(ApplyRoleBindingSnafu)?; + let mut bootstrap_listeners = Vec::::new(); + for (rolegroup_name, rolegroup_config) in role_broker_config.iter() { let rolegroup_ref = kafka.broker_rolegroup_ref(rolegroup_name); @@ -516,6 +510,20 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< &merged_config, &rbac_sa.name_any(), )?; + let rg_bootstrap_listener = build_broker_rolegroup_bootstrap_listener( + &kafka, + &resolved_product_image, + &kafka_security, + &rolegroup_ref, + &merged_config, + )?; + + bootstrap_listeners.push( + cluster_resources + .add(client, rg_bootstrap_listener) + .await + .context(ApplyRoleServiceSnafu)?, + ); cluster_resources .add(client, rg_service) .await @@ -554,7 +562,7 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< &*kafka, &resolved_product_image, &kafka_security, - &bootstrap_listener, + &bootstrap_listeners, ) .await .context(BuildDiscoveryConfigSnafu)? @@ -591,16 +599,18 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< /// Kafka clients will use the load-balanced bootstrap service to get a list of broker addresses and will use those to /// transmit data to the correct broker. -pub fn build_bootstrap_listener( +pub fn build_broker_rolegroup_bootstrap_listener( kafka: &KafkaCluster, resolved_product_image: &ResolvedProductImage, kafka_security: &KafkaTlsSecurity, + rolegroup: &RoleGroupRef, + merged_config: &KafkaConfig, ) -> Result { let role_name = KafkaRole::Broker.to_string(); Ok(Listener { metadata: ObjectMetaBuilder::new() .name_and_namespace(kafka) - .name(kafka.bootstrap_service_name()) + .name(kafka.bootstrap_service_name(rolegroup)) .ownerreference_from_resource(kafka, None, Some(true)) .context(ObjectMissingMetadataForOwnerRefSnafu)? .with_recommended_labels(build_recommended_labels( @@ -613,7 +623,7 @@ pub fn build_bootstrap_listener( .context(MetadataBuildSnafu)? .build(), spec: ListenerSpec { - class_name: Some(kafka.spec.cluster_config.bootstrap_listener_class.clone()), + class_name: Some(merged_config.bootstrap_listener_class.clone()), ports: Some( // TODO:; produce ListenerPorts natively service_ports(kafka_security) @@ -802,11 +812,11 @@ fn build_broker_rolegroup_statefulset( let mut pvcs = merged_config.resources.storage.build_pvcs(); + // bootstrap listener should be persistent, // main broker listener is an ephemeral PVC instead pvcs.push( ListenerOperatorVolumeSourceBuilder::new( - // FIXME: error handling - &ListenerReference::ListenerName(kafka.name_unchecked()), + &ListenerReference::ListenerName(kafka.bootstrap_service_name(rolegroup_ref)), &Labels::new(), ) .and_then(|builder| builder.build_pvc(LISTENER_BOOTSTRAP_VOLUME_NAME)) From bc4488848c2882e43a65892ba7d97b034f498f72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 11 Sep 2024 12:52:40 +0200 Subject: [PATCH 18/42] make crds --- deploy/helm/kafka-operator/crds/crds.yaml | 9 ++++++--- rust/operator-binary/src/kafka_controller.rs | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/deploy/helm/kafka-operator/crds/crds.yaml b/deploy/helm/kafka-operator/crds/crds.yaml index 91ee2873..335188df 100644 --- a/deploy/helm/kafka-operator/crds/crds.yaml +++ b/deploy/helm/kafka-operator/crds/crds.yaml @@ -67,6 +67,9 @@ spec: type: object x-kubernetes-preserve-unknown-fields: true type: object + bootstrapListenerClass: + nullable: true + type: string brokerListenerClass: nullable: true type: string @@ -333,6 +336,9 @@ spec: type: object x-kubernetes-preserve-unknown-fields: true type: object + bootstrapListenerClass: + nullable: true + type: string brokerListenerClass: nullable: true type: string @@ -580,9 +586,6 @@ spec: - configMapName type: object type: object - bootstrapListenerClass: - default: cluster-internal - type: string tls: default: internalSecretClass: tls diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index afe458b5..2afeb392 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -597,7 +597,7 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< Ok(Action::await_change()) } -/// Kafka clients will use the load-balanced bootstrap service to get a list of broker addresses and will use those to +/// Kafka clients will use the load-balanced bootstrap listener to get a list of broker addresses and will use those to /// transmit data to the correct broker. pub fn build_broker_rolegroup_bootstrap_listener( kafka: &KafkaCluster, From 26d59224b0f336ec148ec0db492ac339c0e9fe9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 11 Sep 2024 13:03:37 +0200 Subject: [PATCH 19/42] CRD docs --- deploy/helm/kafka-operator/crds/crds.yaml | 4 ++++ rust/crd/src/lib.rs | 3 +++ 2 files changed, 7 insertions(+) diff --git a/deploy/helm/kafka-operator/crds/crds.yaml b/deploy/helm/kafka-operator/crds/crds.yaml index 335188df..e8786c1a 100644 --- a/deploy/helm/kafka-operator/crds/crds.yaml +++ b/deploy/helm/kafka-operator/crds/crds.yaml @@ -68,9 +68,11 @@ spec: x-kubernetes-preserve-unknown-fields: true type: object bootstrapListenerClass: + description: The ListenerClass used for bootstrapping new clients. Should use a stable ListenerClass to avoid unnecessary client restarts (such as `cluster-internal` or `external-stable`). nullable: true type: string brokerListenerClass: + description: The ListenerClass used for connecting to brokers. Should use a direct connection ListenerClass to minimize cost and minimize performance overhead (such as `cluster-internal` or `external-unstable`). nullable: true type: string gracefulShutdownTimeout: @@ -337,9 +339,11 @@ spec: x-kubernetes-preserve-unknown-fields: true type: object bootstrapListenerClass: + description: The ListenerClass used for bootstrapping new clients. Should use a stable ListenerClass to avoid unnecessary client restarts (such as `cluster-internal` or `external-stable`). nullable: true type: string brokerListenerClass: + description: The ListenerClass used for connecting to brokers. Should use a direct connection ListenerClass to minimize cost and minimize performance overhead (such as `cluster-internal` or `external-unstable`). nullable: true type: string gracefulShutdownTimeout: diff --git a/rust/crd/src/lib.rs b/rust/crd/src/lib.rs index 5561268c..f44338a0 100644 --- a/rust/crd/src/lib.rs +++ b/rust/crd/src/lib.rs @@ -409,7 +409,10 @@ pub struct KafkaConfig { #[fragment_attrs(serde(default))] pub graceful_shutdown_timeout: Option, + /// The ListenerClass used for bootstrapping new clients. Should use a stable ListenerClass to avoid unnecessary client restarts (such as `cluster-internal` or `external-stable`). pub bootstrap_listener_class: String, + + /// The ListenerClass used for connecting to brokers. Should use a direct connection ListenerClass to minimize cost and minimize performance overhead (such as `cluster-internal` or `external-unstable`). pub broker_listener_class: String, } From f1b6c62a1e948b032cb640f9129da093734ffd09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 11 Sep 2024 13:46:39 +0200 Subject: [PATCH 20/42] Delete old test files --- test.yaml | 43 ------------------------------------------- test2.yaml | 36 ------------------------------------ 2 files changed, 79 deletions(-) delete mode 100644 test.yaml delete mode 100644 test2.yaml diff --git a/test.yaml b/test.yaml deleted file mode 100644 index e7205e4a..00000000 --- a/test.yaml +++ /dev/null @@ -1,43 +0,0 @@ ---- -apiVersion: listeners.stackable.tech/v1alpha1 -kind: ListenerClass -metadata: - name: public -spec: - serviceType: NodePort ---- -apiVersion: listeners.stackable.tech/v1alpha1 -kind: ListenerClass -metadata: - name: public-lb -spec: - serviceType: LoadBalancer ---- -apiVersion: v1 -kind: Pod -metadata: - name: example-public-pod -spec: - volumes: - - name: listener - ephemeral: - volumeClaimTemplate: - metadata: - annotations: - listeners.stackable.tech/listener-class: public - spec: - storageClassName: listeners.stackable.tech - accessModes: - - ReadWriteMany - resources: - requests: - storage: "1" - containers: - - name: nginx - image: nginx - ports: - - name: http - containerPort: 80 - volumeMounts: - - name: listener - mountPath: /listener diff --git a/test2.yaml b/test2.yaml deleted file mode 100644 index 9f4204cf..00000000 --- a/test2.yaml +++ /dev/null @@ -1,36 +0,0 @@ ---- -apiVersion: zookeeper.stackable.tech/v1alpha1 -kind: ZookeeperCluster -metadata: - name: simple-zk -spec: - image: - productVersion: 3.8.0 - stackableVersion: "23.1" - servers: - roleGroups: - default: - replicas: 1 ---- -apiVersion: zookeeper.stackable.tech/v1alpha1 -kind: ZookeeperZnode -metadata: - name: simple-kafka-znode -spec: - clusterRef: - name: simple-zk ---- -apiVersion: kafka.stackable.tech/v1alpha1 -kind: KafkaCluster -metadata: - name: simple-kafka -spec: - image: - productVersion: 3.3.1 - stackableVersion: "23.4.0-rc2" - clusterConfig: - zookeeperConfigMapName: simple-kafka-znode - brokers: - roleGroups: - default: - replicas: 3 From a79b91a728a3334654340ec03e1d825f75cd34f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 11 Sep 2024 13:53:37 +0200 Subject: [PATCH 21/42] Documentation --- .../kafka/examples/getting_started/kafka.yaml | 3 +++ .../pages/usage-guide/listenerclass.adoc | 20 +++++++++++++++++++ docs/modules/kafka/partials/nav.adoc | 1 + 3 files changed, 24 insertions(+) create mode 100644 docs/modules/kafka/pages/usage-guide/listenerclass.adoc diff --git a/docs/modules/kafka/examples/getting_started/kafka.yaml b/docs/modules/kafka/examples/getting_started/kafka.yaml index 26ebf007..178e5511 100644 --- a/docs/modules/kafka/examples/getting_started/kafka.yaml +++ b/docs/modules/kafka/examples/getting_started/kafka.yaml @@ -11,6 +11,9 @@ spec: serverSecretClass: null zookeeperConfigMapName: simple-kafka-znode brokers: + config: + bootstrapListenerClass: cluster-internal + brokerListenerClass: cluster-internal roleGroups: default: replicas: 3 diff --git a/docs/modules/kafka/pages/usage-guide/listenerclass.adoc b/docs/modules/kafka/pages/usage-guide/listenerclass.adoc new file mode 100644 index 00000000..942c15c1 --- /dev/null +++ b/docs/modules/kafka/pages/usage-guide/listenerclass.adoc @@ -0,0 +1,20 @@ += Service exposition with ListenerClasses + +The operator deploys a bootstrap xref:listener-operator:listener.adoc[Listener] for each broker rolegroup, as well as a xref:listener-operator:listener.adoc[Listener] for each broker pod. + +The bootstrap Listener is used to negotiate clients' initial connection to the cluster, after which a connection is made to the relevant broker Listeners. + +They both default to only being accessible from within the Kubernetes cluster, but this can be changed by setting `.spec.brokers.config.{bootstrap,broker}ListenerClass`. + +The cluster can be configured to be accessible from outside of Kubernetes like this: + +[source,yaml] +---- +spec: + brokers: + config: + bootstrapListenerClass: external-stable # <1> + brokerListenerClass: external-unstable # <2> +---- +<1> Bootstrap listeners should prioritize having a stable address, since they will be baked into the client configuration. +<2> Broker listeners should prioritize having a direct connection, to minimize network transfer overhead. diff --git a/docs/modules/kafka/partials/nav.adoc b/docs/modules/kafka/partials/nav.adoc index fa2deedc..ed7f9352 100644 --- a/docs/modules/kafka/partials/nav.adoc +++ b/docs/modules/kafka/partials/nav.adoc @@ -2,6 +2,7 @@ ** xref:kafka:getting_started/installation.adoc[] ** xref:kafka:getting_started/first_steps.adoc[] * xref:kafka:usage-guide/index.adoc[] +** xref:kafka:usage-guide/listenerclass.adoc[] ** xref:kafka:usage-guide/storage-resources.adoc[] ** xref:kafka:usage-guide/security.adoc[] ** xref:kafka:usage-guide/monitoring.adoc[] From ad3fd98d00955074c638db802db4b2a2f73f584d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 11 Sep 2024 13:57:28 +0200 Subject: [PATCH 22/42] Try to un-angry rustdoc --- rust/operator-binary/src/discovery.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/operator-binary/src/discovery.rs b/rust/operator-binary/src/discovery.rs index 564a171e..218de7ba 100644 --- a/rust/operator-binary/src/discovery.rs +++ b/rust/operator-binary/src/discovery.rs @@ -84,7 +84,7 @@ pub async fn build_discovery_configmaps( /// Build a discovery [`ConfigMap`] containing information about how to connect to a certain [`KafkaCluster`] /// -/// `hosts` will usually come from either [`service_hosts`] or [`nodeport_hosts`]. +/// `hosts` will usually come from [`listener_hosts`]. fn build_discovery_configmap( kafka: &KafkaCluster, owner: &impl Resource, From b62edf6cd432f742849500b59d83a696e072ecd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 11 Sep 2024 15:37:53 +0200 Subject: [PATCH 23/42] Re-enable orphan cleanup --- Cargo.lock | 54 +++++++++--------- Cargo.nix | 60 ++++++++++---------- Cargo.toml | 3 +- crate-hashes.json | 4 +- rust/operator-binary/src/kafka_controller.rs | 8 +-- 5 files changed, 65 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc4bd22c..8268a403 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,7 +146,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -157,7 +157,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -329,7 +329,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -444,7 +444,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -455,7 +455,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -466,7 +466,7 @@ checksum = "4e018fccbeeb50ff26562ece792ed06659b9c2dae79ece77c4456bb10d9bf79b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -673,7 +673,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1192,7 +1192,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1531,7 +1531,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1562,7 +1562,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1771,7 +1771,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.76", + "syn 2.0.77", "unicode-ident", ] @@ -1888,7 +1888,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1963,7 +1963,7 @@ checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1974,7 +1974,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2102,7 +2102,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2160,7 +2160,7 @@ dependencies = [ [[package]] name = "stackable-operator" version = "0.74.0" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=main#04f3b11719725e144c50f14f0c430191ca26aea0" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=bugfix/clusterresources-ownerreferences#fcb74606adc66a69b8a793da15778b928b20bde1" dependencies = [ "chrono", "clap", @@ -2196,12 +2196,12 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=main#04f3b11719725e144c50f14f0c430191ca26aea0" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=bugfix/clusterresources-ownerreferences#fcb74606adc66a69b8a793da15778b928b20bde1" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2229,7 +2229,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2251,9 +2251,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.76" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -2277,7 +2277,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2384,7 +2384,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2520,7 +2520,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2723,7 +2723,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "wasm-bindgen-shared", ] @@ -2745,7 +2745,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2903,7 +2903,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] diff --git a/Cargo.nix b/Cargo.nix index eefee269..5fb7f001 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -446,7 +446,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "full" "visit-mut" ]; } ]; @@ -473,7 +473,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; usesDefaultFeatures = false; features = [ "full" "visit-mut" "parsing" "printing" "proc-macro" ]; } @@ -983,7 +983,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "full" ]; } ]; @@ -1287,7 +1287,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "full" "extra-traits" ]; } ]; @@ -1317,7 +1317,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; } ]; @@ -1343,7 +1343,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "full" "visit-mut" ]; } ]; @@ -1888,7 +1888,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "full" ]; } ]; @@ -3693,7 +3693,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "extra-traits" ]; } ]; @@ -4788,7 +4788,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; } ]; features = { @@ -4861,7 +4861,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "full" "visit-mut" ]; } ]; @@ -5498,7 +5498,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "full" "parsing" "extra-traits" "visit" "visit-mut" ]; } { @@ -5863,7 +5863,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "extra-traits" ]; } ]; @@ -6081,7 +6081,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; usesDefaultFeatures = false; features = [ "clone-impls" "derive" "parsing" "printing" "proc-macro" ]; } @@ -6113,7 +6113,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; usesDefaultFeatures = false; features = [ "clone-impls" "derive" "parsing" "printing" ]; } @@ -6484,7 +6484,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "full" ]; } ]; @@ -6691,8 +6691,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "04f3b11719725e144c50f14f0c430191ca26aea0"; - sha256 = "0xz4hyca5pyjabwryngq74q1qq7cnhfjrn0b84nc78nv7lynw5g0"; + rev = "fcb74606adc66a69b8a793da15778b928b20bde1"; + sha256 = "16wkpf50np10j8znhjmqvni3pbik1k6ba3z1kqf199yl76079x10"; }; libName = "stackable_operator"; authors = [ @@ -6841,8 +6841,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "04f3b11719725e144c50f14f0c430191ca26aea0"; - sha256 = "0xz4hyca5pyjabwryngq74q1qq7cnhfjrn0b84nc78nv7lynw5g0"; + rev = "fcb74606adc66a69b8a793da15778b928b20bde1"; + sha256 = "16wkpf50np10j8znhjmqvni3pbik1k6ba3z1kqf199yl76079x10"; }; procMacro = true; libName = "stackable_operator_derive"; @@ -6864,7 +6864,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; } ]; @@ -6937,7 +6937,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "parsing" "extra-traits" ]; } ]; @@ -6990,11 +6990,11 @@ rec { }; resolvedDefaultFeatures = [ "clone-impls" "default" "derive" "extra-traits" "full" "parsing" "printing" "proc-macro" "quote" "visit" ]; }; - "syn 2.0.76" = rec { + "syn 2.0.77" = rec { crateName = "syn"; - version = "2.0.76"; + version = "2.0.77"; edition = "2021"; - sha256 = "09fmdkmqqkkfkg53qnldl10ppwqkqlw22ixhg4rgrkp02hd0i3jp"; + sha256 = "1vbkwfp9ymmi0fsyyjsqfvnv7gm8vjgl4pzprbk7p3pxc7gvqdcz"; authors = [ "David Tolnay " ]; @@ -7060,7 +7060,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; } ]; @@ -7422,7 +7422,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "full" ]; } ]; @@ -7956,7 +7956,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; usesDefaultFeatures = false; features = [ "full" "parsing" "printing" "visit-mut" "clone-impls" "extra-traits" "proc-macro" ]; } @@ -8594,7 +8594,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "full" ]; } { @@ -8653,7 +8653,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; features = [ "visit" "full" ]; } { @@ -9250,7 +9250,7 @@ rec { } { name = "syn"; - packageId = "syn 2.0.76"; + packageId = "syn 2.0.77"; } ]; diff --git a/Cargo.toml b/Cargo.toml index 27a1fb74..c0410f49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,4 +29,5 @@ tracing = "0.1" [patch."https://github.com/stackabletech/operator-rs.git"] # stackable-operator = { path = "../operator-rs/crates/stackable-operator" } -stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } +# stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } +stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "bugfix/clusterresources-ownerreferences" } diff --git a/crate-hashes.json b/crate-hashes.json index 739c5e1f..4869917f 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,5 +1,5 @@ { - "git+https://github.com/stackabletech//operator-rs.git?branch=main#stackable-operator-derive@0.3.1": "0xz4hyca5pyjabwryngq74q1qq7cnhfjrn0b84nc78nv7lynw5g0", - "git+https://github.com/stackabletech//operator-rs.git?branch=main#stackable-operator@0.74.0": "0xz4hyca5pyjabwryngq74q1qq7cnhfjrn0b84nc78nv7lynw5g0", + "git+https://github.com/stackabletech//operator-rs.git?branch=bugfix%2Fclusterresources-ownerreferences#stackable-operator-derive@0.3.1": "16wkpf50np10j8znhjmqvni3pbik1k6ba3z1kqf199yl76079x10", + "git+https://github.com/stackabletech//operator-rs.git?branch=bugfix%2Fclusterresources-ownerreferences#stackable-operator@0.74.0": "16wkpf50np10j8znhjmqvni3pbik1k6ba3z1kqf199yl76079x10", "git+https://github.com/stackabletech/product-config.git?tag=0.7.0#product-config@0.7.0": "0gjsm80g6r75pm3824dcyiz4ysq1ka4c1if6k1mjm9cnd5ym0gny" } \ No newline at end of file diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index 2afeb392..478cbde1 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -584,10 +584,10 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< }; // FIXME: https://github.com/stackabletech/operator-rs/issues/861 - // cluster_resources - // .delete_orphaned_resources(client) - // .await - // .context(DeleteOrphansSnafu)?; + cluster_resources + .delete_orphaned_resources(client) + .await + .context(DeleteOrphansSnafu)?; client .apply_patch_status(OPERATOR_NAME, &*kafka, &status) From a6343d40a5544d709ecb010a39f2d30228546507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 11 Sep 2024 15:49:33 +0200 Subject: [PATCH 24/42] Changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fca81f2..35edd7ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ All notable changes to this project will be documented in this file. - Reduce CRD size from `479KB` to `53KB` by accepting arbitrary YAML input instead of the underlying schema for the following fields ([#750]): - `podOverrides` - `affinity` +- Migrate to exposing Kafka using Listener Operator ([#443]). + - BREAKING: The existing services will be migrated to the new format. Clients will need to re-read settings from the discovery configmap. + - BREAKING: Kafka is now only accessible from within the Kubernetes cluster by default. Set listener classes manually to expose it to the outside world (again). ### Fixed @@ -24,6 +27,7 @@ All notable changes to this project will be documented in this file. - Remove versions `3.4.1`, `3.6.1`, `3.6.2` ([#753]). +[#443]: https://github.com/stackabletech/kafka-operator/pull/443 [#741]: https://github.com/stackabletech/kafka-operator/pull/741 [#750]: https://github.com/stackabletech/kafka-operator/pull/750 [#753]: https://github.com/stackabletech/kafka-operator/pull/753 From 6a1a423fc0c06db2d295a5fd1e1fdcfc1942ee0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 11 Sep 2024 16:20:28 +0200 Subject: [PATCH 25/42] Fix configuration test --- tests/templates/kuttl/configuration/20-assert.yaml.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/templates/kuttl/configuration/20-assert.yaml.j2 b/tests/templates/kuttl/configuration/20-assert.yaml.j2 index e44076dc..f3f09708 100644 --- a/tests/templates/kuttl/configuration/20-assert.yaml.j2 +++ b/tests/templates/kuttl/configuration/20-assert.yaml.j2 @@ -36,3 +36,5 @@ spec: # value set in the role configuration and overridden in # the rolegroup configuration storage: 1Gi + - metadata: + name: listener-bootstrap From 194d98d7e7086a4cc24e0cbb7fb9f79eefeb6b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Tue, 1 Oct 2024 16:21:26 +0200 Subject: [PATCH 26/42] Update docs/modules/kafka/examples/getting_started/kafka.yaml Co-authored-by: Sebastian Bernauer --- docs/modules/kafka/examples/getting_started/kafka.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/modules/kafka/examples/getting_started/kafka.yaml b/docs/modules/kafka/examples/getting_started/kafka.yaml index 178e5511..fad811e1 100644 --- a/docs/modules/kafka/examples/getting_started/kafka.yaml +++ b/docs/modules/kafka/examples/getting_started/kafka.yaml @@ -12,8 +12,8 @@ spec: zookeeperConfigMapName: simple-kafka-znode brokers: config: - bootstrapListenerClass: cluster-internal - brokerListenerClass: cluster-internal + bootstrapListenerClass: external-unstable # This exposes your Stacklet outside of Kubernetes. Remove this property if this is not desired + brokerListenerClass: external-unstable # This exposes your Stacklet outside of Kubernetes. Remove this property if this is not desired roleGroups: default: replicas: 3 From b01c22fa8228132ad34f0c841cd200b04ed35fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Tue, 1 Oct 2024 16:36:09 +0200 Subject: [PATCH 27/42] Rename TLS volume variables for consistency --- rust/crd/src/security.rs | 53 +++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/rust/crd/src/security.rs b/rust/crd/src/security.rs index e65263ef..a444bb51 100644 --- a/rust/crd/src/security.rs +++ b/rust/crd/src/security.rs @@ -96,14 +96,12 @@ impl KafkaTlsSecurity { const INTER_SSL_TRUSTSTORE_TYPE: &'static str = "listener.name.internal.ssl.truststore.type"; const INTER_SSL_CLIENT_AUTH: &'static str = "listener.name.internal.ssl.client.auth"; // directories - // for kcat container - const STACKABLE_TLS_CERT_KCAT_DIR: &'static str = "/stackable/tls_cert_kcat"; - const STACKABLE_TLS_CERT_KCAT_DIR_NAME: &'static str = "tls-cert-kcat"; - // kafka container - const STACKABLE_TLS_KEYSTORE_SERVER_DIR: &'static str = "/stackable/tls_keystore_server"; - const STACKABLE_TLS_KEYSTORE_SERVER_DIR_NAME: &'static str = "tls-keystore-server"; - const STACKABLE_TLS_KEYSTORE_INTERNAL_DIR: &'static str = "/stackable/tls_keystore_internal"; - const STACKABLE_TLS_KEYSTORE_INTERNAL_DIR_NAME: &'static str = "tls-keystore-internal"; + const STACKABLE_TLS_KCAT_DIR: &'static str = "/stackable/tls_cert_kcat"; + const STACKABLE_TLS_KCAT_VOLUME_NAME: &'static str = "tls-cert-kcat"; + const STACKABLE_TLS_KAFKA_SERVER_DIR: &'static str = "/stackable/tls_keystore_server"; + const STACKABLE_TLS_KAFKA_SERVER_VOLUME_NAME: &'static str = "tls-keystore-server"; + const STACKABLE_TLS_KAFKA_INTERNAL_DIR: &'static str = "/stackable/tls_keystore_internal"; + const STACKABLE_TLS_KAFKA_INTERNAL_VOLUME_NAME: &'static str = "tls-keystore-internal"; #[cfg(test)] pub fn new( @@ -213,13 +211,11 @@ impl KafkaTlsSecurity { if self.tls_client_authentication_class().is_some() { args.push("-b".to_string()); args.push(format!("localhost:{}", port)); - args.extend(Self::kcat_client_auth_ssl( - Self::STACKABLE_TLS_CERT_KCAT_DIR, - )); + args.extend(Self::kcat_client_auth_ssl(Self::STACKABLE_TLS_KCAT_DIR)); } else if self.tls_server_secret_class().is_some() { args.push("-b".to_string()); args.push(format!("localhost:{}", port)); - args.extend(Self::kcat_client_ssl(Self::STACKABLE_TLS_CERT_KCAT_DIR)); + args.extend(Self::kcat_client_ssl(Self::STACKABLE_TLS_KCAT_DIR)); } else { args.push("-b".to_string()); args.push(format!("localhost:{}", port)); @@ -269,32 +265,32 @@ impl KafkaTlsSecurity { if let Some(tls_server_secret_class) = self.get_tls_secret_class() { // We have to mount tls pem files for kcat (the mount can be used directly) pod_builder.add_volume(Self::create_kcat_tls_volume( - Self::STACKABLE_TLS_CERT_KCAT_DIR_NAME, + Self::STACKABLE_TLS_KCAT_VOLUME_NAME, tls_server_secret_class, )?); cb_kcat_prober.add_volume_mount( - Self::STACKABLE_TLS_CERT_KCAT_DIR_NAME, - Self::STACKABLE_TLS_CERT_KCAT_DIR, + Self::STACKABLE_TLS_KCAT_VOLUME_NAME, + Self::STACKABLE_TLS_KCAT_DIR, ); // Keystores fore the kafka container pod_builder.add_volume(Self::create_tls_keystore_volume( - Self::STACKABLE_TLS_KEYSTORE_SERVER_DIR_NAME, + Self::STACKABLE_TLS_KAFKA_SERVER_VOLUME_NAME, tls_server_secret_class, )?); cb_kafka.add_volume_mount( - Self::STACKABLE_TLS_KEYSTORE_SERVER_DIR_NAME, - Self::STACKABLE_TLS_KEYSTORE_SERVER_DIR, + Self::STACKABLE_TLS_KAFKA_SERVER_VOLUME_NAME, + Self::STACKABLE_TLS_KAFKA_SERVER_DIR, ); } if let Some(tls_internal_secret_class) = self.tls_internal_secret_class() { pod_builder.add_volume(Self::create_tls_keystore_volume( - Self::STACKABLE_TLS_KEYSTORE_INTERNAL_DIR_NAME, + Self::STACKABLE_TLS_KAFKA_INTERNAL_VOLUME_NAME, tls_internal_secret_class, )?); cb_kafka.add_volume_mount( - Self::STACKABLE_TLS_KEYSTORE_INTERNAL_DIR_NAME, - Self::STACKABLE_TLS_KEYSTORE_INTERNAL_DIR, + Self::STACKABLE_TLS_KAFKA_INTERNAL_VOLUME_NAME, + Self::STACKABLE_TLS_KAFKA_INTERNAL_DIR, ); } @@ -312,7 +308,7 @@ impl KafkaTlsSecurity { if self.tls_client_authentication_class().is_some() { config.insert( Self::CLIENT_AUTH_SSL_KEYSTORE_LOCATION.to_string(), - format!("{}/keystore.p12", Self::STACKABLE_TLS_KEYSTORE_SERVER_DIR), + format!("{}/keystore.p12", Self::STACKABLE_TLS_KAFKA_SERVER_DIR), ); config.insert( Self::CLIENT_AUTH_SSL_KEYSTORE_PASSWORD.to_string(), @@ -324,7 +320,7 @@ impl KafkaTlsSecurity { ); config.insert( Self::CLIENT_AUTH_SSL_TRUSTSTORE_LOCATION.to_string(), - format!("{}/truststore.p12", Self::STACKABLE_TLS_KEYSTORE_SERVER_DIR), + format!("{}/truststore.p12", Self::STACKABLE_TLS_KAFKA_SERVER_DIR), ); config.insert( Self::CLIENT_AUTH_SSL_TRUSTSTORE_PASSWORD.to_string(), @@ -342,7 +338,7 @@ impl KafkaTlsSecurity { } else if self.tls_server_secret_class().is_some() { config.insert( Self::CLIENT_SSL_KEYSTORE_LOCATION.to_string(), - format!("{}/keystore.p12", Self::STACKABLE_TLS_KEYSTORE_SERVER_DIR), + format!("{}/keystore.p12", Self::STACKABLE_TLS_KAFKA_SERVER_DIR), ); config.insert( Self::CLIENT_SSL_KEYSTORE_PASSWORD.to_string(), @@ -354,7 +350,7 @@ impl KafkaTlsSecurity { ); config.insert( Self::CLIENT_SSL_TRUSTSTORE_LOCATION.to_string(), - format!("{}/truststore.p12", Self::STACKABLE_TLS_KEYSTORE_SERVER_DIR), + format!("{}/truststore.p12", Self::STACKABLE_TLS_KAFKA_SERVER_DIR), ); config.insert( Self::CLIENT_SSL_TRUSTSTORE_PASSWORD.to_string(), @@ -370,7 +366,7 @@ impl KafkaTlsSecurity { if self.tls_internal_secret_class().is_some() { config.insert( Self::INTER_SSL_KEYSTORE_LOCATION.to_string(), - format!("{}/keystore.p12", Self::STACKABLE_TLS_KEYSTORE_INTERNAL_DIR), + format!("{}/keystore.p12", Self::STACKABLE_TLS_KAFKA_INTERNAL_DIR), ); config.insert( Self::INTER_SSL_KEYSTORE_PASSWORD.to_string(), @@ -382,10 +378,7 @@ impl KafkaTlsSecurity { ); config.insert( Self::INTER_SSL_TRUSTSTORE_LOCATION.to_string(), - format!( - "{}/truststore.p12", - Self::STACKABLE_TLS_KEYSTORE_INTERNAL_DIR - ), + format!("{}/truststore.p12", Self::STACKABLE_TLS_KAFKA_INTERNAL_DIR), ); config.insert( Self::INTER_SSL_TRUSTSTORE_PASSWORD.to_string(), From 220bc4cd362733d501cd595f129bc8ba2c5205f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Tue, 1 Oct 2024 16:38:02 +0200 Subject: [PATCH 28/42] Rename volumes/paths too, correspondingly --- rust/crd/src/security.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rust/crd/src/security.rs b/rust/crd/src/security.rs index a444bb51..f1874049 100644 --- a/rust/crd/src/security.rs +++ b/rust/crd/src/security.rs @@ -96,12 +96,12 @@ impl KafkaTlsSecurity { const INTER_SSL_TRUSTSTORE_TYPE: &'static str = "listener.name.internal.ssl.truststore.type"; const INTER_SSL_CLIENT_AUTH: &'static str = "listener.name.internal.ssl.client.auth"; // directories - const STACKABLE_TLS_KCAT_DIR: &'static str = "/stackable/tls_cert_kcat"; - const STACKABLE_TLS_KCAT_VOLUME_NAME: &'static str = "tls-cert-kcat"; - const STACKABLE_TLS_KAFKA_SERVER_DIR: &'static str = "/stackable/tls_keystore_server"; - const STACKABLE_TLS_KAFKA_SERVER_VOLUME_NAME: &'static str = "tls-keystore-server"; - const STACKABLE_TLS_KAFKA_INTERNAL_DIR: &'static str = "/stackable/tls_keystore_internal"; - const STACKABLE_TLS_KAFKA_INTERNAL_VOLUME_NAME: &'static str = "tls-keystore-internal"; + const STACKABLE_TLS_KCAT_DIR: &'static str = "/stackable/tls-kcat"; + const STACKABLE_TLS_KCAT_VOLUME_NAME: &'static str = "tls-kcat"; + const STACKABLE_TLS_KAFKA_SERVER_DIR: &'static str = "/stackable/tls-kafka-server"; + const STACKABLE_TLS_KAFKA_SERVER_VOLUME_NAME: &'static str = "tls-kafka-server"; + const STACKABLE_TLS_KAFKA_INTERNAL_DIR: &'static str = "/stackable/tls-kafka-internal"; + const STACKABLE_TLS_KAFKA_INTERNAL_VOLUME_NAME: &'static str = "tls-kafka-internal"; #[cfg(test)] pub fn new( From df56f73d2e60a5121c4c7be8429c46ec0d63f19d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Tue, 1 Oct 2024 16:40:36 +0200 Subject: [PATCH 29/42] Remove stale FIXME --- rust/operator-binary/src/kafka_controller.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index 478cbde1..81f0d098 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -583,7 +583,6 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< ), }; - // FIXME: https://github.com/stackabletech/operator-rs/issues/861 cluster_resources .delete_orphaned_resources(client) .await From 66db99c7a42b33c0756bbb0a8ad21f6294bb85b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Tue, 1 Oct 2024 17:13:51 +0200 Subject: [PATCH 30/42] Add RBAC permission to delete listeners (orphan clenaup) --- deploy/helm/kafka-operator/templates/roles.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/helm/kafka-operator/templates/roles.yaml b/deploy/helm/kafka-operator/templates/roles.yaml index c686bda8..52fa9d25 100644 --- a/deploy/helm/kafka-operator/templates/roles.yaml +++ b/deploy/helm/kafka-operator/templates/roles.yaml @@ -123,6 +123,7 @@ rules: - watch - patch - create + - delete - apiGroups: - rbac.authorization.k8s.io resources: From 362dc80299347a5e384777d2d494ccc276135fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Tue, 1 Oct 2024 17:14:19 +0200 Subject: [PATCH 31/42] Make service_ports return ListenerPorts instead --- rust/operator-binary/src/kafka_controller.rs | 36 +++++--------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index 81f0d098..adea8083 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -46,7 +46,7 @@ use stackable_operator::{ core::v1::{ ConfigMap, ConfigMapKeySelector, ConfigMapVolumeSource, ContainerPort, EnvVar, EnvVarSource, ExecAction, ObjectFieldSelector, PodSpec, Probe, Service, - ServicePort, ServiceSpec, Volume, + ServiceSpec, Volume, }, }, apimachinery::pkg::apis::meta::v1::LabelSelector, @@ -484,12 +484,8 @@ pub async fn reconcile_kafka(kafka: Arc, ctx: Arc) -> Result< .merged_config(&KafkaRole::Broker, &rolegroup_ref) .context(FailedToResolveConfigSnafu)?; - let rg_service = build_broker_rolegroup_service( - &kafka, - &resolved_product_image, - &kafka_security, - &rolegroup_ref, - )?; + let rg_service = + build_broker_rolegroup_service(&kafka, &resolved_product_image, &rolegroup_ref)?; let rg_configmap = build_broker_rolegroup_config_map( &kafka, &resolved_product_image, @@ -623,17 +619,7 @@ pub fn build_broker_rolegroup_bootstrap_listener( .build(), spec: ListenerSpec { class_name: Some(merged_config.bootstrap_listener_class.clone()), - ports: Some( - // TODO:; produce ListenerPorts natively - service_ports(kafka_security) - .into_iter() - .map(|port| ListenerPort { - name: port.name.unwrap_or_default(), - port: port.port, - protocol: port.protocol, - }) - .collect(), - ), + ports: Some(listener_ports(kafka_security)), ..ListenerSpec::default() }, status: None, @@ -731,7 +717,6 @@ fn build_broker_rolegroup_config_map( fn build_broker_rolegroup_service( kafka: &KafkaCluster, resolved_product_image: &ResolvedProductImage, - kafka_security: &KafkaTlsSecurity, rolegroup: &RoleGroupRef, ) -> Result { Ok(Service { @@ -752,7 +737,6 @@ fn build_broker_rolegroup_service( .build(), spec: Some(ServiceSpec { cluster_ip: Some("None".to_string()), - ports: Some(service_ports(kafka_security)), selector: Some( Labels::role_group_selector( kafka, @@ -1083,19 +1067,17 @@ pub fn error_policy(_obj: Arc, _error: &Error, _ctx: Arc) -> } /// We only expose client HTTP / HTTPS and Metrics ports. -fn service_ports(kafka_security: &KafkaTlsSecurity) -> Vec { +fn listener_ports(kafka_security: &KafkaTlsSecurity) -> Vec { vec![ - ServicePort { - name: Some(METRICS_PORT_NAME.to_string()), + ListenerPort { + name: METRICS_PORT_NAME.to_string(), port: METRICS_PORT.into(), protocol: Some("TCP".to_string()), - ..ServicePort::default() }, - ServicePort { - name: Some(kafka_security.client_port_name().to_string()), + ListenerPort { + name: kafka_security.client_port_name().to_string(), port: kafka_security.client_port().into(), protocol: Some("TCP".to_string()), - ..ServicePort::default() }, ] } From fa9b8e294d0836d6f366cf395ecf63ffa55db70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Tue, 1 Oct 2024 17:20:42 +0200 Subject: [PATCH 32/42] Recommend using the same ListenerClass across rolegroups --- docs/modules/kafka/pages/usage-guide/listenerclass.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/modules/kafka/pages/usage-guide/listenerclass.adoc b/docs/modules/kafka/pages/usage-guide/listenerclass.adoc index 942c15c1..e484bda3 100644 --- a/docs/modules/kafka/pages/usage-guide/listenerclass.adoc +++ b/docs/modules/kafka/pages/usage-guide/listenerclass.adoc @@ -18,3 +18,5 @@ spec: ---- <1> Bootstrap listeners should prioritize having a stable address, since they will be baked into the client configuration. <2> Broker listeners should prioritize having a direct connection, to minimize network transfer overhead. + +NOTE: All rolegroups should use the same ListenerClass, or at least ones with similar properties. Clients will be unable to access data stored on replicas in rolegroups with inaccessible ListenerClasses. From 88dde6b4adbb67ce1697800956c8c9192412e6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 2 Oct 2024 16:01:22 +0200 Subject: [PATCH 33/42] Apply recommended labels to broker listeners --- rust/operator-binary/src/kafka_controller.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index adea8083..fd94062e 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -948,14 +948,15 @@ fn build_broker_rolegroup_statefulset( }); } + let recommended_labels = build_recommended_labels( + kafka, + KAFKA_CONTROLLER_NAME, + &resolved_product_image.app_version_label, + &rolegroup_ref.role, + &rolegroup_ref.role_group, + ); let metadata = ObjectMetaBuilder::new() - .with_recommended_labels(build_recommended_labels( - kafka, - KAFKA_CONTROLLER_NAME, - &resolved_product_image.app_version_label, - &rolegroup_ref.role, - &rolegroup_ref.role_group, - )) + .with_recommended_labels(recommended_labels.clone()) .context(MetadataBuildSnafu)? .build(); @@ -977,7 +978,7 @@ fn build_broker_rolegroup_statefulset( .add_listener_volume_by_listener_class( LISTENER_BROKER_VOLUME_NAME, &merged_config.broker_listener_class, - &Labels::new(), + &Labels::recommended(recommended_labels).context(LabelBuildSnafu)?, ) .context(AddListenerVolumeSnafu)? .add_empty_dir_volume( From 7aa5919b87babc2ec613025131c0448f63a995e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 2 Oct 2024 16:10:40 +0200 Subject: [PATCH 34/42] Apply the correct rolegroup to bootstrap listeners, too --- rust/operator-binary/src/kafka_controller.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index fd94062e..49eae937 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -601,7 +601,6 @@ pub fn build_broker_rolegroup_bootstrap_listener( rolegroup: &RoleGroupRef, merged_config: &KafkaConfig, ) -> Result { - let role_name = KafkaRole::Broker.to_string(); Ok(Listener { metadata: ObjectMetaBuilder::new() .name_and_namespace(kafka) @@ -612,8 +611,8 @@ pub fn build_broker_rolegroup_bootstrap_listener( kafka, KAFKA_CONTROLLER_NAME, &resolved_product_image.app_version_label, - &role_name, - "global", + &rolegroup.role, + &rolegroup.role_group, )) .context(MetadataBuildSnafu)? .build(), From 534d88e817a3c6ac4cc2b1ac42e66c4bb43e1d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 2 Oct 2024 16:14:15 +0200 Subject: [PATCH 35/42] Apply the correct rolegroup label to the rolegroup configmaps --- rust/operator-binary/src/kafka_controller.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index 49eae937..792680cb 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -671,7 +671,7 @@ fn build_broker_rolegroup_config_map( KAFKA_CONTROLLER_NAME, &resolved_product_image.app_version_label, &rolegroup.role, - "global", + &rolegroup.role_group, )) .context(MetadataBuildSnafu)? .build(), From 7dae34d4fa5774c3415c80de60ba604b8cffdd91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Wed, 2 Oct 2024 16:18:57 +0200 Subject: [PATCH 36/42] Apply recommended labels to the bootstrap listener PVC too --- rust/operator-binary/src/kafka_controller.rs | 22 +++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index 792680cb..0c200d4e 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -772,6 +772,15 @@ fn build_broker_rolegroup_statefulset( let rolegroup = kafka .rolegroup(rolegroup_ref) .context(InternalOperatorSnafu)?; + let recommended_object_labels = build_recommended_labels( + kafka, + KAFKA_CONTROLLER_NAME, + &resolved_product_image.app_version_label, + &rolegroup_ref.role, + &rolegroup_ref.role_group, + ); + let recommended_labels = + Labels::recommended(recommended_object_labels.clone()).context(LabelBuildSnafu)?; let kcat_prober_container_name = Container::KcatProber.to_string(); let mut cb_kcat_prober = @@ -799,7 +808,7 @@ fn build_broker_rolegroup_statefulset( pvcs.push( ListenerOperatorVolumeSourceBuilder::new( &ListenerReference::ListenerName(kafka.bootstrap_service_name(rolegroup_ref)), - &Labels::new(), + &recommended_labels, ) .and_then(|builder| builder.build_pvc(LISTENER_BOOTSTRAP_VOLUME_NAME)) .unwrap(), @@ -947,15 +956,8 @@ fn build_broker_rolegroup_statefulset( }); } - let recommended_labels = build_recommended_labels( - kafka, - KAFKA_CONTROLLER_NAME, - &resolved_product_image.app_version_label, - &rolegroup_ref.role, - &rolegroup_ref.role_group, - ); let metadata = ObjectMetaBuilder::new() - .with_recommended_labels(recommended_labels.clone()) + .with_recommended_labels(recommended_object_labels) .context(MetadataBuildSnafu)? .build(); @@ -977,7 +979,7 @@ fn build_broker_rolegroup_statefulset( .add_listener_volume_by_listener_class( LISTENER_BROKER_VOLUME_NAME, &merged_config.broker_listener_class, - &Labels::recommended(recommended_labels).context(LabelBuildSnafu)?, + &recommended_labels, ) .context(AddListenerVolumeSnafu)? .add_empty_dir_volume( From 291308109e40448f238742ec7a7b0541f608d11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Thu, 3 Oct 2024 15:34:56 +0200 Subject: [PATCH 37/42] Remove version from persistent PVCs It broke upgrading --- rust/operator-binary/src/kafka_controller.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/rust/operator-binary/src/kafka_controller.rs b/rust/operator-binary/src/kafka_controller.rs index d12a3403..e34b5b23 100644 --- a/rust/operator-binary/src/kafka_controller.rs +++ b/rust/operator-binary/src/kafka_controller.rs @@ -797,6 +797,16 @@ fn build_broker_rolegroup_statefulset( ); let recommended_labels = Labels::recommended(recommended_object_labels.clone()).context(LabelBuildSnafu)?; + // Used for PVC templates that cannot be modified once they are deployed + let unversioned_recommended_labels = Labels::recommended(build_recommended_labels( + kafka, + KAFKA_CONTROLLER_NAME, + // A version value is required, and we do want to use the "recommended" format for the other desired labels + "none", + &rolegroup_ref.role, + &rolegroup_ref.role_group, + )) + .context(LabelBuildSnafu)?; let kcat_prober_container_name = Container::KcatProber.to_string(); let mut cb_kcat_prober = @@ -824,7 +834,7 @@ fn build_broker_rolegroup_statefulset( pvcs.push( ListenerOperatorVolumeSourceBuilder::new( &ListenerReference::ListenerName(kafka.bootstrap_service_name(rolegroup_ref)), - &recommended_labels, + &unversioned_recommended_labels, ) .and_then(|builder| builder.build_pvc(LISTENER_BOOTSTRAP_VOLUME_NAME)) .unwrap(), From 11a481461b27a6f474bc7e4c8078c3d78c765df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Fri, 4 Oct 2024 12:07:23 +0200 Subject: [PATCH 38/42] Add note about upgrading to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35edd7ba..2f68b765 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file. - Migrate to exposing Kafka using Listener Operator ([#443]). - BREAKING: The existing services will be migrated to the new format. Clients will need to re-read settings from the discovery configmap. - BREAKING: Kafka is now only accessible from within the Kubernetes cluster by default. Set listener classes manually to expose it to the outside world (again). + - BREAKING: To complete an upgrade to this kafka-operator, all existing Kafka StatefulSets must be deleted manually. This will cause some downtime. ### Fixed From 6e2d0d376cceab3c72296fa896ef167230d7911a Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Mon, 7 Oct 2024 13:39:06 +0200 Subject: [PATCH 39/42] docs: Add note on what bootstrap listeners return --- docs/modules/kafka/pages/usage-guide/listenerclass.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/modules/kafka/pages/usage-guide/listenerclass.adoc b/docs/modules/kafka/pages/usage-guide/listenerclass.adoc index e484bda3..a79d460f 100644 --- a/docs/modules/kafka/pages/usage-guide/listenerclass.adoc +++ b/docs/modules/kafka/pages/usage-guide/listenerclass.adoc @@ -3,6 +3,7 @@ The operator deploys a bootstrap xref:listener-operator:listener.adoc[Listener] for each broker rolegroup, as well as a xref:listener-operator:listener.adoc[Listener] for each broker pod. The bootstrap Listener is used to negotiate clients' initial connection to the cluster, after which a connection is made to the relevant broker Listeners. +Please note that every bootstrap Listener (regardless of the underlying rolegroup) will return all brokers of all rolegroups. They both default to only being accessible from within the Kubernetes cluster, but this can be changed by setting `.spec.brokers.config.{bootstrap,broker}ListenerClass`. From c1c8c9f470e2baf8a844571d585ef1faeb830952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Mon, 7 Oct 2024 14:10:42 +0200 Subject: [PATCH 40/42] Update futures to 0.3.31 0.3.30 was yanked due to soundness issues. --- Cargo.lock | 46 +++++++++++++++++++++++----------------------- Cargo.nix | 50 +++++++++++++++++++++++++------------------------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76929333..2942fd70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -619,9 +619,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -634,9 +634,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -644,15 +644,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -661,15 +661,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -678,15 +678,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-timer" @@ -696,9 +696,9 @@ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures 0.1.31", "futures-channel", @@ -1142,7 +1142,7 @@ dependencies = [ "bytes", "chrono", "either", - "futures 0.3.30", + "futures 0.3.31", "home", "http", "http-body", @@ -1213,7 +1213,7 @@ dependencies = [ "async-trait", "backoff", "derivative", - "futures 0.3.30", + "futures 0.3.31", "hashbrown 0.14.5", "json-patch", "jsonptr", @@ -1766,7 +1766,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a2c585be59b6b5dd66a9d2084aa1d8bd52fbdb806eafdeffb52791147862035" dependencies = [ - "futures 0.3.30", + "futures 0.3.31", "futures-timer", "rstest_macros", "rustc_version", @@ -2171,7 +2171,7 @@ dependencies = [ "anyhow", "built", "clap", - "futures 0.3.30", + "futures 0.3.31", "product-config", "serde", "serde_json", @@ -2196,7 +2196,7 @@ dependencies = [ "derivative", "dockerfile-parser", "either", - "futures 0.3.30", + "futures 0.3.31", "indexmap", "json-patch", "k8s-openapi", diff --git a/Cargo.nix b/Cargo.nix index 6bbf71b5..9690a564 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -1725,11 +1725,11 @@ rec { }; resolvedDefaultFeatures = [ "default" "use_std" "with-deprecated" ]; }; - "futures 0.3.30" = rec { + "futures 0.3.31" = rec { crateName = "futures"; - version = "0.3.30"; + version = "0.3.31"; edition = "2018"; - sha256 = "1c04g14bccmprwsvx2j9m2blhwrynq7vhl151lsvcv4gi0b6jp34"; + sha256 = "0xh8ddbkm9jy8kc5gbvjp9a4b6rqqxvc8471yb2qaz5wm2qhgg35"; dependencies = [ { name = "futures-channel"; @@ -1788,9 +1788,9 @@ rec { }; "futures-channel" = rec { crateName = "futures-channel"; - version = "0.3.30"; + version = "0.3.31"; edition = "2018"; - sha256 = "0y6b7xxqdjm9hlcjpakcg41qfl7lihf6gavk8fyqijsxhvbzgj7a"; + sha256 = "040vpqpqlbk099razq8lyn74m0f161zd0rp36hciqrwcg2zibzrd"; libName = "futures_channel"; dependencies = [ { @@ -1816,9 +1816,9 @@ rec { }; "futures-core" = rec { crateName = "futures-core"; - version = "0.3.30"; + version = "0.3.31"; edition = "2018"; - sha256 = "07aslayrn3lbggj54kci0ishmd1pr367fp7iks7adia1p05miinz"; + sha256 = "0gk6yrxgi5ihfanm2y431jadrll00n5ifhnpx090c2f2q1cr1wh5"; libName = "futures_core"; features = { "default" = [ "std" ]; @@ -1829,9 +1829,9 @@ rec { }; "futures-executor" = rec { crateName = "futures-executor"; - version = "0.3.30"; + version = "0.3.31"; edition = "2018"; - sha256 = "07dh08gs9vfll2h36kq32q9xd86xm6lyl9xikmmwlkqnmrrgqxm5"; + sha256 = "17vcci6mdfzx4gbk0wx64chr2f13wwwpvyf3xd5fb1gmjzcx2a0y"; libName = "futures_executor"; dependencies = [ { @@ -1860,9 +1860,9 @@ rec { }; "futures-io" = rec { crateName = "futures-io"; - version = "0.3.30"; + version = "0.3.31"; edition = "2018"; - sha256 = "1hgh25isvsr4ybibywhr4dpys8mjnscw4wfxxwca70cn1gi26im4"; + sha256 = "1ikmw1yfbgvsychmsihdkwa8a1knank2d9a8dk01mbjar9w1np4y"; libName = "futures_io"; features = { "default" = [ "std" ]; @@ -1871,9 +1871,9 @@ rec { }; "futures-macro" = rec { crateName = "futures-macro"; - version = "0.3.30"; + version = "0.3.31"; edition = "2018"; - sha256 = "1b49qh9d402y8nka4q6wvvj0c88qq91wbr192mdn5h54nzs0qxc7"; + sha256 = "0l1n7kqzwwmgiznn0ywdc5i24z72zvh9q1dwps54mimppi7f6bhn"; procMacro = true; libName = "futures_macro"; dependencies = [ @@ -1895,9 +1895,9 @@ rec { }; "futures-sink" = rec { crateName = "futures-sink"; - version = "0.3.30"; + version = "0.3.31"; edition = "2018"; - sha256 = "1dag8xyyaya8n8mh8smx7x6w2dpmafg2din145v973a3hw7f1f4z"; + sha256 = "1xyly6naq6aqm52d5rh236snm08kw8zadydwqz8bip70s6vzlxg5"; libName = "futures_sink"; features = { "default" = [ "std" ]; @@ -1907,9 +1907,9 @@ rec { }; "futures-task" = rec { crateName = "futures-task"; - version = "0.3.30"; + version = "0.3.31"; edition = "2018"; - sha256 = "013h1724454hj8qczp8vvs10qfiqrxr937qsrv6rhii68ahlzn1q"; + sha256 = "124rv4n90f5xwfsm9qw6y99755y021cmi5dhzh253s920z77s3zr"; libName = "futures_task"; features = { "default" = [ "std" ]; @@ -1934,9 +1934,9 @@ rec { }; "futures-util" = rec { crateName = "futures-util"; - version = "0.3.30"; + version = "0.3.31"; edition = "2018"; - sha256 = "0j0xqhcir1zf2dcbpd421kgw6wvsk0rpxflylcysn1rlp3g02r1x"; + sha256 = "10aa1ar8bgkgbr4wzxlidkqkcxf77gffyj8j7768h831pcaq784z"; libName = "futures_util"; dependencies = [ { @@ -3398,7 +3398,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.30"; + packageId = "futures 0.3.31"; optional = true; usesDefaultFeatures = false; features = [ "std" ]; @@ -3539,7 +3539,7 @@ rec { devDependencies = [ { name = "futures"; - packageId = "futures 0.3.30"; + packageId = "futures 0.3.31"; usesDefaultFeatures = false; features = [ "async-await" ]; } @@ -3757,7 +3757,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.30"; + packageId = "futures 0.3.31"; usesDefaultFeatures = false; features = [ "async-await" ]; } @@ -5476,7 +5476,7 @@ rec { dependencies = [ { name = "futures"; - packageId = "futures 0.3.30"; + packageId = "futures 0.3.31"; optional = true; } { @@ -6697,7 +6697,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.30"; + packageId = "futures 0.3.31"; features = [ "compat" ]; } { @@ -6802,7 +6802,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.30"; + packageId = "futures 0.3.31"; } { name = "indexmap"; From f58c534f0c6c2e1ad2986a722434000dbacff212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Mon, 7 Oct 2024 14:12:14 +0200 Subject: [PATCH 41/42] Drop unused futures compat feature --- Cargo.lock | 17 +++++------------ Cargo.nix | 38 +++++++++----------------------------- Cargo.toml | 2 +- 3 files changed, 15 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2942fd70..dc9f0805 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,12 +611,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - [[package]] name = "futures" version = "0.3.31" @@ -700,7 +694,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "futures 0.1.31", "futures-channel", "futures-core", "futures-io", @@ -1142,7 +1135,7 @@ dependencies = [ "bytes", "chrono", "either", - "futures 0.3.31", + "futures", "home", "http", "http-body", @@ -1213,7 +1206,7 @@ dependencies = [ "async-trait", "backoff", "derivative", - "futures 0.3.31", + "futures", "hashbrown 0.14.5", "json-patch", "jsonptr", @@ -1766,7 +1759,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a2c585be59b6b5dd66a9d2084aa1d8bd52fbdb806eafdeffb52791147862035" dependencies = [ - "futures 0.3.31", + "futures", "futures-timer", "rstest_macros", "rustc_version", @@ -2171,7 +2164,7 @@ dependencies = [ "anyhow", "built", "clap", - "futures 0.3.31", + "futures", "product-config", "serde", "serde_json", @@ -2196,7 +2189,7 @@ dependencies = [ "derivative", "dockerfile-parser", "either", - "futures 0.3.31", + "futures", "indexmap", "json-patch", "k8s-openapi", diff --git a/Cargo.nix b/Cargo.nix index 9690a564..65dc4b46 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -1712,20 +1712,7 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "default" "std" ]; }; - "futures 0.1.31" = rec { - crateName = "futures"; - version = "0.1.31"; - edition = "2015"; - sha256 = "0y46qbmhi37dqkch8dlfq5aninqpzqgrr98awkb3rn4fxww1lirs"; - authors = [ - "Alex Crichton " - ]; - features = { - "default" = [ "use_std" "with-deprecated" ]; - }; - resolvedDefaultFeatures = [ "default" "use_std" "with-deprecated" ]; - }; - "futures 0.3.31" = rec { + "futures" = rec { crateName = "futures"; version = "0.3.31"; edition = "2018"; @@ -1784,7 +1771,7 @@ rec { "unstable" = [ "futures-core/unstable" "futures-task/unstable" "futures-channel/unstable" "futures-io/unstable" "futures-util/unstable" ]; "write-all-vectored" = [ "futures-util/write-all-vectored" ]; }; - resolvedDefaultFeatures = [ "alloc" "async-await" "compat" "default" "executor" "futures-executor" "std" ]; + resolvedDefaultFeatures = [ "alloc" "async-await" "default" "executor" "futures-executor" "std" ]; }; "futures-channel" = rec { crateName = "futures-channel"; @@ -1939,12 +1926,6 @@ rec { sha256 = "10aa1ar8bgkgbr4wzxlidkqkcxf77gffyj8j7768h831pcaq784z"; libName = "futures_util"; dependencies = [ - { - name = "futures"; - packageId = "futures 0.1.31"; - rename = "futures_01"; - optional = true; - } { name = "futures-channel"; packageId = "futures-channel"; @@ -2022,7 +2003,7 @@ rec { "unstable" = [ "futures-core/unstable" "futures-task/unstable" ]; "write-all-vectored" = [ "io" ]; }; - resolvedDefaultFeatures = [ "alloc" "async-await" "async-await-macro" "channel" "compat" "futures-channel" "futures-io" "futures-macro" "futures-sink" "futures_01" "io" "memchr" "sink" "slab" "std" ]; + resolvedDefaultFeatures = [ "alloc" "async-await" "async-await-macro" "channel" "futures-channel" "futures-io" "futures-macro" "futures-sink" "io" "memchr" "sink" "slab" "std" ]; }; "generic-array" = rec { crateName = "generic-array"; @@ -3398,7 +3379,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.31"; + packageId = "futures"; optional = true; usesDefaultFeatures = false; features = [ "std" ]; @@ -3539,7 +3520,7 @@ rec { devDependencies = [ { name = "futures"; - packageId = "futures 0.3.31"; + packageId = "futures"; usesDefaultFeatures = false; features = [ "async-await" ]; } @@ -3757,7 +3738,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.31"; + packageId = "futures"; usesDefaultFeatures = false; features = [ "async-await" ]; } @@ -5476,7 +5457,7 @@ rec { dependencies = [ { name = "futures"; - packageId = "futures 0.3.31"; + packageId = "futures"; optional = true; } { @@ -6697,8 +6678,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.31"; - features = [ "compat" ]; + packageId = "futures"; } { name = "product-config"; @@ -6802,7 +6782,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.31"; + packageId = "futures"; } { name = "indexmap"; diff --git a/Cargo.toml b/Cargo.toml index 3fc1366a..110b7af7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/stackabletech/kafka-operator" anyhow = "1.0" built = { version = "0.7", features = ["chrono", "git2"] } clap = "4.5" -futures = { version = "0.3", features = ["compat"] } +futures = { version = "0.3" } indoc = "2.0" product-config = { git = "https://github.com/stackabletech/product-config.git", tag = "0.7.0" } rstest = "0.23" From 17e96e17c329625944d15c1a0e8d874b53473309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Mon, 7 Oct 2024 14:14:23 +0200 Subject: [PATCH 42/42] Reformat bootstrap rolegroup note slightly --- docs/modules/kafka/pages/usage-guide/listenerclass.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/modules/kafka/pages/usage-guide/listenerclass.adoc b/docs/modules/kafka/pages/usage-guide/listenerclass.adoc index a79d460f..b9fbf741 100644 --- a/docs/modules/kafka/pages/usage-guide/listenerclass.adoc +++ b/docs/modules/kafka/pages/usage-guide/listenerclass.adoc @@ -3,7 +3,8 @@ The operator deploys a bootstrap xref:listener-operator:listener.adoc[Listener] for each broker rolegroup, as well as a xref:listener-operator:listener.adoc[Listener] for each broker pod. The bootstrap Listener is used to negotiate clients' initial connection to the cluster, after which a connection is made to the relevant broker Listeners. -Please note that every bootstrap Listener (regardless of the underlying rolegroup) will return all brokers of all rolegroups. + +NOTE: Every bootstrap xref:listener-operator:listener.adoc[Listener] (regardless of the underlying rolegroup) will direct clients to the broker listeners of all brokers of all rolegroups. They both default to only being accessible from within the Kubernetes cluster, but this can be changed by setting `.spec.brokers.config.{bootstrap,broker}ListenerClass`.