xds: add support for envoy 1.15.0 and drop support for 1.11.x (#8424)

Related changes:

- hard-fail the xDS connection attempt if the envoy version is known to be too old to be supported
- remove the RouterMatchSafeRegex proxy feature since all supported envoy versions have it
- stop using --max-obj-name-len (due to: envoyproxy/envoy#11740)
This commit is contained in:
R.B. Boyer 2020-07-31 15:52:49 -05:00 committed by GitHub
parent e365641a99
commit 8ea4c482b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
184 changed files with 113 additions and 149 deletions

View File

@ -640,13 +640,13 @@ jobs:
command: bash <(curl -s https://codecov.io/bash) -v -c -C $CIRCLE_SHA1 -F ui
- run: *notify-slack-failure
envoy-integration-test-1.11.2:
envoy-integration-test-1.12.6:
docker:
# We only really need bash and docker-compose which is installed on all
# Circle images but pick Go since we have to pick one of them.
- image: *GOLANG_IMAGE
environment:
ENVOY_VERSION: "1.11.2"
ENVOY_VERSION: "1.12.6"
steps: &ENVOY_INTEGRATION_TEST_STEPS
- checkout
# Get go binary from workspace
@ -675,13 +675,6 @@ jobs:
path: *TEST_RESULTS_DIR
- run: *notify-slack-failure
envoy-integration-test-1.12.6:
docker:
- image: *GOLANG_IMAGE
environment:
ENVOY_VERSION: "1.12.6"
steps: *ENVOY_INTEGRATION_TEST_STEPS
envoy-integration-test-1.13.4:
docker:
- image: *GOLANG_IMAGE
@ -696,6 +689,13 @@ jobs:
ENVOY_VERSION: "1.14.4"
steps: *ENVOY_INTEGRATION_TEST_STEPS
envoy-integration-test-1.15.0:
docker:
- image: *GOLANG_IMAGE
environment:
ENVOY_VERSION: "1.15.0"
steps: *ENVOY_INTEGRATION_TEST_STEPS
# run integration tests for the connect ca providers
test-connect-ca-providers:
docker:
@ -807,9 +807,6 @@ workflows:
- nomad-integration-0_8:
requires:
- dev-build
- envoy-integration-test-1.11.2:
requires:
- dev-build
- envoy-integration-test-1.12.6:
requires:
- dev-build
@ -819,6 +816,9 @@ workflows:
- envoy-integration-test-1.14.4:
requires:
- dev-build
- envoy-integration-test-1.15.0:
requires:
- dev-build
website:
jobs:

View File

@ -11,6 +11,7 @@ import (
envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2"
"github.com/hashicorp/consul/agent/proxycfg"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/xds/proxysupport"
"github.com/hashicorp/consul/sdk/testutil"
testinf "github.com/mitchellh/go-testing-interface"
"github.com/stretchr/testify/require"
@ -527,8 +528,9 @@ func TestClustersFromSnapshot(t *testing.T) {
},
}
for _, envoyVersion := range supportedEnvoyVersions {
sf := determineSupportedProxyFeaturesFromString(envoyVersion)
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
t.Run("envoy-"+envoyVersion, func(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -737,13 +739,3 @@ func setupTLSRootsAndLeaf(t *testing.T, snap *proxycfg.ConfigSnapshot) {
snap.Roots.Roots[0].RootCert = golden(t, "test-root-cert", "", "")
}
}
// supportedEnvoyVersions lists the versions that we generated golden tests for
//
// see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions
var supportedEnvoyVersions = []string{
"1.14.4",
"1.13.4",
"1.12.6",
"1.11.2",
}

View File

@ -14,6 +14,7 @@ import (
envoyendpoint "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint"
"github.com/hashicorp/consul/agent/proxycfg"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/xds/proxysupport"
"github.com/hashicorp/consul/sdk/testutil"
testinf "github.com/mitchellh/go-testing-interface"
)
@ -554,8 +555,9 @@ func Test_endpointsFromSnapshot(t *testing.T) {
},
}
for _, envoyVersion := range supportedEnvoyVersions {
sf := determineSupportedProxyFeaturesFromString(envoyVersion)
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
t.Run("envoy-"+envoyVersion, func(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@ -9,25 +9,37 @@ import (
)
var (
// minSafeRegexVersion reflects the minimum version where we could use safe_regex instead of regex
//
// NOTE: the first version that no longer supported the old style was 1.13.0
minSafeRegexVersion = version.Must(version.NewVersion("1.11.2"))
// minSupportedVersion is the oldest mainline version we support. This should always be
// the zero'th point release of the last element of proxysupport.EnvoyVersions.
minSupportedVersion = version.Must(version.NewVersion("1.12.0"))
)
type supportedProxyFeatures struct {
RouterMatchSafeRegex bool // use safe_regex instead of regex in http.router rules
// add version dependent feature flags here
}
func determineSupportedProxyFeatures(node *envoycore.Node) supportedProxyFeatures {
func determineSupportedProxyFeatures(node *envoycore.Node) (supportedProxyFeatures, error) {
version := determineEnvoyVersionFromNode(node)
return determineSupportedProxyFeaturesFromVersion(version)
}
func determineSupportedProxyFeaturesFromString(vs string) (supportedProxyFeatures, error) {
version := version.Must(version.NewVersion(vs))
return determineSupportedProxyFeaturesFromVersion(version)
}
func determineSupportedProxyFeaturesFromVersion(version *version.Version) (supportedProxyFeatures, error) {
if version == nil {
return supportedProxyFeatures{}
// This would happen on either extremely old builds OR perhaps on
// custom builds. Should we error?
return supportedProxyFeatures{}, nil
}
return supportedProxyFeatures{
RouterMatchSafeRegex: !version.LessThan(minSafeRegexVersion),
if version.LessThan(minSupportedVersion) {
return supportedProxyFeatures{}, fmt.Errorf("Envoy %s is too old and is not supported by Consul", version)
}
return supportedProxyFeatures{}, nil
}
// example: 1580db37e9a97c37e410bad0e1507ae1a0fd9e77/1.12.4/Clean/RELEASE/BoringSSL
@ -74,10 +86,3 @@ func determineEnvoyVersionFromNode(node *envoycore.Node) *version.Version {
),
))
}
func determineSupportedProxyFeaturesFromString(vs string) supportedProxyFeatures {
version := version.Must(version.NewVersion(vs))
return supportedProxyFeatures{
RouterMatchSafeRegex: !version.LessThan(minSafeRegexVersion),
}
}

View File

@ -11,6 +11,7 @@ import (
envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2"
"github.com/hashicorp/consul/agent/proxycfg"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/xds/proxysupport"
"github.com/hashicorp/consul/sdk/testutil"
testinf "github.com/mitchellh/go-testing-interface"
"github.com/stretchr/testify/require"
@ -433,8 +434,9 @@ func TestListenersFromSnapshot(t *testing.T) {
},
}
for _, envoyVersion := range supportedEnvoyVersions {
sf := determineSupportedProxyFeaturesFromString(envoyVersion)
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
t.Run("envoy-"+envoyVersion, func(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@ -0,0 +1,11 @@
package proxysupport
// EnvoyVersions lists the latest officially supported versions of envoy.
//
// see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions
var EnvoyVersions = []string{
"1.15.0",
"1.14.4",
"1.13.4",
"1.12.6",
}

View File

@ -277,7 +277,7 @@ func makeUpstreamRouteForDiscoveryChain(
return host, nil
}
func makeRouteMatchForDiscoveryRoute(cInfo connectionInfo, discoveryRoute *structs.DiscoveryRoute) *envoyroute.RouteMatch {
func makeRouteMatchForDiscoveryRoute(_ connectionInfo, discoveryRoute *structs.DiscoveryRoute) *envoyroute.RouteMatch {
match := discoveryRoute.Definition.Match
if match == nil || match.IsEmpty() {
return makeDefaultRouteMatch()
@ -295,15 +295,9 @@ func makeRouteMatchForDiscoveryRoute(cInfo connectionInfo, discoveryRoute *struc
Prefix: match.HTTP.PathPrefix,
}
case match.HTTP.PathRegex != "":
if cInfo.ProxyFeatures.RouterMatchSafeRegex {
em.PathSpecifier = &envoyroute.RouteMatch_SafeRegex{
SafeRegex: makeEnvoyRegexMatch(match.HTTP.PathRegex),
}
} else {
em.PathSpecifier = &envoyroute.RouteMatch_Regex{
Regex: match.HTTP.PathRegex,
}
}
default:
em.PathSpecifier = &envoyroute.RouteMatch_Prefix{
Prefix: "/",
@ -323,15 +317,9 @@ func makeRouteMatchForDiscoveryRoute(cInfo connectionInfo, discoveryRoute *struc
ExactMatch: hdr.Exact,
}
case hdr.Regex != "":
if cInfo.ProxyFeatures.RouterMatchSafeRegex {
eh.HeaderMatchSpecifier = &envoyroute.HeaderMatcher_SafeRegexMatch{
SafeRegexMatch: makeEnvoyRegexMatch(hdr.Regex),
}
} else {
eh.HeaderMatchSpecifier = &envoyroute.HeaderMatcher_RegexMatch{
RegexMatch: hdr.Regex,
}
}
case hdr.Prefix != "":
eh.HeaderMatchSpecifier = &envoyroute.HeaderMatcher_PrefixMatch{
PrefixMatch: hdr.Prefix,
@ -361,15 +349,9 @@ func makeRouteMatchForDiscoveryRoute(cInfo connectionInfo, discoveryRoute *struc
eh := &envoyroute.HeaderMatcher{
Name: ":method",
}
if cInfo.ProxyFeatures.RouterMatchSafeRegex {
eh.HeaderMatchSpecifier = &envoyroute.HeaderMatcher_SafeRegexMatch{
HeaderMatchSpecifier: &envoyroute.HeaderMatcher_SafeRegexMatch{
SafeRegexMatch: makeEnvoyRegexMatch(methodHeaderRegex),
}
} else {
eh.HeaderMatchSpecifier = &envoyroute.HeaderMatcher_RegexMatch{
RegexMatch: methodHeaderRegex,
}
},
}
em.Headers = append(em.Headers, eh)
@ -384,7 +366,6 @@ func makeRouteMatchForDiscoveryRoute(cInfo connectionInfo, discoveryRoute *struc
switch {
case qm.Exact != "":
if cInfo.ProxyFeatures.RouterMatchSafeRegex {
eq.QueryParameterMatchSpecifier = &envoyroute.QueryParameterMatcher_StringMatch{
StringMatch: &envoymatcher.StringMatcher{
MatchPattern: &envoymatcher.StringMatcher_Exact{
@ -392,11 +373,7 @@ func makeRouteMatchForDiscoveryRoute(cInfo connectionInfo, discoveryRoute *struc
},
},
}
} else {
eq.Value = qm.Exact
}
case qm.Regex != "":
if cInfo.ProxyFeatures.RouterMatchSafeRegex {
eq.QueryParameterMatchSpecifier = &envoyroute.QueryParameterMatcher_StringMatch{
StringMatch: &envoymatcher.StringMatcher{
MatchPattern: &envoymatcher.StringMatcher_SafeRegex{
@ -404,18 +381,10 @@ func makeRouteMatchForDiscoveryRoute(cInfo connectionInfo, discoveryRoute *struc
},
},
}
} else {
eq.Value = qm.Regex
eq.Regex = makeBoolValue(true)
}
case qm.Present:
if cInfo.ProxyFeatures.RouterMatchSafeRegex {
eq.QueryParameterMatchSpecifier = &envoyroute.QueryParameterMatcher_PresentMatch{
PresentMatch: true,
}
} else {
eq.Value = ""
}
default:
continue // skip this impossible situation
}

View File

@ -11,6 +11,7 @@ import (
"github.com/hashicorp/consul/agent/consul/discoverychain"
"github.com/hashicorp/consul/agent/proxycfg"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/xds/proxysupport"
testinf "github.com/mitchellh/go-testing-interface"
"github.com/stretchr/testify/require"
)
@ -175,8 +176,9 @@ func TestRoutesFromSnapshot(t *testing.T) {
},
}
for _, envoyVersion := range supportedEnvoyVersions {
sf := determineSupportedProxyFeaturesFromString(envoyVersion)
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
t.Run("envoy-"+envoyVersion, func(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@ -311,7 +311,11 @@ func (s *Server) process(stream ADSStream, reqCh <-chan *envoy.DiscoveryRequest)
if node == nil && req.Node != nil {
node = req.Node
proxyFeatures = determineSupportedProxyFeatures(req.Node)
var err error
proxyFeatures, err = determineSupportedProxyFeatures(req.Node)
if err != nil {
return status.Errorf(codes.InvalidArgument, err.Error())
}
}
if handler, ok := handlers[req.TypeUrl]; ok {

Some files were not shown because too many files have changed in this diff Show More