mirror of https://github.com/status-im/consul.git
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:
parent
71b5a4bf7c
commit
8d4c3aa42c
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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(...)
|
||||
|
|
@ -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 {
|
|
@ -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{
|
||||
|
|
|
@ -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-----
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49
|
||||
AwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav
|
||||
q5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -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-----
|
|
@ -1,4 +1,4 @@
|
|||
package xds
|
||||
package validateupstream
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/consul/acl"
|
|
@ -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)
|
Loading…
Reference in New Issue