mirror of
https://github.com/status-im/consul.git
synced 2025-01-10 22:06:20 +00:00
implement some missing service-router features and add more xDS testing (#6065)
- also implement OnlyPassing filters for non-gateway clusters
This commit is contained in:
parent
8a90185bbd
commit
bcd2de3a2e
@ -495,12 +495,7 @@ func (s *Store) readDiscoveryChainConfigEntriesTxn(
|
|||||||
serviceName string,
|
serviceName string,
|
||||||
overrides map[structs.ConfigEntryKindName]structs.ConfigEntry,
|
overrides map[structs.ConfigEntryKindName]structs.ConfigEntry,
|
||||||
) (uint64, *structs.DiscoveryChainConfigEntries, error) {
|
) (uint64, *structs.DiscoveryChainConfigEntries, error) {
|
||||||
res := &structs.DiscoveryChainConfigEntries{
|
res := structs.NewDiscoveryChainConfigEntries()
|
||||||
Routers: make(map[string]*structs.ServiceRouterConfigEntry),
|
|
||||||
Splitters: make(map[string]*structs.ServiceSplitterConfigEntry),
|
|
||||||
Resolvers: make(map[string]*structs.ServiceResolverConfigEntry),
|
|
||||||
Services: make(map[string]*structs.ServiceConfigEntry),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that below we always look up splitters and resolvers in pairs, even
|
// Note that below we always look up splitters and resolvers in pairs, even
|
||||||
// in some circumstances where both are not strictly necessary.
|
// in some circumstances where both are not strictly necessary.
|
||||||
|
@ -3,9 +3,11 @@ package proxycfg
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/copystructure"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/agent/cache"
|
"github.com/hashicorp/consul/agent/cache"
|
||||||
@ -39,63 +41,264 @@ func assertLastReqArgs(t *testing.T, types *TestCacheTypes, token string, source
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestManager_BasicLifecycle(t *testing.T) {
|
func TestManager_BasicLifecycle(t *testing.T) {
|
||||||
// Use a mocked cache to make life simpler
|
// Create a bunch of common data for the various test cases.
|
||||||
types := NewTestCacheTypes(t)
|
|
||||||
c := TestCacheWithTypes(t, types)
|
|
||||||
|
|
||||||
require := require.New(t)
|
|
||||||
|
|
||||||
roots, leaf := TestCerts(t)
|
roots, leaf := TestCerts(t)
|
||||||
|
|
||||||
// Initialize a default group resolver for "db"
|
|
||||||
dbResolverEntry := &structs.ServiceResolverConfigEntry{
|
|
||||||
Kind: structs.ServiceResolver,
|
|
||||||
Name: "db",
|
|
||||||
}
|
|
||||||
dbTarget := structs.DiscoveryTarget{
|
dbTarget := structs.DiscoveryTarget{
|
||||||
Service: "db",
|
Service: "db",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
}
|
}
|
||||||
dbResolverNode := &structs.DiscoveryGraphNode{
|
dbTarget_v1 := structs.DiscoveryTarget{
|
||||||
Type: structs.DiscoveryGraphNodeTypeGroupResolver,
|
Service: "db",
|
||||||
Name: "db",
|
ServiceSubset: "v1",
|
||||||
GroupResolver: &structs.DiscoveryGroupResolver{
|
Namespace: "default",
|
||||||
Definition: dbResolverEntry,
|
Datacenter: "dc1",
|
||||||
Default: true,
|
|
||||||
Target: dbTarget,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
dbChain := &structs.CompiledDiscoveryChain{
|
dbTarget_v2 := structs.DiscoveryTarget{
|
||||||
ServiceName: "db",
|
Service: "db",
|
||||||
Namespace: "default",
|
ServiceSubset: "v2",
|
||||||
Datacenter: "dc1",
|
Namespace: "default",
|
||||||
Protocol: "tcp",
|
Datacenter: "dc1",
|
||||||
Node: dbResolverNode,
|
}
|
||||||
GroupResolverNodes: map[structs.DiscoveryTarget]*structs.DiscoveryGraphNode{
|
dbDefaultChain := func() *structs.CompiledDiscoveryChain {
|
||||||
dbTarget: dbResolverNode,
|
return TestCompileConfigEntries(t, "db", "default", "dc1",
|
||||||
},
|
&structs.ServiceResolverConfigEntry{
|
||||||
Resolvers: map[string]*structs.ServiceResolverConfigEntry{
|
Kind: structs.ServiceResolver,
|
||||||
"db": dbResolverEntry,
|
Name: "db",
|
||||||
},
|
},
|
||||||
Targets: []structs.DiscoveryTarget{
|
)
|
||||||
dbTarget,
|
}
|
||||||
|
dbSplitChain := func() *structs.CompiledDiscoveryChain {
|
||||||
|
return TestCompileConfigEntries(t, "db", "default", "dc1",
|
||||||
|
&structs.ProxyConfigEntry{
|
||||||
|
Kind: structs.ProxyDefaults,
|
||||||
|
Name: structs.ProxyConfigGlobal,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"protocol": "http",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&structs.ServiceResolverConfigEntry{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "db",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": {
|
||||||
|
Filter: "Service.Meta.version == v1",
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
Filter: "Service.Meta.version == v2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&structs.ServiceSplitterConfigEntry{
|
||||||
|
Kind: structs.ServiceSplitter,
|
||||||
|
Name: "db",
|
||||||
|
Splits: []structs.ServiceSplit{
|
||||||
|
{Weight: 60, ServiceSubset: "v1"},
|
||||||
|
{Weight: 40, ServiceSubset: "v2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
webProxy := &structs.NodeService{
|
||||||
|
Kind: structs.ServiceKindConnectProxy,
|
||||||
|
ID: "web-sidecar-proxy",
|
||||||
|
Service: "web-sidecar-proxy",
|
||||||
|
Port: 9999,
|
||||||
|
Proxy: structs.ConnectProxyConfig{
|
||||||
|
DestinationServiceID: "web",
|
||||||
|
DestinationServiceName: "web",
|
||||||
|
LocalServiceAddress: "127.0.0.1",
|
||||||
|
LocalServicePort: 8080,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
Upstreams: structs.TestUpstreams(t),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup initial values
|
rootsCacheKey := testGenCacheKey(&structs.DCSpecificRequest{
|
||||||
types.roots.value.Store(roots)
|
Datacenter: "dc1",
|
||||||
types.leaf.value.Store(leaf)
|
QueryOptions: structs.QueryOptions{Token: "my-token"},
|
||||||
types.intentions.value.Store(TestIntentions(t))
|
})
|
||||||
types.health.value.Store(
|
leafCacheKey := testGenCacheKey(&cachetype.ConnectCALeafRequest{
|
||||||
&structs.IndexedCheckServiceNodes{
|
Datacenter: "dc1",
|
||||||
Nodes: TestUpstreamNodes(t),
|
Token: "my-token",
|
||||||
})
|
Service: "web",
|
||||||
types.compiledChain.value.Store(
|
})
|
||||||
&structs.DiscoveryChainResponse{
|
intentionCacheKey := testGenCacheKey(&structs.IntentionQueryRequest{
|
||||||
Chain: dbChain,
|
Datacenter: "dc1",
|
||||||
|
QueryOptions: structs.QueryOptions{Token: "my-token"},
|
||||||
|
Match: &structs.IntentionQueryMatch{
|
||||||
|
Type: structs.IntentionMatchDestination,
|
||||||
|
Entries: []structs.IntentionMatchEntry{
|
||||||
|
{
|
||||||
|
Namespace: structs.IntentionDefaultNamespace,
|
||||||
|
Name: "web",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
})
|
||||||
|
|
||||||
|
dbChainCacheKey := testGenCacheKey(&structs.DiscoveryChainRequest{
|
||||||
|
Datacenter: "dc1",
|
||||||
|
QueryOptions: structs.QueryOptions{Token: "my-token"},
|
||||||
|
Name: "db",
|
||||||
|
})
|
||||||
|
|
||||||
|
dbHealthCacheKey := testGenCacheKey(&structs.ServiceSpecificRequest{
|
||||||
|
Datacenter: "dc1",
|
||||||
|
QueryOptions: structs.QueryOptions{Token: "my-token", Filter: ""},
|
||||||
|
ServiceName: "db",
|
||||||
|
Connect: true,
|
||||||
|
})
|
||||||
|
db_v1_HealthCacheKey := testGenCacheKey(&structs.ServiceSpecificRequest{
|
||||||
|
Datacenter: "dc1",
|
||||||
|
QueryOptions: structs.QueryOptions{Token: "my-token",
|
||||||
|
Filter: "Service.Meta.version == v1",
|
||||||
|
},
|
||||||
|
ServiceName: "db",
|
||||||
|
Connect: true,
|
||||||
|
})
|
||||||
|
db_v2_HealthCacheKey := testGenCacheKey(&structs.ServiceSpecificRequest{
|
||||||
|
Datacenter: "dc1",
|
||||||
|
QueryOptions: structs.QueryOptions{Token: "my-token",
|
||||||
|
Filter: "Service.Meta.version == v2",
|
||||||
|
},
|
||||||
|
ServiceName: "db",
|
||||||
|
Connect: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create test cases using some of the common data above.
|
||||||
|
tests := []*testcase_BasicLifecycle{
|
||||||
|
{
|
||||||
|
name: "simple-default-resolver",
|
||||||
|
setup: func(t *testing.T, types *TestCacheTypes) {
|
||||||
|
// Note that we deliberately leave the 'geo-cache' prepared query to time out
|
||||||
|
types.health.Set(dbHealthCacheKey, &structs.IndexedCheckServiceNodes{
|
||||||
|
Nodes: TestUpstreamNodes(t),
|
||||||
|
})
|
||||||
|
types.compiledChain.Set(dbChainCacheKey, &structs.DiscoveryChainResponse{
|
||||||
|
Chain: dbDefaultChain(),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
expectSnap: &ConfigSnapshot{
|
||||||
|
Kind: structs.ServiceKindConnectProxy,
|
||||||
|
Service: webProxy.Service,
|
||||||
|
ProxyID: webProxy.ID,
|
||||||
|
Address: webProxy.Address,
|
||||||
|
Port: webProxy.Port,
|
||||||
|
Proxy: webProxy.Proxy,
|
||||||
|
TaggedAddresses: make(map[string]structs.ServiceAddress),
|
||||||
|
Roots: roots,
|
||||||
|
ConnectProxy: configSnapshotConnectProxy{
|
||||||
|
Leaf: leaf,
|
||||||
|
DiscoveryChain: map[string]*structs.CompiledDiscoveryChain{
|
||||||
|
"db": dbDefaultChain(),
|
||||||
|
},
|
||||||
|
WatchedUpstreams: nil, // Clone() clears this out
|
||||||
|
WatchedUpstreamEndpoints: map[string]map[structs.DiscoveryTarget]structs.CheckServiceNodes{
|
||||||
|
"db": {
|
||||||
|
dbTarget: TestUpstreamNodes(t),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpstreamEndpoints: map[string]structs.CheckServiceNodes{},
|
||||||
|
},
|
||||||
|
Datacenter: "dc1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "chain-resolver-with-version-split",
|
||||||
|
setup: func(t *testing.T, types *TestCacheTypes) {
|
||||||
|
// Note that we deliberately leave the 'geo-cache' prepared query to time out
|
||||||
|
types.health.Set(db_v1_HealthCacheKey, &structs.IndexedCheckServiceNodes{
|
||||||
|
Nodes: TestUpstreamNodes(t),
|
||||||
|
})
|
||||||
|
types.health.Set(db_v2_HealthCacheKey, &structs.IndexedCheckServiceNodes{
|
||||||
|
Nodes: TestUpstreamNodesAlternate(t),
|
||||||
|
})
|
||||||
|
types.compiledChain.Set(dbChainCacheKey, &structs.DiscoveryChainResponse{
|
||||||
|
Chain: dbSplitChain(),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
expectSnap: &ConfigSnapshot{
|
||||||
|
Kind: structs.ServiceKindConnectProxy,
|
||||||
|
Service: webProxy.Service,
|
||||||
|
ProxyID: webProxy.ID,
|
||||||
|
Address: webProxy.Address,
|
||||||
|
Port: webProxy.Port,
|
||||||
|
Proxy: webProxy.Proxy,
|
||||||
|
TaggedAddresses: make(map[string]structs.ServiceAddress),
|
||||||
|
Roots: roots,
|
||||||
|
ConnectProxy: configSnapshotConnectProxy{
|
||||||
|
Leaf: leaf,
|
||||||
|
DiscoveryChain: map[string]*structs.CompiledDiscoveryChain{
|
||||||
|
"db": dbSplitChain(),
|
||||||
|
},
|
||||||
|
WatchedUpstreams: nil, // Clone() clears this out
|
||||||
|
WatchedUpstreamEndpoints: map[string]map[structs.DiscoveryTarget]structs.CheckServiceNodes{
|
||||||
|
"db": {
|
||||||
|
dbTarget_v1: TestUpstreamNodes(t),
|
||||||
|
dbTarget_v2: TestUpstreamNodesAlternate(t),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpstreamEndpoints: map[string]structs.CheckServiceNodes{},
|
||||||
|
},
|
||||||
|
Datacenter: "dc1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
require.NotNil(t, tt.setup)
|
||||||
|
require.NotNil(t, tt.expectSnap)
|
||||||
|
|
||||||
|
// Use a mocked cache to make life simpler
|
||||||
|
types := NewTestCacheTypes(t)
|
||||||
|
|
||||||
|
// Setup initial values
|
||||||
|
types.roots.Set(rootsCacheKey, roots)
|
||||||
|
types.leaf.Set(leafCacheKey, leaf)
|
||||||
|
types.intentions.Set(intentionCacheKey, TestIntentions(t))
|
||||||
|
tt.setup(t, types)
|
||||||
|
|
||||||
|
expectSnapCopy, err := copystructure.Copy(tt.expectSnap)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
webProxyCopy, err := copystructure.Copy(webProxy)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
testManager_BasicLifecycle(t, tt, types,
|
||||||
|
rootsCacheKey, leafCacheKey,
|
||||||
|
roots, leaf,
|
||||||
|
webProxyCopy.(*structs.NodeService),
|
||||||
|
expectSnapCopy.(*ConfigSnapshot),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testcase_BasicLifecycle struct {
|
||||||
|
name string
|
||||||
|
setup func(t *testing.T, types *TestCacheTypes)
|
||||||
|
webProxy *structs.NodeService
|
||||||
|
expectSnap *ConfigSnapshot
|
||||||
|
}
|
||||||
|
|
||||||
|
func testManager_BasicLifecycle(
|
||||||
|
t *testing.T,
|
||||||
|
tt *testcase_BasicLifecycle,
|
||||||
|
types *TestCacheTypes,
|
||||||
|
rootsCacheKey, leafCacheKey string,
|
||||||
|
roots *structs.IndexedCARoots,
|
||||||
|
leaf *structs.IssuedCert,
|
||||||
|
webProxy *structs.NodeService,
|
||||||
|
expectSnap *ConfigSnapshot,
|
||||||
|
) {
|
||||||
|
c := TestCacheWithTypes(t, types)
|
||||||
|
|
||||||
|
require := require.New(t)
|
||||||
|
|
||||||
logger := log.New(os.Stderr, "", log.LstdFlags)
|
logger := log.New(os.Stderr, "", log.LstdFlags)
|
||||||
state := local.NewState(local.Config{}, logger, &token.Store{})
|
state := local.NewState(local.Config{}, logger, &token.Store{})
|
||||||
@ -117,24 +320,6 @@ func TestManager_BasicLifecycle(t *testing.T) {
|
|||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Register a proxy for "web"
|
|
||||||
webProxy := &structs.NodeService{
|
|
||||||
Kind: structs.ServiceKindConnectProxy,
|
|
||||||
ID: "web-sidecar-proxy",
|
|
||||||
Service: "web-sidecar-proxy",
|
|
||||||
Port: 9999,
|
|
||||||
Proxy: structs.ConnectProxyConfig{
|
|
||||||
DestinationServiceID: "web",
|
|
||||||
DestinationServiceName: "web",
|
|
||||||
LocalServiceAddress: "127.0.0.1",
|
|
||||||
LocalServicePort: 8080,
|
|
||||||
Config: map[string]interface{}{
|
|
||||||
"foo": "bar",
|
|
||||||
},
|
|
||||||
Upstreams: structs.TestUpstreams(t),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// BEFORE we register, we should be able to get a watch channel
|
// BEFORE we register, we should be able to get a watch channel
|
||||||
wCh, cancel := m.Watch(webProxy.ID)
|
wCh, cancel := m.Watch(webProxy.ID)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -146,30 +331,6 @@ func TestManager_BasicLifecycle(t *testing.T) {
|
|||||||
|
|
||||||
// We should see the initial config delivered but not until after the
|
// We should see the initial config delivered but not until after the
|
||||||
// coalesce timeout
|
// coalesce timeout
|
||||||
expectSnap := &ConfigSnapshot{
|
|
||||||
Kind: structs.ServiceKindConnectProxy,
|
|
||||||
Service: webProxy.Service,
|
|
||||||
ProxyID: webProxy.ID,
|
|
||||||
Address: webProxy.Address,
|
|
||||||
Port: webProxy.Port,
|
|
||||||
Proxy: webProxy.Proxy,
|
|
||||||
TaggedAddresses: make(map[string]structs.ServiceAddress),
|
|
||||||
Roots: roots,
|
|
||||||
ConnectProxy: configSnapshotConnectProxy{
|
|
||||||
Leaf: leaf,
|
|
||||||
DiscoveryChain: map[string]*structs.CompiledDiscoveryChain{
|
|
||||||
"db": dbChain,
|
|
||||||
},
|
|
||||||
WatchedUpstreams: nil, // Clone() clears this out
|
|
||||||
WatchedUpstreamEndpoints: map[string]map[structs.DiscoveryTarget]structs.CheckServiceNodes{
|
|
||||||
"db": {
|
|
||||||
dbTarget: TestUpstreamNodes(t),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
UpstreamEndpoints: map[string]structs.CheckServiceNodes{},
|
|
||||||
},
|
|
||||||
Datacenter: "dc1",
|
|
||||||
}
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
assertWatchChanRecvs(t, wCh, expectSnap)
|
assertWatchChanRecvs(t, wCh, expectSnap)
|
||||||
require.True(time.Since(start) >= coalesceTimeout)
|
require.True(time.Since(start) >= coalesceTimeout)
|
||||||
@ -202,7 +363,7 @@ func TestManager_BasicLifecycle(t *testing.T) {
|
|||||||
// Update roots
|
// Update roots
|
||||||
newRoots, newLeaf := TestCerts(t)
|
newRoots, newLeaf := TestCerts(t)
|
||||||
newRoots.Roots = append(newRoots.Roots, roots.Roots...)
|
newRoots.Roots = append(newRoots.Roots, roots.Roots...)
|
||||||
types.roots.Set(newRoots)
|
types.roots.Set(rootsCacheKey, newRoots)
|
||||||
|
|
||||||
// Expect new roots in snapshot
|
// Expect new roots in snapshot
|
||||||
expectSnap.Roots = newRoots
|
expectSnap.Roots = newRoots
|
||||||
@ -210,7 +371,7 @@ func TestManager_BasicLifecycle(t *testing.T) {
|
|||||||
assertWatchChanRecvs(t, wCh2, expectSnap)
|
assertWatchChanRecvs(t, wCh2, expectSnap)
|
||||||
|
|
||||||
// Update leaf
|
// Update leaf
|
||||||
types.leaf.Set(newLeaf)
|
types.leaf.Set(leafCacheKey, newLeaf)
|
||||||
|
|
||||||
// Expect new roots in snapshot
|
// Expect new roots in snapshot
|
||||||
expectSnap.ConnectProxy.Leaf = newLeaf
|
expectSnap.ConnectProxy.Leaf = newLeaf
|
||||||
@ -340,3 +501,8 @@ func TestManager_deliverLatest(t *testing.T) {
|
|||||||
// Check we got the _second_ one
|
// Check we got the _second_ one
|
||||||
require.Equal(snap2, <-ch5)
|
require.Equal(snap2, <-ch5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testGenCacheKey(req cache.Request) string {
|
||||||
|
info := req.CacheInfo()
|
||||||
|
return path.Join(info.Key, info.Datacenter)
|
||||||
|
}
|
||||||
|
@ -634,13 +634,24 @@ func (s *state) resetWatchesFromChain(
|
|||||||
meshGateway = s.proxyCfg.MeshGateway.Mode
|
meshGateway = s.proxyCfg.MeshGateway.Mode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filterExp := subset.Filter
|
||||||
|
if subset.OnlyPassing {
|
||||||
|
if filterExp != "" {
|
||||||
|
// TODO (filtering) - Update to "and all Checks as chk { chk.Status == passing }"
|
||||||
|
// once the syntax is supported
|
||||||
|
filterExp = fmt.Sprintf("(%s) and not Checks.Status != passing", filterExp)
|
||||||
|
} else {
|
||||||
|
filterExp = "not Checks.Status != passing"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(rb): update the health endpoint to allow returning even unhealthy endpoints
|
// TODO(rb): update the health endpoint to allow returning even unhealthy endpoints
|
||||||
err = s.watchConnectProxyService(
|
err = s.watchConnectProxyService(
|
||||||
ctx,
|
ctx,
|
||||||
"upstream-target:"+string(encodedTarget)+":"+id,
|
"upstream-target:"+string(encodedTarget)+":"+id,
|
||||||
target.Service,
|
target.Service,
|
||||||
target.Datacenter,
|
target.Datacenter,
|
||||||
subset.Filter,
|
filterExp,
|
||||||
meshGateway,
|
meshGateway,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -3,6 +3,7 @@ package proxycfg
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -10,6 +11,7 @@ import (
|
|||||||
"github.com/hashicorp/consul/agent/cache"
|
"github.com/hashicorp/consul/agent/cache"
|
||||||
cachetype "github.com/hashicorp/consul/agent/cache-types"
|
cachetype "github.com/hashicorp/consul/agent/cache-types"
|
||||||
"github.com/hashicorp/consul/agent/connect"
|
"github.com/hashicorp/consul/agent/connect"
|
||||||
|
"github.com/hashicorp/consul/agent/consul/discoverychain"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/mitchellh/go-testing-interface"
|
"github.com/mitchellh/go-testing-interface"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -155,6 +157,52 @@ func TestUpstreamNodes(t testing.T) structs.CheckServiceNodes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpstreamNodesDC2(t testing.T) structs.CheckServiceNodes {
|
||||||
|
return structs.CheckServiceNodes{
|
||||||
|
structs.CheckServiceNode{
|
||||||
|
Node: &structs.Node{
|
||||||
|
ID: "test1",
|
||||||
|
Node: "test1",
|
||||||
|
Address: "10.20.1.1",
|
||||||
|
Datacenter: "dc2",
|
||||||
|
},
|
||||||
|
Service: structs.TestNodeService(t),
|
||||||
|
},
|
||||||
|
structs.CheckServiceNode{
|
||||||
|
Node: &structs.Node{
|
||||||
|
ID: "test2",
|
||||||
|
Node: "test2",
|
||||||
|
Address: "10.20.1.2",
|
||||||
|
Datacenter: "dc2",
|
||||||
|
},
|
||||||
|
Service: structs.TestNodeService(t),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpstreamNodesAlternate(t testing.T) structs.CheckServiceNodes {
|
||||||
|
return structs.CheckServiceNodes{
|
||||||
|
structs.CheckServiceNode{
|
||||||
|
Node: &structs.Node{
|
||||||
|
ID: "alt-test1",
|
||||||
|
Node: "alt-test1",
|
||||||
|
Address: "10.20.1.1",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
},
|
||||||
|
Service: structs.TestNodeService(t),
|
||||||
|
},
|
||||||
|
structs.CheckServiceNode{
|
||||||
|
Node: &structs.Node{
|
||||||
|
ID: "alt-test2",
|
||||||
|
Node: "alt-test2",
|
||||||
|
Address: "10.20.1.2",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
},
|
||||||
|
Service: structs.TestNodeService(t),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGatewayNodesDC2(t testing.T) structs.CheckServiceNodes {
|
func TestGatewayNodesDC2(t testing.T) structs.CheckServiceNodes {
|
||||||
return structs.CheckServiceNodes{
|
return structs.CheckServiceNodes{
|
||||||
structs.CheckServiceNode{
|
structs.CheckServiceNode{
|
||||||
@ -379,6 +427,181 @@ func TestConfigSnapshot(t testing.T) *ConfigSnapshot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestConfigSnapshotDiscoveryChain returns a fully populated snapshot using a discovery chain
|
||||||
|
func TestConfigSnapshotDiscoveryChain(t testing.T) *ConfigSnapshot {
|
||||||
|
return testConfigSnapshotDiscoveryChain(t, "simple")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConfigSnapshotDiscoveryChainWithFailover(t testing.T) *ConfigSnapshot {
|
||||||
|
return testConfigSnapshotDiscoveryChain(t, "failover")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConfigSnapshotDiscoveryChain_SplitterWithResolverRedirectMultiDC(t testing.T) *ConfigSnapshot {
|
||||||
|
return testConfigSnapshotDiscoveryChain(t, "splitter-with-resolver-redirect-multidc")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConfigSnapshotDiscoveryChainWithEntries(t testing.T, additionalEntries ...structs.ConfigEntry) *ConfigSnapshot {
|
||||||
|
return testConfigSnapshotDiscoveryChain(t, "simple", additionalEntries...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testConfigSnapshotDiscoveryChain(t testing.T, variation string, additionalEntries ...structs.ConfigEntry) *ConfigSnapshot {
|
||||||
|
roots, leaf := TestCerts(t)
|
||||||
|
|
||||||
|
// Compile a chain.
|
||||||
|
var entries []structs.ConfigEntry
|
||||||
|
switch variation {
|
||||||
|
case "simple":
|
||||||
|
entries = append(entries,
|
||||||
|
&structs.ServiceResolverConfigEntry{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "db",
|
||||||
|
ConnectTimeout: 33 * time.Second,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
case "failover":
|
||||||
|
entries = append(entries,
|
||||||
|
&structs.ServiceResolverConfigEntry{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "db",
|
||||||
|
ConnectTimeout: 33 * time.Second,
|
||||||
|
Failover: map[string]structs.ServiceResolverFailover{
|
||||||
|
"*": {
|
||||||
|
Service: "fail",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
case "splitter-with-resolver-redirect-multidc":
|
||||||
|
entries = append(entries,
|
||||||
|
&structs.ProxyConfigEntry{
|
||||||
|
Kind: structs.ProxyDefaults,
|
||||||
|
Name: structs.ProxyConfigGlobal,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"protocol": "http",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&structs.ServiceSplitterConfigEntry{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "db",
|
||||||
|
Splits: []structs.ServiceSplit{
|
||||||
|
{Weight: 50, Service: "db-dc1"},
|
||||||
|
{Weight: 50, Service: "db-dc2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&structs.ServiceResolverConfigEntry{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "db-dc1",
|
||||||
|
Redirect: &structs.ServiceResolverRedirect{
|
||||||
|
Service: "db",
|
||||||
|
ServiceSubset: "v1",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&structs.ServiceResolverConfigEntry{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "db-dc2",
|
||||||
|
Redirect: &structs.ServiceResolverRedirect{
|
||||||
|
Service: "db",
|
||||||
|
ServiceSubset: "v2",
|
||||||
|
Datacenter: "dc2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&structs.ServiceResolverConfigEntry{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "db",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": structs.ServiceResolverSubset{
|
||||||
|
Filter: "Service.Meta.version == v1",
|
||||||
|
},
|
||||||
|
"v2": structs.ServiceResolverSubset{
|
||||||
|
Filter: "Service.Meta.version == v2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected variation: %q", variation)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(additionalEntries) > 0 {
|
||||||
|
entries = append(entries, additionalEntries...)
|
||||||
|
}
|
||||||
|
|
||||||
|
dbChain := TestCompileConfigEntries(t, "db", "default", "dc1", entries...)
|
||||||
|
|
||||||
|
dbTarget := structs.DiscoveryTarget{
|
||||||
|
Service: "db",
|
||||||
|
Namespace: "default",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
}
|
||||||
|
failTarget := structs.DiscoveryTarget{
|
||||||
|
Service: "fail",
|
||||||
|
Namespace: "default",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
}
|
||||||
|
|
||||||
|
snap := &ConfigSnapshot{
|
||||||
|
Kind: structs.ServiceKindConnectProxy,
|
||||||
|
Service: "web-sidecar-proxy",
|
||||||
|
ProxyID: "web-sidecar-proxy",
|
||||||
|
Address: "0.0.0.0",
|
||||||
|
Port: 9999,
|
||||||
|
Proxy: structs.ConnectProxyConfig{
|
||||||
|
DestinationServiceID: "web",
|
||||||
|
DestinationServiceName: "web",
|
||||||
|
LocalServiceAddress: "127.0.0.1",
|
||||||
|
LocalServicePort: 8080,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
Upstreams: structs.TestUpstreams(t),
|
||||||
|
},
|
||||||
|
Roots: roots,
|
||||||
|
ConnectProxy: configSnapshotConnectProxy{
|
||||||
|
Leaf: leaf,
|
||||||
|
DiscoveryChain: map[string]*structs.CompiledDiscoveryChain{
|
||||||
|
"db": dbChain,
|
||||||
|
},
|
||||||
|
WatchedUpstreamEndpoints: map[string]map[structs.DiscoveryTarget]structs.CheckServiceNodes{
|
||||||
|
"db": map[structs.DiscoveryTarget]structs.CheckServiceNodes{
|
||||||
|
dbTarget: TestUpstreamNodes(t),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Datacenter: "dc1",
|
||||||
|
}
|
||||||
|
|
||||||
|
switch variation {
|
||||||
|
case "simple":
|
||||||
|
case "failover":
|
||||||
|
snap.ConnectProxy.WatchedUpstreamEndpoints["db"][failTarget] =
|
||||||
|
TestUpstreamNodesAlternate(t)
|
||||||
|
case "splitter-with-resolver-redirect-multidc":
|
||||||
|
dbTarget_v1_dc1 := structs.DiscoveryTarget{
|
||||||
|
Service: "db",
|
||||||
|
ServiceSubset: "v1",
|
||||||
|
Namespace: "default",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
}
|
||||||
|
dbTarget_v2_dc2 := structs.DiscoveryTarget{
|
||||||
|
Service: "db",
|
||||||
|
ServiceSubset: "v2",
|
||||||
|
Namespace: "default",
|
||||||
|
Datacenter: "dc2",
|
||||||
|
}
|
||||||
|
snap.ConnectProxy.WatchedUpstreamEndpoints["db"] = map[structs.DiscoveryTarget]structs.CheckServiceNodes{
|
||||||
|
dbTarget_v1_dc1: TestUpstreamNodes(t),
|
||||||
|
dbTarget_v2_dc2: TestUpstreamNodesDC2(t),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected variation: %q", variation)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return snap
|
||||||
|
}
|
||||||
|
|
||||||
func TestConfigSnapshotMeshGateway(t testing.T) *ConfigSnapshot {
|
func TestConfigSnapshotMeshGateway(t testing.T) *ConfigSnapshot {
|
||||||
roots, _ := TestCerts(t)
|
roots, _ := TestCerts(t)
|
||||||
return &ConfigSnapshot{
|
return &ConfigSnapshot{
|
||||||
@ -421,11 +644,33 @@ func TestConfigSnapshotMeshGateway(t testing.T) *ConfigSnapshot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCompileConfigEntries(
|
||||||
|
t testing.T,
|
||||||
|
serviceName string,
|
||||||
|
currentNamespace string,
|
||||||
|
currentDatacenter string,
|
||||||
|
entries ...structs.ConfigEntry,
|
||||||
|
) *structs.CompiledDiscoveryChain {
|
||||||
|
set := structs.NewDiscoveryChainConfigEntries()
|
||||||
|
|
||||||
|
set.AddEntries(entries...)
|
||||||
|
|
||||||
|
chain, err := discoverychain.Compile(discoverychain.CompileRequest{
|
||||||
|
ServiceName: serviceName,
|
||||||
|
CurrentNamespace: currentNamespace,
|
||||||
|
CurrentDatacenter: currentDatacenter,
|
||||||
|
InferDefaults: true,
|
||||||
|
Entries: set,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
return chain
|
||||||
|
}
|
||||||
|
|
||||||
// ControllableCacheType is a cache.Type that simulates a typical blocking RPC
|
// ControllableCacheType is a cache.Type that simulates a typical blocking RPC
|
||||||
// but lets us control the responses and when they are delivered easily.
|
// but lets us control the responses and when they are delivered easily.
|
||||||
type ControllableCacheType struct {
|
type ControllableCacheType struct {
|
||||||
index uint64
|
index uint64
|
||||||
value atomic.Value
|
value sync.Map
|
||||||
// Need a condvar to trigger all blocking requests (there might be multiple
|
// Need a condvar to trigger all blocking requests (there might be multiple
|
||||||
// for same type due to background refresh and timing issues) when values
|
// for same type due to background refresh and timing issues) when values
|
||||||
// change. Chans make it nondeterministic which one triggers or need extra
|
// change. Chans make it nondeterministic which one triggers or need extra
|
||||||
@ -449,9 +694,9 @@ func NewControllableCacheType(t testing.T) *ControllableCacheType {
|
|||||||
|
|
||||||
// Set sets the response value to be returned from subsequent cache gets for the
|
// Set sets the response value to be returned from subsequent cache gets for the
|
||||||
// type.
|
// type.
|
||||||
func (ct *ControllableCacheType) Set(value interface{}) {
|
func (ct *ControllableCacheType) Set(key string, value interface{}) {
|
||||||
atomic.AddUint64(&ct.index, 1)
|
atomic.AddUint64(&ct.index, 1)
|
||||||
ct.value.Store(value)
|
ct.value.Store(key, value)
|
||||||
ct.triggerMu.Lock()
|
ct.triggerMu.Lock()
|
||||||
ct.trigger.Broadcast()
|
ct.trigger.Broadcast()
|
||||||
ct.triggerMu.Unlock()
|
ct.triggerMu.Unlock()
|
||||||
@ -459,7 +704,6 @@ func (ct *ControllableCacheType) Set(value interface{}) {
|
|||||||
|
|
||||||
// Fetch implements cache.Type. It simulates blocking or non-blocking queries.
|
// Fetch implements cache.Type. It simulates blocking or non-blocking queries.
|
||||||
func (ct *ControllableCacheType) Fetch(opts cache.FetchOptions, req cache.Request) (cache.FetchResult, error) {
|
func (ct *ControllableCacheType) Fetch(opts cache.FetchOptions, req cache.Request) (cache.FetchResult, error) {
|
||||||
|
|
||||||
index := atomic.LoadUint64(&ct.index)
|
index := atomic.LoadUint64(&ct.index)
|
||||||
|
|
||||||
ct.lastReq.Store(req)
|
ct.lastReq.Store(req)
|
||||||
@ -475,9 +719,12 @@ func (ct *ControllableCacheType) Fetch(opts cache.FetchOptions, req cache.Reques
|
|||||||
ct.triggerMu.Unlock()
|
ct.triggerMu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info := req.CacheInfo()
|
||||||
|
key := path.Join(info.Key, info.Datacenter) // omit token for testing purposes
|
||||||
|
|
||||||
// reload index as it probably got bumped
|
// reload index as it probably got bumped
|
||||||
index = atomic.LoadUint64(&ct.index)
|
index = atomic.LoadUint64(&ct.index)
|
||||||
val := ct.value.Load()
|
val, _ := ct.value.Load(key)
|
||||||
|
|
||||||
if err, ok := val.(error); ok {
|
if err, ok := val.(error); ok {
|
||||||
return cache.FetchResult{
|
return cache.FetchResult{
|
||||||
|
@ -99,6 +99,8 @@ func (e *ServiceRouterConfigEntry) Validate() error {
|
|||||||
return fmt.Errorf("Route[%d] should only contain at most one of PathExact, PathPrefix, or PathRegex", i)
|
return fmt.Errorf("Route[%d] should only contain at most one of PathExact, PathPrefix, or PathRegex", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(rb): do some validation of PathExact and PathPrefix
|
||||||
|
|
||||||
for j, hdr := range route.Match.HTTP.Header {
|
for j, hdr := range route.Match.HTTP.Header {
|
||||||
if hdr.Name == "" {
|
if hdr.Name == "" {
|
||||||
return fmt.Errorf("Route[%d] Header[%d] missing required Name field", i, j)
|
return fmt.Errorf("Route[%d] Header[%d] missing required Name field", i, j)
|
||||||
@ -284,6 +286,10 @@ type ServiceRouteDestination struct {
|
|||||||
RetryOnStatusCodes []uint32 `json:",omitempty"`
|
RetryOnStatusCodes []uint32 `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *ServiceRouteDestination) HasRetryFeatures() bool {
|
||||||
|
return d.NumRetries > 0 || d.RetryOnConnectFailure || len(d.RetryOnStatusCodes) > 0
|
||||||
|
}
|
||||||
|
|
||||||
// ServiceSplitterConfigEntry defines how incoming requests are split across
|
// ServiceSplitterConfigEntry defines how incoming requests are split across
|
||||||
// different subsets of a single service (like during staged canary rollouts),
|
// different subsets of a single service (like during staged canary rollouts),
|
||||||
// or perhaps across different services (like during a v2 rewrite or other type
|
// or perhaps across different services (like during a v2 rewrite or other type
|
||||||
@ -845,6 +851,15 @@ type DiscoveryChainConfigEntries struct {
|
|||||||
GlobalProxy *ProxyConfigEntry
|
GlobalProxy *ProxyConfigEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewDiscoveryChainConfigEntries() *DiscoveryChainConfigEntries {
|
||||||
|
return &DiscoveryChainConfigEntries{
|
||||||
|
Routers: make(map[string]*ServiceRouterConfigEntry),
|
||||||
|
Splitters: make(map[string]*ServiceSplitterConfigEntry),
|
||||||
|
Resolvers: make(map[string]*ServiceResolverConfigEntry),
|
||||||
|
Services: make(map[string]*ServiceConfigEntry),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *DiscoveryChainConfigEntries) GetRouter(name string) *ServiceRouterConfigEntry {
|
func (e *DiscoveryChainConfigEntries) GetRouter(name string) *ServiceRouterConfigEntry {
|
||||||
if e.Routers != nil {
|
if e.Routers != nil {
|
||||||
return e.Routers[name]
|
return e.Routers[name]
|
||||||
@ -913,6 +928,30 @@ func (e *DiscoveryChainConfigEntries) AddServices(entries ...*ServiceConfigEntry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddEntries adds generic configs. Convenience function for testing. Panics on
|
||||||
|
// operator error.
|
||||||
|
func (e *DiscoveryChainConfigEntries) AddEntries(entries ...ConfigEntry) {
|
||||||
|
for _, entry := range entries {
|
||||||
|
switch entry.GetKind() {
|
||||||
|
case ServiceRouter:
|
||||||
|
e.AddRouters(entry.(*ServiceRouterConfigEntry))
|
||||||
|
case ServiceSplitter:
|
||||||
|
e.AddSplitters(entry.(*ServiceSplitterConfigEntry))
|
||||||
|
case ServiceResolver:
|
||||||
|
e.AddResolvers(entry.(*ServiceResolverConfigEntry))
|
||||||
|
case ServiceDefaults:
|
||||||
|
e.AddServices(entry.(*ServiceConfigEntry))
|
||||||
|
case ProxyDefaults:
|
||||||
|
if entry.GetName() != ProxyConfigGlobal {
|
||||||
|
panic("the only supported proxy-defaults name is '" + ProxyConfigGlobal + "'")
|
||||||
|
}
|
||||||
|
e.GlobalProxy = entry.(*ProxyConfigEntry)
|
||||||
|
default:
|
||||||
|
panic("unhandled config entry kind: " + entry.GetKind())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *DiscoveryChainConfigEntries) IsEmpty() bool {
|
func (e *DiscoveryChainConfigEntries) IsEmpty() bool {
|
||||||
return e.IsChainEmpty() && len(e.Services) == 0 && e.GlobalProxy == nil
|
return e.IsChainEmpty() && len(e.Services) == 0 && e.GlobalProxy == nil
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ func TestNodeService(t testing.T) *NodeService {
|
|||||||
return &NodeService{
|
return &NodeService{
|
||||||
Kind: ServiceKindTypical,
|
Kind: ServiceKindTypical,
|
||||||
Service: "web",
|
Service: "web",
|
||||||
|
Port: 8080,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,8 +255,6 @@ func (s *Server) makeUpstreamClustersForDiscoveryChain(
|
|||||||
var out []*envoy.Cluster
|
var out []*envoy.Cluster
|
||||||
for target, node := range chain.GroupResolverNodes {
|
for target, node := range chain.GroupResolverNodes {
|
||||||
groupResolver := node.GroupResolver
|
groupResolver := node.GroupResolver
|
||||||
// TODO(rb): failover
|
|
||||||
// Failover *DiscoveryFailover `json:",omitempty"` // sad path
|
|
||||||
|
|
||||||
sni := TargetSNI(target, cfgSnap)
|
sni := TargetSNI(target, cfgSnap)
|
||||||
s.Logger.Printf("[DEBUG] xds.clusters - generating cluster for %s", sni)
|
s.Logger.Printf("[DEBUG] xds.clusters - generating cluster for %s", sni)
|
||||||
|
@ -100,6 +100,21 @@ func TestClustersFromSnapshot(t *testing.T) {
|
|||||||
snap.Proxy.Upstreams[0].Config["connect_timeout_ms"] = 2345
|
snap.Proxy.Upstreams[0].Config["connect_timeout_ms"] = 2345
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-chain",
|
||||||
|
create: proxycfg.TestConfigSnapshotDiscoveryChain,
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-chain-and-failover",
|
||||||
|
create: proxycfg.TestConfigSnapshotDiscoveryChainWithFailover,
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "splitter-with-resolver-redirect",
|
||||||
|
create: proxycfg.TestConfigSnapshotDiscoveryChain_SplitterWithResolverRedirectMultiDC,
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "mesh-gateway",
|
name: "mesh-gateway",
|
||||||
create: proxycfg.TestConfigSnapshotMeshGateway,
|
create: proxycfg.TestConfigSnapshotMeshGateway,
|
||||||
|
@ -234,6 +234,39 @@ func Test_endpointsFromSnapshot(t *testing.T) {
|
|||||||
create: proxycfg.TestConfigSnapshotMeshGateway,
|
create: proxycfg.TestConfigSnapshotMeshGateway,
|
||||||
setup: nil,
|
setup: nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-chain",
|
||||||
|
create: proxycfg.TestConfigSnapshotDiscoveryChain,
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-chain-and-failover",
|
||||||
|
create: proxycfg.TestConfigSnapshotDiscoveryChainWithFailover,
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-chain-and-sliding-failover",
|
||||||
|
create: proxycfg.TestConfigSnapshotDiscoveryChainWithFailover,
|
||||||
|
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||||
|
chain := snap.ConnectProxy.DiscoveryChain["db"]
|
||||||
|
|
||||||
|
dbTarget := structs.DiscoveryTarget{
|
||||||
|
Service: "db",
|
||||||
|
Namespace: "default",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
}
|
||||||
|
dbResolverNode := chain.GroupResolverNodes[dbTarget]
|
||||||
|
|
||||||
|
groupResolverFailover := dbResolverNode.GroupResolver.Failover
|
||||||
|
|
||||||
|
groupResolverFailover.Definition.OverprovisioningFactor = 160
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "splitter-with-resolver-redirect",
|
||||||
|
create: proxycfg.TestConfigSnapshotDiscoveryChain_SplitterWithResolverRedirectMultiDC,
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "mesh-gateway-service-subsets",
|
name: "mesh-gateway-service-subsets",
|
||||||
create: proxycfg.TestConfigSnapshotMeshGateway,
|
create: proxycfg.TestConfigSnapshotMeshGateway,
|
||||||
|
@ -427,6 +427,7 @@ func makeTLSInspectorListenerFilter() (envoylistener.ListenerFilter, error) {
|
|||||||
return envoylistener.ListenerFilter{Name: util.TlsInspector}, nil
|
return envoylistener.ListenerFilter{Name: util.TlsInspector}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(rb): should this be dead code?
|
||||||
func makeSNIFilterChainMatch(sniMatch string) (*envoylistener.FilterChainMatch, error) {
|
func makeSNIFilterChainMatch(sniMatch string) (*envoylistener.FilterChainMatch, error) {
|
||||||
return &envoylistener.FilterChainMatch{
|
return &envoylistener.FilterChainMatch{
|
||||||
ServerNames: []string{sniMatch},
|
ServerNames: []string{sniMatch},
|
||||||
|
@ -129,6 +129,61 @@ func TestListenersFromSnapshot(t *testing.T) {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "splitter-with-resolver-redirect",
|
||||||
|
create: proxycfg.TestConfigSnapshotDiscoveryChain_SplitterWithResolverRedirectMultiDC,
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-tcp-chain",
|
||||||
|
create: proxycfg.TestConfigSnapshotDiscoveryChain,
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-http-chain",
|
||||||
|
create: func(t testinf.T) *proxycfg.ConfigSnapshot {
|
||||||
|
return proxycfg.TestConfigSnapshotDiscoveryChainWithEntries(t,
|
||||||
|
&structs.ProxyConfigEntry{
|
||||||
|
Kind: structs.ProxyDefaults,
|
||||||
|
Name: structs.ProxyConfigGlobal,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"protocol": "http",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-http2-chain",
|
||||||
|
create: func(t testinf.T) *proxycfg.ConfigSnapshot {
|
||||||
|
return proxycfg.TestConfigSnapshotDiscoveryChainWithEntries(t,
|
||||||
|
&structs.ProxyConfigEntry{
|
||||||
|
Kind: structs.ProxyDefaults,
|
||||||
|
Name: structs.ProxyConfigGlobal,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"protocol": "http2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-grpc-chain",
|
||||||
|
create: func(t testinf.T) *proxycfg.ConfigSnapshot {
|
||||||
|
return proxycfg.TestConfigSnapshotDiscoveryChainWithEntries(t,
|
||||||
|
&structs.ProxyConfigEntry{
|
||||||
|
Kind: structs.ProxyDefaults,
|
||||||
|
Name: structs.ProxyConfigGlobal,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"protocol": "grpc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "mesh-gateway",
|
name: "mesh-gateway",
|
||||||
create: proxycfg.TestConfigSnapshotMeshGateway,
|
create: proxycfg.TestConfigSnapshotMeshGateway,
|
||||||
|
@ -79,10 +79,6 @@ func makeUpstreamRouteForDiscoveryChain(
|
|||||||
for _, discoveryRoute := range chain.Node.Routes {
|
for _, discoveryRoute := range chain.Node.Routes {
|
||||||
routeMatch := makeRouteMatchForDiscoveryRoute(discoveryRoute, chain.Protocol)
|
routeMatch := makeRouteMatchForDiscoveryRoute(discoveryRoute, chain.Protocol)
|
||||||
|
|
||||||
// TODO(rb): handle PrefixRewrite
|
|
||||||
// TODO(rb): handle RequestTimeout
|
|
||||||
// TODO(rb): handle Retries
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
routeAction *envoyroute.Route_Route
|
routeAction *envoyroute.Route_Route
|
||||||
err error
|
err error
|
||||||
@ -103,6 +99,41 @@ func makeUpstreamRouteForDiscoveryChain(
|
|||||||
return nil, fmt.Errorf("unexpected graph node after route %q", next.Type)
|
return nil, fmt.Errorf("unexpected graph node after route %q", next.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(rb): Better help handle the envoy case where you need (prefix=/foo/,rewrite=/) and (exact=/foo,rewrite=/) to do a full rewrite
|
||||||
|
|
||||||
|
destination := discoveryRoute.Definition.Destination
|
||||||
|
if destination != nil {
|
||||||
|
if destination.PrefixRewrite != "" {
|
||||||
|
routeAction.Route.PrefixRewrite = destination.PrefixRewrite
|
||||||
|
}
|
||||||
|
|
||||||
|
if destination.RequestTimeout > 0 {
|
||||||
|
routeAction.Route.Timeout = &destination.RequestTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
if destination.HasRetryFeatures() {
|
||||||
|
retryPolicy := &envoyroute.RetryPolicy{}
|
||||||
|
if destination.NumRetries > 0 {
|
||||||
|
retryPolicy.NumRetries = makeUint32Value(int(destination.NumRetries))
|
||||||
|
}
|
||||||
|
|
||||||
|
// The RetryOn magic values come from: https://www.envoyproxy.io/docs/envoy/v1.10.0/configuration/http_filters/router_filter#config-http-filters-router-x-envoy-retry-on
|
||||||
|
if destination.RetryOnConnectFailure {
|
||||||
|
retryPolicy.RetryOn = "connect-failure"
|
||||||
|
}
|
||||||
|
if len(destination.RetryOnStatusCodes) > 0 {
|
||||||
|
if retryPolicy.RetryOn != "" {
|
||||||
|
retryPolicy.RetryOn = ",retriable-status-codes"
|
||||||
|
} else {
|
||||||
|
retryPolicy.RetryOn = "retriable-status-codes"
|
||||||
|
}
|
||||||
|
retryPolicy.RetriableStatusCodes = destination.RetryOnStatusCodes
|
||||||
|
}
|
||||||
|
|
||||||
|
routeAction.Route.RetryPolicy = retryPolicy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
routes = append(routes, envoyroute.Route{
|
routes = append(routes, envoyroute.Route{
|
||||||
Match: routeMatch,
|
Match: routeMatch,
|
||||||
Action: routeAction,
|
Action: routeAction,
|
||||||
@ -171,13 +202,21 @@ func makeRouteMatchForDiscoveryRoute(discoveryRoute *structs.DiscoveryRoute, pro
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
case match.HTTP.PathExact != "":
|
case match.HTTP.PathExact != "":
|
||||||
em.PathSpecifier = &envoyroute.RouteMatch_Path{Path: "/"}
|
em.PathSpecifier = &envoyroute.RouteMatch_Path{
|
||||||
|
Path: match.HTTP.PathExact,
|
||||||
|
}
|
||||||
case match.HTTP.PathPrefix != "":
|
case match.HTTP.PathPrefix != "":
|
||||||
em.PathSpecifier = &envoyroute.RouteMatch_Prefix{Prefix: "/"}
|
em.PathSpecifier = &envoyroute.RouteMatch_Prefix{
|
||||||
|
Prefix: match.HTTP.PathPrefix,
|
||||||
|
}
|
||||||
case match.HTTP.PathRegex != "":
|
case match.HTTP.PathRegex != "":
|
||||||
em.PathSpecifier = &envoyroute.RouteMatch_Regex{Regex: "/"}
|
em.PathSpecifier = &envoyroute.RouteMatch_Regex{
|
||||||
|
Regex: match.HTTP.PathRegex,
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
em.PathSpecifier = &envoyroute.RouteMatch_Prefix{Prefix: "/"}
|
em.PathSpecifier = &envoyroute.RouteMatch_Prefix{
|
||||||
|
Prefix: "/",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(match.HTTP.Header) > 0 {
|
if len(match.HTTP.Header) > 0 {
|
||||||
@ -277,9 +316,10 @@ func makeRouteActionForSplitter(splits []*structs.DiscoverySplit, cfgSnap *proxy
|
|||||||
target := groupResolver.Target
|
target := groupResolver.Target
|
||||||
clusterName := TargetSNI(target, cfgSnap)
|
clusterName := TargetSNI(target, cfgSnap)
|
||||||
|
|
||||||
// TODO(rb): scale up by 100 and adjust total weight
|
// The smallest representable weight is 1/10000 or .01% but envoy
|
||||||
|
// deals with integers so scale everything up by 100x.
|
||||||
cw := &envoyroute.WeightedCluster_ClusterWeight{
|
cw := &envoyroute.WeightedCluster_ClusterWeight{
|
||||||
Weight: makeUint32Value(int(split.Weight)),
|
Weight: makeUint32Value(int(split.Weight * 100)),
|
||||||
Name: clusterName,
|
Name: clusterName,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +331,7 @@ func makeRouteActionForSplitter(splits []*structs.DiscoverySplit, cfgSnap *proxy
|
|||||||
ClusterSpecifier: &envoyroute.RouteAction_WeightedClusters{
|
ClusterSpecifier: &envoyroute.RouteAction_WeightedClusters{
|
||||||
WeightedClusters: &envoyroute.WeightedCluster{
|
WeightedClusters: &envoyroute.WeightedCluster{
|
||||||
Clusters: clusters,
|
Clusters: clusters,
|
||||||
TotalWeight: makeUint32Value(100),
|
TotalWeight: makeUint32Value(10000), // scaled up 100%
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
307
agent/xds/routes_test.go
Normal file
307
agent/xds/routes_test.go
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
package xds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path"
|
||||||
|
"sort"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
||||||
|
"github.com/hashicorp/consul/agent/proxycfg"
|
||||||
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
|
testinf "github.com/mitchellh/go-testing-interface"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRoutesFromSnapshot(t *testing.T) {
|
||||||
|
httpMatch := func(http *structs.ServiceRouteHTTPMatch) *structs.ServiceRouteMatch {
|
||||||
|
return &structs.ServiceRouteMatch{HTTP: http}
|
||||||
|
}
|
||||||
|
httpMatchHeader := func(headers ...structs.ServiceRouteHTTPMatchHeader) *structs.ServiceRouteMatch {
|
||||||
|
return httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
Header: headers,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
httpMatchParam := func(params ...structs.ServiceRouteHTTPMatchQueryParam) *structs.ServiceRouteMatch {
|
||||||
|
return httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
QueryParam: params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
toService := func(svc string) *structs.ServiceRouteDestination {
|
||||||
|
return &structs.ServiceRouteDestination{Service: svc}
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
create func(t testinf.T) *proxycfg.ConfigSnapshot
|
||||||
|
// Setup is called before the test starts. It is passed the snapshot from
|
||||||
|
// create func and is allowed to modify it in any way to setup the
|
||||||
|
// test input.
|
||||||
|
setup func(snap *proxycfg.ConfigSnapshot)
|
||||||
|
overrideGoldenName string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "defaults-no-chain",
|
||||||
|
create: proxycfg.TestConfigSnapshot,
|
||||||
|
setup: nil, // Default snapshot
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-chain",
|
||||||
|
create: proxycfg.TestConfigSnapshotDiscoveryChain,
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "splitter-with-resolver-redirect",
|
||||||
|
create: proxycfg.TestConfigSnapshotDiscoveryChain_SplitterWithResolverRedirectMultiDC,
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-chain-and-splitter",
|
||||||
|
create: func(t testinf.T) *proxycfg.ConfigSnapshot {
|
||||||
|
return proxycfg.TestConfigSnapshotDiscoveryChainWithEntries(t,
|
||||||
|
&structs.ProxyConfigEntry{
|
||||||
|
Kind: structs.ProxyDefaults,
|
||||||
|
Name: structs.ProxyConfigGlobal,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"protocol": "http",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&structs.ServiceSplitterConfigEntry{
|
||||||
|
Kind: structs.ServiceSplitter,
|
||||||
|
Name: "db",
|
||||||
|
Splits: []structs.ServiceSplit{
|
||||||
|
{Weight: 95.5, Service: "big-side"},
|
||||||
|
{Weight: 4, Service: "goldilocks-side"},
|
||||||
|
{Weight: 0.5, Service: "lil-bit-side"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "connect-proxy-with-chain-and-router",
|
||||||
|
create: func(t testinf.T) *proxycfg.ConfigSnapshot {
|
||||||
|
return proxycfg.TestConfigSnapshotDiscoveryChainWithEntries(t,
|
||||||
|
&structs.ProxyConfigEntry{
|
||||||
|
Kind: structs.ProxyDefaults,
|
||||||
|
Name: structs.ProxyConfigGlobal,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"protocol": "http",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&structs.ServiceSplitterConfigEntry{
|
||||||
|
Kind: structs.ServiceSplitter,
|
||||||
|
Name: "split-3-ways",
|
||||||
|
Splits: []structs.ServiceSplit{
|
||||||
|
{Weight: 95.5, Service: "big-side"},
|
||||||
|
{Weight: 4, Service: "goldilocks-side"},
|
||||||
|
{Weight: 0.5, Service: "lil-bit-side"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&structs.ServiceRouterConfigEntry{
|
||||||
|
Kind: structs.ServiceRouter,
|
||||||
|
Name: "db",
|
||||||
|
Routes: []structs.ServiceRoute{
|
||||||
|
{
|
||||||
|
Match: httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
PathPrefix: "/prefix",
|
||||||
|
}),
|
||||||
|
Destination: toService("prefix"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
PathExact: "/exact",
|
||||||
|
}),
|
||||||
|
Destination: toService("exact"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
PathRegex: "/regex",
|
||||||
|
}),
|
||||||
|
Destination: toService("regex"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatchHeader(structs.ServiceRouteHTTPMatchHeader{
|
||||||
|
Name: "x-debug",
|
||||||
|
Present: true,
|
||||||
|
}),
|
||||||
|
Destination: toService("hdr-present"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatchHeader(structs.ServiceRouteHTTPMatchHeader{
|
||||||
|
Name: "x-debug",
|
||||||
|
Invert: true,
|
||||||
|
}),
|
||||||
|
Destination: toService("hdr-not-present"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatchHeader(structs.ServiceRouteHTTPMatchHeader{
|
||||||
|
Name: "x-debug",
|
||||||
|
Exact: "exact",
|
||||||
|
}),
|
||||||
|
Destination: toService("hdr-exact"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatchHeader(structs.ServiceRouteHTTPMatchHeader{
|
||||||
|
Name: "x-debug",
|
||||||
|
Prefix: "prefix",
|
||||||
|
}),
|
||||||
|
Destination: toService("hdr-prefix"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatchHeader(structs.ServiceRouteHTTPMatchHeader{
|
||||||
|
Name: "x-debug",
|
||||||
|
Suffix: "suffix",
|
||||||
|
}),
|
||||||
|
Destination: toService("hdr-suffix"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatchHeader(structs.ServiceRouteHTTPMatchHeader{
|
||||||
|
Name: "x-debug",
|
||||||
|
Regex: "regex",
|
||||||
|
}),
|
||||||
|
Destination: toService("hdr-regex"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatchParam(structs.ServiceRouteHTTPMatchQueryParam{
|
||||||
|
Name: "secretparam",
|
||||||
|
Value: "exact",
|
||||||
|
}),
|
||||||
|
Destination: toService("prm-exact"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatchParam(structs.ServiceRouteHTTPMatchQueryParam{
|
||||||
|
Name: "secretparam",
|
||||||
|
Value: "regex",
|
||||||
|
Regex: true,
|
||||||
|
}),
|
||||||
|
Destination: toService("prm-regex"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: nil,
|
||||||
|
Destination: toService("nil-match"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: &structs.ServiceRouteMatch{},
|
||||||
|
Destination: toService("empty-match-1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: &structs.ServiceRouteMatch{
|
||||||
|
HTTP: &structs.ServiceRouteHTTPMatch{},
|
||||||
|
},
|
||||||
|
Destination: toService("empty-match-2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
PathPrefix: "/prefix",
|
||||||
|
}),
|
||||||
|
Destination: &structs.ServiceRouteDestination{
|
||||||
|
Service: "prefix-rewrite-1",
|
||||||
|
PrefixRewrite: "/",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
PathPrefix: "/prefix",
|
||||||
|
}),
|
||||||
|
Destination: &structs.ServiceRouteDestination{
|
||||||
|
Service: "prefix-rewrite-2",
|
||||||
|
PrefixRewrite: "/nested/newlocation",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
PathPrefix: "/timeout",
|
||||||
|
}),
|
||||||
|
Destination: &structs.ServiceRouteDestination{
|
||||||
|
Service: "req-timeout",
|
||||||
|
RequestTimeout: 33 * time.Second,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
PathPrefix: "/retry-connect",
|
||||||
|
}),
|
||||||
|
Destination: &structs.ServiceRouteDestination{
|
||||||
|
Service: "retry-connect",
|
||||||
|
NumRetries: 15,
|
||||||
|
RetryOnConnectFailure: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
PathPrefix: "/retry-codes",
|
||||||
|
}),
|
||||||
|
Destination: &structs.ServiceRouteDestination{
|
||||||
|
Service: "retry-codes",
|
||||||
|
NumRetries: 15,
|
||||||
|
RetryOnStatusCodes: []uint32{401, 409, 451},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
PathPrefix: "/retry-both",
|
||||||
|
}),
|
||||||
|
Destination: &structs.ServiceRouteDestination{
|
||||||
|
Service: "retry-both",
|
||||||
|
RetryOnConnectFailure: true,
|
||||||
|
RetryOnStatusCodes: []uint32{401, 409, 451},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Match: httpMatch(&structs.ServiceRouteHTTPMatch{
|
||||||
|
PathPrefix: "/split-3-ways",
|
||||||
|
}),
|
||||||
|
Destination: toService("split-3-ways"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
setup: nil,
|
||||||
|
},
|
||||||
|
// TODO(rb): test match stanza skipped for grpc
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
require := require.New(t)
|
||||||
|
|
||||||
|
// Sanity check default with no overrides first
|
||||||
|
snap := tt.create(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!
|
||||||
|
if snap.ConnectProxy.Leaf != nil {
|
||||||
|
snap.ConnectProxy.Leaf.CertPEM = golden(t, "test-leaf-cert", "")
|
||||||
|
snap.ConnectProxy.Leaf.PrivateKeyPEM = golden(t, "test-leaf-key", "")
|
||||||
|
}
|
||||||
|
if snap.Roots != nil {
|
||||||
|
snap.Roots.Roots[0].RootCert = golden(t, "test-root-cert", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.setup != nil {
|
||||||
|
tt.setup(snap)
|
||||||
|
}
|
||||||
|
|
||||||
|
routes, err := routesFromSnapshot(snap, "my-token")
|
||||||
|
require.NoError(err)
|
||||||
|
sort.Slice(routes, func(i, j int) bool {
|
||||||
|
return routes[i].(*envoy.RouteConfiguration).Name < routes[j].(*envoy.RouteConfiguration).Name
|
||||||
|
})
|
||||||
|
r, err := createResponse(RouteType, "00000001", "00000001", routes)
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
gotJSON := responseToJSON(t, r)
|
||||||
|
|
||||||
|
gName := tt.name
|
||||||
|
if tt.overrideGoldenName != "" {
|
||||||
|
gName = tt.overrideGoldenName
|
||||||
|
}
|
||||||
|
|
||||||
|
require.JSONEq(golden(t, path.Join("routes", gName), gotJSON), gotJSON)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -245,7 +245,7 @@ func expectEndpointsJSON(t *testing.T, snap *proxycfg.ConfigSnapshot, token stri
|
|||||||
"address": {
|
"address": {
|
||||||
"socketAddress": {
|
"socketAddress": {
|
||||||
"address": "10.10.1.1",
|
"address": "10.10.1.1",
|
||||||
"portValue": 0
|
"portValue": 8080
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -257,7 +257,7 @@ func expectEndpointsJSON(t *testing.T, snap *proxycfg.ConfigSnapshot, token stri
|
|||||||
"address": {
|
"address": {
|
||||||
"socketAddress": {
|
"socketAddress": {
|
||||||
"address": "10.10.1.2",
|
"address": "10.10.1.2",
|
||||||
"portValue": 0
|
"portValue": 8080
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
116
agent/xds/testdata/clusters/connect-proxy-with-chain-and-failover.golden
vendored
Normal file
116
agent/xds/testdata/clusters/connect-proxy-with-chain-and-failover.golden
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "33s",
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
},
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"commonLbConfig": {
|
||||||
|
"healthyPanicThreshold": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
},
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "local_app",
|
||||||
|
"type": "STATIC",
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"loadAssignment": {
|
||||||
|
"clusterName": "local_app",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
116
agent/xds/testdata/clusters/connect-proxy-with-chain.golden
vendored
Normal file
116
agent/xds/testdata/clusters/connect-proxy-with-chain.golden
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "33s",
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
},
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"commonLbConfig": {
|
||||||
|
"healthyPanicThreshold": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
},
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "local_app",
|
||||||
|
"type": "STATIC",
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"loadAssignment": {
|
||||||
|
"clusterName": "local_app",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
161
agent/xds/testdata/clusters/splitter-with-resolver-redirect.golden
vendored
Normal file
161
agent/xds/testdata/clusters/splitter-with-resolver-redirect.golden
vendored
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
},
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "local_app",
|
||||||
|
"type": "STATIC",
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"loadAssignment": {
|
||||||
|
"clusterName": "local_app",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"altStatName": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sni": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
},
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"commonLbConfig": {
|
||||||
|
"healthyPanicThreshold": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"name": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"altStatName": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "EDS",
|
||||||
|
"edsClusterConfig": {
|
||||||
|
"edsConfig": {
|
||||||
|
"ads": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sni": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
},
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"commonLbConfig": {
|
||||||
|
"healthyPanicThreshold": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.Cluster",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
73
agent/xds/testdata/endpoints/connect-proxy-with-chain-and-failover.golden
vendored
Normal file
73
agent/xds/testdata/endpoints/connect-proxy-with-chain-and-failover.golden
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.1",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.2",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.20.1.1",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.20.1.2",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"priority": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"policy": {
|
||||||
|
"overprovisioningFactor": 100000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
73
agent/xds/testdata/endpoints/connect-proxy-with-chain-and-sliding-failover.golden
vendored
Normal file
73
agent/xds/testdata/endpoints/connect-proxy-with-chain-and-sliding-failover.golden
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.1",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.2",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.20.1.1",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.20.1.2",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"priority": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"policy": {
|
||||||
|
"overprovisioningFactor": 160
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
41
agent/xds/testdata/endpoints/connect-proxy-with-chain.golden
vendored
Normal file
41
agent/xds/testdata/endpoints/connect-proxy-with-chain.golden
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.1",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.2",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
4
agent/xds/testdata/endpoints/defaults.golden
vendored
4
agent/xds/testdata/endpoints/defaults.golden
vendored
@ -12,7 +12,7 @@
|
|||||||
"address": {
|
"address": {
|
||||||
"socketAddress": {
|
"socketAddress": {
|
||||||
"address": "10.10.1.1",
|
"address": "10.10.1.1",
|
||||||
"portValue": 0
|
"portValue": 8080
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -24,7 +24,7 @@
|
|||||||
"address": {
|
"address": {
|
||||||
"socketAddress": {
|
"socketAddress": {
|
||||||
"address": "10.10.1.2",
|
"address": "10.10.1.2",
|
||||||
"portValue": 0
|
"portValue": 8080
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
75
agent/xds/testdata/endpoints/splitter-with-resolver-redirect.golden
vendored
Normal file
75
agent/xds/testdata/endpoints/splitter-with-resolver-redirect.golden
vendored
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.1",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.10.1.2",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"clusterName": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.20.1.1",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "10.20.1.2",
|
||||||
|
"portValue": 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
139
agent/xds/testdata/listeners/connect-proxy-with-grpc-chain.golden
vendored
Normal file
139
agent/xds/testdata/listeners/connect-proxy-with-grpc-chain.golden
vendored
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "db:127.0.0.1:9191",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"portValue": 9191
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.http_connection_manager",
|
||||||
|
"config": {
|
||||||
|
"http2_protocol_options": {
|
||||||
|
},
|
||||||
|
"http_filters": [
|
||||||
|
{
|
||||||
|
"config": {
|
||||||
|
},
|
||||||
|
"name": "envoy.grpc_http1_bridge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.router"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rds": {
|
||||||
|
"config_source": {
|
||||||
|
"ads": {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"route_config_name": "db"
|
||||||
|
},
|
||||||
|
"stat_prefix": "upstream_db_grpc",
|
||||||
|
"tracing": {
|
||||||
|
"operation_name": "EGRESS",
|
||||||
|
"random_sampling": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "prepared_query:geo-cache:127.10.10.10:8181",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.10.10.10",
|
||||||
|
"portValue": 8181
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"stat_prefix": "upstream_prepared_query_geo-cache_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "public_listener:0.0.0.0:9999",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "0.0.0.0",
|
||||||
|
"portValue": 9999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requireClientCertificate": true
|
||||||
|
},
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.ext_authz",
|
||||||
|
"config": {
|
||||||
|
"grpc_service": {
|
||||||
|
"envoy_grpc": {
|
||||||
|
"cluster_name": "local_agent"
|
||||||
|
},
|
||||||
|
"initial_metadata": [
|
||||||
|
{
|
||||||
|
"key": "x-consul-token",
|
||||||
|
"value": "my-token"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stat_prefix": "connect_authz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "local_app",
|
||||||
|
"stat_prefix": "public_listener_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
132
agent/xds/testdata/listeners/connect-proxy-with-http-chain.golden
vendored
Normal file
132
agent/xds/testdata/listeners/connect-proxy-with-http-chain.golden
vendored
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "db:127.0.0.1:9191",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"portValue": 9191
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.http_connection_manager",
|
||||||
|
"config": {
|
||||||
|
"http_filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.router"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rds": {
|
||||||
|
"config_source": {
|
||||||
|
"ads": {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"route_config_name": "db"
|
||||||
|
},
|
||||||
|
"stat_prefix": "upstream_db_http",
|
||||||
|
"tracing": {
|
||||||
|
"operation_name": "EGRESS",
|
||||||
|
"random_sampling": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "prepared_query:geo-cache:127.10.10.10:8181",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.10.10.10",
|
||||||
|
"portValue": 8181
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"stat_prefix": "upstream_prepared_query_geo-cache_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "public_listener:0.0.0.0:9999",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "0.0.0.0",
|
||||||
|
"portValue": 9999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requireClientCertificate": true
|
||||||
|
},
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.ext_authz",
|
||||||
|
"config": {
|
||||||
|
"grpc_service": {
|
||||||
|
"envoy_grpc": {
|
||||||
|
"cluster_name": "local_agent"
|
||||||
|
},
|
||||||
|
"initial_metadata": [
|
||||||
|
{
|
||||||
|
"key": "x-consul-token",
|
||||||
|
"value": "my-token"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stat_prefix": "connect_authz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "local_app",
|
||||||
|
"stat_prefix": "public_listener_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
134
agent/xds/testdata/listeners/connect-proxy-with-http2-chain.golden
vendored
Normal file
134
agent/xds/testdata/listeners/connect-proxy-with-http2-chain.golden
vendored
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "db:127.0.0.1:9191",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"portValue": 9191
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.http_connection_manager",
|
||||||
|
"config": {
|
||||||
|
"http2_protocol_options": {
|
||||||
|
},
|
||||||
|
"http_filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.router"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rds": {
|
||||||
|
"config_source": {
|
||||||
|
"ads": {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"route_config_name": "db"
|
||||||
|
},
|
||||||
|
"stat_prefix": "upstream_db_http",
|
||||||
|
"tracing": {
|
||||||
|
"operation_name": "EGRESS",
|
||||||
|
"random_sampling": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "prepared_query:geo-cache:127.10.10.10:8181",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.10.10.10",
|
||||||
|
"portValue": 8181
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"stat_prefix": "upstream_prepared_query_geo-cache_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "public_listener:0.0.0.0:9999",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "0.0.0.0",
|
||||||
|
"portValue": 9999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requireClientCertificate": true
|
||||||
|
},
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.ext_authz",
|
||||||
|
"config": {
|
||||||
|
"grpc_service": {
|
||||||
|
"envoy_grpc": {
|
||||||
|
"cluster_name": "local_agent"
|
||||||
|
},
|
||||||
|
"initial_metadata": [
|
||||||
|
{
|
||||||
|
"key": "x-consul-token",
|
||||||
|
"value": "my-token"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stat_prefix": "connect_authz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "local_app",
|
||||||
|
"stat_prefix": "public_listener_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
116
agent/xds/testdata/listeners/connect-proxy-with-tcp-chain.golden
vendored
Normal file
116
agent/xds/testdata/listeners/connect-proxy-with-tcp-chain.golden
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "db:127.0.0.1:9191",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"portValue": 9191
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "",
|
||||||
|
"stat_prefix": "upstream_db_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "prepared_query:geo-cache:127.10.10.10:8181",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.10.10.10",
|
||||||
|
"portValue": 8181
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"stat_prefix": "upstream_prepared_query_geo-cache_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "public_listener:0.0.0.0:9999",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "0.0.0.0",
|
||||||
|
"portValue": 9999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requireClientCertificate": true
|
||||||
|
},
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.ext_authz",
|
||||||
|
"config": {
|
||||||
|
"grpc_service": {
|
||||||
|
"envoy_grpc": {
|
||||||
|
"cluster_name": "local_agent"
|
||||||
|
},
|
||||||
|
"initial_metadata": [
|
||||||
|
{
|
||||||
|
"key": "x-consul-token",
|
||||||
|
"value": "my-token"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stat_prefix": "connect_authz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "local_app",
|
||||||
|
"stat_prefix": "public_listener_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
132
agent/xds/testdata/listeners/splitter-with-resolver-redirect.golden
vendored
Normal file
132
agent/xds/testdata/listeners/splitter-with-resolver-redirect.golden
vendored
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "db:127.0.0.1:9191",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"portValue": 9191
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.http_connection_manager",
|
||||||
|
"config": {
|
||||||
|
"http_filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.router"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rds": {
|
||||||
|
"config_source": {
|
||||||
|
"ads": {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"route_config_name": "db"
|
||||||
|
},
|
||||||
|
"stat_prefix": "upstream_db_http",
|
||||||
|
"tracing": {
|
||||||
|
"operation_name": "EGRESS",
|
||||||
|
"random_sampling": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "prepared_query:geo-cache:127.10.10.10:8181",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.10.10.10",
|
||||||
|
"portValue": 8181
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"stat_prefix": "upstream_prepared_query_geo-cache_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"name": "public_listener:0.0.0.0:9999",
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "0.0.0.0",
|
||||||
|
"portValue": 9999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterChains": [
|
||||||
|
{
|
||||||
|
"tlsContext": {
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"tlsCertificates": [
|
||||||
|
{
|
||||||
|
"certificateChain": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"privateKey": {
|
||||||
|
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requireClientCertificate": true
|
||||||
|
},
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"name": "envoy.ext_authz",
|
||||||
|
"config": {
|
||||||
|
"grpc_service": {
|
||||||
|
"envoy_grpc": {
|
||||||
|
"cluster_name": "local_agent"
|
||||||
|
},
|
||||||
|
"initial_metadata": [
|
||||||
|
{
|
||||||
|
"key": "x-consul-token",
|
||||||
|
"value": "my-token"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stat_prefix": "connect_authz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "envoy.tcp_proxy",
|
||||||
|
"config": {
|
||||||
|
"cluster": "local_app",
|
||||||
|
"stat_prefix": "public_listener_tcp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.Listener",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
289
agent/xds/testdata/routes/connect-proxy-with-chain-and-router.golden
vendored
Normal file
289
agent/xds/testdata/routes/connect-proxy-with-chain-and-router.golden
vendored
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration",
|
||||||
|
"name": "db",
|
||||||
|
"virtualHosts": [
|
||||||
|
{
|
||||||
|
"name": "db",
|
||||||
|
"domains": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/prefix"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "prefix.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"path": "/exact"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "exact.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"regex": "/regex"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "regex.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/",
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"name": "x-debug",
|
||||||
|
"presentMatch": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "hdr-present.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/",
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"name": "x-debug",
|
||||||
|
"presentMatch": true,
|
||||||
|
"invertMatch": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "hdr-not-present.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/",
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"name": "x-debug",
|
||||||
|
"exactMatch": "exact"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "hdr-exact.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/",
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"name": "x-debug",
|
||||||
|
"prefixMatch": "prefix"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "hdr-prefix.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/",
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"name": "x-debug",
|
||||||
|
"suffixMatch": "suffix"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "hdr-suffix.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/",
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"name": "x-debug",
|
||||||
|
"regexMatch": "regex"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "hdr-regex.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/",
|
||||||
|
"queryParameters": [
|
||||||
|
{
|
||||||
|
"name": "secretparam",
|
||||||
|
"value": "exact",
|
||||||
|
"regex": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "prm-exact.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/",
|
||||||
|
"queryParameters": [
|
||||||
|
{
|
||||||
|
"name": "secretparam",
|
||||||
|
"value": "regex",
|
||||||
|
"regex": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "prm-regex.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "nil-match.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "empty-match-1.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "empty-match-2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/prefix"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "prefix-rewrite-1.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"prefixRewrite": "/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/prefix"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "prefix-rewrite-2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"prefixRewrite": "/nested/newlocation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/timeout"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "req-timeout.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"timeout": "33s"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/retry-connect"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "retry-connect.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"retryPolicy": {
|
||||||
|
"retryOn": "connect-failure",
|
||||||
|
"numRetries": 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/retry-codes"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "retry-codes.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"retryPolicy": {
|
||||||
|
"retryOn": "retriable-status-codes",
|
||||||
|
"numRetries": 15,
|
||||||
|
"retriableStatusCodes": [
|
||||||
|
401,
|
||||||
|
409,
|
||||||
|
451
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/retry-both"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "retry-both.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"retryPolicy": {
|
||||||
|
"retryOn": ",retriable-status-codes",
|
||||||
|
"retriableStatusCodes": [
|
||||||
|
401,
|
||||||
|
409,
|
||||||
|
451
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/split-3-ways"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"weightedClusters": {
|
||||||
|
"clusters": [
|
||||||
|
{
|
||||||
|
"name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"weight": 9550
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"weight": 400
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"weight": 50
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"totalWeight": 10000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validateClusters": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
46
agent/xds/testdata/routes/connect-proxy-with-chain-and-splitter.golden
vendored
Normal file
46
agent/xds/testdata/routes/connect-proxy-with-chain-and-splitter.golden
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration",
|
||||||
|
"name": "db",
|
||||||
|
"virtualHosts": [
|
||||||
|
{
|
||||||
|
"name": "db",
|
||||||
|
"domains": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"weightedClusters": {
|
||||||
|
"clusters": [
|
||||||
|
{
|
||||||
|
"name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"weight": 9550
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"weight": 400
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"weight": 50
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"totalWeight": 10000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validateClusters": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
30
agent/xds/testdata/routes/connect-proxy-with-chain.golden
vendored
Normal file
30
agent/xds/testdata/routes/connect-proxy-with-chain.golden
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration",
|
||||||
|
"name": "db",
|
||||||
|
"virtualHosts": [
|
||||||
|
{
|
||||||
|
"name": "db",
|
||||||
|
"domains": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validateClusters": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
7
agent/xds/testdata/routes/defaults-no-chain.golden
vendored
Normal file
7
agent/xds/testdata/routes/defaults-no-chain.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
42
agent/xds/testdata/routes/splitter-with-resolver-redirect.golden
vendored
Normal file
42
agent/xds/testdata/routes/splitter-with-resolver-redirect.golden
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration",
|
||||||
|
"name": "db",
|
||||||
|
"virtualHosts": [
|
||||||
|
{
|
||||||
|
"name": "db",
|
||||||
|
"domains": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"prefix": "/"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"weightedClusters": {
|
||||||
|
"clusters": [
|
||||||
|
{
|
||||||
|
"name": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"weight": 5000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"weight": 5000
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"totalWeight": 10000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validateClusters": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user