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 @@
+(Appears on:
+HTTPProxySpec)
+
+
+
HttpVersion is an alias to enforce validation
+
IPFilterPolicy