Skip to content

enable nodepool controller for stretch cluster operator; update accep…#1346

Merged
hidalgopl merged 3 commits intopb/k8s-803/ensure-stretch-cluster-spec-samenessfrom
pb/enable-nodepool-controller-for-stretch-cluster
Apr 1, 2026
Merged

enable nodepool controller for stretch cluster operator; update accep…#1346
hidalgopl merged 3 commits intopb/k8s-803/ensure-stretch-cluster-spec-samenessfrom
pb/enable-nodepool-controller-for-stretch-cluster

Conversation

@hidalgopl
Copy link
Copy Markdown
Contributor

…tance test to assert on nodepools bound and deployed

…tance test to assert on nodepools bound and deployed

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>
@hidalgopl hidalgopl force-pushed the pb/enable-nodepool-controller-for-stretch-cluster branch from 9d9f3e6 to 43b2bac Compare March 26, 2026 16:39
Copy link
Copy Markdown
Contributor

@andrewstucki andrewstucki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving just to keep the ball rolling, but I think we should likely simplify the setup methods sooner than later

Manager multicluster.Manager
}

func SetupWithMultiClusterManager(mgr multicluster.Manager) error {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this alternative setup method, but if we do this, can we simplify the other method as it does the cluster name iteration, which, in the case of a single cluster will either only return "" or nothing at all (I don't remember which off the top of my head)

hidalgopl and others added 2 commits April 1, 2026 12:35
* distribute bootstrap admin credentials across stretch cluster k8s clusters

Add syncBootstrapUser syncer that runs before reconcilers to ensure the
bootstrap user secret exists consistently in all k8s clusters. Replace
hardcoded admin/admin credentials in AdminClientForStretch with credentials
read from the distributed secret.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* add BootstrapUserSynced condition and password mismatch detection

Scan all clusters for existing bootstrap user secrets and error with a
PasswordMismatch condition if different passwords are found. Set a
BootstrapUserSynced condition on StretchCluster status for all outcomes:
Synced (newly generated), ExistingReused (found in a cluster), or
PasswordMismatch (conflicting secrets require manual intervention).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* make sure we set canonical cluster name in the condition reason

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* fix per pod service, comment out nodepool watches temporarily

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* fix issue with nodepools with .spec.replicas > 1

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* Fix misc issues with multiple statefulset replicas

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* try to use v1 license in acceptance test

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* pass license env var to docker command in

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* operator: Distinguish in-cluster pools from all pools in RenderState

RenderState previously used a single `pools` slice for both rendering
local resources (StatefulSets, ConfigMaps, Secrets). The per Pod service
were not generated for remote NodePools. Those Kubernetes Services are
required to create DNS entries even if Pod does not exist in particular
Kubernetes cluster.

Split into two fields:
- `inClusterPools`: NodePools local to this K8s cluster, used for
  StatefulSets, ConfigMaps, Secrets, and pod name generation
- `pools`: all NodePools across clusters, used for seed server
  computation and per Pod Service

Move seed server generation from lifecycle into RenderState via
seedServersFromNodePools(), removing the now-unused
SeedServersFromNodePools() export. Add GetAllNodePools() to
StretchClusterWithPools so callers can pass the full pool list.

* regenerate golden files

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* add configuration of NodePool.Spec.Services that allows to modify spec/annotations for local and remote per-pod services

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* operator: Move spec consistency check after finalizer removal

* operator: Fix seed server port type and propagate config errors

The seed server port was rendered as a string in redpanda.yaml instead of
an integer, which Redpanda rejects. Parse the port with strconv.ParseInt
and propagate the resulting error through redpandaConfigFile, configMaps,
and statefulSetChecksumAnnotation. Also add missing namespace to NodePool
test fixtures so seed server addresses render correctly.

---------

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Rafal Korepta <rafal.korepta@gmail.com>
Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>
@hidalgopl hidalgopl merged commit d2841af into pb/k8s-803/ensure-stretch-cluster-spec-sameness Apr 1, 2026
2 of 7 checks passed
hidalgopl added a commit that referenced this pull request Apr 1, 2026
#1338)

* Detect StrechCluster.spec drift, halt reconcilation and set condition on all StrechClusters

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* enable nodepool controller for stretch cluster operator; update accep… (#1346)

* enable nodepool controller for stretch cluster operator; update acceptance test to assert on nodepools bound and deployed

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* Bootstrap admin for StretchCluster (#1348)

* distribute bootstrap admin credentials across stretch cluster k8s clusters

Add syncBootstrapUser syncer that runs before reconcilers to ensure the
bootstrap user secret exists consistently in all k8s clusters. Replace
hardcoded admin/admin credentials in AdminClientForStretch with credentials
read from the distributed secret.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* add BootstrapUserSynced condition and password mismatch detection

Scan all clusters for existing bootstrap user secrets and error with a
PasswordMismatch condition if different passwords are found. Set a
BootstrapUserSynced condition on StretchCluster status for all outcomes:
Synced (newly generated), ExistingReused (found in a cluster), or
PasswordMismatch (conflicting secrets require manual intervention).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* make sure we set canonical cluster name in the condition reason

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* fix per pod service, comment out nodepool watches temporarily

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* fix issue with nodepools with .spec.replicas > 1

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* Fix misc issues with multiple statefulset replicas

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* try to use v1 license in acceptance test

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* pass license env var to docker command in

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* operator: Distinguish in-cluster pools from all pools in RenderState

RenderState previously used a single `pools` slice for both rendering
local resources (StatefulSets, ConfigMaps, Secrets). The per Pod service
were not generated for remote NodePools. Those Kubernetes Services are
required to create DNS entries even if Pod does not exist in particular
Kubernetes cluster.

Split into two fields:
- `inClusterPools`: NodePools local to this K8s cluster, used for
  StatefulSets, ConfigMaps, Secrets, and pod name generation
- `pools`: all NodePools across clusters, used for seed server
  computation and per Pod Service

Move seed server generation from lifecycle into RenderState via
seedServersFromNodePools(), removing the now-unused
SeedServersFromNodePools() export. Add GetAllNodePools() to
StretchClusterWithPools so callers can pass the full pool list.

* regenerate golden files

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* add configuration of NodePool.Spec.Services that allows to modify spec/annotations for local and remote per-pod services

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* operator: Move spec consistency check after finalizer removal

* operator: Fix seed server port type and propagate config errors

The seed server port was rendered as a string in redpanda.yaml instead of
an integer, which Redpanda rejects. Parse the port with strconv.ParseInt
and propagate the resulting error through redpandaConfigFile, configMaps,
and statefulSetChecksumAnnotation. Also add missing namespace to NodePool
test fixtures so seed server addresses render correctly.

---------

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Rafal Korepta <rafal.korepta@gmail.com>

* regenerate golden files

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

---------

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Rafal Korepta <rafal.korepta@gmail.com>

---------

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Rafal Korepta <rafal.korepta@gmail.com>
hidalgopl added a commit that referenced this pull request Apr 2, 2026
* operator: Implement Multicluster reconciler

* add dns override for bootstrap

* * task dev:setup-multicluster-dev-env command for setting up StretchCluster locally in k3s on vClusters
* fix panics & ownership issues in multicluster controller
* fix initAdminClient

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* misc fixes

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* make sure we don't overwrite the nodepool service with the service generated by vcluster

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* pass seed_servers to the redpanda configmap

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* set --advertise-rpc-addr correctly to the svc per pod name

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* fix lint issues

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* regenerate golden files

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* implement acceptance test for stretch cluster

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* Detect StrechCluster.spec drift, halt reconcilation and set condition… (#1338)

* Detect StrechCluster.spec drift, halt reconcilation and set condition on all StrechClusters

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* enable nodepool controller for stretch cluster operator; update accep… (#1346)

* enable nodepool controller for stretch cluster operator; update acceptance test to assert on nodepools bound and deployed

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* Bootstrap admin for StretchCluster (#1348)

* distribute bootstrap admin credentials across stretch cluster k8s clusters

Add syncBootstrapUser syncer that runs before reconcilers to ensure the
bootstrap user secret exists consistently in all k8s clusters. Replace
hardcoded admin/admin credentials in AdminClientForStretch with credentials
read from the distributed secret.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* add BootstrapUserSynced condition and password mismatch detection

Scan all clusters for existing bootstrap user secrets and error with a
PasswordMismatch condition if different passwords are found. Set a
BootstrapUserSynced condition on StretchCluster status for all outcomes:
Synced (newly generated), ExistingReused (found in a cluster), or
PasswordMismatch (conflicting secrets require manual intervention).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* make sure we set canonical cluster name in the condition reason

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* fix per pod service, comment out nodepool watches temporarily

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* fix issue with nodepools with .spec.replicas > 1

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* Fix misc issues with multiple statefulset replicas

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* try to use v1 license in acceptance test

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* pass license env var to docker command in

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* operator: Distinguish in-cluster pools from all pools in RenderState

RenderState previously used a single `pools` slice for both rendering
local resources (StatefulSets, ConfigMaps, Secrets). The per Pod service
were not generated for remote NodePools. Those Kubernetes Services are
required to create DNS entries even if Pod does not exist in particular
Kubernetes cluster.

Split into two fields:
- `inClusterPools`: NodePools local to this K8s cluster, used for
  StatefulSets, ConfigMaps, Secrets, and pod name generation
- `pools`: all NodePools across clusters, used for seed server
  computation and per Pod Service

Move seed server generation from lifecycle into RenderState via
seedServersFromNodePools(), removing the now-unused
SeedServersFromNodePools() export. Add GetAllNodePools() to
StretchClusterWithPools so callers can pass the full pool list.

* regenerate golden files

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* add configuration of NodePool.Spec.Services that allows to modify spec/annotations for local and remote per-pod services

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* operator: Move spec consistency check after finalizer removal

* operator: Fix seed server port type and propagate config errors

The seed server port was rendered as a string in redpanda.yaml instead of
an integer, which Redpanda rejects. Parse the port with strconv.ParseInt
and propagate the resulting error through redpandaConfigFile, configMaps,
and statefulSetChecksumAnnotation. Also add missing namespace to NodePool
test fixtures so seed server addresses render correctly.

---------

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Rafal Korepta <rafal.korepta@gmail.com>

* regenerate golden files

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

---------

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Rafal Korepta <rafal.korepta@gmail.com>

---------

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Rafal Korepta <rafal.korepta@gmail.com>

* fix console app version test

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

* fix bug in the redpanda_controller & fix TestLicenseReal test

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>

---------

Signed-off-by: Paweł Bojanowski <pawel.bojanowski@redpanda.com>
Co-authored-by: Rafal Korepta <rafal.korepta@gmail.com>
Co-authored-by: Andrew Stucki <andrew.stucki@redpanda.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@RafalKorepta RafalKorepta deleted the pb/enable-nodepool-controller-for-stretch-cluster branch April 8, 2026 07:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants