Skip to content

Proposal: Generics for CustomValidator & CustomDefaulter #2675

Closed

Description

@ahmetb

CustomValidator and CustomDefaulter interfaces could use generics support to potentially shorten the handler funcs like this:

func (w *KubernetesPoolWebhook) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) {
	oldO, ok := oldObj.(apiv1alpha1.KubernetesPool)
	if err != nil {
		return nil, errors.NewBadRequest(fmt.Sprintf("unexpected type %T", oldObj))
	}
	newO, ok := newObj.(apiv1alpha1.KubernetesPool)
	if err != nil {
		return nil,  errors.NewBadRequest(fmt.Sprintf("unexpected type %T", newObj))
	}
	return nil, validateUpdate(oldO, newO)
}

to

func (w *KubernetesPoolWebhook) ValidateUpdate(ctx context.Context, oldObj, newObj apiv1alpha1.KubernetesPool) (admission.Warnings, error) {
	return nil, validateUpdate(oldO, newO)
}

Also statements like:

return ctrl.NewWebhookManagedBy(mgr).
	For(&apiv1alpha1.KubernetesPool{}).
	WithDefaulter(w).
	WithValidator(w).
	Complete()

can probably be inferred with more type safety (right now there's nothing ensures a & b are handlers of the same type in WithDefaulter(a).WithDefaulter(b)?). e.g.

return ctrl.NewWebhookManagedBy[apiv1alpha1.KubernetesPool](mgr).
	WithDefaulter(w).
	WithValidator(w).
	Complete()

/kind proposal
/kind feature

Activity

  1. k8s-ci-robot commented on Feb 7, 2024

    @k8s-ci-robot
    Contributor

    @ahmetb: The label(s) kind/proposal cannot be applied, because the repository doesn't have them.

    Details

    In response to this:

    CustomValidator and CustomDefaulter interfaces could use generics support to potentially shorten the handler funcs like this:

    func (w *KubernetesPoolWebhook) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) {
      oldO, ok := oldObj.(apiv1alpha1.KubernetesPool)
      if err != nil {
      	return nil, errors.NewBadRequest(fmt.Sprintf("unexpected type %T", oldObj))
      }
      newO, ok := newObj.(apiv1alpha1.KubernetesPool)
      if err != nil {
      	return nil,  errors.NewBadRequest(fmt.Sprintf("unexpected type %T", newObj))
      }
      return nil, validateUpdate(oldO, newO)
    }

    to

    func (w *KubernetesPoolWebhook) ValidateUpdate(ctx context.Context, oldObj, newObj apiv1alpha1.KubernetesPool) (admission.Warnings, error) {
      return nil, validateUpdate(oldO, newO)
    }

    Also statements like:

    return ctrl.NewWebhookManagedBy(mgr).
      For(&apiv1alpha1.KubernetesPool{}).
      WithDefaulter(w).
      WithValidator(w).
      Complete()
    

    can probably be inferred with more type safety (right now there's nothing ensures a & b are handlers of the same type in WithDefaulter(a).WithDefaulter(b)?).

    /kind proposal
    /kind feature

    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/test-infra repository.

  2. alvaroaleman commented on Feb 8, 2024

    @alvaroaleman
    Member

    @ahmetb are you sure this is possible? My understanding is that it isn't due to golang/go#49085, the WebhookBuilder would only be able to support one type. I'd love to be wrong on this though.

  3. ahmetb commented on Feb 9, 2024

    @ahmetb
    MemberAuthor

    I will give it a shot. I hit that in porting go-linq to generics as well.

  4. k8s-triage-robot commented on May 9, 2024

    @k8s-triage-robot

    The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

    This bot triages un-triaged issues according to the following rules:

    • After 90d of inactivity, lifecycle/stale is applied
    • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
    • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

    You can:

    • Mark this issue as fresh with /remove-lifecycle stale
    • Close this issue with /close
    • Offer to help out with Issue Triage

    Please send feedback to sig-contributor-experience at kubernetes/community.

    /lifecycle stale

  5. added
    lifecycle/staleDenotes an issue or PR has remained open with no activity and has become stale.
    on May 9, 2024
  6. k8s-triage-robot commented on Jun 8, 2024

    @k8s-triage-robot

    The Kubernetes project currently lacks enough active contributors to adequately respond to all issues.

    This bot triages un-triaged issues according to the following rules:

    • After 90d of inactivity, lifecycle/stale is applied
    • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
    • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

    You can:

    • Mark this issue as fresh with /remove-lifecycle rotten
    • Close this issue with /close
    • Offer to help out with Issue Triage

    Please send feedback to sig-contributor-experience at kubernetes/community.

    /lifecycle rotten

  7. added
    lifecycle/rottenDenotes an issue or PR that has aged beyond stale and will be auto-closed.
    and removed
    lifecycle/staleDenotes an issue or PR has remained open with no activity and has become stale.
    on Jun 8, 2024
  8. sbueringer commented on Jun 18, 2024

    @sbueringer
    Member

    /remove-lifecycle rotten

  9. removed
    lifecycle/rottenDenotes an issue or PR that has aged beyond stale and will be auto-closed.
    on Jun 18, 2024
  10. k8s-triage-robot commented on Sep 16, 2024

    @k8s-triage-robot

    The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

    This bot triages un-triaged issues according to the following rules:

    • After 90d of inactivity, lifecycle/stale is applied
    • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
    • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

    You can:

    • Mark this issue as fresh with /remove-lifecycle stale
    • Close this issue with /close
    • Offer to help out with Issue Triage

    Please send feedback to sig-contributor-experience at kubernetes/community.

    /lifecycle stale

  11. added
    lifecycle/staleDenotes an issue or PR has remained open with no activity and has become stale.
    on Sep 16, 2024
  12. k8s-triage-robot commented on Oct 16, 2024

    @k8s-triage-robot

    The Kubernetes project currently lacks enough active contributors to adequately respond to all issues.

    This bot triages un-triaged issues according to the following rules:

    • After 90d of inactivity, lifecycle/stale is applied
    • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
    • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

    You can:

    • Mark this issue as fresh with /remove-lifecycle rotten
    • Close this issue with /close
    • Offer to help out with Issue Triage

    Please send feedback to sig-contributor-experience at kubernetes/community.

    /lifecycle rotten

  13. added
    lifecycle/rottenDenotes an issue or PR that has aged beyond stale and will be auto-closed.
    and removed
    lifecycle/staleDenotes an issue or PR has remained open with no activity and has become stale.
    on Oct 16, 2024
  14. k8s-triage-robot commented on Nov 15, 2024

    @k8s-triage-robot

    The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

    This bot triages issues according to the following rules:

    • After 90d of inactivity, lifecycle/stale is applied
    • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
    • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

    You can:

    • Reopen this issue with /reopen
    • Mark this issue as fresh with /remove-lifecycle rotten
    • Offer to help out with Issue Triage

    Please send feedback to sig-contributor-experience at kubernetes/community.

    /close not-planned

  15. k8s-ci-robot commented on Nov 15, 2024

    @k8s-ci-robot
    Contributor

    @k8s-triage-robot: Closing this issue, marking it as "Not Planned".

    Details

    In response to this:

    The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

    This bot triages issues according to the following rules:

    • After 90d of inactivity, lifecycle/stale is applied
    • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
    • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

    You can:

    • Reopen this issue with /reopen
    • Mark this issue as fresh with /remove-lifecycle rotten
    • Offer to help out with Issue Triage

    Please send feedback to sig-contributor-experience at kubernetes/community.

    /close not-planned

    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.

  16. alvaroaleman commented on Oct 16, 2025

    @alvaroaleman
    Member

    /reopen
    /lifecycle frozen

    Currently also running into this and its annoying. I just had a look at all of this and I think this is totally possible, it is just that the typing changes would need to go up until including the webhook builder. Since the webhook builder conceptionally represents a webhook for one type, that seems fine

  17. added
    lifecycle/frozenIndicates that an issue or PR should not be auto-closed due to staleness.
    and removed
    lifecycle/rottenDenotes an issue or PR that has aged beyond stale and will be auto-closed.
    on Oct 16, 2025
  18. sbueringer commented on Oct 20, 2025

    @sbueringer
    Member

    +1 Makes sense to me. We might have to add new builder methods to keep supporting the Custom* interfaces until they are removed but that's fine for me (I think that depends on if we use the generic type parameter for For or not).

    We could also maybe add a type parameter and only use it for defaulter/validator and once the Custom* interfaces are gone we also use it in For

  19. self-assigned this
    on Oct 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

kind/featureCategorizes issue or PR as related to a new feature.lifecycle/frozenIndicates that an issue or PR should not be auto-closed due to staleness.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions