From 75ceb00ab4daba7d2de05c24613d59a59d97377e Mon Sep 17 00:00:00 2001 From: Ahmad Karimi Date: Wed, 4 Oct 2023 16:35:38 +0330 Subject: [PATCH] add per-httpproxy http-version support Signed-off-by: Ahmad Karimi --- apis/projectcontour/v1/httpproxy.go | 9 ++++ .../v1/zz_generated.deepcopy.go | 5 +++ .../unreleased/5802-therealak12-small.md | 1 + examples/contour/01-crds.yaml | 11 +++++ examples/render/contour-deployment.yaml | 11 +++++ .../render/contour-gateway-provisioner.yaml | 11 +++++ examples/render/contour-gateway.yaml | 11 +++++ examples/render/contour.yaml | 11 +++++ internal/dag/dag.go | 3 ++ internal/dag/httpproxy_processor.go | 16 ++++++++ internal/xdscache/v3/listener.go | 6 ++- .../docs/main/config/api-reference.html | 41 +++++++++++++++++++ 12 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/5802-therealak12-small.md diff --git a/apis/projectcontour/v1/httpproxy.go b/apis/projectcontour/v1/httpproxy.go index 498be837a8b..431c7101248 100644 --- a/apis/projectcontour/v1/httpproxy.go +++ b/apis/projectcontour/v1/httpproxy.go @@ -18,6 +18,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// HttpVersion is an alias to enforce validation +// +kubebuilder:validation:Enum=h2;http/1.1 +type HttpVersion string + // HTTPProxySpec defines the spec of the CRD. type HTTPProxySpec struct { // Virtualhost appears at most once. If it is present, the object is considered @@ -40,6 +44,11 @@ type HTTPProxySpec struct { // is given precedence over this field. // +optional IngressClassName string `json:"ingressClassName,omitempty"` + + // HttpVersions specify the http versions to offer for this HTTPProxy. + // If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. + // It is ignored when TCPProxy is set. + HttpVersions []HttpVersion `json:"httpVersions,omitempty"` } // Include describes a set of policies that can be applied to an HTTPProxy in a namespace. diff --git a/apis/projectcontour/v1/zz_generated.deepcopy.go b/apis/projectcontour/v1/zz_generated.deepcopy.go index 3c3537ef24e..ccd5db9c496 100644 --- a/apis/projectcontour/v1/zz_generated.deepcopy.go +++ b/apis/projectcontour/v1/zz_generated.deepcopy.go @@ -461,6 +461,11 @@ func (in *HTTPProxySpec) DeepCopyInto(out *HTTPProxySpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.HttpVersions != nil { + in, out := &in.HttpVersions, &out.HttpVersions + *out = make([]HttpVersion, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPProxySpec. diff --git a/changelogs/unreleased/5802-therealak12-small.md b/changelogs/unreleased/5802-therealak12-small.md new file mode 100644 index 00000000000..f6cdb4c3ebc --- /dev/null +++ b/changelogs/unreleased/5802-therealak12-small.md @@ -0,0 +1 @@ +Adds HttpVersions field to HTTPProxy spec. The field is used to specify ALPNProtocols on the corresponding tls context. diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml index 98b9fe9cebd..97cb8587a40 100644 --- a/examples/contour/01-crds.yaml +++ b/examples/contour/01-crds.yaml @@ -5011,6 +5011,17 @@ spec: spec: description: HTTPProxySpec defines the spec of the CRD. properties: + httpVersions: + description: HttpVersions specify the http versions to offer for this + HTTPProxy. If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig + will be used. It is ignored when TCPProxy is set. + items: + description: HttpVersion is an alias to enforce validation + enum: + - h2 + - http/1.1 + type: string + type: array includes: description: Includes allow for specific routing configuration to be included from another HTTPProxy, possibly in another namespace. diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml index 4caa7156abd..2d0eb8783c8 100644 --- a/examples/render/contour-deployment.yaml +++ b/examples/render/contour-deployment.yaml @@ -5230,6 +5230,17 @@ spec: spec: description: HTTPProxySpec defines the spec of the CRD. properties: + httpVersions: + description: HttpVersions specify the http versions to offer for this + HTTPProxy. If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig + will be used. It is ignored when TCPProxy is set. + items: + description: HttpVersion is an alias to enforce validation + enum: + - h2 + - http/1.1 + type: string + type: array includes: description: Includes allow for specific routing configuration to be included from another HTTPProxy, possibly in another namespace. diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml index b0097c823ca..d53e1ada7ce 100644 --- a/examples/render/contour-gateway-provisioner.yaml +++ b/examples/render/contour-gateway-provisioner.yaml @@ -5022,6 +5022,17 @@ spec: spec: description: HTTPProxySpec defines the spec of the CRD. properties: + httpVersions: + description: HttpVersions specify the http versions to offer for this + HTTPProxy. If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig + will be used. It is ignored when TCPProxy is set. + items: + description: HttpVersion is an alias to enforce validation + enum: + - h2 + - http/1.1 + type: string + type: array includes: description: Includes allow for specific routing configuration to be included from another HTTPProxy, possibly in another namespace. diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml index 9843bce947b..89bd109955d 100644 --- a/examples/render/contour-gateway.yaml +++ b/examples/render/contour-gateway.yaml @@ -5233,6 +5233,17 @@ spec: spec: description: HTTPProxySpec defines the spec of the CRD. properties: + httpVersions: + description: HttpVersions specify the http versions to offer for this + HTTPProxy. If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig + will be used. It is ignored when TCPProxy is set. + items: + description: HttpVersion is an alias to enforce validation + enum: + - h2 + - http/1.1 + type: string + type: array includes: description: Includes allow for specific routing configuration to be included from another HTTPProxy, possibly in another namespace. diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml index f5fdc105ce2..5c884a5ca87 100644 --- a/examples/render/contour.yaml +++ b/examples/render/contour.yaml @@ -5230,6 +5230,17 @@ spec: spec: description: HTTPProxySpec defines the spec of the CRD. properties: + httpVersions: + description: HttpVersions specify the http versions to offer for this + HTTPProxy. If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig + will be used. It is ignored when TCPProxy is set. + items: + description: HttpVersion is an alias to enforce validation + enum: + - h2 + - http/1.1 + type: string + type: array includes: description: Includes allow for specific routing configuration to be included from another HTTPProxy, possibly in another namespace. diff --git a/internal/dag/dag.go b/internal/dag/dag.go index aea888e4b16..5e6452ee9e3 100644 --- a/internal/dag/dag.go +++ b/internal/dag/dag.go @@ -793,6 +793,9 @@ type SecureVirtualHost struct { // JWTProviders specify how to verify JWTs. JWTProviders []JWTProvider + + // AlpnProtos specify the HTTP version to offer for this vhost + HttpVersions []string } type JWTProvider struct { diff --git a/internal/dag/httpproxy_processor.go b/internal/dag/httpproxy_processor.go index 255a1fa0b71..329f188bca5 100644 --- a/internal/dag/httpproxy_processor.go +++ b/internal/dag/httpproxy_processor.go @@ -263,6 +263,7 @@ func (p *HTTPProxyProcessor) computeHTTPProxy(proxy *contour_api_v1.HTTPProxy) { svhost.Secret = sec svhost.MinTLSVersion = minTLSVer svhost.MaxTLSVersion = maxTLSVer + svhost.HttpVersions = p.getSortedHttpVersions(proxy) // Check if FallbackCertificate && ClientValidation are both enabled in the same vhost if tls.EnableFallbackCertificate && tls.ClientValidation != nil { @@ -1473,6 +1474,21 @@ func (p *HTTPProxyProcessor) GlobalAuthorizationContext() map[string]string { return nil } +// getSortedHttpVersions returns and empty slice or ["h2", "http/1.1"] or ["http/1.1"]. +// This is done to conform with how envoy expects AlpnProtocols in tlsv3.CommonTlsContext. +func (p *HTTPProxyProcessor) getSortedHttpVersions(proxy *contour_api_v1.HTTPProxy) []string { + proxyHttpVersions := proxy.Spec.HttpVersions + if len(proxyHttpVersions) == 0 { + return nil + } + for _, httpVersion := range proxyHttpVersions { + if httpVersion == "h2" { + return []string{"h2", "http/1.1"} + } + } + return []string{"http/1.1"} +} + // expandPrefixMatches adds new Routes to account for the difference // between prefix replacement when matching on '/foo' and '/foo/'. // diff --git a/internal/xdscache/v3/listener.go b/internal/xdscache/v3/listener.go index c9cf6d04aaf..1f37936e378 100644 --- a/internal/xdscache/v3/listener.go +++ b/internal/xdscache/v3/listener.go @@ -502,7 +502,11 @@ func (c *ListenerCache) OnChange(root *dag.DAG) { filters = envoy_v3.Filters(cm) - alpnProtos = envoy_v3.ProtoNamesForVersions(cfg.DefaultHTTPVersions...) + if len(vh.HttpVersions) != 0 { + alpnProtos = vh.HttpVersions + } else { + alpnProtos = envoy_v3.ProtoNamesForVersions(cfg.DefaultHTTPVersions...) + } } else { filters = envoy_v3.Filters(envoy_v3.TCPProxy(listener.Name, vh.TCPProxy, cfg.newSecureAccessLog())) diff --git a/site/content/docs/main/config/api-reference.html b/site/content/docs/main/config/api-reference.html index b91773147ef..30036f0d0d0 100644 --- a/site/content/docs/main/config/api-reference.html +++ b/site/content/docs/main/config/api-reference.html @@ -161,6 +161,22 @@

HTTPProxy is given precedence over this field.

+ + +httpVersions +
+ + +[]HttpVersion + + + + +

HttpVersions specify the http versions to offer for this HTTPProxy. +If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. +It is ignored when TCPProxy is set.

+ + @@ -1608,6 +1624,22 @@

HTTPProxySpec is given precedence over this field.

+ + +httpVersions +
+ + +[]HttpVersion + + + + +

HttpVersions specify the http versions to offer for this HTTPProxy. +If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. +It is ignored when TCPProxy is set.

+ +

HTTPProxyStatus @@ -2140,6 +2172,15 @@

HeadersPolicy +

HttpVersion +(string alias)

+

+(Appears on: +HTTPProxySpec) +

+

+

HttpVersion is an alias to enforce validation

+

IPFilterPolicy