Skip to content

✨ add a controller-name for multi-controller#5474

Draft
guilhem wants to merge 3 commits intokubernetes-sigs:masterfrom
guilhem:controllername
Draft

✨ add a controller-name for multi-controller#5474
guilhem wants to merge 3 commits intokubernetes-sigs:masterfrom
guilhem:controllername

Conversation

@guilhem
Copy link

@guilhem guilhem commented Feb 13, 2026

Naive implementation of #5473

This pull request introduces support for scaffolding multiple controllers for the same Group/Version/Kind (GVK) in Kubebuilder, allowing users to split reconciliation responsibilities, run different reconciliation modes, or manage migration scenarios. The main enhancement is the addition of the --controller-name flag to the create api command, along with corresponding updates to documentation, configuration, and code generation logic.

Feature: Multiple Controllers for the Same GVK

  • Added support for the --controller-name flag in create api, enabling scaffolding of additional controllers for an existing API. Each controller gets its own file, struct, and unique registration, and the controller name is tracked in the PROJECT file. [1] [2] [3] [4] [5]
  • Updated the resource model and configuration logic to allow multiple entries for the same GVK with different controller names, including proper handling in resource addition and updating. [1] [2] [3] [4] [5] [6]
  • Improved code generation to use the controller name for file naming, struct naming (PascalCase conversion), and registration, and updated templates and replacers accordingly. [1] [2] [3] [4] [5]

Validation and CLI Enhancements

  • Added validation for the controller name to ensure it conforms to DNS-1035 label requirements, and integrated the flag into the CLI and scaffolding logic. [1] [2] [3]

Documentation Updates

  • Expanded documentation to describe the new feature, including use cases, configuration examples, and instructions for tracking controller names in the PROJECT file. [1] [2] [3] [4] [5]

Code Generation and Template Changes

  • Updated scaffolding logic and templates to support multiple controllers, including changes to cmd/main.go and controller test files. [1] [2]

These changes make Kubebuilder more flexible for advanced controller patterns and improve clarity and maintainability in projects with complex reconciliation needs.

Fix kubernetes-sigs#5473

Signed-off-by: Guilhem Lettron <glettron@akamai.com>
@k8s-ci-robot k8s-ci-robot added do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Feb 13, 2026
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: guilhem
Once this PR has been reviewed and has the lgtm label, please assign camilamacedo86 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot
Copy link
Contributor

Welcome @guilhem!

It looks like this is your first PR to kubernetes-sigs/kubebuilder 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes-sigs/kubebuilder has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Feb 13, 2026
@k8s-ci-robot
Copy link
Contributor

Hi @guilhem. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Feb 13, 2026
kind: Memcached
path: example.com/memcached-operator/api/v1alpha1
version: v1alpha1
- controller: true
Copy link
Member

@camilamacedo86 camilamacedo86 Feb 13, 2026

Choose a reason for hiding this comment

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

How it would be if instead of replicated GKV for each controller
we have:
controller
name:

  • nameA
  • nameB
  • nameC

I think that would be a more clean structure
It would either facilitate the implementation for alpha generate.
WDYT?

Copy link
Author

@guilhem guilhem Feb 13, 2026

Choose a reason for hiding this comment

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

That's a cleaner structure indeed :)

Is something like that ok?

controllers:
- name: nameA
- name: nameB
- name: nameC

It gives the opportunity to add more fields in the future for each controllers.

Copy link
Author

@guilhem guilhem Feb 13, 2026

Choose a reason for hiding this comment

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

or, if we want to prevent an array:

controllers:
  nameA: {}
  nameB: {}
  nameC: {}

Copy link
Author

Choose a reason for hiding this comment

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

I just fear when using the cli:
When the first name hasn't been set, we will have to set "nameA" to the first computed and nameB to the one set.
(not really a problem, just something to do)

Copy link
Member

@camilamacedo86 camilamacedo86 Feb 13, 2026

Choose a reason for hiding this comment

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

When the first name hasn't been set, we will have to set "nameA" to the first computed and nameB to the one set.

We have a method that do the "merge" of GKV.
I think we need to have exactly the same but for the new Controller as well.

We will need to think a lot here to ensure that we have a great API
Because we cannot change easily those after we release the changes.

So maybe it will be acctually like

resource:
controller:
   - name: A
controller: 
    -Name B 

