open-consul/envoyextensions/xdscommon/envoy_versioning.go
Nitya Dhanushkodi 77f6b20db0
refactor: remove troubleshoot module dependency on consul top level module (#16162)
Ensure nothing in the troubleshoot go module depends on consul's top level module. This is so we can import troubleshoot into consul-k8s and not import all of consul.

* turns troubleshoot into a go module [authored by @curtbushko]
* gets the envoy protos into the troubleshoot module [authored by @curtbushko]
* adds a new go module `envoyextensions` which has xdscommon and extensioncommon folders that both the xds package and the troubleshoot package can import
* adds testing and linting for the new go modules
* moves the unit tests in `troubleshoot/validateupstream` that depend on proxycfg/xds into the xds package, with a comment describing why those tests cannot be in the troubleshoot package
* fixes all the imports everywhere as a result of these changes 

Co-authored-by: Curt Bushko <cbushko@gmail.com>
2023-02-06 09:14:35 -08:00

100 lines
2.7 KiB
Go

package xdscommon
import (
"fmt"
envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
"github.com/hashicorp/go-version"
)
var (
// minSupportedVersion is the oldest mainline version we support. This should always be
// the zero'th point release of the last element of xdscommon.EnvoyVersions.
minSupportedVersion = version.Must(version.NewVersion(GetMinEnvoyMinorVersion()))
specificUnsupportedVersions = []unsupportedVersion{}
)
type unsupportedVersion struct {
Version *version.Version
UpgradeTo string
Why string
}
type SupportedProxyFeatures struct {
// Put feature switches here when necessary. For reference, The most recent remove of a feature flag was removed in
// <insert PR here>.
}
func DetermineSupportedProxyFeatures(node *envoy_core_v3.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 {
// This would happen on either extremely old builds OR perhaps on
// custom builds. Should we error?
return SupportedProxyFeatures{}, nil
}
if version.LessThan(minSupportedVersion) {
return SupportedProxyFeatures{}, fmt.Errorf("Envoy %s is too old and is not supported by Consul", version)
}
for _, uv := range specificUnsupportedVersions {
if version.Equal(uv.Version) {
return SupportedProxyFeatures{}, fmt.Errorf(
"Envoy %s is too old of a point release and is not supported by Consul because it %s. "+
"Please upgrade to version %s.",
version,
uv.Why,
uv.UpgradeTo,
)
}
}
sf := SupportedProxyFeatures{}
// when feature flags necessary, populate here by calling version.LessThan(...)
return sf, nil
}
func determineEnvoyVersionFromNode(node *envoy_core_v3.Node) *version.Version {
if node == nil {
return nil
}
if node.UserAgentVersionType == nil {
return nil
}
if node.UserAgentName != "envoy" {
return nil
}
bv, ok := node.UserAgentVersionType.(*envoy_core_v3.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(),
),
))
}