Skip to content

feat: implement User resource for managing Kafka users#194

Open
zanozbot wants to merge 5 commits into
crossplane-contrib:mainfrom
zanozbot:main
Open

feat: implement User resource for managing Kafka users#194
zanozbot wants to merge 5 commits into
crossplane-contrib:mainfrom
zanozbot:main

Conversation

@zanozbot

Copy link
Copy Markdown

Description of your changes

Implements the User managed resource for managing Kafka SCRAM users in both cluster-scoped (user.kafka.crossplane.io/v1alpha1) and namespace-scoped (user.kafka.m.crossplane.io/v1alpha1) APIs.

What the User resource does:

  • Provisions a Kafka SCRAM user with one or more mechanisms (SCRAM-SHA-256, SCRAM-SHA-512; defaults to SCRAM-SHA-512)
  • Auto-generates a cryptographically secure random password when spec.forProvider.passwordSecretRef is omitted, and persists it in the connection Secret
  • Optionally reads the password from a referenced Kubernetes Secret (Ωspec.forProvider.passwordSecretRef`) — use this to supply an existing password or to import a pre-existing Kafka user
  • Writes a connection Secret containing username, password, and brokers so applications have a single source of truth for Kafka credentials
  • Supports the Observe management policy for importing existing SCRAM users without resetting their credentials

I have:

  • Read and followed Crossplane's contribution process.
  • Run make reviewable test to ensure this PR is ready for review.

How has this code been tested

  • Unit tests added for the SCRAM client helpers user_test.go: mechanism parsing, Exists, ObservedMechanisms, Upsert, `Delete``
  • Controller-level unit tests for both cluster-scoped and namespace-scoped user_test.go controllers covering Observe/Create/Update/Delete reconciliation paths, auto-password generation, passwordSecretRef resolution, and connection Secret contents
  • Manually tested against a local kind cluster with Strimzi Kafka using the examples in user

zanozbot added 4 commits June 12, 2026 13:04
Signed-off-by: Žan Ožbot <zan.ozbot@gmail.com>
Signed-off-by: Žan Ožbot <zan.ozbot@gmail.com>
Signed-off-by: Žan Ožbot <zan.ozbot@gmail.com>
Signed-off-by: Žan Ožbot <zan.ozbot@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Implements a new Crossplane managed resource (User) to manage Kafka SCRAM users, including controllers and helper client logic for both cluster-scoped (user.kafka.crossplane.io/v1alpha1) and namespace-scoped (user.kafka.m.crossplane.io/v1alpha1) APIs.

Changes:

  • Added User CRDs, API types, and scheme registration for cluster-scoped and namespaced variants.
  • Implemented new controllers (cluster + namespaced) that support Observe/Create/Update/Delete, password resolution (BYOP vs auto-generate), and connection Secret publishing.
  • Added Kafka SCRAM helper client implementation and unit tests, plus docs/examples updates for the new resource.

Reviewed changes

Copilot reviewed 24 out of 30 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
README.md Documents the User resource, connection Secret contents, and import workflow.
package/crds/user.kafka.m.crossplane.io_users.yaml Adds namespaced User CRD.
package/crds/user.kafka.crossplane.io_users.yaml Adds cluster-scoped User CRD.
internal/controller/namespaced/user/user.go Namespaced User controller implementation.
internal/controller/namespaced/user/user_test.go Unit tests for namespaced controller helpers (password resolution, etc.).
internal/controller/namespaced/kafka.go Registers the namespaced User controller.
internal/controller/cluster/user/user.go Cluster-scoped User controller implementation.
internal/controller/cluster/user/user_test.go Unit tests for cluster-scoped controller helpers (password resolution, etc.).
internal/controller/cluster/kafka.go Registers the cluster-scoped User controller.
internal/clients/kafka/user/user.go Kafka SCRAM helper client (exists/observe/upsert/delete).
internal/clients/kafka/user/user_test.go Unit tests for Kafka SCRAM helper client.
examples/namespaced/user/v1alpha1/user.yaml Example manifest for namespaced User.
examples/namespaced/user/v1alpha1/user-with-password-secret.yaml Example for namespaced import/BYOP password usage.
examples/cluster/user/v1alpha1/user.yaml Example manifest for cluster-scoped User.
examples/cluster/user/v1alpha1/user-with-password-secret.yaml Example for cluster-scoped import/BYOP password usage.
apis/v1alpha1/user_types.go Shared parameter/observation types for User (incl. secret selectors).
apis/namespaced/user/v1alpha1/doc.go Namespaced User API package metadata.
apis/namespaced/user/v1alpha1/groupversion_info.go Namespaced User group/version registration.
apis/namespaced/user/v1alpha1/user_types.go Namespaced User type definitions.
apis/namespaced/user/v1alpha1/zz_generated.deepcopy.go Generated deepcopy for namespaced User types.
apis/namespaced/user/v1alpha1/zz_generated.managed.go Generated managed-resource interface methods for namespaced User.
apis/namespaced/user/v1alpha1/zz_generated.managedlist.go Generated managed list helper for namespaced UserList.
apis/namespaced/kafka.go Adds namespaced User types to the namespaced API scheme.
apis/cluster/user/v1alpha1/doc.go Cluster-scoped User API package metadata.
apis/cluster/user/v1alpha1/groupversion_info.go Cluster-scoped User group/version registration.
apis/cluster/user/v1alpha1/user_types.go Cluster-scoped User type definitions.
apis/cluster/user/v1alpha1/zz_generated.deepcopy.go Generated deepcopy for cluster-scoped User types.
apis/cluster/user/v1alpha1/zz_generated.managed.go Generated managed-resource interface methods for cluster-scoped User.
apis/cluster/user/v1alpha1/zz_generated.managedlist.go Generated managed list helper for cluster-scoped UserList.
apis/cluster/kafka.go Adds cluster-scoped User types to the cluster API scheme.
Files not reviewed (6)
  • apis/cluster/user/v1alpha1/zz_generated.deepcopy.go: Generated file
  • apis/cluster/user/v1alpha1/zz_generated.managed.go: Generated file
  • apis/cluster/user/v1alpha1/zz_generated.managedlist.go: Generated file
  • apis/namespaced/user/v1alpha1/zz_generated.deepcopy.go: Generated file
  • apis/namespaced/user/v1alpha1/zz_generated.managed.go: Generated file
  • apis/namespaced/user/v1alpha1/zz_generated.managedlist.go: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/controller/namespaced/user/user.go
Comment thread internal/controller/cluster/user/user.go
Comment thread internal/controller/namespaced/user/user.go
Comment thread internal/controller/namespaced/user/user.go
Comment thread internal/controller/cluster/user/user.go
Comment thread internal/clients/kafka/user/user.go
Comment thread README.md
Comment thread README.md
Comment thread examples/namespaced/user/v1alpha1/user-with-password-secret.yaml
Comment thread examples/cluster/user/v1alpha1/user-with-password-secret.yaml
Signed-off-by: Žan Ožbot <zan.ozbot@gmail.com>
@zanozbot

Copy link
Copy Markdown
Author

Resolved Copilot comments and rerun tests.

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.

3 participants