Skip to content

Commit 8185c7d

Browse files
dprotasoyoungnick
andauthored
GEP-1713 Revisions (#3744)
* formatting * clarify optional port semantics * clarify listener name semantics * clarify attachment/grants semantics - Route attachment without sectionName - re-order policy attachment section - include a section about ReferenceGrants * set proper min/max value for listenerentry.port We had to drop the use of the PortNumber type because of limitations with overriding min max using kubebuilder annotations * Update geps/gep-1713/index.md Co-authored-by: Nick Young <[email protected]> * Drop validation markers this is handled in another PR See: #3750 * address Nick's feedback * remove stray backtick * address Rob's feedback * incorporate gep changes into godoc --------- Co-authored-by: Nick Young <[email protected]>
1 parent 7d8e56b commit 8185c7d

File tree

5 files changed

+126
-35
lines changed

5 files changed

+126
-35
lines changed

apis/v1/gateway_types.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,37 @@ const (
10621062
GatewayReasonListenersNotReady GatewayConditionReason = "ListenersNotReady"
10631063
)
10641064

1065+
const (
1066+
// AttachedListenerSets is a condition that is true when the Gateway has
1067+
// at least one ListenerSet attached to it.
1068+
//
1069+
// Possible reasons for this condition to be True are:
1070+
//
1071+
// * "ListenerSetsAttached"
1072+
//
1073+
// Possible reasons for this condition to be False are:
1074+
//
1075+
// * "NoListenerSetsAttached"
1076+
// * "ListenerSetsNotAllowed"
1077+
//
1078+
// Controllers may raise this condition with other reasons,
1079+
// but should prefer to use the reasons listed above to improve
1080+
// interoperability.
1081+
GatewayConditionAttachedListenerSets GatewayConditionType = "AttachedListenerSets"
1082+
1083+
// This reason is used with the "AttachedListenerSets" condition when the
1084+
// Gateway has at least one ListenerSet attached to it.
1085+
GatewayReasonListenerSetsAttached GatewayConditionReason = "ListenerSetsAttached"
1086+
1087+
// This reason is used with the "AttachedListenerSets" condition when the
1088+
// Gateway has no ListenerSets attached to it.
1089+
GatewayReasonNoListenerSetsAttached GatewayConditionReason = "NoListenerSetsAttached"
1090+
1091+
// This reason is used with the "AttachedListenerSets" condition when the
1092+
// Gateway has ListenerSets attached to it, but the ListenerSets are not allowed.
1093+
GatewayReasonListenerSetsNotAllowed GatewayConditionReason = "ListenerSetsNotAllowed"
1094+
)
1095+
10651096
// ListenerStatus is the status associated with a Listener.
10661097
type ListenerStatus struct {
10671098
// Name is the name of the Listener that this status corresponds to.

apisx/v1alpha1/xlistenerset_types.go

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,33 @@ import (
2929
// +kubebuilder:printcolumn:name="Programmed",type=string,JSONPath=`.status.conditions[?(@.type=="Programmed")].status`
3030
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
3131

32-
// XListenerSet defines a set of additional listeners
33-
// to attach to an existing Gateway.
32+
// XListenerSet defines a set of additional listeners to attach to an existing Gateway.
33+
// This resource provides a mechanism to merge multiple listeners into a single Gateway.
34+
//
35+
// The parent Gateway must explicitly allow ListenerSet attachment through its
36+
// AllowedListeners configuration. By default, Gateways do not allow ListenerSet
37+
// attachment.
38+
//
39+
// Routes can attach to a ListenerSet by specifying it as a parentRef, and can
40+
// optionally target specific listeners using the sectionName field.
41+
//
42+
// Policy Attachment:
43+
// - Policies that attach to a ListenerSet apply to all listeners defined in that resource
44+
// - Policies do not impact listeners in the parent Gateway
45+
// - Different ListenerSets attached to the same Gateway can have different policies
46+
// - If an implementation cannot apply a policy to specific listeners, it should reject the policy
47+
//
48+
// ReferenceGrant Semantics:
49+
// - ReferenceGrants applied to a Gateway are not inherited by child ListenerSets
50+
// - ReferenceGrants applied to a ListenerSet do not grant permission to the parent Gateway's listeners
51+
// - A ListenerSet can reference secrets/backends in its own namespace without a ReferenceGrant
52+
//
53+
// Gateway Integration:
54+
// - The parent Gateway's status will include an "AttachedListenerSets" condition
55+
// - This condition will be:
56+
// - True: when AllowedListeners is set and at least one child ListenerSet is attached
57+
// - False: when AllowedListeners is set but no valid listeners are attached, or when AllowedListeners is not set or false
58+
// - Unknown: when no AllowedListeners config is present
3459
type XListenerSet struct {
3560
metav1.TypeMeta `json:",inline"`
3661
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -63,10 +88,10 @@ type ListenerSetSpec struct {
6388
//
6489
// 1. "parent" Gateway
6590
// 2. ListenerSet ordered by creation time (oldest first)
66-
// 3. ListenerSet ordered alphabetically by {namespace}/{name}.
91+
// 3. ListenerSet ordered alphabetically by "{namespace}/{name}".
6792
//
6893
// An implementation MAY reject listeners by setting the ListenerEntryStatus
69-
// `Accepted`` condition to False with the Reason `TooManyListeners`
94+
// `Accepted` condition to False with the Reason `TooManyListeners`
7095
//
7196
// If a listener has a conflict, this will be reported in the
7297
// Status.ListenerEntryStatus setting the `Conflicted` condition to True.

config/crd/experimental/gateway.networking.x-k8s.io_xlistenersets.yaml

Lines changed: 29 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

geps/gep-1713/index.md

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ Thus updating a single `Gateway` resource with this many certificates is a conte
3636

3737
More broadly, large scale gateway users often expose `O(1000)` domains, but are currently limited by the maximum of 64 `listeners`.
3838

39-
The spec currently has language to indicate implementations `MAY` merge `Gateways` resources but does not define any specific requirements for how that should work.
40-
https://github.com/kubernetes-sigs/gateway-api/blob/541e9fc2b3c2f62915cb58dc0ee5e43e4096b3e2/apis/v1beta1/gateway_types.go#L76-L78
39+
The [spec currently has language](https://github.com/kubernetes-sigs/gateway-api/blob/541e9fc2b3c2f62915cb58dc0ee5e43e4096b3e2/apis/v1beta1/gateway_types.go#L76-L78) to indicate implementations `MAY` merge `Gateways` resources but does not define any specific requirements for how that should work.
40+
4141

4242
## Feature Details
4343

@@ -164,15 +164,8 @@ type ListenerEntry struct {
164164
// Port is the network port. Multiple listeners may use the
165165
// same port, subject to the Listener compatibility rules.
166166
//
167-
// If the port is specified as zero, the implementation will assign
168-
// a unique port. If the implementation does not support dynamic port
169-
// assignment, it MUST set `Accepted` condition to `False` with the
170-
// `UnsupportedPort` reason.
171-
//
172167
// Support: Core
173-
//
174-
// +optional
175-
Port *PortNumber `json:"port,omitempty"`
168+
Port PortNumber `json:"port,omitempty"`
176169

177170
// Protocol specifies the network protocol this listener expects to receive.
178171
//
@@ -385,8 +378,7 @@ spec:
385378
```
386379
### ListenerEntry
387380
388-
`ListenerEntry` is currently a copy of the `Listener` struct with some changes
389-
1. `Port` is now a pointer to allow for dynamic port assignment.
381+
`ListenerEntry` is currently a copy of the `Listener` struct with some changes noted in the below sections
390382

391383
## Semantics
392384

@@ -399,7 +391,7 @@ When there are no listeners the `Gateway`'s `status.listeners` should be empty o
399391

400392
Implementations, when creating a `Gateway`, may provision underlying infrastructure when there are no listeners present. The status conditions `Accepted` and `Programmed` conditions should reflect state of this provisioning.
401393

402-
### Gateway <> ListenerSet Handshake
394+
### Gateway & ListenerSet Handshake
403395

404396
By default a `Gateway` MUST NOT allow `ListenerSets` to be attached. Users can enable this behaviour by configuring their `Gateway` to allow `ListenerSet` attachment:
405397

@@ -413,7 +405,7 @@ spec:
413405
- from: Same
414406
```
415407

416-
### Route Attaching
408+
### Route Attachment
417409

418410
Routes MUST be able to specify a `ListenerSet` as a `parentRef`. Routes can use `sectionName`/`port` fields in `ParentReference` to help target a specific listener. If no listener is targeted (`sectionName`/`port` are unset) then the Route attaches to all the listeners in the `ListenerSet`.
419411

@@ -461,10 +453,36 @@ spec:
461453
sectionName: foo
462454
```
463455

456+
#### Optional Section Name
457+
458+
If a `sectionName` in a Route's `parentRef` is not set then the Route MUST attach to only the listeners in the referenced parent. As an example given a `Gateway` and it's child `ListenerSets` a route attaching to the `Gateway` with an empty `sectionName` shall only attach to the listeners in the `Gateways` immediate `spec.listeners` list. In other words, the Route will not attach to any listeners in the `ListenerSets`. This is necessary because, for UX reasons, the `name` field does not have to be unique across all Listeners merged into a Gateway (see the section below for details).
459+
460+
### Policy Attachment
461+
462+
Policy attachment is [under discussion] in https://github.com/kubernetes-sigs/gateway-api/discussions/2927
463+
464+
Similar to Routes, `ListenerSet` can inherit policy from a Gateway.
465+
Policies that attach to a `ListenerSet` apply to all listeners defined in that resource, but do not impact listeners in the parent `Gateway`. This allows `ListenerSets` attached to the same `Gateway` to have different policies.
466+
If the implementation cannot apply the policy to only specific listeners, it should reject the policy.
467+
468+
### ReferenceGrant Semantics
469+
470+
When a `ReferenceGrant` is applied to a `Gateway` it MUST NOT be inherited by child `ListenerSets`. Thus a `ListenerSet` listener MUST NOT access secrets granted to the `Gateway` listeners.
471+
472+
When a `ReferenceGrant` is applied to a `ListenerSet` it MUST NOT grant permission to the parent `Gateway`'s listeners. Thus a `Gateway` listener MUST NOT access secrets granted to the `ListenerSet` listeners.
473+
474+
A `ListenerSet` must be able to reference a secret/backend in the same namespace as itself without a `ReferenceGrant`.
475+
476+
464477
### Listener Validation
465478

466-
Implementations MUST treat the parent `Gateway`s as having the merged list of all listeners from itself and attached `ListenerSets`. See 'Listener Precedence' for more details on ordering.
467-
Validation of this list of listeners MUST behave the same as if the list were part of a single `Gateway`.
479+
Within a single resource such as a `Gateway` or `ListenerSet` the list of listeners MUST have unique names. Implementations MUST allow listeners from a child `ListenerSet` to be merged into a parent `Gateway` when listeners have the same name. Likewise implementations MUST allow sibling `ListenerSets` listeners with matching names to be merged into a parent `Gateway`. This allows for authors of Routes to simply attach to their desired parentRef and listener without having to worry about naming conflicts across resources.
480+
481+
It is up to the implementations how unique names are generated internally. One example would be to hash the `ListenerSet` name+namespace and prepend it to the listener entry `name`.
482+
483+
Implementations MUST treat the parent `Gateway`s as having the merged list of all listeners from itself and attached `ListenerSets` and validation of this list of listeners MUST behave the same as if the list were part of a single `Gateway` with the relaxed listener name constraints.
484+
485+
Ordering will follow the semantics defined in [Listener Precedence](#listener-precedence).
468486

469487
From the earlier example the above resources would be equivalent to a single `Gateway` where the listeners are collapsed into a single list.
470488

@@ -514,7 +532,7 @@ Listeners should be merged using the following precedence:
514532

515533
Conflicts are covered in the section 'ListenerConditions within a ListenerSet'
516534

517-
### Gateway Conditions
535+
### Gateway Conditions
518536

519537
`Gateway`'s `Accepted` and `Programmed` top-level conditions remain unchanged and reflect the status of the local configuration.
520538
@@ -555,14 +573,6 @@ If a listener has a conflict, this should be reported in the `ListenerEntryStatu
555573

556574
Implementations SHOULD be cautious about what information from the parent or siblings are reported to avoid accidentally leaking sensitive information that the child would not otherwise have access to. This can include contents of secrets etc.
557575

558-
### Policy Attachment
559-
560-
Policy attachment is [under discussion] in https://github.com/kubernetes-sigs/gateway-api/discussions/2927
561-
562-
Similar to Routes, `ListenerSet` can inherit policy from a Gateway.
563-
Policies that attach to a `ListenerSet` apply to all listeners defined in that resource, but do not impact listeners in the parent `Gateway`. This allows `ListenerSets` attached to the same `Gateway` to have different policies.
564-
If the implementation cannot apply the policy to only specific listeners, it should reject the policy.
565-
566576
## Alternatives
567577

568578
### Re-using Gateway Resource

pkg/generated/openapi/zz_generated.openapi.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)