Skip to content
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

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

Merged
merged 5 commits into from
Jul 31, 2020
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
22 changes: 11 additions & 11 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -675,25 +675,25 @@ jobs:
path: *TEST_RESULTS_DIR
- run: *notify-slack-failure

envoy-integration-test-1.12.6:
envoy-integration-test-1.13.4:
docker:
- image: *GOLANG_IMAGE
environment:
ENVOY_VERSION: "1.12.6"
ENVOY_VERSION: "1.13.4"
steps: *ENVOY_INTEGRATION_TEST_STEPS

envoy-integration-test-1.13.4:
envoy-integration-test-1.14.4:
docker:
- image: *GOLANG_IMAGE
environment:
ENVOY_VERSION: "1.13.4"
ENVOY_VERSION: "1.14.4"
steps: *ENVOY_INTEGRATION_TEST_STEPS

envoy-integration-test-1.14.4:
envoy-integration-test-1.15.0:
docker:
- image: *GOLANG_IMAGE
environment:
ENVOY_VERSION: "1.14.4"
ENVOY_VERSION: "1.15.0"
steps: *ENVOY_INTEGRATION_TEST_STEPS

# run integration tests for the connect ca providers
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand Down
16 changes: 4 additions & 12 deletions agent/xds/clusters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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{
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 moved this so that the command/connect/envoy package can just take the zeroth element to get the default envoy version rather than having it hard coded in two places.

"1.14.4",
"1.13.4",
"1.12.6",
"1.11.2",
}
6 changes: 4 additions & 2 deletions agent/xds/endpoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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) {
Expand Down
37 changes: 21 additions & 16 deletions agent/xds/envoy_versioning.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
}
}
6 changes: 4 additions & 2 deletions agent/xds/listeners_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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) {
Expand Down
11 changes: 11 additions & 0 deletions agent/xds/proxysupport/proxysupport.go
Original file line number Diff line number Diff line change
@@ -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",
}
69 changes: 19 additions & 50 deletions agent/xds/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -295,14 +295,8 @@ 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,
}
em.PathSpecifier = &envoyroute.RouteMatch_SafeRegex{
SafeRegex: makeEnvoyRegexMatch(match.HTTP.PathRegex),
}
default:
em.PathSpecifier = &envoyroute.RouteMatch_Prefix{
Expand All @@ -323,14 +317,8 @@ 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,
}
eh.HeaderMatchSpecifier = &envoyroute.HeaderMatcher_SafeRegexMatch{
SafeRegexMatch: makeEnvoyRegexMatch(hdr.Regex),
}
case hdr.Prefix != "":
eh.HeaderMatchSpecifier = &envoyroute.HeaderMatcher_PrefixMatch{
Expand Down Expand Up @@ -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)
Expand All @@ -384,37 +366,24 @@ 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{
Exact: qm.Exact,
},
eq.QueryParameterMatchSpecifier = &envoyroute.QueryParameterMatcher_StringMatch{
StringMatch: &envoymatcher.StringMatcher{
MatchPattern: &envoymatcher.StringMatcher_Exact{
Exact: qm.Exact,
},
}
} else {
eq.Value = qm.Exact
},
}
case qm.Regex != "":
if cInfo.ProxyFeatures.RouterMatchSafeRegex {
eq.QueryParameterMatchSpecifier = &envoyroute.QueryParameterMatcher_StringMatch{
StringMatch: &envoymatcher.StringMatcher{
MatchPattern: &envoymatcher.StringMatcher_SafeRegex{
SafeRegex: makeEnvoyRegexMatch(qm.Regex),
},
eq.QueryParameterMatchSpecifier = &envoyroute.QueryParameterMatcher_StringMatch{
StringMatch: &envoymatcher.StringMatcher{
MatchPattern: &envoymatcher.StringMatcher_SafeRegex{
SafeRegex: makeEnvoyRegexMatch(qm.Regex),
},
}
} 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 = ""
eq.QueryParameterMatchSpecifier = &envoyroute.QueryParameterMatcher_PresentMatch{
PresentMatch: true,
}
default:
continue // skip this impossible situation
Expand Down
6 changes: 4 additions & 2 deletions agent/xds/routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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) {
Expand Down
6 changes: 5 additions & 1 deletion agent/xds/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
8 changes: 4 additions & 4 deletions command/connect/envoy/envoy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/xds"
"github.com/hashicorp/consul/agent/xds/proxysupport"
"github.com/hashicorp/consul/api"
proxyCmd "github.com/hashicorp/consul/command/connect/proxy"
"github.com/hashicorp/consul/command/flags"
Expand Down Expand Up @@ -68,10 +69,9 @@ type cmd struct {
gatewayKind api.ServiceKind
}

const (
defaultEnvoyVersion = "1.14.4"
meshGatewayVal = "mesh"
)
const meshGatewayVal = "mesh"

var defaultEnvoyVersion = proxysupport.EnvoyVersions[0]

var supportedGateways = map[string]api.ServiceKind{
"mesh": api.ServiceKindMeshGateway,
Expand Down
Loading