Merge pull request #11757 from hashicorp/ap/discovery-chain
This commit is contained in:
commit
cfabdbba21
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
connect: **(Enterprise only)** add support for targeting partitions in discovery chain routes, splits, and redirects.
|
||||
```
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/agent/cache"
|
||||
"github.com/hashicorp/consul/agent/checks"
|
||||
"github.com/hashicorp/consul/agent/consul"
|
||||
|
@ -4085,6 +4086,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
Service: "carrot",
|
||||
ServiceSubset: "kale",
|
||||
Namespace: "leek",
|
||||
Partition: acl.DefaultPartitionName,
|
||||
PrefixRewrite: "/alternate",
|
||||
RequestTimeout: 99 * time.Second,
|
||||
NumRetries: 12345,
|
||||
|
|
|
@ -185,7 +185,7 @@ type customizationMarkers struct {
|
|||
// the String() method on the type itself. It is this way to be more
|
||||
// consistent with other string ids within the discovery chain.
|
||||
func serviceIDString(sid structs.ServiceID) string {
|
||||
return fmt.Sprintf("%s.%s", sid.ID, sid.NamespaceOrDefault())
|
||||
return fmt.Sprintf("%s.%s.%s", sid.ID, sid.NamespaceOrDefault(), sid.PartitionOrDefault())
|
||||
}
|
||||
|
||||
func (m *customizationMarkers) IsZero() bool {
|
||||
|
@ -213,10 +213,10 @@ func (c *compiler) recordServiceProtocol(sid structs.ServiceID) error {
|
|||
if serviceDefault := c.entries.GetService(sid); serviceDefault != nil {
|
||||
return c.recordProtocol(sid, serviceDefault.Protocol)
|
||||
}
|
||||
if c.entries.GlobalProxy != nil {
|
||||
if proxyDefault := c.entries.GetProxyDefaults(sid.PartitionOrDefault()); proxyDefault != nil {
|
||||
var cfg proxyConfig
|
||||
// Ignore errors and fallback on defaults if it does happen.
|
||||
_ = mapstructure.WeakDecode(c.entries.GlobalProxy.Config, &cfg)
|
||||
_ = mapstructure.WeakDecode(proxyDefault.Config, &cfg)
|
||||
if cfg.Protocol != "" {
|
||||
return c.recordProtocol(sid, cfg.Protocol)
|
||||
}
|
||||
|
@ -567,11 +567,12 @@ func (c *compiler) assembleChain() error {
|
|||
dest = &structs.ServiceRouteDestination{
|
||||
Service: c.serviceName,
|
||||
Namespace: router.NamespaceOrDefault(),
|
||||
Partition: router.PartitionOrDefault(),
|
||||
}
|
||||
}
|
||||
svc := defaultIfEmpty(dest.Service, c.serviceName)
|
||||
destNamespace := defaultIfEmpty(dest.Namespace, router.NamespaceOrDefault())
|
||||
destPartition := router.PartitionOrDefault()
|
||||
destPartition := defaultIfEmpty(dest.Partition, router.PartitionOrDefault())
|
||||
|
||||
// Check to see if the destination is eligible for splitting.
|
||||
var (
|
||||
|
@ -602,7 +603,7 @@ func (c *compiler) assembleChain() error {
|
|||
}
|
||||
|
||||
defaultRoute := &structs.DiscoveryRoute{
|
||||
Definition: newDefaultServiceRoute(router.Name, router.NamespaceOrDefault()),
|
||||
Definition: newDefaultServiceRoute(router.Name, router.NamespaceOrDefault(), router.PartitionOrDefault()),
|
||||
NextNode: defaultDestinationNode.MapKey(),
|
||||
}
|
||||
routeNode.Routes = append(routeNode.Routes, defaultRoute)
|
||||
|
@ -613,7 +614,7 @@ func (c *compiler) assembleChain() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func newDefaultServiceRoute(serviceName string, namespace string) *structs.ServiceRoute {
|
||||
func newDefaultServiceRoute(serviceName, namespace, partition string) *structs.ServiceRoute {
|
||||
return &structs.ServiceRoute{
|
||||
Match: &structs.ServiceRouteMatch{
|
||||
HTTP: &structs.ServiceRouteHTTPMatch{
|
||||
|
@ -623,6 +624,7 @@ func newDefaultServiceRoute(serviceName string, namespace string) *structs.Servi
|
|||
Destination: &structs.ServiceRouteDestination{
|
||||
Service: serviceName,
|
||||
Namespace: namespace,
|
||||
Partition: partition,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -836,7 +838,7 @@ RESOLVE_AGAIN:
|
|||
target,
|
||||
redirect.Service,
|
||||
redirect.ServiceSubset,
|
||||
target.Partition,
|
||||
redirect.Partition,
|
||||
redirect.Namespace,
|
||||
redirect.Datacenter,
|
||||
)
|
||||
|
@ -940,9 +942,9 @@ RESOLVE_AGAIN:
|
|||
if serviceDefault := c.entries.GetService(targetID); serviceDefault != nil {
|
||||
target.MeshGateway = serviceDefault.MeshGateway
|
||||
}
|
||||
|
||||
if c.entries.GlobalProxy != nil && target.MeshGateway.Mode == structs.MeshGatewayModeDefault {
|
||||
target.MeshGateway.Mode = c.entries.GlobalProxy.MeshGateway.Mode
|
||||
proxyDefault := c.entries.GetProxyDefaults(targetID.PartitionOrDefault())
|
||||
if proxyDefault != nil && target.MeshGateway.Mode == structs.MeshGatewayModeDefault {
|
||||
target.MeshGateway.Mode = proxyDefault.MeshGateway.Mode
|
||||
}
|
||||
|
||||
if c.overrideMeshGateway.Mode != structs.MeshGatewayModeDefault {
|
||||
|
|
|
@ -158,14 +158,14 @@ func testcase_JustRouterWithDefaults() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "router:main.default",
|
||||
StartNode: "router:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"router:main.default": {
|
||||
"router:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeRouter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Routes: []*structs.DiscoveryRoute{
|
||||
{
|
||||
Definition: newDefaultServiceRoute("main", "default"),
|
||||
Definition: newDefaultServiceRoute("main", "default", "default"),
|
||||
NextNode: "resolver:main.default.default.dc1",
|
||||
},
|
||||
},
|
||||
|
@ -210,11 +210,11 @@ func testcase_JustRouterWithNoDestination() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "router:main.default",
|
||||
StartNode: "router:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"router:main.default": {
|
||||
"router:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeRouter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Routes: []*structs.DiscoveryRoute{
|
||||
{
|
||||
Definition: &structs.ServiceRoute{
|
||||
|
@ -227,7 +227,7 @@ func testcase_JustRouterWithNoDestination() compileTestCase {
|
|||
NextNode: "resolver:main.default.default.dc1",
|
||||
},
|
||||
{
|
||||
Definition: newDefaultServiceRoute("main", "default"),
|
||||
Definition: newDefaultServiceRoute("main", "default", "default"),
|
||||
NextNode: "resolver:main.default.default.dc1",
|
||||
},
|
||||
},
|
||||
|
@ -270,14 +270,14 @@ func testcase_RouterWithDefaults_NoSplit_WithResolver() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "router:main.default",
|
||||
StartNode: "router:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"router:main.default": {
|
||||
"router:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeRouter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Routes: []*structs.DiscoveryRoute{
|
||||
{
|
||||
Definition: newDefaultServiceRoute("main", "default"),
|
||||
Definition: newDefaultServiceRoute("main", "default", "default"),
|
||||
NextNode: "resolver:main.default.default.dc1",
|
||||
},
|
||||
},
|
||||
|
@ -321,21 +321,21 @@ func testcase_RouterWithDefaults_WithNoopSplit_DefaultResolver() compileTestCase
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "router:main.default",
|
||||
StartNode: "router:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"router:main.default": {
|
||||
"router:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeRouter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Routes: []*structs.DiscoveryRoute{
|
||||
{
|
||||
Definition: newDefaultServiceRoute("main", "default"),
|
||||
NextNode: "splitter:main.default",
|
||||
Definition: newDefaultServiceRoute("main", "default", "default"),
|
||||
NextNode: "splitter:main.default.default",
|
||||
},
|
||||
},
|
||||
},
|
||||
"splitter:main.default": {
|
||||
"splitter:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -386,21 +386,21 @@ func testcase_NoopSplit_DefaultResolver_ProtocolFromProxyDefaults() compileTestC
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "router:main.default",
|
||||
StartNode: "router:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"router:main.default": {
|
||||
"router:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeRouter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Routes: []*structs.DiscoveryRoute{
|
||||
{
|
||||
Definition: newDefaultServiceRoute("main", "default"),
|
||||
NextNode: "splitter:main.default",
|
||||
Definition: newDefaultServiceRoute("main", "default", "default"),
|
||||
NextNode: "splitter:main.default.default",
|
||||
},
|
||||
},
|
||||
},
|
||||
"splitter:main.default": {
|
||||
"splitter:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -458,21 +458,21 @@ func testcase_RouterWithDefaults_WithNoopSplit_WithResolver() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "router:main.default",
|
||||
StartNode: "router:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"router:main.default": {
|
||||
"router:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeRouter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Routes: []*structs.DiscoveryRoute{
|
||||
{
|
||||
Definition: newDefaultServiceRoute("main", "default"),
|
||||
NextNode: "splitter:main.default",
|
||||
Definition: newDefaultServiceRoute("main", "default", "default"),
|
||||
NextNode: "splitter:main.default.default",
|
||||
},
|
||||
},
|
||||
},
|
||||
"splitter:main.default": {
|
||||
"splitter:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -542,18 +542,18 @@ func testcase_RouteBypassesSplit() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "router:main.default",
|
||||
StartNode: "router:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"router:main.default": {
|
||||
"router:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeRouter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Routes: []*structs.DiscoveryRoute{
|
||||
{
|
||||
Definition: &router.Routes[0],
|
||||
NextNode: "resolver:bypass.other.default.default.dc1",
|
||||
},
|
||||
{
|
||||
Definition: newDefaultServiceRoute("main", "default"),
|
||||
Definition: newDefaultServiceRoute("main", "default", "default"),
|
||||
NextNode: "resolver:main.default.default.dc1",
|
||||
},
|
||||
},
|
||||
|
@ -605,11 +605,11 @@ func testcase_NoopSplit_DefaultResolver() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "splitter:main.default",
|
||||
StartNode: "splitter:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"splitter:main.default": {
|
||||
"splitter:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -661,11 +661,11 @@ func testcase_NoopSplit_WithResolver() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "splitter:main.default",
|
||||
StartNode: "splitter:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"splitter:main.default": {
|
||||
"splitter:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -724,11 +724,11 @@ func testcase_SubsetSplit() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "splitter:main.default",
|
||||
StartNode: "splitter:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"splitter:main.default": {
|
||||
"splitter:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -801,11 +801,11 @@ func testcase_ServiceSplit() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "splitter:main.default",
|
||||
StartNode: "splitter:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"splitter:main.default": {
|
||||
"splitter:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -898,11 +898,11 @@ func testcase_SplitBypassesSplit() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "splitter:main.default",
|
||||
StartNode: "splitter:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"splitter:main.default": {
|
||||
"splitter:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -1053,13 +1053,14 @@ func testcase_DatacenterRedirect() compileTestCase {
|
|||
|
||||
func testcase_DatacenterRedirect_WithMeshGateways() compileTestCase {
|
||||
entries := newEntries()
|
||||
entries.GlobalProxy = &structs.ProxyConfigEntry{
|
||||
entries.AddProxyDefaults(&structs.ProxyConfigEntry{
|
||||
Kind: structs.ProxyDefaults,
|
||||
Name: structs.ProxyConfigGlobal,
|
||||
MeshGateway: structs.MeshGatewayConfig{
|
||||
Mode: structs.MeshGatewayModeRemote,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
entries.AddResolvers(
|
||||
&structs.ServiceResolverConfigEntry{
|
||||
Kind: "service-resolver",
|
||||
|
@ -1300,13 +1301,15 @@ func testcase_DatacenterFailover() compileTestCase {
|
|||
|
||||
func testcase_DatacenterFailover_WithMeshGateways() compileTestCase {
|
||||
entries := newEntries()
|
||||
entries.GlobalProxy = &structs.ProxyConfigEntry{
|
||||
|
||||
entries.AddProxyDefaults(&structs.ProxyConfigEntry{
|
||||
Kind: structs.ProxyDefaults,
|
||||
Name: structs.ProxyConfigGlobal,
|
||||
MeshGateway: structs.MeshGatewayConfig{
|
||||
Mode: structs.MeshGatewayModeRemote,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
entries.AddResolvers(
|
||||
&structs.ServiceResolverConfigEntry{
|
||||
Kind: "service-resolver",
|
||||
|
@ -1384,11 +1387,11 @@ func testcase_NoopSplit_WithDefaultSubset() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "splitter:main.default",
|
||||
StartNode: "splitter:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"splitter:main.default": {
|
||||
"splitter:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -1446,7 +1449,8 @@ func testcase_DefaultResolver() compileTestCase {
|
|||
|
||||
func testcase_DefaultResolver_WithProxyDefaults() compileTestCase {
|
||||
entries := newEntries()
|
||||
entries.GlobalProxy = &structs.ProxyConfigEntry{
|
||||
|
||||
entries.AddProxyDefaults(&structs.ProxyConfigEntry{
|
||||
Kind: structs.ProxyDefaults,
|
||||
Name: structs.ProxyConfigGlobal,
|
||||
Config: map[string]interface{}{
|
||||
|
@ -1455,7 +1459,7 @@ func testcase_DefaultResolver_WithProxyDefaults() compileTestCase {
|
|||
MeshGateway: structs.MeshGatewayConfig{
|
||||
Mode: structs.MeshGatewayModeRemote,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "grpc",
|
||||
|
@ -1699,11 +1703,11 @@ func testcase_MultiDatacenterCanary() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "splitter:main.default",
|
||||
StartNode: "splitter:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"splitter:main.default": {
|
||||
"splitter:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -1880,11 +1884,11 @@ func testcase_AllBellsAndWhistles() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "router:main.default",
|
||||
StartNode: "router:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"router:main.default": {
|
||||
"router:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeRouter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Routes: []*structs.DiscoveryRoute{
|
||||
{
|
||||
Definition: &router.Routes[0],
|
||||
|
@ -1892,17 +1896,17 @@ func testcase_AllBellsAndWhistles() compileTestCase {
|
|||
},
|
||||
{
|
||||
Definition: &router.Routes[1],
|
||||
NextNode: "splitter:svc-split.default",
|
||||
NextNode: "splitter:svc-split.default.default",
|
||||
},
|
||||
{
|
||||
Definition: newDefaultServiceRoute("main", "default"),
|
||||
Definition: newDefaultServiceRoute("main", "default", "default"),
|
||||
NextNode: "resolver:default-subset.main.default.default.dc1",
|
||||
},
|
||||
},
|
||||
},
|
||||
"splitter:svc-split.default": {
|
||||
"splitter:svc-split.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "svc-split.default",
|
||||
Name: "svc-split.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -2455,11 +2459,11 @@ func testcase_LBSplitterAndResolver() compileTestCase {
|
|||
|
||||
expect := &structs.CompiledDiscoveryChain{
|
||||
Protocol: "http",
|
||||
StartNode: "splitter:main.default",
|
||||
StartNode: "splitter:main.default.default",
|
||||
Nodes: map[string]*structs.DiscoveryGraphNode{
|
||||
"splitter:main.default": {
|
||||
"splitter:main.default.default": {
|
||||
Type: structs.DiscoveryGraphNodeTypeSplitter,
|
||||
Name: "main.default",
|
||||
Name: "main.default.default",
|
||||
Splits: []*structs.DiscoverySplit{
|
||||
{
|
||||
Definition: &structs.ServiceSplit{
|
||||
|
@ -2642,13 +2646,13 @@ func newSimpleRoute(name string, muts ...func(*structs.ServiceRoute)) structs.Se
|
|||
}
|
||||
|
||||
func setGlobalProxyProtocol(entries *structs.DiscoveryChainConfigEntries, protocol string) {
|
||||
entries.GlobalProxy = &structs.ProxyConfigEntry{
|
||||
entries.AddProxyDefaults(&structs.ProxyConfigEntry{
|
||||
Kind: structs.ProxyDefaults,
|
||||
Name: structs.ProxyConfigGlobal,
|
||||
Config: map[string]interface{}{
|
||||
"protocol": protocol,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func setServiceProtocol(entries *structs.DiscoveryChainConfigEntries, name, protocol string) {
|
||||
|
|
|
@ -880,24 +880,21 @@ func readDiscoveryChainConfigEntriesTxn(
|
|||
|
||||
sid := structs.NewServiceID(serviceName, entMeta)
|
||||
|
||||
// Grab the proxy defaults if they exist.
|
||||
idx, proxy, err := getProxyConfigEntryTxn(tx, ws, structs.ProxyConfigGlobal, overrides, entMeta)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
} else if proxy != nil {
|
||||
res.GlobalProxy = proxy
|
||||
}
|
||||
|
||||
// At every step we'll need service defaults.
|
||||
// At every step we'll need service and proxy defaults.
|
||||
todoDefaults[sid] = struct{}{}
|
||||
|
||||
var maxIdx uint64
|
||||
|
||||
// first fetch the router, of which we only collect 1 per chain eval
|
||||
_, router, err := getRouterConfigEntryTxn(tx, ws, serviceName, overrides, entMeta)
|
||||
idx, router, err := getRouterConfigEntryTxn(tx, ws, serviceName, overrides, entMeta)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
} else if router != nil {
|
||||
res.Routers[sid] = router
|
||||
}
|
||||
if idx > maxIdx {
|
||||
maxIdx = idx
|
||||
}
|
||||
|
||||
if router != nil {
|
||||
for _, svc := range router.ListRelatedServices() {
|
||||
|
@ -922,10 +919,13 @@ func readDiscoveryChainConfigEntriesTxn(
|
|||
// Yes, even for splitters.
|
||||
todoDefaults[splitID] = struct{}{}
|
||||
|
||||
_, splitter, err := getSplitterConfigEntryTxn(tx, ws, splitID.ID, overrides, &splitID.EnterpriseMeta)
|
||||
idx, splitter, err := getSplitterConfigEntryTxn(tx, ws, splitID.ID, overrides, &splitID.EnterpriseMeta)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if idx > maxIdx {
|
||||
maxIdx = idx
|
||||
}
|
||||
|
||||
if splitter == nil {
|
||||
res.Splitters[splitID] = nil
|
||||
|
@ -959,10 +959,13 @@ func readDiscoveryChainConfigEntriesTxn(
|
|||
// And resolvers, too.
|
||||
todoDefaults[resolverID] = struct{}{}
|
||||
|
||||
_, resolver, err := getResolverConfigEntryTxn(tx, ws, resolverID.ID, overrides, &resolverID.EnterpriseMeta)
|
||||
idx, resolver, err := getResolverConfigEntryTxn(tx, ws, resolverID.ID, overrides, &resolverID.EnterpriseMeta)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if idx > maxIdx {
|
||||
maxIdx = idx
|
||||
}
|
||||
|
||||
if resolver == nil {
|
||||
res.Resolvers[resolverID] = nil
|
||||
|
@ -987,16 +990,31 @@ func readDiscoveryChainConfigEntriesTxn(
|
|||
continue // already fetched
|
||||
}
|
||||
|
||||
_, entry, err := getServiceConfigEntryTxn(tx, ws, svcID.ID, overrides, &svcID.EnterpriseMeta)
|
||||
if _, ok := res.ProxyDefaults[svcID.PartitionOrDefault()]; !ok {
|
||||
idx, proxy, err := getProxyConfigEntryTxn(tx, ws, structs.ProxyConfigGlobal, overrides, &svcID.EnterpriseMeta)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if idx > maxIdx {
|
||||
maxIdx = idx
|
||||
}
|
||||
if proxy != nil {
|
||||
res.ProxyDefaults[proxy.PartitionOrDefault()] = proxy
|
||||
}
|
||||
}
|
||||
|
||||
idx, entry, err := getServiceConfigEntryTxn(tx, ws, svcID.ID, overrides, &svcID.EnterpriseMeta)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if idx > maxIdx {
|
||||
maxIdx = idx
|
||||
}
|
||||
|
||||
if entry == nil {
|
||||
res.Services[svcID] = nil
|
||||
continue
|
||||
}
|
||||
|
||||
res.Services[svcID] = entry
|
||||
}
|
||||
|
||||
|
@ -1022,7 +1040,7 @@ func readDiscoveryChainConfigEntriesTxn(
|
|||
}
|
||||
}
|
||||
|
||||
return idx, res, nil
|
||||
return maxIdx, res, nil
|
||||
}
|
||||
|
||||
// anyKey returns any key from the provided map if any exist. Useful for using
|
||||
|
|
|
@ -1347,6 +1347,13 @@ func entrySetToKindNames(entrySet *structs.DiscoveryChainConfigEntries) []Config
|
|||
&entry.EnterpriseMeta,
|
||||
))
|
||||
}
|
||||
for _, entry := range entrySet.ProxyDefaults {
|
||||
out = append(out, NewConfigEntryKindName(
|
||||
entry.Kind,
|
||||
entry.Name,
|
||||
&entry.EnterpriseMeta,
|
||||
))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,9 @@ func (e *ServiceRouterConfigEntry) Normalize() error {
|
|||
if route.Destination != nil && route.Destination.Namespace == "" {
|
||||
route.Destination.Namespace = e.EnterpriseMeta.NamespaceOrEmpty()
|
||||
}
|
||||
if route.Destination != nil && route.Destination.Partition == "" {
|
||||
route.Destination.Partition = e.EnterpriseMeta.PartitionOrEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -381,6 +384,13 @@ type ServiceRouteDestination struct {
|
|||
// splitting.
|
||||
Namespace string `json:",omitempty"`
|
||||
|
||||
// Partition is the partition to resolve the service from instead of the
|
||||
// current partition. If empty the current partition is assumed.
|
||||
//
|
||||
// If this field is specified then this route is ineligible for further
|
||||
// splitting.
|
||||
Partition string `json:",omitempty"`
|
||||
|
||||
// PrefixRewrite allows for the proxied request to have its matching path
|
||||
// prefix modified before being sent to the destination. Described more
|
||||
// below in the envoy implementation section.
|
||||
|
@ -557,8 +567,8 @@ func (e *ServiceSplitterConfigEntry) Validate() error {
|
|||
}
|
||||
if _, ok := found[splitKey]; ok {
|
||||
return fmt.Errorf(
|
||||
"split destination occurs more than once: service=%q, subset=%q, namespace=%q",
|
||||
splitKey.Service, splitKey.ServiceSubset, splitKey.Namespace,
|
||||
"split destination occurs more than once: service=%q, subset=%q, namespace=%q, partition=%q",
|
||||
splitKey.Service, splitKey.ServiceSubset, splitKey.Namespace, splitKey.Partition,
|
||||
)
|
||||
}
|
||||
found[splitKey] = struct{}{}
|
||||
|
@ -665,7 +675,12 @@ type ServiceSplit struct {
|
|||
// splitting.
|
||||
Namespace string `json:",omitempty"`
|
||||
|
||||
// NOTE: Partition is not represented here by design. Do not add it.
|
||||
// Partition is the partition to resolve the service from instead of the
|
||||
// current partition. If empty the current partition is assumed (optional).
|
||||
//
|
||||
// If this field is specified then this route is ineligible for further
|
||||
// splitting.
|
||||
Partition string `json:",omitempty"`
|
||||
|
||||
// NOTE: Any configuration added to Splits that needs to be passed to the
|
||||
// proxy needs special handling MergeParent below.
|
||||
|
@ -930,9 +945,13 @@ func (e *ServiceResolverConfigEntry) Validate() error {
|
|||
}
|
||||
|
||||
if e.Redirect != nil {
|
||||
if e.PartitionOrEmpty() != acl.DefaultPartitionName && e.Redirect.Datacenter != "" {
|
||||
return fmt.Errorf("Cross datacenters redirect is not allowed for non default partition")
|
||||
if !e.InDefaultPartition() && e.Redirect.Datacenter != "" {
|
||||
return fmt.Errorf("Cross-datacenter redirect is only supported in the default partition")
|
||||
}
|
||||
if PartitionOrDefault(e.Redirect.Partition) != e.PartitionOrDefault() && e.Redirect.Datacenter != "" {
|
||||
return fmt.Errorf("Cross-datacenter and cross-partition redirect is not supported")
|
||||
}
|
||||
|
||||
r := e.Redirect
|
||||
|
||||
if len(e.Failover) > 0 {
|
||||
|
@ -941,7 +960,7 @@ func (e *ServiceResolverConfigEntry) Validate() error {
|
|||
|
||||
// TODO(rb): prevent subsets and default subsets from being defined?
|
||||
|
||||
if r.Service == "" && r.ServiceSubset == "" && r.Namespace == "" && r.Datacenter == "" {
|
||||
if r.Service == "" && r.ServiceSubset == "" && r.Namespace == "" && r.Partition == "" && r.Datacenter == "" {
|
||||
return fmt.Errorf("Redirect is empty")
|
||||
}
|
||||
|
||||
|
@ -952,6 +971,9 @@ func (e *ServiceResolverConfigEntry) Validate() error {
|
|||
if r.Namespace != "" {
|
||||
return fmt.Errorf("Redirect.Namespace defined without Redirect.Service")
|
||||
}
|
||||
if r.Partition != "" {
|
||||
return fmt.Errorf("Redirect.Partition defined without Redirect.Service")
|
||||
}
|
||||
} else if r.Service == e.Name {
|
||||
if r.ServiceSubset != "" && !isSubset(r.ServiceSubset) {
|
||||
return fmt.Errorf("Redirect.ServiceSubset %q is not a valid subset of %q", r.ServiceSubset, r.Service)
|
||||
|
@ -962,9 +984,10 @@ func (e *ServiceResolverConfigEntry) Validate() error {
|
|||
if len(e.Failover) > 0 {
|
||||
|
||||
for subset, f := range e.Failover {
|
||||
if e.PartitionOrEmpty() != acl.DefaultPartitionName && len(f.Datacenters) != 0 {
|
||||
return fmt.Errorf("Cross datacenters failover is not allowed for non default partition")
|
||||
if !e.InDefaultPartition() && len(f.Datacenters) != 0 {
|
||||
return fmt.Errorf("Cross-datacenter failover is only supported in the default partition")
|
||||
}
|
||||
|
||||
if subset != "*" && !isSubset(subset) {
|
||||
return fmt.Errorf("Bad Failover[%q]: not a valid subset", subset)
|
||||
}
|
||||
|
@ -1141,6 +1164,10 @@ type ServiceResolverRedirect struct {
|
|||
// current one (optional).
|
||||
Namespace string `json:",omitempty"`
|
||||
|
||||
// Partition is the partition to resolve the service from instead of the
|
||||
// current one (optional).
|
||||
Partition string `json:",omitempty"`
|
||||
|
||||
// Datacenter is the datacenter to resolve the service from instead of the
|
||||
// current one (optional).
|
||||
Datacenter string `json:",omitempty"`
|
||||
|
@ -1309,19 +1336,20 @@ func canWriteDiscoveryChain(entry discoveryChainConfigEntry, authz acl.Authorize
|
|||
// DiscoveryChainConfigEntries wraps just the raw cross-referenced config
|
||||
// entries. None of these are defaulted.
|
||||
type DiscoveryChainConfigEntries struct {
|
||||
Routers map[ServiceID]*ServiceRouterConfigEntry
|
||||
Splitters map[ServiceID]*ServiceSplitterConfigEntry
|
||||
Resolvers map[ServiceID]*ServiceResolverConfigEntry
|
||||
Services map[ServiceID]*ServiceConfigEntry
|
||||
GlobalProxy *ProxyConfigEntry
|
||||
Routers map[ServiceID]*ServiceRouterConfigEntry
|
||||
Splitters map[ServiceID]*ServiceSplitterConfigEntry
|
||||
Resolvers map[ServiceID]*ServiceResolverConfigEntry
|
||||
Services map[ServiceID]*ServiceConfigEntry
|
||||
ProxyDefaults map[string]*ProxyConfigEntry
|
||||
}
|
||||
|
||||
func NewDiscoveryChainConfigEntries() *DiscoveryChainConfigEntries {
|
||||
return &DiscoveryChainConfigEntries{
|
||||
Routers: make(map[ServiceID]*ServiceRouterConfigEntry),
|
||||
Splitters: make(map[ServiceID]*ServiceSplitterConfigEntry),
|
||||
Resolvers: make(map[ServiceID]*ServiceResolverConfigEntry),
|
||||
Services: make(map[ServiceID]*ServiceConfigEntry),
|
||||
Routers: make(map[ServiceID]*ServiceRouterConfigEntry),
|
||||
Splitters: make(map[ServiceID]*ServiceSplitterConfigEntry),
|
||||
Resolvers: make(map[ServiceID]*ServiceResolverConfigEntry),
|
||||
Services: make(map[ServiceID]*ServiceConfigEntry),
|
||||
ProxyDefaults: make(map[string]*ProxyConfigEntry),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1353,6 +1381,13 @@ func (e *DiscoveryChainConfigEntries) GetService(sid ServiceID) *ServiceConfigEn
|
|||
return nil
|
||||
}
|
||||
|
||||
func (e *DiscoveryChainConfigEntries) GetProxyDefaults(partition string) *ProxyConfigEntry {
|
||||
if e.ProxyDefaults != nil {
|
||||
return e.ProxyDefaults[partition]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddRouters adds router configs. Convenience function for testing.
|
||||
func (e *DiscoveryChainConfigEntries) AddRouters(entries ...*ServiceRouterConfigEntry) {
|
||||
if e.Routers == nil {
|
||||
|
@ -1393,6 +1428,16 @@ func (e *DiscoveryChainConfigEntries) AddServices(entries ...*ServiceConfigEntry
|
|||
}
|
||||
}
|
||||
|
||||
// AddProxyDefaults adds proxy-defaults configs. Convenience function for testing.
|
||||
func (e *DiscoveryChainConfigEntries) AddProxyDefaults(entries ...*ProxyConfigEntry) {
|
||||
if e.ProxyDefaults == nil {
|
||||
e.ProxyDefaults = make(map[string]*ProxyConfigEntry)
|
||||
}
|
||||
for _, entry := range entries {
|
||||
e.ProxyDefaults[entry.PartitionOrDefault()] = entry
|
||||
}
|
||||
}
|
||||
|
||||
// AddEntries adds generic configs. Convenience function for testing. Panics on
|
||||
// operator error.
|
||||
func (e *DiscoveryChainConfigEntries) AddEntries(entries ...ConfigEntry) {
|
||||
|
@ -1410,7 +1455,7 @@ func (e *DiscoveryChainConfigEntries) AddEntries(entries ...ConfigEntry) {
|
|||
if entry.GetName() != ProxyConfigGlobal {
|
||||
panic("the only supported proxy-defaults name is '" + ProxyConfigGlobal + "'")
|
||||
}
|
||||
e.GlobalProxy = entry.(*ProxyConfigEntry)
|
||||
e.AddProxyDefaults(entry.(*ProxyConfigEntry))
|
||||
default:
|
||||
panic("unhandled config entry kind: " + entry.GetKind())
|
||||
}
|
||||
|
@ -1418,7 +1463,7 @@ func (e *DiscoveryChainConfigEntries) AddEntries(entries ...ConfigEntry) {
|
|||
}
|
||||
|
||||
func (e *DiscoveryChainConfigEntries) IsEmpty() bool {
|
||||
return e.IsChainEmpty() && len(e.Services) == 0 && e.GlobalProxy == nil
|
||||
return e.IsChainEmpty() && len(e.Services) == 0 && len(e.ProxyDefaults) == 0
|
||||
}
|
||||
|
||||
func (e *DiscoveryChainConfigEntries) IsChainEmpty() bool {
|
||||
|
|
|
@ -63,10 +63,10 @@ type ServiceRouteHTTPMatchQueryParam struct {
|
|||
}
|
||||
|
||||
type ServiceRouteDestination struct {
|
||||
Service string `json:",omitempty"`
|
||||
ServiceSubset string `json:",omitempty" alias:"service_subset"`
|
||||
// Referencing other partitions is not supported.
|
||||
Service string `json:",omitempty"`
|
||||
ServiceSubset string `json:",omitempty" alias:"service_subset"`
|
||||
Namespace string `json:",omitempty"`
|
||||
Partition string `json:",omitempty"`
|
||||
PrefixRewrite string `json:",omitempty" alias:"prefix_rewrite"`
|
||||
RequestTimeout time.Duration `json:",omitempty" alias:"request_timeout"`
|
||||
NumRetries uint32 `json:",omitempty" alias:"num_retries"`
|
||||
|
@ -134,11 +134,11 @@ func (e *ServiceSplitterConfigEntry) GetCreateIndex() uint64 { return e.Crea
|
|||
func (e *ServiceSplitterConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex }
|
||||
|
||||
type ServiceSplit struct {
|
||||
Weight float32
|
||||
Service string `json:",omitempty"`
|
||||
ServiceSubset string `json:",omitempty" alias:"service_subset"`
|
||||
// Referencing other partitions is not supported.
|
||||
Weight float32
|
||||
Service string `json:",omitempty"`
|
||||
ServiceSubset string `json:",omitempty" alias:"service_subset"`
|
||||
Namespace string `json:",omitempty"`
|
||||
Partition string `json:",omitempty"`
|
||||
RequestHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"request_headers"`
|
||||
ResponseHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"response_headers"`
|
||||
}
|
||||
|
@ -216,9 +216,9 @@ type ServiceResolverSubset struct {
|
|||
type ServiceResolverRedirect struct {
|
||||
Service string `json:",omitempty"`
|
||||
ServiceSubset string `json:",omitempty" alias:"service_subset"`
|
||||
// Referencing other partitions is not supported.
|
||||
Namespace string `json:",omitempty"`
|
||||
Datacenter string `json:",omitempty"`
|
||||
Namespace string `json:",omitempty"`
|
||||
Partition string `json:",omitempty"`
|
||||
Datacenter string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ServiceResolverFailover struct {
|
||||
|
|
|
@ -242,6 +242,7 @@ func TestAPI_ConfigEntry_DiscoveryChain(t *testing.T) {
|
|||
Service: "test-failover",
|
||||
ServiceSubset: "v2",
|
||||
Namespace: defaultNamespace,
|
||||
Partition: defaultPartition,
|
||||
PrefixRewrite: "/",
|
||||
RequestTimeout: 5 * time.Second,
|
||||
NumRetries: 5,
|
||||
|
|
|
@ -791,6 +791,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
snake: `
|
||||
kind = "service-router"
|
||||
name = "main"
|
||||
partition = "pepper"
|
||||
meta {
|
||||
"foo" = "bar"
|
||||
"gir" = "zim"
|
||||
|
@ -830,12 +831,13 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
}
|
||||
}
|
||||
destination {
|
||||
service = "carrot"
|
||||
service_subset = "kale"
|
||||
namespace = "leek"
|
||||
prefix_rewrite = "/alternate"
|
||||
request_timeout = "99s"
|
||||
num_retries = 12345
|
||||
service = "carrot"
|
||||
service_subset = "kale"
|
||||
namespace = "leek"
|
||||
partition = "chard"
|
||||
prefix_rewrite = "/alternate"
|
||||
request_timeout = "99s"
|
||||
num_retries = 12345
|
||||
retry_on_connect_failure = true
|
||||
retry_on_status_codes = [401, 209]
|
||||
}
|
||||
|
@ -874,6 +876,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
camel: `
|
||||
Kind = "service-router"
|
||||
Name = "main"
|
||||
Partition = "pepper"
|
||||
Meta {
|
||||
"foo" = "bar"
|
||||
"gir" = "zim"
|
||||
|
@ -916,6 +919,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
Service = "carrot"
|
||||
ServiceSubset = "kale"
|
||||
Namespace = "leek"
|
||||
Partition = "chard"
|
||||
PrefixRewrite = "/alternate"
|
||||
RequestTimeout = "99s"
|
||||
NumRetries = 12345
|
||||
|
@ -958,6 +962,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
{
|
||||
"kind": "service-router",
|
||||
"name": "main",
|
||||
"partition": "pepper",
|
||||
"meta" : {
|
||||
"foo": "bar",
|
||||
"gir": "zim"
|
||||
|
@ -1000,6 +1005,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
"service": "carrot",
|
||||
"service_subset": "kale",
|
||||
"namespace": "leek",
|
||||
"partition": "chard",
|
||||
"prefix_rewrite": "/alternate",
|
||||
"request_timeout": "99s",
|
||||
"num_retries": 12345,
|
||||
|
@ -1049,6 +1055,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
{
|
||||
"Kind": "service-router",
|
||||
"Name": "main",
|
||||
"Partition": "pepper",
|
||||
"Meta" : {
|
||||
"foo": "bar",
|
||||
"gir": "zim"
|
||||
|
@ -1091,6 +1098,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
"Service": "carrot",
|
||||
"ServiceSubset": "kale",
|
||||
"Namespace": "leek",
|
||||
"Partition": "chard",
|
||||
"PrefixRewrite": "/alternate",
|
||||
"RequestTimeout": "99s",
|
||||
"NumRetries": 12345,
|
||||
|
@ -1137,8 +1145,9 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
}
|
||||
`,
|
||||
expect: &api.ServiceRouterConfigEntry{
|
||||
Kind: "service-router",
|
||||
Name: "main",
|
||||
Kind: "service-router",
|
||||
Name: "main",
|
||||
Partition: "pepper",
|
||||
Meta: map[string]string{
|
||||
"foo": "bar",
|
||||
"gir": "zim",
|
||||
|
@ -1181,6 +1190,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
Service: "carrot",
|
||||
ServiceSubset: "kale",
|
||||
Namespace: "leek",
|
||||
Partition: "chard",
|
||||
PrefixRewrite: "/alternate",
|
||||
RequestTimeout: 99 * time.Second,
|
||||
NumRetries: 12345,
|
||||
|
@ -1225,6 +1235,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
snake: `
|
||||
kind = "service-splitter"
|
||||
name = "main"
|
||||
partition = "east"
|
||||
meta {
|
||||
"foo" = "bar"
|
||||
"gir" = "zim"
|
||||
|
@ -1242,12 +1253,14 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
weight = 0.9
|
||||
service = "other"
|
||||
namespace = "alt"
|
||||
partition = "west"
|
||||
},
|
||||
]
|
||||
`,
|
||||
camel: `
|
||||
Kind = "service-splitter"
|
||||
Name = "main"
|
||||
Partition = "east"
|
||||
Meta {
|
||||
"foo" = "bar"
|
||||
"gir" = "zim"
|
||||
|
@ -1265,6 +1278,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
Weight = 0.9
|
||||
Service = "other"
|
||||
Namespace = "alt"
|
||||
Partition = "west"
|
||||
},
|
||||
]
|
||||
`,
|
||||
|
@ -1272,6 +1286,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
{
|
||||
"kind": "service-splitter",
|
||||
"name": "main",
|
||||
"partition": "east",
|
||||
"meta" : {
|
||||
"foo": "bar",
|
||||
"gir": "zim"
|
||||
|
@ -1288,7 +1303,8 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
{
|
||||
"weight": 0.9,
|
||||
"service": "other",
|
||||
"namespace": "alt"
|
||||
"namespace": "alt",
|
||||
"partition": "west"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1297,6 +1313,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
{
|
||||
"Kind": "service-splitter",
|
||||
"Name": "main",
|
||||
"Partition": "east",
|
||||
"Meta" : {
|
||||
"foo": "bar",
|
||||
"gir": "zim"
|
||||
|
@ -1313,14 +1330,16 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
{
|
||||
"Weight": 0.9,
|
||||
"Service": "other",
|
||||
"Namespace": "alt"
|
||||
"Namespace": "alt",
|
||||
"Partition": "west"
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
expect: &api.ServiceSplitterConfigEntry{
|
||||
Kind: api.ServiceSplitter,
|
||||
Name: "main",
|
||||
Kind: api.ServiceSplitter,
|
||||
Name: "main",
|
||||
Partition: "east",
|
||||
Meta: map[string]string{
|
||||
"foo": "bar",
|
||||
"gir": "zim",
|
||||
|
@ -1338,6 +1357,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
Weight: 0.9,
|
||||
Service: "other",
|
||||
Namespace: "alt",
|
||||
Partition: "west",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1512,20 +1532,24 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
snake: `
|
||||
kind = "service-resolver"
|
||||
name = "main"
|
||||
partition = "east"
|
||||
redirect {
|
||||
service = "other"
|
||||
service_subset = "backup"
|
||||
namespace = "alt"
|
||||
partition = "west"
|
||||
datacenter = "dc9"
|
||||
}
|
||||
`,
|
||||
camel: `
|
||||
Kind = "service-resolver"
|
||||
Name = "main"
|
||||
Partition = "east"
|
||||
Redirect {
|
||||
Service = "other"
|
||||
ServiceSubset = "backup"
|
||||
Namespace = "alt"
|
||||
Partition = "west"
|
||||
Datacenter = "dc9"
|
||||
}
|
||||
`,
|
||||
|
@ -1533,10 +1557,12 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
{
|
||||
"kind": "service-resolver",
|
||||
"name": "main",
|
||||
"partition": "east",
|
||||
"redirect": {
|
||||
"service": "other",
|
||||
"service_subset": "backup",
|
||||
"namespace": "alt",
|
||||
"partition": "west",
|
||||
"datacenter": "dc9"
|
||||
}
|
||||
}
|
||||
|
@ -1545,21 +1571,25 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
{
|
||||
"Kind": "service-resolver",
|
||||
"Name": "main",
|
||||
"Partition": "east",
|
||||
"Redirect": {
|
||||
"Service": "other",
|
||||
"ServiceSubset": "backup",
|
||||
"Namespace": "alt",
|
||||
"Partition": "west",
|
||||
"Datacenter": "dc9"
|
||||
}
|
||||
}
|
||||
`,
|
||||
expect: &api.ServiceResolverConfigEntry{
|
||||
Kind: "service-resolver",
|
||||
Name: "main",
|
||||
Kind: "service-resolver",
|
||||
Name: "main",
|
||||
Partition: "east",
|
||||
Redirect: &api.ServiceResolverRedirect{
|
||||
Service: "other",
|
||||
ServiceSubset: "backup",
|
||||
Namespace: "alt",
|
||||
Partition: "west",
|
||||
Datacenter: "dc9",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -513,6 +513,14 @@ function run_container_s2-secondary {
|
|||
common_run_container_service s2-secondary secondary 8181 8179
|
||||
}
|
||||
|
||||
function run_container_s2-ap1 {
|
||||
common_run_container_service s2 ap1 8480 8479
|
||||
}
|
||||
|
||||
function run_container_s3-ap1 {
|
||||
common_run_container_service s3 ap1 8580 8579
|
||||
}
|
||||
|
||||
function common_run_container_sidecar_proxy {
|
||||
local service="$1"
|
||||
local CLUSTER="$2"
|
||||
|
@ -581,6 +589,14 @@ function run_container_s2-sidecar-proxy-secondary {
|
|||
common_run_container_sidecar_proxy s2 secondary
|
||||
}
|
||||
|
||||
function run_container_s2-ap1-sidecar-proxy {
|
||||
common_run_container_sidecar_proxy s2 ap1
|
||||
}
|
||||
|
||||
function run_container_s3-ap1-sidecar-proxy {
|
||||
common_run_container_sidecar_proxy s3 ap1
|
||||
}
|
||||
|
||||
function common_run_container_gateway {
|
||||
local name="$1"
|
||||
local DC="$2"
|
||||
|
|
Loading…
Reference in New Issue