-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[backport: 1.8.x] xds: version sniff envoy and switch regular express…
…ions from 'regex' to 'safe_regex' on newer envoy versions (#8265) cherry-pick of #8222 onto origin/release/1.8.x Fixes: #8205
- Loading branch information
Showing
651 changed files
with
43,465 additions
and
212 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package xds | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
|
||
envoycore "github.com/envoyproxy/go-control-plane/envoy/api/v2/core" | ||
"github.com/hashicorp/go-version" | ||
) | ||
|
||
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")) | ||
) | ||
|
||
type supportedProxyFeatures struct { | ||
RouterMatchSafeRegex bool // use safe_regex instead of regex in http.router rules | ||
} | ||
|
||
func determineSupportedProxyFeatures(node *envoycore.Node) supportedProxyFeatures { | ||
version := determineEnvoyVersionFromNode(node) | ||
if version == nil { | ||
return supportedProxyFeatures{} | ||
} | ||
|
||
return supportedProxyFeatures{ | ||
RouterMatchSafeRegex: !version.LessThan(minSafeRegexVersion), | ||
} | ||
} | ||
|
||
// example: 1580db37e9a97c37e410bad0e1507ae1a0fd9e77/1.12.4/Clean/RELEASE/BoringSSL | ||
var buildVersionPattern = regexp.MustCompile(`^[a-f0-9]{40}/([^/]+)/Clean/RELEASE/BoringSSL$`) | ||
|
||
func determineEnvoyVersionFromNode(node *envoycore.Node) *version.Version { | ||
if node == nil { | ||
return nil | ||
} | ||
|
||
if node.UserAgentVersionType == nil { | ||
if node.BuildVersion == "" { | ||
return nil | ||
} | ||
|
||
// Must be an older pre-1.13 envoy | ||
m := buildVersionPattern.FindStringSubmatch(node.BuildVersion) | ||
if m == nil { | ||
return nil | ||
} | ||
|
||
return version.Must(version.NewVersion(m[1])) | ||
} | ||
|
||
if node.UserAgentName != "envoy" { | ||
return nil | ||
} | ||
|
||
bv, ok := node.UserAgentVersionType.(*envoycore.Node_UserAgentBuildVersion) | ||
if !ok { | ||
// NOTE: we could sniff for *envoycore.Node_UserAgentVersion and do more regex but official builds don't have this problem. | ||
return nil | ||
} | ||
if bv.UserAgentBuildVersion == nil { | ||
return nil | ||
} | ||
v := bv.UserAgentBuildVersion.Version | ||
|
||
return version.Must(version.NewVersion( | ||
fmt.Sprintf("%d.%d.%d", | ||
v.GetMajorNumber(), | ||
v.GetMinorNumber(), | ||
v.GetPatch(), | ||
), | ||
)) | ||
} | ||
|
||
func determineSupportedProxyFeaturesFromString(vs string) supportedProxyFeatures { | ||
version := version.Must(version.NewVersion(vs)) | ||
return supportedProxyFeatures{ | ||
RouterMatchSafeRegex: !version.LessThan(minSafeRegexVersion), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package xds | ||
|
||
import ( | ||
"testing" | ||
|
||
envoycore "github.com/envoyproxy/go-control-plane/envoy/api/v2/core" | ||
envoytype "github.com/envoyproxy/go-control-plane/envoy/type" | ||
"github.com/hashicorp/go-version" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestDetermineEnvoyVersionFromNode(t *testing.T) { | ||
cases := map[string]struct { | ||
node *envoycore.Node | ||
expect *version.Version | ||
}{ | ||
"empty": { | ||
node: &envoycore.Node{}, | ||
expect: nil, | ||
}, | ||
"only build version": { | ||
node: &envoycore.Node{ | ||
BuildVersion: "1580db37e9a97c37e410bad0e1507ae1a0fd9e77/1.9.0/Clean/RELEASE/BoringSSL", | ||
}, | ||
expect: version.Must(version.NewVersion("1.9.0")), | ||
}, | ||
"user agent build version but no user agent": { | ||
node: &envoycore.Node{ | ||
UserAgentName: "", | ||
UserAgentVersionType: &envoycore.Node_UserAgentBuildVersion{ | ||
UserAgentBuildVersion: &envoycore.BuildVersion{ | ||
Version: &envoytype.SemanticVersion{ | ||
MajorNumber: 1, | ||
MinorNumber: 14, | ||
Patch: 4, | ||
}, | ||
}, | ||
}, | ||
}, | ||
expect: nil, | ||
}, | ||
"user agent build version with user agent": { | ||
node: &envoycore.Node{ | ||
UserAgentName: "envoy", | ||
UserAgentVersionType: &envoycore.Node_UserAgentBuildVersion{ | ||
UserAgentBuildVersion: &envoycore.BuildVersion{ | ||
Version: &envoytype.SemanticVersion{ | ||
MajorNumber: 1, | ||
MinorNumber: 14, | ||
Patch: 4, | ||
}, | ||
}, | ||
}, | ||
}, | ||
expect: version.Must(version.NewVersion("1.14.4")), | ||
}, | ||
} | ||
|
||
for name, tc := range cases { | ||
tc := tc | ||
t.Run(name, func(t *testing.T) { | ||
got := determineEnvoyVersionFromNode(tc.node) | ||
if tc.expect != nil { | ||
require.Equal(t, tc.expect, got) | ||
} else { | ||
require.Nil(t, got) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.