Skip to content

Tightening validation + adding basic validation tests #772

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

Merged
merged 1 commit into from
Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 5 additions & 12 deletions apis/v1alpha2/gateway_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,7 @@ type Listener struct {
// within a Gateway.
//
// Support: Core
//
// +kubebuilder:validation:MaxLength=253
Name string `json:"name"`
Name SectionName `json:"name"`

// Hostname specifies the virtual hostname to match for protocol types that
// define this concept. When unspecified, "", or `*`, all hostnames are
Expand Down Expand Up @@ -322,6 +320,7 @@ type GatewayTLSConfig struct {
// Support: Implementation-specific
//
// +optional
// +kubebuilder:validation:MaxProperties=16
Options map[string]string `json:"options,omitempty"`
}

Expand Down Expand Up @@ -414,14 +413,10 @@ type RouteGroupKind struct {
//
// +optional
// +kubebuilder:default=gateway.networking.k8s.io
// +kubebuilder:validation:MaxLength=253
Group *string `json:"group,omitempty"`
Group *Group `json:"group,omitempty"`

// Kind is the kind of the Route.
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Kind string `json:"kind"`
Kind Kind `json:"kind"`
}

// GatewayAddress describes an address that can be bound to a Gateway.
Expand Down Expand Up @@ -622,9 +617,7 @@ type ListenerStatus struct {
// Name is the name of the Listener. If the Gateway has more than one
// Listener present, each ListenerStatus MUST specify a name. The names of
// ListenerStatus objects MUST be unique within a Gateway.
//
// +kubebuilder:validation:MaxLength=253
Name string `json:"name"`
Name SectionName `json:"name"`

// SupportedKinds is the list indicating the Kinds supported by this
// listener. When this is not specified on the Listener, this MUST represent
Expand Down
19 changes: 5 additions & 14 deletions apis/v1alpha2/gatewayclass_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,7 @@ type GatewayClassSpec struct {
// and PATH is a valid HTTP path as defined by RFC 3986.
//
// Support: Core
//
// +kubebuilder:validation:MaxLength=253
Controller string `json:"controller"`
Controller GatewayController `json:"controller"`

// ParametersRef is a reference to a resource that contains the configuration
// parameters corresponding to the GatewayClass. This is optional if the
Expand All @@ -83,7 +81,6 @@ type GatewayClassSpec struct {

// Description helps describe a GatewayClass with more details.
//
//
// +kubebuilder:validation:MaxLength=64
// +optional
Description *string `json:"description,omitempty"`
Expand All @@ -93,15 +90,10 @@ type GatewayClassSpec struct {
// configuration resource within the cluster.
type ParametersReference struct {
// Group is the group of the referent.
//
// +kubebuilder:validation:MaxLength=253
Group string `json:"group"`
Group Group `json:"group"`

// Kind is kind of the referent.
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Kind string `json:"kind"`
Kind Kind `json:"kind"`

// Name is the name of the referent.
//
Expand All @@ -111,6 +103,7 @@ type ParametersReference struct {

// Scope represents if the referent is a Cluster or Namespace scoped resource.
// This may be set to "Cluster" or "Namespace".
//
// +kubebuilder:validation:Enum=Cluster;Namespace
// +kubebuilder:default=Cluster
// +optional
Expand All @@ -120,10 +113,8 @@ type ParametersReference struct {
// This field is required when scope is set to "Namespace" and ignored when
// scope is set to "Cluster".
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +optional
Namespace *string `json:"namespace,omitempty"`
Namespace *Namespace `json:"namespace,omitempty"`
}

// GatewayClassConditionType is the type for status conditions on
Expand Down
50 changes: 39 additions & 11 deletions apis/v1alpha2/httproute_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ type HTTPPathMatch struct {
//
// +optional
// +kubebuilder:default="/"
// +kubebuilder:validation:MaxLength=1024
Copy link
Contributor

Choose a reason for hiding this comment

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

apparently 2000 is the accepted folk limit around the web

Copy link
Contributor

Choose a reason for hiding this comment

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

opinion:
Can you imagine anyone using a 2000 character path to do matching though?
If anything, I think we are already generous here.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's likely safer to start with the lower limit and expand if necessary. At least that's been our practice so far.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe? There is data that 2000 is effectively the max which is well known. For the others, yes, we have less info so just have to pick a number. I'm not super tied to increase this -- just that we know that more about what the max is.

Value *string `json:"value,omitempty"`
}

Expand All @@ -282,6 +283,24 @@ const (
HeaderMatchImplementationSpecific HeaderMatchType = "ImplementationSpecific"
)

// HTTPHeaderName is the name of an HTTP header.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to say it's case-insensitive?

Copy link
Contributor

Choose a reason for hiding this comment

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

We say in the place where this type is used. I'm not sure what is the right place for it. The place of use seems more correct because that gets added to the CRD. I can argue either way though.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's more appropriate to specify that it's case insensitive on the match field itself (current state). There's nothing on this type definition that can require that matching is case insensitive.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm ok with anything as long as the generated documentation is clear.

//
// Valid values include:
//
// * "Authorization"
// * "Set-Cookie"
//
// Invalid values include:
//
// * ":method" - ":" is an invalid character. This means that pseudo headers are
// not currently supported by this type.
// * "/invalid" - "/" is an invalid character
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=256
// +kubebuilder:validation:Pattern=`^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$`
type HTTPHeaderName string

// HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request
// headers.
type HTTPHeaderMatch struct {
Expand Down Expand Up @@ -314,10 +333,7 @@ type HTTPHeaderMatch struct {
// Generally, proxies should follow the guidance from the RFC:
// https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding
// processing a repeated header, with special handling for "Set-Cookie".
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=256
Name string `json:"name"`
Name HTTPHeaderName `json:"name"`

// Value is the value of HTTP Header to be matched.
//
Expand Down Expand Up @@ -423,14 +439,20 @@ type HTTPRouteMatch struct {
// ANDed together, meaning, a request must match all the specified headers
// to select the route.
//
// +listType=map
// +listMapKey=name
// +optional
// +kubebuilder:validation:MaxItems=16
Headers []HTTPHeaderMatch `json:"headers,omitempty"`

// QueryParams specifies HTTP query parameter matchers. Multiple match
// values are ANDed together, meaning, a request must match all the
// specified query parameters to select the route.
//
// +listType=map
// +listMapKey=name
// +optional
// +kubebuilder:validation:MaxItems=16
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any harm to increase this to 30-50? I can see hitting 16 limit, probably not 30

Copy link
Member Author

Choose a reason for hiding this comment

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

I hadn't really thought of a use case with that many matches, but I can increase to 32.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually we're using 16 as a limit in a lot of places, including header matching. Unless there's a clear use case I'd be tempted to leave that as is to minimize the changes here.

QueryParams []HTTPQueryParamMatch `json:"queryParams,omitempty"`

// Method specifies HTTP method matcher.
Expand Down Expand Up @@ -574,10 +596,7 @@ type HTTPHeader struct {
// entries with an equivalent header name MUST be ignored. Due to the
// case-insensitivity of header names, "foo" and "Foo" are considered
// equivalent.
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=256
Name string `json:"name"`
Name HTTPHeaderName `json:"name"`

// Value is the value of HTTP Header to be matched.
//
Expand All @@ -604,6 +623,9 @@ type HTTPRequestHeaderFilter struct {
// my-header: bar
//
// +optional
// +listType=map
// +listMapKey=name
// +kubebuilder:validation:MaxItems=16
Set []HTTPHeader `json:"set,omitempty"`

// Add adds the given header(s) (name, value) to the request
Expand All @@ -623,6 +645,9 @@ type HTTPRequestHeaderFilter struct {
// my-header: bar
//
// +optional
// +listType=map
// +listMapKey=name
// +kubebuilder:validation:MaxItems=16
Add []HTTPHeader `json:"add,omitempty"`

// Remove the given header(s) from the HTTP request before the
Expand Down Expand Up @@ -659,29 +684,32 @@ type HTTPRequestRedirect struct {
// +optional
// +kubebuilder:validation:Enum=HTTP;HTTPS
Protocol *string `json:"protocol,omitempty"`

// Hostname is the hostname to be used in the value of the `Location`
// header in the response.
// When empty, the hostname of the request is used.
//
// Support: Core
//
// +optional
Hostname *string `json:"hostname,omitempty"`
Hostname *Hostname `json:"hostname,omitempty"`

// Port is the port to be used in the value of the `Location`
// header in the response.
// When empty, port (if specified) of the request is used.
//
// Support: Extended
//
// +optional
Port *int `json:"port,omitempty"`
Port *PortNumber `json:"port,omitempty"`

// StatusCode is the HTTP status code to be used in response.
//
// Support: Core
//
// +optional
// +kubebuilder:default=302
// +kubebuilder:validation=301;302
// +kubebuilder:validation:Enum=301;302
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like we should just include all the valid redirects from here:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages

Copy link
Member Author

Choose a reason for hiding this comment

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

Agree that we should add this, but didn't want to expand the scope of this PR so added #793 to track this.

Copy link
Contributor

Choose a reason for hiding this comment

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

There was a conformance concern for not adding them in the first place.

StatusCode *int `json:"statusCode,omitempty"`
}

Expand Down
44 changes: 15 additions & 29 deletions apis/v1alpha2/object_reference_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,12 @@ package v1alpha2
// LocalObjectReference identifies an API object within the namespace of the
// referrer.
type LocalObjectReference struct {
// Group is the group of the referent.
//
// +kubebuilder:validation:MaxLength=253
Group string `json:"group"`
// Group is the group of the referent. For example, "networking.k8s.io".
// When unspecified (empty string), core API group is inferred.
Group Group `json:"group"`

// Kind is kind of the referent.
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Kind string `json:"kind"`
// Kind is kind of the referent. For example "HTTPRoute" or "Service".
Kind Kind `json:"kind"`

// Name is the name of the referent.
//
Expand All @@ -39,21 +35,18 @@ type LocalObjectReference struct {

// ObjectReference identifies an API object including its namespace.
type ObjectReference struct {
// Group is the group of the referent.
// Group is the group of the referent. For example, "networking.k8s.io".
// When unspecified (empty string), core API group is inferred.
//
// +optional
// +kubebuilder:default=""
// +kubebuilder:validation:MaxLength=253
Group *string `json:"group"`
Group *Group `json:"group"`

// Kind is kind of the referent.
// Kind is kind of the referent. For example "HTTPRoute" or "Service".
//
// +optional
// +kubebuilder:default=Service
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Kind *string `json:"kind"`
Kind *Kind `json:"kind"`

// Name is the name of the referent.
//
Expand All @@ -71,10 +64,8 @@ type ObjectReference struct {
//
// Support: Core
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +optional
Namespace *string `json:"namespace,omitempty"`
Namespace *Namespace `json:"namespace,omitempty"`
}

// BackendObjectReference defines how an ObjectReference that is
Expand All @@ -86,21 +77,18 @@ type ObjectReference struct {
// owner to accept the reference. See the ReferencePolicy documentation
// for details.
type BackendObjectReference struct {
// Group is the group of the referent.
// Group is the group of the referent. For example, "networking.k8s.io".
// When unspecified (empty string), core API group is inferred.
//
// +optional
// +kubebuilder:default=""
// +kubebuilder:validation:MaxLength=253
Group *string `json:"group,omitempty"`
Group *Group `json:"group,omitempty"`

// Kind is kind of the referent.
// Kind is kind of the referent. For example "HTTPRoute" or "Service".
//
// +optional
// +kubebuilder:default=Service
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Kind *string `json:"kind,omitempty"`
Kind *Kind `json:"kind,omitempty"`

// Name is the name of the referent.
//
Expand All @@ -118,10 +106,8 @@ type BackendObjectReference struct {
//
// Support: Core
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +optional
Namespace *string `json:"namespace,omitempty"`
Namespace *Namespace `json:"namespace,omitempty"`

// Port specifies the destination port number to use for this resource.
// Port is required when the referent is a Kubernetes Service.
Expand Down
14 changes: 3 additions & 11 deletions apis/v1alpha2/policy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,10 @@ package v1alpha2
// for Gateway API.
type PolicyTargetReference struct {
// Group is the group of the target resource.
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Group string `json:"group"`
Group Group `json:"group"`

// Kind is kind of the target resource.
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Kind string `json:"kind"`
Kind Kind `json:"kind"`
Copy link
Contributor

Choose a reason for hiding this comment

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

rant: Why can't github highlight the specific text that has changed in this line.


// Name is the name of the target resource.
//
Expand All @@ -45,10 +39,8 @@ type PolicyTargetReference struct {
// namespace, it MUST only apply to traffic originating from the same
// namespace as the policy.
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +optional
Namespace *string `json:"namespace,omitempty"`
Namespace *Namespace `json:"namespace,omitempty"`

// ClassName is the name of the class this policy should apply to. When
// unspecified, the policy will apply to all classes that support it.
Expand Down
Loading