refactor: move service to service validation to troubleshoot package (#16132)

This is to reduce the dependency on xds from within the troubleshoot package.
This commit is contained in:
Nitya Dhanushkodi 2023-02-02 22:18:10 -08:00 committed by GitHub
parent ffd311c2b7
commit 6151bcfa75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 179 additions and 123 deletions

View File

@ -8,6 +8,7 @@ import (
"text/template"
envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
"github.com/hashicorp/consul/agent/xds/testcommon"
testinf "github.com/mitchellh/go-testing-interface"
"github.com/stretchr/testify/require"
@ -769,7 +770,7 @@ func TestClustersFromSnapshot(t *testing.T) {
latestEnvoyVersion := proxysupport.EnvoyVersions[0]
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
sf, err := xdscommon.DetermineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
t.Run("envoy-"+envoyVersion, func(t *testing.T) {
for _, tt := range tests {
@ -780,10 +781,10 @@ func TestClustersFromSnapshot(t *testing.T) {
// We need to replace the TLS certs with deterministic ones to make golden
// files workable. Note we don't update these otherwise they'd change
// golder files for every test case and so not be any use!
setupTLSRootsAndLeaf(t, snap)
testcommon.SetupTLSRootsAndLeaf(t, snap)
// Need server just for logger dependency
g := newResourceGenerator(testutil.Logger(t), nil, false)
g := NewResourceGenerator(testutil.Logger(t), nil, false)
g.ProxyFeatures = sf
clusters, err := g.clustersFromSnapshot(snap)
@ -861,25 +862,6 @@ func customAppClusterJSON(t testinf.T, opts customClusterJSONOptions) string {
return buf.String()
}
func setupTLSRootsAndLeaf(t *testing.T, snap *proxycfg.ConfigSnapshot) {
if snap.Leaf() != nil {
switch snap.Kind {
case structs.ServiceKindConnectProxy:
snap.ConnectProxy.Leaf.CertPEM = loadTestResource(t, "test-leaf-cert")
snap.ConnectProxy.Leaf.PrivateKeyPEM = loadTestResource(t, "test-leaf-key")
case structs.ServiceKindIngressGateway:
snap.IngressGateway.Leaf.CertPEM = loadTestResource(t, "test-leaf-cert")
snap.IngressGateway.Leaf.PrivateKeyPEM = loadTestResource(t, "test-leaf-key")
case structs.ServiceKindMeshGateway:
snap.MeshGateway.Leaf.CertPEM = loadTestResource(t, "test-leaf-cert")
snap.MeshGateway.Leaf.PrivateKeyPEM = loadTestResource(t, "test-leaf-key")
}
}
if snap.Roots != nil {
snap.Roots.Roots[0].RootCert = loadTestResource(t, "test-root-cert")
}
}
func TestEnvoyLBConfig_InjectToCluster(t *testing.T) {
var tests = []struct {
name string

View File

@ -11,14 +11,10 @@ import (
"time"
"github.com/armon/go-metrics"
envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
envoy_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
"github.com/hashicorp/go-hclog"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
@ -121,7 +117,7 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove
currentVersions = make(map[string]map[string]string)
)
generator := newResourceGenerator(
generator := NewResourceGenerator(
s.Logger.Named(logging.XDS).With("xdsVersion", "v3"),
s.CfgFetcher,
true,
@ -206,7 +202,7 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove
if node == nil && req.Node != nil {
node = req.Node
var err error
generator.ProxyFeatures, err = determineSupportedProxyFeatures(req.Node)
generator.ProxyFeatures, err = xdscommon.DetermineSupportedProxyFeatures(req.Node)
if err != nil {
return status.Errorf(codes.InvalidArgument, err.Error())
}
@ -239,13 +235,13 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove
}
cfgSnap = cs
newRes, err := generator.allResourcesFromSnapshot(cfgSnap)
newRes, err := generator.AllResourcesFromSnapshot(cfgSnap)
if err != nil {
return status.Errorf(codes.Unavailable, "failed to generate all xDS resources from the snapshot: %v", err)
}
// index and hash the xDS structures
newResourceMap := indexResources(generator.Logger, newRes)
newResourceMap := xdscommon.IndexResources(generator.Logger, newRes)
if s.ResourceMapMutateFn != nil {
s.ResourceMapMutateFn(newResourceMap)
@ -592,7 +588,7 @@ func newDeltaType(
// Recv handles new discovery requests from envoy.
//
// Returns true the first time a type receives a request.
func (t *xDSDeltaType) Recv(req *envoy_discovery_v3.DeltaDiscoveryRequest, sf supportedProxyFeatures) deltaRecvResponse {
func (t *xDSDeltaType) Recv(req *envoy_discovery_v3.DeltaDiscoveryRequest, sf xdscommon.SupportedProxyFeatures) deltaRecvResponse {
if t == nil {
return deltaRecvUnknownType // not something we care about
}
@ -987,39 +983,6 @@ func populateChildIndexMap(resourceMap *xdscommon.IndexedResources) error {
return nil
}
func indexResources(logger hclog.Logger, resources map[string][]proto.Message) *xdscommon.IndexedResources {
data := xdscommon.EmptyIndexedResources()
for typeURL, typeRes := range resources {
for _, res := range typeRes {
name := getResourceName(res)
if name == "" {
logger.Warn("skipping unexpected xDS type found in delta snapshot", "typeURL", typeURL)
} else {
data.Index[typeURL][name] = res
}
}
}
return data
}
func getResourceName(res proto.Message) string {
// NOTE: this only covers types that we currently care about for LDS/RDS/CDS/EDS
switch x := res.(type) {
case *envoy_listener_v3.Listener: // LDS
return x.Name
case *envoy_route_v3.RouteConfiguration: // RDS
return x.Name
case *envoy_cluster_v3.Cluster: // CDS
return x.Name
case *envoy_endpoint_v3.ClusterLoadAssignment: // EDS
return x.ClusterName
default:
return ""
}
}
func hashResourceMap(resources map[string]proto.Message) (map[string]string, error) {
m := make(map[string]string)
for name, res := range resources {

View File

@ -12,6 +12,7 @@ import (
envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
"github.com/hashicorp/consul/agent/xds/testcommon"
testinf "github.com/mitchellh/go-testing-interface"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
@ -212,7 +213,7 @@ end`,
latestEnvoyVersion := proxysupport.EnvoyVersions[0]
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
sf, err := xdscommon.DetermineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
t.Run("envoy-"+envoyVersion, func(t *testing.T) {
for _, tt := range tests {
@ -223,15 +224,15 @@ end`,
// We need to replace the TLS certs with deterministic ones to make golden
// files workable. Note we don't update these otherwise they'd change
// golden files for every test case and so not be any use!
setupTLSRootsAndLeaf(t, snap)
testcommon.SetupTLSRootsAndLeaf(t, snap)
g := newResourceGenerator(testutil.Logger(t), nil, false)
g := NewResourceGenerator(testutil.Logger(t), nil, false)
g.ProxyFeatures = sf
res, err := g.allResourcesFromSnapshot(snap)
res, err := g.AllResourcesFromSnapshot(snap)
require.NoError(t, err)
indexedResources := indexResources(g.Logger, res)
indexedResources := xdscommon.IndexResources(g.Logger, res)
cfgs := extensionruntime.GetRuntimeConfigurations(snap)
for _, extensions := range cfgs {
for _, ext := range extensions {

View File

@ -1538,7 +1538,7 @@ func assertDeltaResponse(t *testing.T, got, want *envoy_discovery_v3.DeltaDiscov
func mustMakeVersionMap(t *testing.T, resources ...proto.Message) map[string]string {
m := make(map[string]string)
for _, res := range resources {
name := getResourceName(res)
name := xdscommon.GetResourceName(res)
m[name] = mustHashResource(t, res)
}
return m

View File

@ -8,6 +8,7 @@ import (
envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
"github.com/hashicorp/consul/agent/xds/xdscommon"
"github.com/hashicorp/go-bexpr"
"google.golang.org/protobuf/proto"
@ -782,7 +783,7 @@ func (s *ResourceGenerator) makeExportedUpstreamEndpointsForMeshGateway(cfgSnap
return nil, err
}
for _, endpoints := range clusterEndpoints {
clusterName := getResourceName(endpoints)
clusterName := xdscommon.GetResourceName(endpoints)
if _, ok := populatedExportedClusters[clusterName]; ok {
continue
}

View File

@ -7,6 +7,7 @@ import (
envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
"github.com/hashicorp/consul/agent/xds/testcommon"
"github.com/mitchellh/copystructure"
testinf "github.com/mitchellh/go-testing-interface"
@ -500,7 +501,7 @@ func TestEndpointsFromSnapshot(t *testing.T) {
latestEnvoyVersion := proxysupport.EnvoyVersions[0]
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
sf, err := xdscommon.DetermineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
t.Run("envoy-"+envoyVersion, func(t *testing.T) {
for _, tt := range tests {
@ -511,10 +512,10 @@ func TestEndpointsFromSnapshot(t *testing.T) {
// We need to replace the TLS certs with deterministic ones to make golden
// files workable. Note we don't update these otherwise they'd change
// golden files for every test case and so not be any use!
setupTLSRootsAndLeaf(t, snap)
testcommon.SetupTLSRootsAndLeaf(t, snap)
// Need server just for logger dependency
g := newResourceGenerator(testutil.Logger(t), nil, false)
g := NewResourceGenerator(testutil.Logger(t), nil, false)
g.ProxyFeatures = sf
endpoints, err := g.endpointsFromSnapshot(snap)

View File

@ -123,14 +123,6 @@ func golden(t *testing.T, name, subname, latestSubname, got string) string {
return string(expected)
}
func loadTestResource(t *testing.T, name string) string {
t.Helper()
expected, err := os.ReadFile(filepath.Join("testdata", name+".golden"))
require.NoError(t, err)
return string(expected)
}
func protoToJSON(t *testing.T, pb proto.Message) string {
t.Helper()
m := protojson.MarshalOptions{

View File

@ -7,6 +7,7 @@ import (
"testing"
"text/template"
"github.com/hashicorp/consul/agent/xds/testcommon"
"github.com/stretchr/testify/assert"
envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
@ -890,7 +891,7 @@ func TestListenersFromSnapshot(t *testing.T) {
latestEnvoyVersion := proxysupport.EnvoyVersions[0]
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
sf, err := xdscommon.DetermineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
t.Run("envoy-"+envoyVersion, func(t *testing.T) {
for _, tt := range tests {
@ -904,14 +905,14 @@ func TestListenersFromSnapshot(t *testing.T) {
// We need to replace the TLS certs with deterministic ones to make golden
// files workable. Note we don't update these otherwise they'd change
// golder files for every test case and so not be any use!
setupTLSRootsAndLeaf(t, snap)
testcommon.SetupTLSRootsAndLeaf(t, snap)
if tt.setup != nil {
tt.setup(snap)
}
// Need server just for logger dependency
g := newResourceGenerator(testutil.Logger(t), nil, false)
g := NewResourceGenerator(testutil.Logger(t), nil, false)
g.ProxyFeatures = sf
if tt.generatorSetup != nil {
tt.generatorSetup(g)

View File

@ -3,11 +3,11 @@ package xds
import (
"fmt"
"github.com/hashicorp/consul/agent/xds/xdscommon"
"github.com/hashicorp/go-hclog"
"google.golang.org/protobuf/proto"
"github.com/hashicorp/consul/agent/proxycfg"
"github.com/hashicorp/consul/agent/xds/xdscommon"
)
// ResourceGenerator is associated with a single gRPC stream and creates xDS
@ -17,10 +17,10 @@ type ResourceGenerator struct {
CfgFetcher ConfigFetcher
IncrementalXDS bool
ProxyFeatures supportedProxyFeatures
ProxyFeatures xdscommon.SupportedProxyFeatures
}
func newResourceGenerator(
func NewResourceGenerator(
logger hclog.Logger,
cfgFetcher ConfigFetcher,
incrementalXDS bool,
@ -32,7 +32,7 @@ func newResourceGenerator(
}
}
func (g *ResourceGenerator) allResourcesFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot) (map[string][]proto.Message, error) {
func (g *ResourceGenerator) AllResourcesFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot) (map[string][]proto.Message, error) {
all := make(map[string][]proto.Message)
for _, typeUrl := range []string{xdscommon.ListenerType, xdscommon.RouteType, xdscommon.ClusterType, xdscommon.EndpointType} {
res, err := g.resourcesFromSnapshot(typeUrl, cfgSnap)

View File

@ -9,6 +9,8 @@ import (
envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
"github.com/hashicorp/consul/agent/xds/testcommon"
"github.com/hashicorp/consul/agent/xds/xdscommon"
testinf "github.com/mitchellh/go-testing-interface"
"github.com/stretchr/testify/require"
@ -16,7 +18,6 @@ import (
"github.com/hashicorp/consul/agent/proxycfg"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/xds/proxysupport"
"github.com/hashicorp/consul/agent/xds/xdscommon"
"github.com/hashicorp/consul/sdk/testutil"
)
@ -47,7 +48,7 @@ func TestAllResourcesFromSnapshot(t *testing.T) {
run := func(
t *testing.T,
sf supportedProxyFeatures,
sf xdscommon.SupportedProxyFeatures,
envoyVersion string,
latestEnvoyVersion string,
tt testcase,
@ -61,20 +62,20 @@ func TestAllResourcesFromSnapshot(t *testing.T) {
// We need to replace the TLS certs with deterministic ones to make golden
// files workable. Note we don't update these otherwise they'd change
// golder files for every test case and so not be any use!
setupTLSRootsAndLeaf(t, snap)
testcommon.SetupTLSRootsAndLeaf(t, snap)
if tt.setup != nil {
tt.setup(snap)
}
// Need server just for logger dependency
g := newResourceGenerator(testutil.Logger(t), nil, false)
g := NewResourceGenerator(testutil.Logger(t), nil, false)
g.ProxyFeatures = sf
if tt.generatorSetup != nil {
tt.generatorSetup(g)
}
resources, err := g.allResourcesFromSnapshot(snap)
resources, err := g.AllResourcesFromSnapshot(snap)
require.NoError(t, err)
typeUrls := []string{
@ -168,7 +169,7 @@ func TestAllResourcesFromSnapshot(t *testing.T) {
latestEnvoyVersion := proxysupport.EnvoyVersions[0]
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
sf, err := xdscommon.DetermineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
t.Run("envoy-"+envoyVersion, func(t *testing.T) {
for _, tt := range tests {

View File

@ -7,6 +7,7 @@ import (
"time"
envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
"github.com/hashicorp/consul/agent/xds/testcommon"
testinf "github.com/mitchellh/go-testing-interface"
"github.com/stretchr/testify/require"
@ -190,7 +191,7 @@ func TestRoutesFromSnapshot(t *testing.T) {
latestEnvoyVersion := proxysupport.EnvoyVersions[0]
for _, envoyVersion := range proxysupport.EnvoyVersions {
sf, err := determineSupportedProxyFeaturesFromString(envoyVersion)
sf, err := xdscommon.DetermineSupportedProxyFeaturesFromString(envoyVersion)
require.NoError(t, err)
t.Run("envoy-"+envoyVersion, func(t *testing.T) {
for _, tt := range tests {
@ -201,9 +202,9 @@ func TestRoutesFromSnapshot(t *testing.T) {
// We need to replace the TLS certs with deterministic ones to make golden
// files workable. Note we don't update these otherwise they'd change
// golden files for every test case and so not be any use!
setupTLSRootsAndLeaf(t, snap)
testcommon.SetupTLSRootsAndLeaf(t, snap)
g := newResourceGenerator(testutil.Logger(t), nil, false)
g := NewResourceGenerator(testutil.Logger(t), nil, false)
g.ProxyFeatures = sf
routes, err := g.routesFromSnapshot(snap)

View File

@ -7,6 +7,7 @@ import (
"time"
envoy_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
"github.com/hashicorp/consul/agent/xds/xdscommon"
"github.com/armon/go-metrics"
"github.com/armon/go-metrics/prometheus"
@ -20,7 +21,6 @@ import (
"github.com/hashicorp/consul/agent/grpc-external/limiter"
"github.com/hashicorp/consul/agent/proxycfg"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/xds/xdscommon"
)
var (

View File

@ -0,0 +1,37 @@
package testcommon
import (
"os"
"path/filepath"
"testing"
"github.com/hashicorp/consul/agent/proxycfg"
"github.com/hashicorp/consul/agent/structs"
"github.com/stretchr/testify/require"
)
func SetupTLSRootsAndLeaf(t *testing.T, snap *proxycfg.ConfigSnapshot) {
if snap.Leaf() != nil {
switch snap.Kind {
case structs.ServiceKindConnectProxy:
snap.ConnectProxy.Leaf.CertPEM = loadTestResource(t, "test-leaf-cert")
snap.ConnectProxy.Leaf.PrivateKeyPEM = loadTestResource(t, "test-leaf-key")
case structs.ServiceKindIngressGateway:
snap.IngressGateway.Leaf.CertPEM = loadTestResource(t, "test-leaf-cert")
snap.IngressGateway.Leaf.PrivateKeyPEM = loadTestResource(t, "test-leaf-key")
case structs.ServiceKindMeshGateway:
snap.MeshGateway.Leaf.CertPEM = loadTestResource(t, "test-leaf-cert")
snap.MeshGateway.Leaf.PrivateKeyPEM = loadTestResource(t, "test-leaf-key")
}
}
if snap.Roots != nil {
snap.Roots.Roots[0].RootCert = loadTestResource(t, "test-root-cert")
}
}
func loadTestResource(t *testing.T, name string) string {
t.Helper()
expected, err := os.ReadFile(filepath.Join("testdata", name+".golden"))
require.NoError(t, err)
return string(expected)
}

View File

@ -8,6 +8,7 @@ import (
"github.com/hashicorp/consul/agent/connect"
"github.com/hashicorp/consul/agent/grpc-external/limiter"
"github.com/hashicorp/consul/agent/xds/xdscommon"
envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
@ -371,7 +372,7 @@ func makeTestResource(t *testing.T, raw interface{}) *envoy_discovery_v3.Resourc
require.NoError(t, err)
return &envoy_discovery_v3.Resource{
Name: getResourceName(res),
Name: xdscommon.GetResourceName(res),
Version: mustHashResource(t, res),
Resource: any,
}

View File

@ -1,4 +1,4 @@
package xds
package xdscommon
import (
"fmt"
@ -23,35 +23,35 @@ type unsupportedVersion struct {
Why string
}
type supportedProxyFeatures struct {
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) {
func DetermineSupportedProxyFeatures(node *envoy_core_v3.Node) (SupportedProxyFeatures, error) {
version := determineEnvoyVersionFromNode(node)
return determineSupportedProxyFeaturesFromVersion(version)
}
func determineSupportedProxyFeaturesFromString(vs string) (supportedProxyFeatures, error) {
func DetermineSupportedProxyFeaturesFromString(vs string) (SupportedProxyFeatures, error) {
version := version.Must(version.NewVersion(vs))
return determineSupportedProxyFeaturesFromVersion(version)
}
func determineSupportedProxyFeaturesFromVersion(version *version.Version) (supportedProxyFeatures, error) {
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
return SupportedProxyFeatures{}, nil
}
if version.LessThan(minSupportedVersion) {
return supportedProxyFeatures{}, fmt.Errorf("Envoy %s is too old and is not supported by Consul", version)
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(
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,
@ -61,7 +61,7 @@ func determineSupportedProxyFeaturesFromVersion(version *version.Version) (suppo
}
}
sf := supportedProxyFeatures{}
sf := SupportedProxyFeatures{}
// when feature flags necessary, populate here by calling version.LessThan(...)

View File

@ -1,4 +1,4 @@
package xds
package xdscommon
import (
"testing"
@ -72,7 +72,7 @@ func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) {
)
type testcase struct {
expect supportedProxyFeatures
expect SupportedProxyFeatures
expectErr string
}
@ -129,7 +129,7 @@ func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) {
for _, v := range []string{
"1.18.0", "1.18.1", "1.18.2", "1.18.3", "1.18.4", "1.18.5", "1.18.6",
} {
cases[v] = testcase{expect: supportedProxyFeatures{
cases[v] = testcase{expect: SupportedProxyFeatures{
ForceLDSandCDSToAlwaysUseWildcardsOnReconnect: true,
}}
}
@ -140,13 +140,13 @@ func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) {
"1.23.0", "1.23.1", "1.23.2",
"1.24.0",
} {
cases[v] = testcase{expect: supportedProxyFeatures{}}
cases[v] = testcase{expect: SupportedProxyFeatures{}}
}
for name, tc := range cases {
tc := tc
t.Run(name, func(t *testing.T) {
sf, err := determineSupportedProxyFeaturesFromString(name)
sf, err := DetermineSupportedProxyFeaturesFromString(name)
if tc.expectErr == "" {
require.Equal(t, tc.expect, sf)
} else {

View File

@ -1,6 +1,11 @@
package xdscommon
import (
envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
"github.com/hashicorp/go-hclog"
"google.golang.org/protobuf/proto"
)
@ -53,6 +58,39 @@ type IndexedResources struct {
ChildIndex map[string]map[string][]string
}
func IndexResources(logger hclog.Logger, resources map[string][]proto.Message) *IndexedResources {
data := EmptyIndexedResources()
for typeURL, typeRes := range resources {
for _, res := range typeRes {
name := GetResourceName(res)
if name == "" {
logger.Warn("skipping unexpected xDS type found in delta snapshot", "typeURL", typeURL)
} else {
data.Index[typeURL][name] = res
}
}
}
return data
}
func GetResourceName(res proto.Message) string {
// NOTE: this only covers types that we currently care about for LDS/RDS/CDS/EDS
switch x := res.(type) {
case *envoy_listener_v3.Listener: // LDS
return x.Name
case *envoy_route_v3.RouteConfiguration: // RDS
return x.Name
case *envoy_cluster_v3.Cluster: // CDS
return x.Name
case *envoy_endpoint_v3.ClusterLoadAssignment: // EDS
return x.ClusterName
default:
return ""
}
}
func EmptyIndexedResources() *IndexedResources {
return &IndexedResources{
Index: map[string]map[string]proto.Message{

View File

@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE-----
MIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ
VGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG
A1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR
AB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7
SkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD
AgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6
NDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6
NWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf
ZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6
ZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw
WQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1
NTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG
SM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA
pY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=
-----END CERTIFICATE-----

View File

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49
AwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav
q5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ
VGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG
A1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx
AsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2
ThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD
AQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi
ZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3
Mzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi
MjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1
ZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x
MTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG
SM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA
oR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=
-----END CERTIFICATE-----

View File

@ -1,4 +1,4 @@
package xds
package validateupstream
import (
"github.com/hashicorp/consul/acl"

View File

@ -1,4 +1,4 @@
package xds
package validateupstream
import (
"io"
@ -7,6 +7,8 @@ import (
envoy_admin_v3 "github.com/envoyproxy/go-control-plane/envoy/admin/v3"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/xds"
"github.com/hashicorp/consul/agent/xds/testcommon"
testinf "github.com/mitchellh/go-testing-interface"
"github.com/stretchr/testify/require"
@ -205,7 +207,7 @@ func TestValidateUpstreams(t *testing.T) {
}
latestEnvoyVersion := proxysupport.EnvoyVersions[0]
sf, err := determineSupportedProxyFeaturesFromString(latestEnvoyVersion)
sf, err := xdscommon.DetermineSupportedProxyFeaturesFromString(latestEnvoyVersion)
require.NoError(t, err)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -215,15 +217,15 @@ func TestValidateUpstreams(t *testing.T) {
// We need to replace the TLS certs with deterministic ones to make golden
// files workable. Note we don't update these otherwise they'd change
// golden files for every test case and so not be any use!
setupTLSRootsAndLeaf(t, snap)
testcommon.SetupTLSRootsAndLeaf(t, snap)
g := newResourceGenerator(testutil.Logger(t), nil, false)
g := xds.NewResourceGenerator(testutil.Logger(t), nil, false)
g.ProxyFeatures = sf
res, err := g.allResourcesFromSnapshot(snap)
res, err := g.AllResourcesFromSnapshot(snap)
require.NoError(t, err)
indexedResources := indexResources(g.Logger, res)
indexedResources := xdscommon.IndexResources(g.Logger, res)
if tt.patcher != nil {
indexedResources = tt.patcher(indexedResources)
}
@ -249,8 +251,7 @@ func TestValidateUpstreams(t *testing.T) {
}
}
// TODO make config.json and clusters.json use an http upstream with L7 config entries for more confidence.
func TestValidate(t *testing.T) {
func TestValidate2(t *testing.T) {
indexedResources := getConfig(t)
clusters := getClusters(t)
err := Validate(indexedResources, service, "", "", true, clusters)