Skip to content

Commit

Permalink
Implementing GEP 724: Refresh Route-Gateway Binding
Browse files Browse the repository at this point in the history
  • Loading branch information
robscott committed Aug 9, 2021
1 parent 86faa74 commit 0366715
Show file tree
Hide file tree
Showing 17 changed files with 736 additions and 503 deletions.
133 changes: 66 additions & 67 deletions apis/v1alpha2/gateway_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ type GatewaySpec struct {
// combination of Hostname, Port, and Protocol. This will be enforced by a
// validating webhook.
type Listener struct {
// Name is the name of the Listener. If more than one Listener is present
// each Listener MUST specify a name. The names of Listeners MUST be unique
// within a Gateway.
//
// Support: Core
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +optional
Name *string `json:"name,omitempty"`

// Hostname specifies the virtual hostname to match for protocol types that
// define this concept. When unspecified, "", or `*`, all hostnames are
// matched. This field can be omitted for protocols that don't require
Expand Down Expand Up @@ -198,18 +209,7 @@ type Listener struct {
// +optional
TLS *GatewayTLSConfig `json:"tls,omitempty"`

// Routes specifies a schema for associating routes with the
// Listener using selectors. A Route is a resource capable of
// servicing a request and allows a cluster operator to expose
// a cluster resource (i.e. Service) by externally-reachable
// URL, load-balance traffic and terminate SSL/TLS. Typically,
// a route is a "HTTPRoute" or "TCPRoute" in group
// "gateway.networking.k8s.io", however, an implementation may support
// other types of resources.
//
// The Routes selector MUST select a set of objects that
// are compatible with the application protocol specified in
// the Protocol field.
// Routes specifies which Routes may be attached to this Listener.
//
// Although a client request may technically match multiple route rules,
// only one rule may ultimately receive the request. Matching precedence
Expand All @@ -232,7 +232,9 @@ type Listener struct {
// invalid, the rest of the Route should still be supported.
//
// Support: Core
Routes RouteBindingSelector `json:"routes"`
// +kubebuilder:default={namespaces:{from: Same}}
// +optional
Routes *ListenerRoutes `json:"routes,omitempty"`
}

// ProtocolType defines the application protocol accepted by a Listener.
Expand Down Expand Up @@ -383,59 +385,32 @@ const (
TLSModePassthrough TLSModeType = "Passthrough"
)

// RouteBindingSelector defines a schema for associating routes with the Gateway.
// If Namespaces and Selector are defined, only routes matching both selectors are
// associated with the Gateway.
type RouteBindingSelector struct {
// Namespaces indicates in which namespaces Routes should be selected
// for this Gateway. This is restricted to the namespace of this Gateway by
// ListenerRoutes defines which Routes may be attached to this Listener.
type ListenerRoutes struct {
// Namespaces indicates which namespaces Routes may be attached to this
// Listener from. This is restricted to the namespace of this Gateway by
// default.
//
// Support: Core
//
// +optional
// +kubebuilder:default={from: Same}
Namespaces *RouteNamespaces `json:"namespaces,omitempty"`
// Selector specifies a set of route labels used for selecting
// routes to associate with the Gateway. If this Selector is defined,
// only routes matching the Selector are associated with the Gateway.
// An empty Selector matches all routes.
//
// Support: Core
//
// +optional
Selector *metav1.LabelSelector `json:"selector,omitempty"`
// Group is the group of the route resource to select. Omitting the value
// indicates the gateway.networking.k8s.io API group.
// For example, use the following to select an HTTPRoute:
//
// routes:
// kind: HTTPRoute
//
// Otherwise, if an alternative API group is desired, specify the desired
// group:
//
// routes:
// group: acme.io
// kind: FooRoute

// Kinds specifies the groups and kinds of Routes that are allowed to bind to
// this Gateway listener. When unspecified or empty, the only limitation on
// the kinds of Routes supported is the Listener protocol. Kind MUST
// correspond to kinds of Routes that are compatible with the application
// protocol specified in the Listener's Protocol field. If an implementation
// does not support or recognize this resource type, it SHOULD set the
// "ResolvedRefs" condition to false for this listener with the
// "InvalidRoutesRef" reason.
//
// Support: Core
//
// +optional
// +kubebuilder:default=gateway.networking.k8s.io
// +kubebuilder:validation:MaxLength=253
Group *string `json:"group,omitempty"`
// Kind is the kind of the route resource to select.
//
// Kind MUST correspond to kinds of routes that are compatible with the
// application protocol specified in the Listener's Protocol field.
//
// If an implementation does not support or recognize this
// resource type, it SHOULD set the "ResolvedRefs" condition to false for
// this listener with the "InvalidRoutesRef" reason.
//
// Support: Core
Kind string `json:"kind"`
// +kubebuilder:validation:MaxItems=10
Kinds []RouteGroupKind `json:"kinds,omitempty"`
}

// RouteSelectType specifies where Routes should be selected by a Gateway.
Expand Down Expand Up @@ -477,6 +452,24 @@ type RouteNamespaces struct {
Selector *metav1.LabelSelector `json:"selector,omitempty"`
}

type RouteGroupKind struct {
// Group is the group of the Route.
//
// Support: Core
//
// +optional
// +kubebuilder:default=gateway.networking.k8s.io
// +kubebuilder:validation:MaxLength=253
Group *string `json:"group,omitempty"`
// Kind is the kind of the Route.
//
// Support: Core
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Kind string `json:"kind"`
}

// GatewayAddress describes an address that can be bound to a Gateway.
type GatewayAddress struct {
// Type of the address.
Expand Down Expand Up @@ -566,8 +559,6 @@ type GatewayStatus struct {
// Listeners provide status for each unique listener port defined in the Spec.
//
// +optional
// +listType=map
// +listMapKey=port
// +kubebuilder:validation:MaxItems=64
Listeners []ListenerStatus `json:"listeners,omitempty"`
}
Expand Down Expand Up @@ -672,19 +663,27 @@ const (

// ListenerStatus is the status associated with a Listener.
type ListenerStatus struct {
// Port is the unique Listener port value for which this message is
// reporting the status.
Port PortNumber `json:"port"`

// Protocol is the Listener protocol value for which this message is
// reporting the status.
Protocol ProtocolType `json:"protocol"`
// Name is the name of the Listener.
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +optional
Name *string `json:"name,omitempty"`

// Hostname is the Listener hostname value for which this message is
// reporting the status.
// SupportedKinds is the list indicating the Kinds supported by this
// listener. When this is not specified on the Listener, this MUST represent
// the kinds an implementation supports for the specified protocol. When
// there are kinds specified on the Listener, this MUST represent the
// intersection of those kinds and the kinds supported by the implementation
// for the specified protocol.
//
// +kubebuilder:validation:MaxItems=10
// +optional
Hostname *Hostname `json:"hostname,omitempty"`
SupportedKinds []RouteGroupKind `json:"supportedKinds,omitempty"`

// AttachedRoutes represents the total number of Routes that have been
// successfully attached to this Listener.
AttachedRoutes int32 `json:"attachedRoutes"`

// Conditions describe the current condition of this listener.
//
Expand Down
18 changes: 15 additions & 3 deletions apis/v1alpha2/httproute_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,23 @@ type HTTPRouteList struct {

// HTTPRouteSpec defines the desired state of HTTPRoute
type HTTPRouteSpec struct {
// Gateways defines which Gateways can use this Route.
// ParentRefs references the resources that can attach to this Route. The
// only kind of parent resource with "Core" support is Gateway. This API may
// be extended in the future to support additional kinds of parent resources
// such as one of the route kinds. It is invalid to reference an identical
// parent more than once. It is valid to reference multiple distinct
// sections within the same parent resource, such as 2 Listeners within a
// Gateway.
//
// It is possible to separately reference multiple distinct objects that may
// be collapsed by an implementation. For example, some implementations may
// choose to merge compatible Gateway Listeners together. If that is the
// case, the list of routes attached to those resources should also be
// merged.
//
// +optional
// +kubebuilder:default={allow: "SameNamespace"}
Gateways *RouteGateways `json:"gateways,omitempty"`
// +kubebuilder:validation:MaxItems=16
ParentRefs []ParentRef `json:"parentRefs,omitempty"`

// Hostnames defines a set of hostname that should match against
// the HTTP Host header to select a HTTPRoute to process the request.
Expand Down
109 changes: 71 additions & 38 deletions apis/v1alpha2/shared_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,63 +20,96 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// GatewayAllowType specifies which Gateways should be allowed to use a Route.
type GatewayAllowType string

const (
// Any Gateway will be able to use this route.
GatewayAllowAll GatewayAllowType = "All"
// Only Gateways that have been specified in GatewayRefs will be able to use this route.
GatewayAllowFromList GatewayAllowType = "FromList"
// Only Gateways within the same namespace as the route will be able to use this route.
GatewayAllowSameNamespace GatewayAllowType = "SameNamespace"
)
// ParentRef identifies an API object that should be considered a parent of this
// resource. The only kind of parent resource with "Core" support is Gateway.
// This API may be extended in the future to support additional kinds of parent
// resources, such as HTTPRoute.
type ParentRef struct {
// Group is the group of the referent.
//
// Support: Core
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +kubebuilder:default=gateway.networking.k8s.io
// +default
Group *string `json:"group,omitempty"`

// RouteGateways defines which Gateways will be able to use a route. If this
// field results in preventing the selection of a Route by a Gateway, an
// "Admitted" condition with a status of false must be set for the Gateway on
// that Route.
type RouteGateways struct {
// Allow indicates which Gateways will be allowed to use this route.
// Possible values are:
// * All: Gateways in any namespace can use this route.
// * FromList: Only Gateways specified in GatewayRefs may use this route.
// * SameNamespace: Only Gateways in the same namespace may use this route.
// Kind is kind of the referent.
//
// Support: Core (Gateway)
// Support: Extended (Other Resources)
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +kubebuilder:default=Gateway
// +optional
// +kubebuilder:validation:Enum=All;FromList;SameNamespace
// +kubebuilder:default=SameNamespace
Allow *GatewayAllowType `json:"allow,omitempty"`
Kind *string `json:"kind,omitempty"`

// GatewayRefs must be specified when Allow is set to "FromList". In that
// case, only Gateways referenced in this list will be allowed to use this
// route. This field is ignored for other values of "Allow".
// Namespace is the namespace of the referent. When unspecified (empty
// string), this will either be:
//
// * local namespace of the target is a namespace scoped resource
// * no namespace (not applicable) if the target is cluster-scoped.
//
// Support: Extended
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +optional
GatewayRefs []GatewayReference `json:"gatewayRefs,omitempty"`
}
Namespace *string `json:"namespace,omitempty"`

// PortNumber defines a network port.
//
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=65535
type PortNumber int32
// Scope represents if this refers to a cluster or namespace scoped resource.
// This may be set to "Cluster" or "Namespace".
//
// Support: Core (Namespace)
// Support: Extended (Cluster)
//
// +kubebuilder:validation:Enum=Cluster;Namespace
// +kubebuilder:default=Namespace
// +optional
Scope *string `json:"scope,omitempty"`

// GatewayReference identifies a Gateway in a specified namespace.
type GatewayReference struct {
// Name is the name of the referent.
//
// Support: Core
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Name string `json:"name"`

// Namespace is the namespace of the referent.
// SectionName is the name of a section within the target resource. In the
// following resources, SectionName is interpreted as the following:
//
// * Gateway: Listener Name
//
// Implementations MAY choose to support attaching Routes to other resources.
// If that is the case, they MUST clearly document how SectionName is
// interpreted.
//
// When unspecified (empty string), this will reference the entire resource.
// For the purpose of status, an attachment is considered successful if at
// least one section in the parent resource accepts it. For example, Gateway
// listeners can restrict which Routes can bind to them by Route kind,
// namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from
// the referencing Route, the Route MUST be considered successfully
// attached. If no Gateway listeners accept attachment from this Route, the
// Route MUST be considered detached from the Gateway.
//
// Support: Core
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Namespace string `json:"namespace"`
// +optional
SectionName *string `json:"sectionName,omitempty"`
}

// PortNumber defines a network port.
//
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=65535
type PortNumber int32

// BackendObjectReference defines how an ObjectReference that is
// specific to BackendRef. It includes a few additional fields and features
// than a regular ObjectReference.
Expand Down
24 changes: 18 additions & 6 deletions apis/v1alpha2/tcproute_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,29 @@ type TCPRoute struct {

// TCPRouteSpec defines the desired state of TCPRoute
type TCPRouteSpec struct {
// ParentRefs references the resources that can attach to this Route. The
// only kind of parent resource with "Core" support is Gateway. This API may
// be extended in the future to support additional kinds of parent resources
// such as one of the route kinds. It is invalid to reference an identical
// parent more than once. It is valid to reference multiple distinct
// sections within the same parent resource, such as 2 Listeners within a
// Gateway.
//
// It is possible to separately reference multiple distinct objects that may
// be collapsed by an implementation. For example, some implementations may
// choose to merge compatible Gateway Listeners together. If that is the
// case, the list of routes attached to those resources should also be
// merged.
//
// +optional
// +kubebuilder:validation:MaxItems=16
ParentRefs []ParentRef `json:"parentRefs,omitempty"`

// Rules are a list of TCP matchers and actions.
//
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=16
Rules []TCPRouteRule `json:"rules"`

// Gateways defines which Gateways can use this Route.
//
// +optional
// +kubebuilder:default={allow: "SameNamespace"}
Gateways *RouteGateways `json:"gateways,omitempty"`
}

// TCPRouteStatus defines the observed state of TCPRoute
Expand Down
Loading

0 comments on commit 0366715

Please sign in to comment.