Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
578d2c7
Add agent-binary as workspace member
labrenbe Sep 24, 2026
2a1fae0
deploy the agent if spec.platformAcces.enabled is configured
labrenbe Sep 24, 2026
f15777c
add agent image and cluster role to Helm chart
labrenbe Sep 24, 2026
ed51b0e
build a separate agent image
labrenbe Sep 24, 2026
f01e5ce
Merge remote-tracking branch 'origin/main' into feat/kafka-agent
labrenbe Sep 24, 2026
9507079
run ghs build for matrix of operator and agent
labrenbe Sep 24, 2026
177cfb1
move staged framework code to operator-rs
labrenbe Oct 1, 2026
7f6d5a1
fix issues identified by Claude
labrenbe Oct 2, 2026
e5f431b
add support for anonymous access via operator-rs
labrenbe Oct 6, 2026
18a4ff2
use versioned for platform access CRD fragments
labrenbe Oct 13, 2026
773d3bd
use the recreate strategy for the agent deployment
labrenbe Oct 21, 2026
679a24a
ship agent binary in operator image
labrenbe Oct 21, 2026
0a9ce61
Merge remote-tracking branch 'origin/main' into feat/kafka-agent
labrenbe Oct 21, 2026
85716c9
cleanup & only watch deployments with agent labels
labrenbe Oct 21, 2026
146602d
set fsGroup on the agent pod so it can read secret-operator volumes
labrenbe Oct 23, 2026
60f0123
align CRD and validation with operator-rs and decision outcome
labrenbe Oct 23, 2026
1d68476
configure the agent's connection to Kafka via a shared contract crate
labrenbe Oct 23, 2026
87a290e
use AgentResourceNames from operator-rs
labrenbe Oct 26, 2026
469caf2
Merge branch 'main' into feat/kafka-agent
labrenbe Oct 26, 2026
61b1005
update operator-rs
labrenbe Oct 27, 2026
66bf00b
replace hard-coded selectors on agent deployment with util from opera…
labrenbe Oct 27, 2026
14f9ee8
use headless service to connect to bootstrap servers
labrenbe Oct 27, 2026
cbde956
rename cb_agent to container_builder_agent
labrenbe Oct 27, 2026
e5e54fd
add deref tests for new constants
labrenbe Oct 27, 2026
42d02bf
regenerate-nix
labrenbe Oct 27, 2026
bdda9d0
bump operator-rs
labrenbe Oct 28, 2026
a89b5db
regenerate nix
labrenbe Oct 28, 2026
43657d4
regenerate nix
labrenbe Oct 28, 2026
f579456
update operator-rs
labrenbe Oct 29, 2026
8b7c86d
Merge remote-tracking branch 'origin/main' into feat/kafka-agent
labrenbe Oct 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
478 changes: 251 additions & 227 deletions Cargo.lock

Large diffs are not rendered by default.

1,455 changes: 778 additions & 677 deletions Cargo.nix

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["rust/operator-binary"]
members = ["rust/operator-binary", "rust/agent-binary", "rust/shared"]
resolver = "2"

[workspace.package]
Expand All @@ -10,7 +10,8 @@ edition = "2024"
repository = "https://github.com/stackabletech/kafka-operator"

[workspace.dependencies]
stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.121.0", features = ["crds", "webhook"] }
stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", branch = "feat/platform-access", features = ["agent", "crds", "webhook"] }
stackable-kafka-shared = { path = "rust/shared" }