The list I think should be of controllers.
ONE API/GKV can have MANY controllers ;-)

So that tomorrow we can either

resource:
controller:
   - name: A
   - key: value
    - key: value
controller: 
    -Name B 

Signed-off-by: Guilhem Lettron <glettron@akamai.com>
| `resources.api.crdVersion` | The Kubernetes API version (`apiVersion`) used to do the scaffolding for the CRD resource. |
| `resources.api.namespaced` | The API RBAC permissions which can be namespaced or cluster scoped. |
| `resources.controller` | Indicates whether a controller was scaffolded for the API. |
| `resources.controllerName` | **(Optional)** A custom name for the controller, provided via the `--controller-name` flag. When set, it allows multiple controllers for the same GVK. The name is used for the controller file name, the reconciler struct name, and the controller's `Named()` registration. Must be a DNS-1035 label (lowercase alphanumeric and hyphens). |
Copy link
Member

Choose a reason for hiding this comment

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

Let's try check out it with a list of Namespaces

controller.names LIST
WDYT?

@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Feb 13, 2026

for i, r := range c.Resources {
if res.IsEqualTo(r.GVK) {
if res.IsEqualTo(r.GVK) && res.ControllerName == r.ControllerName {
Copy link
Member

Choose a reason for hiding this comment

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

I think we need a method to check in the LIST something like
resource.HasControllerName()

API: &resource.API{CRDVersion: "v1", Namespaced: true},
},
{
GVK: resource.GVK{
Copy link
Member

Choose a reason for hiding this comment

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

We should not duplicate the GKV we could not have more than one on the cluster less yet in the project

// Validate controller name if provided
if p.options.ControllerName != "" {
if !p.options.DoController {
return errors.New("cannot use '--controller-name' with '--controller=false'")
Copy link
Member

Choose a reason for hiding this comment

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

Valiations should be in the preScaffold
We probably need to add this one inside of the method that validate GKV already

}
if errs := validation.IsDNS1035Label(p.options.ControllerName); len(errs) != 0 {
return fmt.Errorf("invalid controller name %q: must be a DNS-1035 label "+
"(lowercase, alphanumeric, hyphens, starting with a letter)", p.options.ControllerName)
Copy link
Member

Choose a reason for hiding this comment

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

Same here.

}

// When adding a named controller for an existing GVK, skip API re-scaffolding
if p.options.ControllerName != "" && p.options.DoAPI {
Copy link
Member

Choose a reason for hiding this comment

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

I think it is not accurate.
At the same way that we have many controllers for a core API we should be able to have many controllers for a external type too.


// ControllerName is an optional custom name for the controller.
// When set, allows scaffolding multiple controllers for the same GVK.
ControllerName string
Copy link
Member

Choose a reason for hiding this comment

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

Lets try to do a list
But we need to properly think in how we will design the API here
I think we will need a new struct Controller and then inside of it we add name

Therefore, in the future we can add other specs for Controller if we have the need.

Copy link
Author

Choose a reason for hiding this comment

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

I totally agree

Copy link
Member

@camilamacedo86 camilamacedo86 left a comment

Choose a reason for hiding this comment

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

HI @guilhem

Thank you for looking on that.
I did some comments.
Mainly IHMO:

  • The API must be a design choice that allow us to grow if we need. So we will probably need to have a new struct Controller inside of Resources and that allows pass a List of names.
  • The validations for GKV need to be done in the preScaffold. Those should be in the funcs that we have already today in the API
  • We will need either ensure that alpha generate work with. So, if we have resources.Crontroller.names we should call create api resource false and controller true with the name for each name after create the API.

Signed-off-by: Guilhem Lettron <glettron@akamai.com>
@k8s-ci-robot
Copy link
Contributor

Keywords which can automatically close issues and hashtag(#) mentions are not allowed in commit messages.

The list of commits with invalid commit messages:

  • 6829f40 feat: add a controller-name for multi-controller
Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@k8s-ci-robot k8s-ci-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Feb 13, 2026
@guilhem guilhem marked this pull request as draft February 13, 2026 14:32
@k8s-ci-robot k8s-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 13, 2026
@guilhem
Copy link
Author

guilhem commented Feb 13, 2026

@camilamacedo86 I changed to new API for PROJECT and passed this PR as a draft to be certain it's not merged until the API is stabilized.

@k8s-ci-robot
Copy link
Contributor

PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants