Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ListenerSet APIs + Generated Clients #3588

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

dprotaso
Copy link
Contributor

@dprotaso dprotaso commented Feb 3, 2025

Part of #1713

Merge #3589 beforehand (to make this diff easier)

Note: this required two different client sets because if you try to generate a client set containing the stable group (gateway.networking.k8s.io) and experimental (gateway.networking.k8s-x.io) client-gen uses gateway part from both api groups for naming in the client set and it creates a conflict

  • refactor codegen scripts to make it easier to generate two clients (to be removed)
  • add listenerset types
  • adjust GEP to match go type
  • run deepcopy-gen & register-gen
  • perform code generation

Release Note

Introduces ListenerSet API & Generate Clients (in the group gateway.networking.k8s-x.io)

@k8s-ci-robot k8s-ci-robot added the do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. label Feb 3, 2025
@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. kind/gep PRs related to Gateway Enhancement Proposal(GEP) size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Feb 3, 2025
@dprotaso
Copy link
Contributor Author

dprotaso commented Feb 3, 2025

I'm going to pull

refactor codegen scripts to make it easier to generate two clients

Into a separate PR

@dprotaso
Copy link
Contributor Author

dprotaso commented Feb 3, 2025

/hold for #3589

@dprotaso dprotaso changed the title ListenerSet APIs + Generated Clients [wip] ListenerSet APIs + Generated Clients Feb 3, 2025
@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 3, 2025
@dprotaso dprotaso changed the title [wip] ListenerSet APIs + Generated Clients ListenerSet APIs + Generated Clients Feb 3, 2025
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 3, 2025
// +kubebuilder:validation:XValidation:message="Listener name must be unique within the Gateway",rule="self.all(l1, self.exists_one(l2, l1.name == l2.name))"
//
// # TODO: Figure out how to allow empty port here
// #+kubebuilder:validation:XValidation:message="Combination of port, protocol and hostname must be unique for each listener",rule="self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

note this TODO

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok this should become

self.all(l1, 
  !has(l1.port) || // Port is missing no conflict can ever occur
  self.exists_one(l2,
    has(l2.port) && // If L2 has no port than there can't be a conflict
   // Regular check since both listeners have a port
    l1.port == l2.port &&
    l1.protocol == l2.protocol  &&
    (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))
  )
)

@dprotaso
Copy link
Contributor Author

dprotaso commented Feb 4, 2025

/hold need to add the Gateway changes

@dprotaso
Copy link
Contributor Author

dprotaso commented Feb 4, 2025

/hold cancel

@k8s-ci-robot k8s-ci-robot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. and removed do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels Feb 4, 2025
@shaneutt shaneutt self-assigned this Feb 6, 2025
@shaneutt shaneutt self-requested a review February 6, 2025 15:52
@dprotaso
Copy link
Contributor Author

dprotaso commented Feb 6, 2025

Note: this required two different client sets because if you try to generate a client set containing the stable group (gateway.networking.k8s.io) and experimental (gateway.networking.k8s-x.io) client-gen uses gateway part from both api groups for naming in the client set and it creates a conflict

Ok - I figured out there's a marker

+groupGoName=SomeUniqueShortName

So we could have a single clientset that has stable and experimental apis - let me know what people prefer

@@ -74,7 +74,7 @@ type ListenerNamespaces struct {
// * None: Only listeners defined in the Gateway's spec are allowed
//
// +optional
// +kubebuilder:default=Same
Copy link
Member

Choose a reason for hiding this comment

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

This PR seems to jump us all the way from provisional to experimental without hitting implementable. If we have consensus then there might not actually be anything wrong with that, but bare minimum we should update the GEP status accordingly here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Want me to split out the APIs in to a separate PR?

Copy link
Member

Choose a reason for hiding this comment

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

No that's OK! I just think we should flag the status change here and then please feel free to consider this comment resolved.

I just realized another opportunity to update the GEP, but I'll create a separate comment.

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

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

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

Comment on lines +293 to +300
type AllowedListeners struct {
// Namespaces defines which namespaces ListenerSets can be attached to this Gateway.
// While this feature is experimental, the default value is to allow no ListenerSets.
//
// +optional
// +kubebuilder:default={from: None}
Namespaces *ListenerNamespaces `json:"namespaces,omitempty"`
}
Copy link
Member

@shaneutt shaneutt Feb 7, 2025

Choose a reason for hiding this comment

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

I love this part of the API, because I think it captures a very important use case for cluster admins: when they want a Gateway to operate more like a classic ingress-controller, in that there's a single LB for routes across many namespaces.

What occurs to me is that we should update the GEP, as it currently states cross-namespace as a "later goal" but it seems like we're already going for it, and I'm very much in favor of this being an immediate goal. Anything I'm missing? (if not, please just feel free to update the GEP to reflect the goal and then consider my comment resolved at your discretion)

Eventually I personally would like to take this a step further: I would like our documentation to be even more clear about a strong intention for this kind of use case as I anticipate it being a very common ask over time.

Copy link
Member

Choose a reason for hiding this comment

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

+1. I think that cross-namespace is very important for this GEP and I'd love to see it in the first iteration of the API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With the deadline this week I don't think I have time to add this - I can imagine ParentGatewayReference type supporting a Namespace field.

Copy link
Member

@shaneutt shaneutt left a comment

Choose a reason for hiding this comment

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

I think overall we're heading in a good direction here, but I think we need to reiterate what feels like a more obvious question as I read more: "What is a Gateway after this, really?"

Personally I'll have to think on this quite a bit and come back around to it 🤔

@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 8, 2025
ericdbishop added a commit to ericdbishop/gateway-api that referenced this pull request Feb 13, 2025
ericdbishop added a commit to ericdbishop/gateway-api that referenced this pull request Feb 13, 2025
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 14, 2025
@dprotaso
Copy link
Contributor Author

dprotaso commented Feb 14, 2025

I pushed a change to combine everything into a single clientset. It requires me to have a single applyconfiguration package that contains apis and apisx. So folks will have to change their package names if they're using the types there directly. (We could add type aliases)

It should be easy to revert the single client changes so let me know what you prefer

Copy link
Member

@robscott robscott left a comment

Choose a reason for hiding this comment

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

Thanks @dprotaso!

Comment on lines +293 to +300
type AllowedListeners struct {
// Namespaces defines which namespaces ListenerSets can be attached to this Gateway.
// While this feature is experimental, the default value is to allow no ListenerSets.
//
// +optional
// +kubebuilder:default={from: None}
Namespaces *ListenerNamespaces `json:"namespaces,omitempty"`
}
Copy link
Member

Choose a reason for hiding this comment

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

+1. I think that cross-namespace is very important for this GEP and I'd love to see it in the first iteration of the API.


// ParentGatewayReference identifies an API object including its namespace,
// defaulting to Gateway.
type ParentGatewayReference struct {
Copy link
Member

Choose a reason for hiding this comment

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

Since this is a generic reference, I would consider naming it differently than ParentGatewayReference, as the reference can of any group/kind

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a new type so we can default the Group and Kind - also we might add a Namespace in the future here

// ListenerSetSpec defines the desired state of a ListenerSet.
type ListenerSetSpec struct {
// ParentRef references the Gateway that the listeners are attached to.
ParentRef ParentGatewayReference `json:"parentRef,omitempty"`
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 should consider to make this field Required. Is there any specific reason to accept a ListenerSet with an empty ParentRef?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought it is required since there's no +optional marker - is there something else to do?

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 ,omitempty is the actual bit that makes this optional and the +optional tag is just a convention. Recommend removing the ,omitempty as well.

@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 21, 2025
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 25, 2025
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/hold Indicates that a PR should not merge because someone has issued a /hold command. kind/gep PRs related to Gateway Enhancement Proposal(GEP) release-note Denotes a PR that will be considered when it comes time to generate release notes. 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.

5 participants