anyhow = "1.0"
built = { version = "0.8", features = ["chrono", "git2"] }
Expand Down
19 changes: 10 additions & 9 deletions crate-hashes.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions deploy/helm/kafka-operator/templates/clusterrole-agent.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
# Agent ClusterRole: bound (via per KafkaCluster RoleBinding) to the ServiceAccount that the
# agent pod runs as.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "kafka-operator.name" . }}-agent-clusterrole
labels:
{{- include "kafka-operator.labels" . | nindent 4 }}
rules:
{{ if .Capabilities.APIVersions.Has "security.openshift.io/v1" }}
# On OpenShift, the agent pod must be allowed to use the nonroot-v2 SCC
- apiGroups:
- security.openshift.io
resources:
- securitycontextconstraints
resourceNames:
- nonroot-v2
verbs:
- use
{{ end }}
15 changes: 14 additions & 1 deletion deploy/helm/kafka-operator/templates/clusterrole-operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ rules:
- list
- patch
- watch
# Required to bind the product ClusterRole to the per-cluster ServiceAccount.
# Required to bind the product and agent ClusterRoles to the per-cluster ServiceAccounts.
- apiGroups:
- rbac.authorization.k8s.io
resources:
Expand All @@ -50,6 +50,7 @@ rules:
- bind
resourceNames:
- {{ include "kafka-operator.name" . }}-clusterrole
- {{ include "kafka-operator.name" . }}-agent-clusterrole
# StatefulSet created per role group (broker, KRaft controller). Applied via
# SSA, tracked for orphan cleanup, and owned by the controller.
- apiGroups:
Expand All @@ -63,6 +64,18 @@ rules:
- list
- patch
- watch
# Deployment of the agent.
- apiGroups:
- apps
resources:
- deployments
verbs:
- create
- delete
- get
- list
- patch
- watch
# PodDisruptionBudget created per role group. Applied via SSA and tracked for orphan cleanup, and owned by the controller.
- apiGroups:
- policy
Expand Down
54 changes: 54 additions & 0 deletions extra/crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,60 @@ spec:
nullable: true
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
managementAccess:
description: |-
Management access of the Stackable Data Platform to this Kafka cluster, used to manage
resources like `KafkaTopic`s. The credential must be authorized in Kafka by the user.
nullable: true
properties:
authentication:
description: How the Stackable Data Platform authenticates to Kafka.
properties:
userProvided:
description: A credential provided by the user.
oneOf:
- required:
- anonymous
- required:
- tls
properties:
anonymous:
description: 'No credential: the product does not require authentication.'
type: object
tls:
description: 'Source of a TLS client certificate: a secret-operator SecretClass or a static Secret.'
oneOf:
- required:
- secretClassName
- required:
- secretName
properties:
secretClassName:
description: A SecretClass providing the certificate.
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
secretName:
description: |-
A static Secret holding the certificate in the keys `tls.crt` and `tls.key` (PEM), e.g. as
a Secret of type `kubernetes.io/tls`.
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
type: object
type: object
required:
- userProvided
type: object
enabled:
description: Whether management access is enabled.
type: boolean
required:
- authentication
Comment thread
xeniape marked this conversation as resolved.
Resolved
- enabled
type: object
metadataManager:
description: |-
Metadata manager to use for the Kafka cluster.
Expand Down
24 changes: 24 additions & 0 deletions rust/agent-binary/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "stackable-kafka-agent"
description = "Stackable Agent for Apache Kafka"
version.workspace = true
authors.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true
publish = false

[dependencies]
stackable-operator.workspace = true

anyhow.workspace = true
clap.workspace = true
tokio.workspace = true
tracing.workspace = true

[build-dependencies]
built.workspace = true

[[bin]]
name = "stackable-kafka-agent"
path = "src/main.rs"
3 changes: 3 additions & 0 deletions rust/agent-binary/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
built::write_built_file().unwrap();
}
44 changes: 44 additions & 0 deletions rust/agent-binary/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! The Stackable Kafka agent: a per-cluster controller that reconciles in-cluster resources like `KafkaTopic`s.

use clap::Parser;
use stackable_operator::{
cli::{Command, CommonOptions},
telemetry::Tracing,
utils::signal::SignalWatcher,
};

mod built_info {
include!(concat!(env!("OUT_DIR"), "/built.rs"));
}

#[derive(clap::Parser)]
#[clap(about, author)]
struct Opts {
#[clap(subcommand)]
cmd: Command<CommonOptions>,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
match Opts::parse().cmd {
Command::Crd => anyhow::bail!("this agent has no CRDs, they are owned by the operator"),
Command::Run(CommonOptions { telemetry, .. }) => {
let _tracing_guard = Tracing::pre_configured(built_info::PKG_NAME, telemetry).init()?;

tracing::info!(
built_info.pkg_version = built_info::PKG_VERSION,
built_info.git_version = built_info::GIT_VERSION,
built_info.target = built_info::TARGET,
built_info.built_time_utc = built_info::BUILT_TIME_UTC,
built_info.rustc_version = built_info::RUSTC_VERSION,
"Starting {description}",
description = built_info::PKG_DESCRIPTION
);

let sigterm_watcher = SignalWatcher::sigterm()?;
sigterm_watcher.handle().await;
}
}

Ok(())
}
1 change: 1 addition & 0 deletions rust/operator-binary/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ repository.workspace = true
publish = false

[dependencies]
stackable-kafka-shared.workspace = true
stackable-operator.workspace = true

indoc.workspace = true
Expand Down
Loading
Loading