OSS Changes for various config entry namespacing bugs (#7226)

This commit is contained in:
Matt Keeler 2020-02-06 10:52:25 -05:00 committed by GitHub
parent 6a18f01b42
commit 9e5fd7f925
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 159 additions and 70 deletions

View File

@ -2207,8 +2207,8 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
},
patch: func(rt *RuntimeConfig) {
rt.Checks = []*structs.CheckDefinition{
&structs.CheckDefinition{Name: "a", ScriptArgs: []string{"/bin/true"}, OutputMaxSize: checks.DefaultBufSize, EnterpriseMeta: *structs.DefaultEnterpriseMeta()},
&structs.CheckDefinition{Name: "b", ScriptArgs: []string{"/bin/false"}, OutputMaxSize: checks.DefaultBufSize, EnterpriseMeta: *structs.DefaultEnterpriseMeta()},
&structs.CheckDefinition{Name: "a", ScriptArgs: []string{"/bin/true"}, OutputMaxSize: checks.DefaultBufSize},
&structs.CheckDefinition{Name: "b", ScriptArgs: []string{"/bin/false"}, OutputMaxSize: checks.DefaultBufSize},
}
rt.DataDir = dataDir
},
@ -2226,7 +2226,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
},
patch: func(rt *RuntimeConfig) {
rt.Checks = []*structs.CheckDefinition{
&structs.CheckDefinition{Name: "a", GRPC: "localhost:12345/foo", GRPCUseTLS: true, OutputMaxSize: checks.DefaultBufSize, EnterpriseMeta: *structs.DefaultEnterpriseMeta()},
&structs.CheckDefinition{Name: "a", GRPC: "localhost:12345/foo", GRPCUseTLS: true, OutputMaxSize: checks.DefaultBufSize},
}
rt.DataDir = dataDir
},
@ -2244,7 +2244,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
},
patch: func(rt *RuntimeConfig) {
rt.Checks = []*structs.CheckDefinition{
&structs.CheckDefinition{Name: "a", AliasService: "foo", OutputMaxSize: checks.DefaultBufSize, EnterpriseMeta: *structs.DefaultEnterpriseMeta()},
&structs.CheckDefinition{Name: "a", AliasService: "foo", OutputMaxSize: checks.DefaultBufSize},
}
rt.DataDir = dataDir
},
@ -2271,7 +2271,6 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
Passing: 1,
Warning: 1,
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
&structs.ServiceDefinition{
Name: "b",
@ -2281,7 +2280,6 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
Passing: 13,
Warning: 1,
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
}
rt.DataDir = dataDir
@ -2399,7 +2397,6 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
Passing: 1,
Warning: 1,
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
}
rt.DataDir = dataDir
@ -2540,14 +2537,12 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
Passing: 1,
Warning: 1,
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
},
Weights: &structs.Weights{
Passing: 1,
Warning: 1,
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
}
},
@ -2671,14 +2666,12 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
Passing: 1,
Warning: 1,
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
},
Weights: &structs.Weights{
Passing: 1,
Warning: 1,
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
}
},
@ -5087,7 +5080,6 @@ func TestFullConfig(t *testing.T) {
Timeout: 1813 * time.Second,
TTL: 21743 * time.Second,
DeregisterCriticalServiceAfter: 14232 * time.Second,
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
&structs.CheckDefinition{
ID: "Cqq95BhP",
@ -5112,7 +5104,6 @@ func TestFullConfig(t *testing.T) {
Timeout: 18506 * time.Second,
TTL: 31006 * time.Second,
DeregisterCriticalServiceAfter: 2366 * time.Second,
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
&structs.CheckDefinition{
ID: "fZaCAXww",
@ -5137,7 +5128,6 @@ func TestFullConfig(t *testing.T) {
Timeout: 5954 * time.Second,
TTL: 30044 * time.Second,
DeregisterCriticalServiceAfter: 13209 * time.Second,
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
},
CheckUpdateInterval: 16507 * time.Second,
@ -5324,10 +5314,8 @@ func TestFullConfig(t *testing.T) {
Passing: 1,
Warning: 1,
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
{
ID: "MRHVMZuD",
@ -5387,8 +5375,7 @@ func TestFullConfig(t *testing.T) {
DeregisterCriticalServiceAfter: 68482 * time.Second,
},
},
Connect: &structs.ServiceConnect{},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
Connect: &structs.ServiceConnect{},
},
{
ID: "Kh81CPF6",
@ -5436,7 +5423,6 @@ func TestFullConfig(t *testing.T) {
Passing: 1,
Warning: 1,
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
{
ID: "kvVqbwSE",
@ -5452,7 +5438,6 @@ func TestFullConfig(t *testing.T) {
Passing: 1,
Warning: 1,
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
{
ID: "dLOXpSCI",
@ -5548,7 +5533,6 @@ func TestFullConfig(t *testing.T) {
DeregisterCriticalServiceAfter: 68787 * time.Second,
},
},
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
},
},
SerfAdvertiseAddrLAN: tcpAddr("17.99.29.16:8301"),

View File

@ -191,8 +191,7 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
Kind: structs.ServiceSplitter,
Name: "main",
Splits: []structs.ServiceSplit{
{Weight: 90, Namespace: "v1"},
{Weight: 10, Namespace: "v2"},
{Weight: 100},
},
}
return s.EnsureConfigEntry(0, entry, nil)
@ -213,8 +212,7 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
Kind: structs.ServiceSplitter,
Name: "main",
Splits: []structs.ServiceSplit{
{Weight: 90, Namespace: "v1"},
{Weight: 10, Namespace: "v2"},
{Weight: 100},
},
}
return s.EnsureConfigEntry(0, entry, nil)
@ -272,14 +270,26 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
"protocol": "http",
},
},
&structs.ServiceResolverConfigEntry{
Kind: structs.ServiceResolver,
Name: "main",
Subsets: map[string]structs.ServiceResolverSubset{
"v1": structs.ServiceResolverSubset{
Filter: "Service.Meta.version == v1",
},
"v2": structs.ServiceResolverSubset{
Filter: "Service.Meta.version == v2",
},
},
},
},
op: func(t *testing.T, s *Store) error {
entry := &structs.ServiceSplitterConfigEntry{
Kind: structs.ServiceSplitter,
Name: "main",
Splits: []structs.ServiceSplit{
{Weight: 90, Namespace: "v1"},
{Weight: 10, Namespace: "v2"},
{Weight: 90, ServiceSubset: "v1"},
{Weight: 10, ServiceSubset: "v2"},
},
}
return s.EnsureConfigEntry(0, entry, nil)
@ -292,6 +302,15 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
Name: "main",
Protocol: "tcp",
},
&structs.ServiceResolverConfigEntry{
Kind: structs.ServiceResolver,
Name: "main",
Subsets: map[string]structs.ServiceResolverSubset{
"other": structs.ServiceResolverSubset{
Filter: "Service.Meta.version == other",
},
},
},
},
op: func(t *testing.T, s *Store) error {
entry := &structs.ServiceRouterConfigEntry{
@ -305,7 +324,7 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
},
},
Destination: &structs.ServiceRouteDestination{
Namespace: "other",
ServiceSubset: "other",
},
},
},
@ -316,7 +335,17 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
expectGraphErr: true,
},
"router fails without default protocol": tcase{
entries: []structs.ConfigEntry{},
entries: []structs.ConfigEntry{
&structs.ServiceResolverConfigEntry{
Kind: structs.ServiceResolver,
Name: "main",
Subsets: map[string]structs.ServiceResolverSubset{
"other": structs.ServiceResolverSubset{
Filter: "Service.Meta.version == other",
},
},
},
},
op: func(t *testing.T, s *Store) error {
entry := &structs.ServiceRouterConfigEntry{
Kind: structs.ServiceRouter,
@ -329,7 +358,7 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
},
},
Destination: &structs.ServiceRouteDestination{
Namespace: "other",
ServiceSubset: "other",
},
},
},
@ -383,12 +412,24 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
"protocol": "http",
},
},
&structs.ServiceResolverConfigEntry{
Kind: structs.ServiceResolver,
Name: "main",
Subsets: map[string]structs.ServiceResolverSubset{
"v1": structs.ServiceResolverSubset{
Filter: "Service.Meta.version == v1",
},
"v2": structs.ServiceResolverSubset{
Filter: "Service.Meta.version == v2",
},
},
},
&structs.ServiceSplitterConfigEntry{
Kind: structs.ServiceSplitter,
Name: "main",
Splits: []structs.ServiceSplit{
{Weight: 90, Namespace: "v1"},
{Weight: 10, Namespace: "v2"},
{Weight: 90, ServiceSubset: "v1"},
{Weight: 10, ServiceSubset: "v2"},
},
},
},
@ -798,6 +839,7 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
t.Run(name, func(t *testing.T) {
s := testStateStore(t)
for _, entry := range tc.entries {
require.NoError(t, entry.Normalize())
require.NoError(t, s.EnsureConfigEntry(0, entry, nil))
}

View File

@ -18,6 +18,12 @@ import (
"github.com/hashicorp/consul/sdk/testutil"
)
func mustCopyProxyConfig(t *testing.T, ns *structs.NodeService) structs.ConnectProxyConfig {
cfg, err := copyProxyConfig(ns)
require.NoError(t, err)
return cfg
}
// assertLastReqArgs verifies that each request type had the correct source
// parameters (e.g. Datacenter name) and token.
func assertLastReqArgs(t *testing.T, types *TestCacheTypes, token string, source *structs.QuerySource) {
@ -137,7 +143,7 @@ func TestManager_BasicLifecycle(t *testing.T) {
dbChainCacheKey := testGenCacheKey(&structs.DiscoveryChainRequest{
Name: "db",
EvaluateInDatacenter: "dc1",
EvaluateInNamespace: "",
EvaluateInNamespace: "default",
// This is because structs.TestUpstreams uses an opaque config
// to override connect timeouts.
OverrideConnectTimeout: 1 * time.Second,
@ -190,7 +196,7 @@ func TestManager_BasicLifecycle(t *testing.T) {
ProxyID: webProxy.CompoundServiceID(),
Address: webProxy.Address,
Port: webProxy.Port,
Proxy: webProxy.Proxy,
Proxy: mustCopyProxyConfig(t, webProxy),
TaggedAddresses: make(map[string]structs.ServiceAddress),
Roots: roots,
ConnectProxy: configSnapshotConnectProxy{
@ -234,7 +240,7 @@ func TestManager_BasicLifecycle(t *testing.T) {
ProxyID: webProxy.CompoundServiceID(),
Address: webProxy.Address,
Port: webProxy.Port,
Proxy: webProxy.Proxy,
Proxy: mustCopyProxyConfig(t, webProxy),
TaggedAddresses: make(map[string]structs.ServiceAddress),
Roots: roots,
ConnectProxy: configSnapshotConnectProxy{

View File

@ -63,6 +63,35 @@ type state struct {
reqCh chan chan *ConfigSnapshot
}
func copyProxyConfig(ns *structs.NodeService) (structs.ConnectProxyConfig, error) {
if ns == nil {
return structs.ConnectProxyConfig{}, nil
}
// Copy the config map
proxyCfgRaw, err := copystructure.Copy(ns.Proxy)
if err != nil {
return structs.ConnectProxyConfig{}, err
}
proxyCfg, ok := proxyCfgRaw.(structs.ConnectProxyConfig)
if !ok {
return structs.ConnectProxyConfig{}, errors.New("failed to copy proxy config")
}
// we can safely modify these since we just copied them
for idx, _ := range proxyCfg.Upstreams {
us := &proxyCfg.Upstreams[idx]
if us.DestinationType != structs.UpstreamDestTypePreparedQuery && us.DestinationNamespace == "" {
// default the upstreams target namespace to the namespace of the proxy
// doing this here prevents needing much more complex logic a bunch of other
// places and makes tracking these upstreams simpler as we can dedup them
// with the maps tracking upstream ids being watched.
proxyCfg.Upstreams[idx].DestinationNamespace = ns.EnterpriseMeta.NamespaceOrDefault()
}
}
return proxyCfg, nil
}
// newState populates the state struct by copying relevant fields from the
// NodeService and Token. We copy so that we can use them in a separate
// goroutine later without reasoning about races with the NodeService passed
@ -75,15 +104,10 @@ func newState(ns *structs.NodeService, token string) (*state, error) {
return nil, errors.New("not a connect-proxy or mesh-gateway")
}
// Copy the config map
proxyCfgRaw, err := copystructure.Copy(ns.Proxy)
proxyCfg, err := copyProxyConfig(ns)
if err != nil {
return nil, err
}
proxyCfg, ok := proxyCfgRaw.(structs.ConnectProxyConfig)
if !ok {
return nil, errors.New("failed to copy proxy config")
}
taggedAddresses := make(map[string]structs.ServiceAddress)
for k, v := range ns.TaggedAddresses {
@ -232,8 +256,8 @@ func (s *state) initWatchesConnectProxy() error {
return err
}
// let namespace inference happen server side
currentNamespace := ""
// default the namespace to the namespace of this proxy service
currentNamespace := s.proxyID.NamespaceOrDefault()
// Watch for updates to service endpoints for all upstreams
for _, u := range s.proxyCfg.Upstreams {
@ -889,10 +913,16 @@ func (s *state) Changed(ns *structs.NodeService, token string) bool {
if ns == nil {
return true
}
proxyCfg, err := copyProxyConfig(ns)
if err != nil {
s.logger.Warn("Failed to parse proxy config and will treat the new service as unchanged")
}
return ns.Kind != s.kind ||
s.proxyID != ns.CompoundServiceID() ||
s.address != ns.Address ||
s.port != ns.Port ||
!reflect.DeepEqual(s.proxyCfg, ns.Proxy) ||
!reflect.DeepEqual(s.proxyCfg, proxyCfg) ||
s.token != token
}

View File

@ -147,7 +147,7 @@ func (cn *testCacheNotifier) getNotifierRequest(t testing.TB, correlationId stri
cn.lock.RLock()
req, ok := cn.notifiers[correlationId]
cn.lock.RUnlock()
require.True(t, ok)
require.True(t, ok, "Correlation ID: %s is missing", correlationId)
return req
}
@ -384,7 +384,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
"discovery-chain:api": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
Name: "api",
EvaluateInDatacenter: "dc1",
EvaluateInNamespace: "",
EvaluateInNamespace: "default",
Datacenter: "dc1",
OverrideMeshGateway: structs.MeshGatewayConfig{
Mode: meshGatewayProxyConfigValue,
@ -393,7 +393,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
"discovery-chain:api-failover-remote?dc=dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
Name: "api-failover-remote",
EvaluateInDatacenter: "dc2",
EvaluateInNamespace: "",
EvaluateInNamespace: "default",
Datacenter: "dc1",
OverrideMeshGateway: structs.MeshGatewayConfig{
Mode: structs.MeshGatewayModeRemote,
@ -402,7 +402,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
"discovery-chain:api-failover-local?dc=dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
Name: "api-failover-local",
EvaluateInDatacenter: "dc2",
EvaluateInNamespace: "",
EvaluateInNamespace: "default",
Datacenter: "dc1",
OverrideMeshGateway: structs.MeshGatewayConfig{
Mode: structs.MeshGatewayModeLocal,
@ -411,7 +411,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
"discovery-chain:api-failover-direct?dc=dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
Name: "api-failover-direct",
EvaluateInDatacenter: "dc2",
EvaluateInNamespace: "",
EvaluateInNamespace: "default",
Datacenter: "dc1",
OverrideMeshGateway: structs.MeshGatewayConfig{
Mode: structs.MeshGatewayModeNone,
@ -420,7 +420,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
"discovery-chain:api-dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
Name: "api-dc2",
EvaluateInDatacenter: "dc1",
EvaluateInNamespace: "",
EvaluateInNamespace: "default",
Datacenter: "dc1",
OverrideMeshGateway: structs.MeshGatewayConfig{
Mode: meshGatewayProxyConfigValue,

View File

@ -46,6 +46,7 @@ func TestAgent_sidecarServiceFromNodeService(t *testing.T) {
},
token: "foo",
wantNS: &structs.NodeService{
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
Kind: structs.ServiceKindConnectProxy,
ID: "web1-sidecar-proxy",
Service: "web-sidecar-proxy",
@ -105,12 +106,13 @@ func TestAgent_sidecarServiceFromNodeService(t *testing.T) {
},
token: "foo",
wantNS: &structs.NodeService{
Kind: structs.ServiceKindConnectProxy,
ID: "web1-sidecar-proxy",
Service: "motorbike1",
Port: 3333,
Tags: []string{"foo", "bar"},
Address: "127.127.127.127",
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
Kind: structs.ServiceKindConnectProxy,
ID: "web1-sidecar-proxy",
Service: "motorbike1",
Port: 3333,
Tags: []string{"foo", "bar"},
Address: "127.127.127.127",
Meta: map[string]string{
"foo": "bar",
},
@ -182,6 +184,7 @@ func TestAgent_sidecarServiceFromNodeService(t *testing.T) {
},
},
wantNS: &structs.NodeService{
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
Kind: structs.ServiceKindConnectProxy,
ID: "web1-sidecar-proxy",
Service: "web-sidecar-proxy",
@ -271,6 +274,7 @@ func TestAgent_sidecarServiceFromNodeService(t *testing.T) {
},
token: "foo",
wantNS: &structs.NodeService{
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
Kind: structs.ServiceKindConnectProxy,
ID: "web1-sidecar-proxy",
Service: "web-sidecar-proxy",

View File

@ -204,11 +204,15 @@ func (e *ServiceRouterConfigEntry) ListRelatedServices() []ServiceID {
found := make(map[ServiceID]struct{})
// We always inject a default catch-all route to the same service as the router.
found[NewServiceID(e.Name, &e.EnterpriseMeta)] = struct{}{}
svcID := NewServiceID(e.Name, &e.EnterpriseMeta)
found[svcID] = struct{}{}
for _, route := range e.Routes {
if route.Destination != nil && route.Destination.Service != "" {
found[NewServiceID(route.Destination.Service, route.Destination.GetEnterpriseMeta(&e.EnterpriseMeta))] = struct{}{}
if route.Destination != nil {
destID := NewServiceID(defaultIfEmpty(route.Destination.Service, e.Name), route.Destination.GetEnterpriseMeta(&e.EnterpriseMeta))
if destID != svcID {
found[destID] = struct{}{}
}
}
}
@ -527,9 +531,12 @@ func (e *ServiceSplitterConfigEntry) GetEnterpriseMeta() *EnterpriseMeta {
func (e *ServiceSplitterConfigEntry) ListRelatedServices() []ServiceID {
found := make(map[ServiceID]struct{})
svcID := NewServiceID(e.Name, &e.EnterpriseMeta)
for _, split := range e.Splits {
if split.Service != "" {
found[NewServiceID(split.Service, split.GetEnterpriseMeta(&e.EnterpriseMeta))] = struct{}{}
splitID := NewServiceID(defaultIfEmpty(split.Service, e.Name), split.GetEnterpriseMeta(&e.EnterpriseMeta))
if splitID != svcID {
found[splitID] = struct{}{}
}
}
@ -830,16 +837,19 @@ func (e *ServiceResolverConfigEntry) GetEnterpriseMeta() *EnterpriseMeta {
func (e *ServiceResolverConfigEntry) ListRelatedServices() []ServiceID {
found := make(map[ServiceID]struct{})
svcID := NewServiceID(e.Name, &e.EnterpriseMeta)
if e.Redirect != nil {
if e.Redirect.Service != "" {
found[NewServiceID(e.Redirect.Service, e.Redirect.GetEnterpriseMeta(&e.EnterpriseMeta))] = struct{}{}
redirectID := NewServiceID(defaultIfEmpty(e.Redirect.Service, e.Name), e.Redirect.GetEnterpriseMeta(&e.EnterpriseMeta))
if redirectID != svcID {
found[redirectID] = struct{}{}
}
}
if len(e.Failover) > 0 {
for _, failover := range e.Failover {
if failover.Service != "" {
found[NewServiceID(failover.Service, failover.GetEnterpriseMeta(&e.EnterpriseMeta))] = struct{}{}
failoverID := NewServiceID(defaultIfEmpty(failover.Service, e.Name), failover.GetEnterpriseMeta(&e.EnterpriseMeta))
if failoverID != svcID {
found[failoverID] = struct{}{}
}
}
}
@ -947,8 +957,10 @@ func canReadDiscoveryChain(entry discoveryChainConfigEntry, authz acl.Authorizer
}
func canWriteDiscoveryChain(entry discoveryChainConfigEntry, rule acl.Authorizer) bool {
entryID := NewServiceID(entry.GetName(), entry.GetEnterpriseMeta())
var authzContext acl.AuthorizerContext
entry.GetEnterpriseMeta().FillAuthzContext(&authzContext)
entryID.FillAuthzContext(&authzContext)
name := entry.GetName()
@ -957,7 +969,7 @@ func canWriteDiscoveryChain(entry discoveryChainConfigEntry, rule acl.Authorizer
}
for _, svc := range entry.ListRelatedServices() {
if svc.ID == name {
if entryID == svc {
continue
}
@ -1193,3 +1205,10 @@ func validateServiceSubset(subset string) error {
}
return nil
}
func defaultIfEmpty(val, defaultVal string) string {
if val != "" {
return val
}
return defaultVal
}

View File

@ -356,13 +356,15 @@ func (k UpstreamKey) String() string {
// upstream in a canonical but human readable way.
func (u *Upstream) Identifier() string {
name := u.DestinationName
if u.DestinationNamespace != "" && u.DestinationNamespace != "default" {
typ := u.DestinationType
if typ != UpstreamDestTypePreparedQuery && u.DestinationNamespace != "" && u.DestinationNamespace != "default" {
name = u.DestinationNamespace + "/" + u.DestinationName
}
if u.Datacenter != "" {
name += "?dc=" + u.Datacenter
}
typ := u.DestinationType
// Service is default type so never prefix it. This is more readable and long
// term it is the only type that matters so we can drop the prefix and have
// nicer naming in metrics etc.

View File

@ -85,7 +85,7 @@ func (c *CompiledDiscoveryChain) IsDefault() bool {
target := c.Targets[node.Resolver.Target]
return target.Service == c.ServiceName
return target.Service == c.ServiceName && target.Namespace == c.Namespace
}
const (

View File

@ -71,6 +71,8 @@ func (s *ServiceDefinition) NodeService() *NodeService {
EnableTagOverride: s.EnableTagOverride,
EnterpriseMeta: s.EnterpriseMeta,
}
ns.EnterpriseMeta.Normalize()
if s.Connect != nil {
ns.Connect = *s.Connect
}