mirror of https://github.com/status-im/consul.git
OSS Changes for various config entry namespacing bugs (#7226)
This commit is contained in:
parent
6a18f01b42
commit
9e5fd7f925
|
@ -2207,8 +2207,8 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
},
|
},
|
||||||
patch: func(rt *RuntimeConfig) {
|
patch: func(rt *RuntimeConfig) {
|
||||||
rt.Checks = []*structs.CheckDefinition{
|
rt.Checks = []*structs.CheckDefinition{
|
||||||
&structs.CheckDefinition{Name: "a", ScriptArgs: []string{"/bin/true"}, 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, EnterpriseMeta: *structs.DefaultEnterpriseMeta()},
|
&structs.CheckDefinition{Name: "b", ScriptArgs: []string{"/bin/false"}, OutputMaxSize: checks.DefaultBufSize},
|
||||||
}
|
}
|
||||||
rt.DataDir = dataDir
|
rt.DataDir = dataDir
|
||||||
},
|
},
|
||||||
|
@ -2226,7 +2226,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
},
|
},
|
||||||
patch: func(rt *RuntimeConfig) {
|
patch: func(rt *RuntimeConfig) {
|
||||||
rt.Checks = []*structs.CheckDefinition{
|
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
|
rt.DataDir = dataDir
|
||||||
},
|
},
|
||||||
|
@ -2244,7 +2244,7 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
},
|
},
|
||||||
patch: func(rt *RuntimeConfig) {
|
patch: func(rt *RuntimeConfig) {
|
||||||
rt.Checks = []*structs.CheckDefinition{
|
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
|
rt.DataDir = dataDir
|
||||||
},
|
},
|
||||||
|
@ -2271,7 +2271,6 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
Passing: 1,
|
Passing: 1,
|
||||||
Warning: 1,
|
Warning: 1,
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
&structs.ServiceDefinition{
|
&structs.ServiceDefinition{
|
||||||
Name: "b",
|
Name: "b",
|
||||||
|
@ -2281,7 +2280,6 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
Passing: 13,
|
Passing: 13,
|
||||||
Warning: 1,
|
Warning: 1,
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
rt.DataDir = dataDir
|
rt.DataDir = dataDir
|
||||||
|
@ -2399,7 +2397,6 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
Passing: 1,
|
Passing: 1,
|
||||||
Warning: 1,
|
Warning: 1,
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
rt.DataDir = dataDir
|
rt.DataDir = dataDir
|
||||||
|
@ -2540,14 +2537,12 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
Passing: 1,
|
Passing: 1,
|
||||||
Warning: 1,
|
Warning: 1,
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Weights: &structs.Weights{
|
Weights: &structs.Weights{
|
||||||
Passing: 1,
|
Passing: 1,
|
||||||
Warning: 1,
|
Warning: 1,
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2671,14 +2666,12 @@ func TestConfigFlagsAndEdgecases(t *testing.T) {
|
||||||
Passing: 1,
|
Passing: 1,
|
||||||
Warning: 1,
|
Warning: 1,
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Weights: &structs.Weights{
|
Weights: &structs.Weights{
|
||||||
Passing: 1,
|
Passing: 1,
|
||||||
Warning: 1,
|
Warning: 1,
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -5087,7 +5080,6 @@ func TestFullConfig(t *testing.T) {
|
||||||
Timeout: 1813 * time.Second,
|
Timeout: 1813 * time.Second,
|
||||||
TTL: 21743 * time.Second,
|
TTL: 21743 * time.Second,
|
||||||
DeregisterCriticalServiceAfter: 14232 * time.Second,
|
DeregisterCriticalServiceAfter: 14232 * time.Second,
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
&structs.CheckDefinition{
|
&structs.CheckDefinition{
|
||||||
ID: "Cqq95BhP",
|
ID: "Cqq95BhP",
|
||||||
|
@ -5112,7 +5104,6 @@ func TestFullConfig(t *testing.T) {
|
||||||
Timeout: 18506 * time.Second,
|
Timeout: 18506 * time.Second,
|
||||||
TTL: 31006 * time.Second,
|
TTL: 31006 * time.Second,
|
||||||
DeregisterCriticalServiceAfter: 2366 * time.Second,
|
DeregisterCriticalServiceAfter: 2366 * time.Second,
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
&structs.CheckDefinition{
|
&structs.CheckDefinition{
|
||||||
ID: "fZaCAXww",
|
ID: "fZaCAXww",
|
||||||
|
@ -5137,7 +5128,6 @@ func TestFullConfig(t *testing.T) {
|
||||||
Timeout: 5954 * time.Second,
|
Timeout: 5954 * time.Second,
|
||||||
TTL: 30044 * time.Second,
|
TTL: 30044 * time.Second,
|
||||||
DeregisterCriticalServiceAfter: 13209 * time.Second,
|
DeregisterCriticalServiceAfter: 13209 * time.Second,
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CheckUpdateInterval: 16507 * time.Second,
|
CheckUpdateInterval: 16507 * time.Second,
|
||||||
|
@ -5324,10 +5314,8 @@ func TestFullConfig(t *testing.T) {
|
||||||
Passing: 1,
|
Passing: 1,
|
||||||
Warning: 1,
|
Warning: 1,
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "MRHVMZuD",
|
ID: "MRHVMZuD",
|
||||||
|
@ -5388,7 +5376,6 @@ func TestFullConfig(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Connect: &structs.ServiceConnect{},
|
Connect: &structs.ServiceConnect{},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "Kh81CPF6",
|
ID: "Kh81CPF6",
|
||||||
|
@ -5436,7 +5423,6 @@ func TestFullConfig(t *testing.T) {
|
||||||
Passing: 1,
|
Passing: 1,
|
||||||
Warning: 1,
|
Warning: 1,
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "kvVqbwSE",
|
ID: "kvVqbwSE",
|
||||||
|
@ -5452,7 +5438,6 @@ func TestFullConfig(t *testing.T) {
|
||||||
Passing: 1,
|
Passing: 1,
|
||||||
Warning: 1,
|
Warning: 1,
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "dLOXpSCI",
|
ID: "dLOXpSCI",
|
||||||
|
@ -5548,7 +5533,6 @@ func TestFullConfig(t *testing.T) {
|
||||||
DeregisterCriticalServiceAfter: 68787 * time.Second,
|
DeregisterCriticalServiceAfter: 68787 * time.Second,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
SerfAdvertiseAddrLAN: tcpAddr("17.99.29.16:8301"),
|
SerfAdvertiseAddrLAN: tcpAddr("17.99.29.16:8301"),
|
||||||
|
|
|
@ -191,8 +191,7 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
|
||||||
Kind: structs.ServiceSplitter,
|
Kind: structs.ServiceSplitter,
|
||||||
Name: "main",
|
Name: "main",
|
||||||
Splits: []structs.ServiceSplit{
|
Splits: []structs.ServiceSplit{
|
||||||
{Weight: 90, Namespace: "v1"},
|
{Weight: 100},
|
||||||
{Weight: 10, Namespace: "v2"},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return s.EnsureConfigEntry(0, entry, nil)
|
return s.EnsureConfigEntry(0, entry, nil)
|
||||||
|
@ -213,8 +212,7 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
|
||||||
Kind: structs.ServiceSplitter,
|
Kind: structs.ServiceSplitter,
|
||||||
Name: "main",
|
Name: "main",
|
||||||
Splits: []structs.ServiceSplit{
|
Splits: []structs.ServiceSplit{
|
||||||
{Weight: 90, Namespace: "v1"},
|
{Weight: 100},
|
||||||
{Weight: 10, Namespace: "v2"},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return s.EnsureConfigEntry(0, entry, nil)
|
return s.EnsureConfigEntry(0, entry, nil)
|
||||||
|
@ -272,14 +270,26 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
|
||||||
"protocol": "http",
|
"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 {
|
op: func(t *testing.T, s *Store) error {
|
||||||
entry := &structs.ServiceSplitterConfigEntry{
|
entry := &structs.ServiceSplitterConfigEntry{
|
||||||
Kind: structs.ServiceSplitter,
|
Kind: structs.ServiceSplitter,
|
||||||
Name: "main",
|
Name: "main",
|
||||||
Splits: []structs.ServiceSplit{
|
Splits: []structs.ServiceSplit{
|
||||||
{Weight: 90, Namespace: "v1"},
|
{Weight: 90, ServiceSubset: "v1"},
|
||||||
{Weight: 10, Namespace: "v2"},
|
{Weight: 10, ServiceSubset: "v2"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return s.EnsureConfigEntry(0, entry, nil)
|
return s.EnsureConfigEntry(0, entry, nil)
|
||||||
|
@ -292,6 +302,15 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
|
||||||
Name: "main",
|
Name: "main",
|
||||||
Protocol: "tcp",
|
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 {
|
op: func(t *testing.T, s *Store) error {
|
||||||
entry := &structs.ServiceRouterConfigEntry{
|
entry := &structs.ServiceRouterConfigEntry{
|
||||||
|
@ -305,7 +324,7 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Destination: &structs.ServiceRouteDestination{
|
Destination: &structs.ServiceRouteDestination{
|
||||||
Namespace: "other",
|
ServiceSubset: "other",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -316,7 +335,17 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
|
||||||
expectGraphErr: true,
|
expectGraphErr: true,
|
||||||
},
|
},
|
||||||
"router fails without default protocol": tcase{
|
"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 {
|
op: func(t *testing.T, s *Store) error {
|
||||||
entry := &structs.ServiceRouterConfigEntry{
|
entry := &structs.ServiceRouterConfigEntry{
|
||||||
Kind: structs.ServiceRouter,
|
Kind: structs.ServiceRouter,
|
||||||
|
@ -329,7 +358,7 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Destination: &structs.ServiceRouteDestination{
|
Destination: &structs.ServiceRouteDestination{
|
||||||
Namespace: "other",
|
ServiceSubset: "other",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -383,12 +412,24 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
|
||||||
"protocol": "http",
|
"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{
|
&structs.ServiceSplitterConfigEntry{
|
||||||
Kind: structs.ServiceSplitter,
|
Kind: structs.ServiceSplitter,
|
||||||
Name: "main",
|
Name: "main",
|
||||||
Splits: []structs.ServiceSplit{
|
Splits: []structs.ServiceSplit{
|
||||||
{Weight: 90, Namespace: "v1"},
|
{Weight: 90, ServiceSubset: "v1"},
|
||||||
{Weight: 10, Namespace: "v2"},
|
{Weight: 10, ServiceSubset: "v2"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -798,6 +839,7 @@ func TestStore_ConfigEntry_GraphValidation(t *testing.T) {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
s := testStateStore(t)
|
s := testStateStore(t)
|
||||||
for _, entry := range tc.entries {
|
for _, entry := range tc.entries {
|
||||||
|
require.NoError(t, entry.Normalize())
|
||||||
require.NoError(t, s.EnsureConfigEntry(0, entry, nil))
|
require.NoError(t, s.EnsureConfigEntry(0, entry, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,12 @@ import (
|
||||||
"github.com/hashicorp/consul/sdk/testutil"
|
"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
|
// assertLastReqArgs verifies that each request type had the correct source
|
||||||
// parameters (e.g. Datacenter name) and token.
|
// parameters (e.g. Datacenter name) and token.
|
||||||
func assertLastReqArgs(t *testing.T, types *TestCacheTypes, token string, source *structs.QuerySource) {
|
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{
|
dbChainCacheKey := testGenCacheKey(&structs.DiscoveryChainRequest{
|
||||||
Name: "db",
|
Name: "db",
|
||||||
EvaluateInDatacenter: "dc1",
|
EvaluateInDatacenter: "dc1",
|
||||||
EvaluateInNamespace: "",
|
EvaluateInNamespace: "default",
|
||||||
// This is because structs.TestUpstreams uses an opaque config
|
// This is because structs.TestUpstreams uses an opaque config
|
||||||
// to override connect timeouts.
|
// to override connect timeouts.
|
||||||
OverrideConnectTimeout: 1 * time.Second,
|
OverrideConnectTimeout: 1 * time.Second,
|
||||||
|
@ -190,7 +196,7 @@ func TestManager_BasicLifecycle(t *testing.T) {
|
||||||
ProxyID: webProxy.CompoundServiceID(),
|
ProxyID: webProxy.CompoundServiceID(),
|
||||||
Address: webProxy.Address,
|
Address: webProxy.Address,
|
||||||
Port: webProxy.Port,
|
Port: webProxy.Port,
|
||||||
Proxy: webProxy.Proxy,
|
Proxy: mustCopyProxyConfig(t, webProxy),
|
||||||
TaggedAddresses: make(map[string]structs.ServiceAddress),
|
TaggedAddresses: make(map[string]structs.ServiceAddress),
|
||||||
Roots: roots,
|
Roots: roots,
|
||||||
ConnectProxy: configSnapshotConnectProxy{
|
ConnectProxy: configSnapshotConnectProxy{
|
||||||
|
@ -234,7 +240,7 @@ func TestManager_BasicLifecycle(t *testing.T) {
|
||||||
ProxyID: webProxy.CompoundServiceID(),
|
ProxyID: webProxy.CompoundServiceID(),
|
||||||
Address: webProxy.Address,
|
Address: webProxy.Address,
|
||||||
Port: webProxy.Port,
|
Port: webProxy.Port,
|
||||||
Proxy: webProxy.Proxy,
|
Proxy: mustCopyProxyConfig(t, webProxy),
|
||||||
TaggedAddresses: make(map[string]structs.ServiceAddress),
|
TaggedAddresses: make(map[string]structs.ServiceAddress),
|
||||||
Roots: roots,
|
Roots: roots,
|
||||||
ConnectProxy: configSnapshotConnectProxy{
|
ConnectProxy: configSnapshotConnectProxy{
|
||||||
|
|
|
@ -63,6 +63,35 @@ type state struct {
|
||||||
reqCh chan chan *ConfigSnapshot
|
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
|
// 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
|
// NodeService and Token. We copy so that we can use them in a separate
|
||||||
// goroutine later without reasoning about races with the NodeService passed
|
// 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")
|
return nil, errors.New("not a connect-proxy or mesh-gateway")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the config map
|
proxyCfg, err := copyProxyConfig(ns)
|
||||||
proxyCfgRaw, err := copystructure.Copy(ns.Proxy)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
taggedAddresses := make(map[string]structs.ServiceAddress)
|
||||||
for k, v := range ns.TaggedAddresses {
|
for k, v := range ns.TaggedAddresses {
|
||||||
|
@ -232,8 +256,8 @@ func (s *state) initWatchesConnectProxy() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// let namespace inference happen server side
|
// default the namespace to the namespace of this proxy service
|
||||||
currentNamespace := ""
|
currentNamespace := s.proxyID.NamespaceOrDefault()
|
||||||
|
|
||||||
// Watch for updates to service endpoints for all upstreams
|
// Watch for updates to service endpoints for all upstreams
|
||||||
for _, u := range s.proxyCfg.Upstreams {
|
for _, u := range s.proxyCfg.Upstreams {
|
||||||
|
@ -889,10 +913,16 @@ func (s *state) Changed(ns *structs.NodeService, token string) bool {
|
||||||
if ns == nil {
|
if ns == nil {
|
||||||
return true
|
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 ||
|
return ns.Kind != s.kind ||
|
||||||
s.proxyID != ns.CompoundServiceID() ||
|
s.proxyID != ns.CompoundServiceID() ||
|
||||||
s.address != ns.Address ||
|
s.address != ns.Address ||
|
||||||
s.port != ns.Port ||
|
s.port != ns.Port ||
|
||||||
!reflect.DeepEqual(s.proxyCfg, ns.Proxy) ||
|
!reflect.DeepEqual(s.proxyCfg, proxyCfg) ||
|
||||||
s.token != token
|
s.token != token
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ func (cn *testCacheNotifier) getNotifierRequest(t testing.TB, correlationId stri
|
||||||
cn.lock.RLock()
|
cn.lock.RLock()
|
||||||
req, ok := cn.notifiers[correlationId]
|
req, ok := cn.notifiers[correlationId]
|
||||||
cn.lock.RUnlock()
|
cn.lock.RUnlock()
|
||||||
require.True(t, ok)
|
require.True(t, ok, "Correlation ID: %s is missing", correlationId)
|
||||||
return req
|
return req
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,7 +384,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
|
||||||
"discovery-chain:api": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
|
"discovery-chain:api": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
|
||||||
Name: "api",
|
Name: "api",
|
||||||
EvaluateInDatacenter: "dc1",
|
EvaluateInDatacenter: "dc1",
|
||||||
EvaluateInNamespace: "",
|
EvaluateInNamespace: "default",
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
OverrideMeshGateway: structs.MeshGatewayConfig{
|
OverrideMeshGateway: structs.MeshGatewayConfig{
|
||||||
Mode: meshGatewayProxyConfigValue,
|
Mode: meshGatewayProxyConfigValue,
|
||||||
|
@ -393,7 +393,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
|
||||||
"discovery-chain:api-failover-remote?dc=dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
|
"discovery-chain:api-failover-remote?dc=dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
|
||||||
Name: "api-failover-remote",
|
Name: "api-failover-remote",
|
||||||
EvaluateInDatacenter: "dc2",
|
EvaluateInDatacenter: "dc2",
|
||||||
EvaluateInNamespace: "",
|
EvaluateInNamespace: "default",
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
OverrideMeshGateway: structs.MeshGatewayConfig{
|
OverrideMeshGateway: structs.MeshGatewayConfig{
|
||||||
Mode: structs.MeshGatewayModeRemote,
|
Mode: structs.MeshGatewayModeRemote,
|
||||||
|
@ -402,7 +402,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
|
||||||
"discovery-chain:api-failover-local?dc=dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
|
"discovery-chain:api-failover-local?dc=dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
|
||||||
Name: "api-failover-local",
|
Name: "api-failover-local",
|
||||||
EvaluateInDatacenter: "dc2",
|
EvaluateInDatacenter: "dc2",
|
||||||
EvaluateInNamespace: "",
|
EvaluateInNamespace: "default",
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
OverrideMeshGateway: structs.MeshGatewayConfig{
|
OverrideMeshGateway: structs.MeshGatewayConfig{
|
||||||
Mode: structs.MeshGatewayModeLocal,
|
Mode: structs.MeshGatewayModeLocal,
|
||||||
|
@ -411,7 +411,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
|
||||||
"discovery-chain:api-failover-direct?dc=dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
|
"discovery-chain:api-failover-direct?dc=dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
|
||||||
Name: "api-failover-direct",
|
Name: "api-failover-direct",
|
||||||
EvaluateInDatacenter: "dc2",
|
EvaluateInDatacenter: "dc2",
|
||||||
EvaluateInNamespace: "",
|
EvaluateInNamespace: "default",
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
OverrideMeshGateway: structs.MeshGatewayConfig{
|
OverrideMeshGateway: structs.MeshGatewayConfig{
|
||||||
Mode: structs.MeshGatewayModeNone,
|
Mode: structs.MeshGatewayModeNone,
|
||||||
|
@ -420,7 +420,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
|
||||||
"discovery-chain:api-dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
|
"discovery-chain:api-dc2": genVerifyDiscoveryChainWatch(&structs.DiscoveryChainRequest{
|
||||||
Name: "api-dc2",
|
Name: "api-dc2",
|
||||||
EvaluateInDatacenter: "dc1",
|
EvaluateInDatacenter: "dc1",
|
||||||
EvaluateInNamespace: "",
|
EvaluateInNamespace: "default",
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
OverrideMeshGateway: structs.MeshGatewayConfig{
|
OverrideMeshGateway: structs.MeshGatewayConfig{
|
||||||
Mode: meshGatewayProxyConfigValue,
|
Mode: meshGatewayProxyConfigValue,
|
||||||
|
|
|
@ -46,6 +46,7 @@ func TestAgent_sidecarServiceFromNodeService(t *testing.T) {
|
||||||
},
|
},
|
||||||
token: "foo",
|
token: "foo",
|
||||||
wantNS: &structs.NodeService{
|
wantNS: &structs.NodeService{
|
||||||
|
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
||||||
Kind: structs.ServiceKindConnectProxy,
|
Kind: structs.ServiceKindConnectProxy,
|
||||||
ID: "web1-sidecar-proxy",
|
ID: "web1-sidecar-proxy",
|
||||||
Service: "web-sidecar-proxy",
|
Service: "web-sidecar-proxy",
|
||||||
|
@ -105,6 +106,7 @@ func TestAgent_sidecarServiceFromNodeService(t *testing.T) {
|
||||||
},
|
},
|
||||||
token: "foo",
|
token: "foo",
|
||||||
wantNS: &structs.NodeService{
|
wantNS: &structs.NodeService{
|
||||||
|
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
||||||
Kind: structs.ServiceKindConnectProxy,
|
Kind: structs.ServiceKindConnectProxy,
|
||||||
ID: "web1-sidecar-proxy",
|
ID: "web1-sidecar-proxy",
|
||||||
Service: "motorbike1",
|
Service: "motorbike1",
|
||||||
|
@ -182,6 +184,7 @@ func TestAgent_sidecarServiceFromNodeService(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantNS: &structs.NodeService{
|
wantNS: &structs.NodeService{
|
||||||
|
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
||||||
Kind: structs.ServiceKindConnectProxy,
|
Kind: structs.ServiceKindConnectProxy,
|
||||||
ID: "web1-sidecar-proxy",
|
ID: "web1-sidecar-proxy",
|
||||||
Service: "web-sidecar-proxy",
|
Service: "web-sidecar-proxy",
|
||||||
|
@ -271,6 +274,7 @@ func TestAgent_sidecarServiceFromNodeService(t *testing.T) {
|
||||||
},
|
},
|
||||||
token: "foo",
|
token: "foo",
|
||||||
wantNS: &structs.NodeService{
|
wantNS: &structs.NodeService{
|
||||||
|
EnterpriseMeta: *structs.DefaultEnterpriseMeta(),
|
||||||
Kind: structs.ServiceKindConnectProxy,
|
Kind: structs.ServiceKindConnectProxy,
|
||||||
ID: "web1-sidecar-proxy",
|
ID: "web1-sidecar-proxy",
|
||||||
Service: "web-sidecar-proxy",
|
Service: "web-sidecar-proxy",
|
||||||
|
|
|
@ -204,11 +204,15 @@ func (e *ServiceRouterConfigEntry) ListRelatedServices() []ServiceID {
|
||||||
found := make(map[ServiceID]struct{})
|
found := make(map[ServiceID]struct{})
|
||||||
|
|
||||||
// We always inject a default catch-all route to the same service as the router.
|
// 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 {
|
for _, route := range e.Routes {
|
||||||
if route.Destination != nil && route.Destination.Service != "" {
|
if route.Destination != nil {
|
||||||
found[NewServiceID(route.Destination.Service, route.Destination.GetEnterpriseMeta(&e.EnterpriseMeta))] = struct{}{}
|
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 {
|
func (e *ServiceSplitterConfigEntry) ListRelatedServices() []ServiceID {
|
||||||
found := make(map[ServiceID]struct{})
|
found := make(map[ServiceID]struct{})
|
||||||
|
|
||||||
|
svcID := NewServiceID(e.Name, &e.EnterpriseMeta)
|
||||||
for _, split := range e.Splits {
|
for _, split := range e.Splits {
|
||||||
if split.Service != "" {
|
splitID := NewServiceID(defaultIfEmpty(split.Service, e.Name), split.GetEnterpriseMeta(&e.EnterpriseMeta))
|
||||||
found[NewServiceID(split.Service, split.GetEnterpriseMeta(&e.EnterpriseMeta))] = struct{}{}
|
|
||||||
|
if splitID != svcID {
|
||||||
|
found[splitID] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,16 +837,19 @@ func (e *ServiceResolverConfigEntry) GetEnterpriseMeta() *EnterpriseMeta {
|
||||||
func (e *ServiceResolverConfigEntry) ListRelatedServices() []ServiceID {
|
func (e *ServiceResolverConfigEntry) ListRelatedServices() []ServiceID {
|
||||||
found := make(map[ServiceID]struct{})
|
found := make(map[ServiceID]struct{})
|
||||||
|
|
||||||
|
svcID := NewServiceID(e.Name, &e.EnterpriseMeta)
|
||||||
if e.Redirect != nil {
|
if e.Redirect != nil {
|
||||||
if e.Redirect.Service != "" {
|
redirectID := NewServiceID(defaultIfEmpty(e.Redirect.Service, e.Name), e.Redirect.GetEnterpriseMeta(&e.EnterpriseMeta))
|
||||||
found[NewServiceID(e.Redirect.Service, e.Redirect.GetEnterpriseMeta(&e.EnterpriseMeta))] = struct{}{}
|
if redirectID != svcID {
|
||||||
|
found[redirectID] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(e.Failover) > 0 {
|
if len(e.Failover) > 0 {
|
||||||
for _, failover := range e.Failover {
|
for _, failover := range e.Failover {
|
||||||
if failover.Service != "" {
|
failoverID := NewServiceID(defaultIfEmpty(failover.Service, e.Name), failover.GetEnterpriseMeta(&e.EnterpriseMeta))
|
||||||
found[NewServiceID(failover.Service, failover.GetEnterpriseMeta(&e.EnterpriseMeta))] = struct{}{}
|
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 {
|
func canWriteDiscoveryChain(entry discoveryChainConfigEntry, rule acl.Authorizer) bool {
|
||||||
|
entryID := NewServiceID(entry.GetName(), entry.GetEnterpriseMeta())
|
||||||
|
|
||||||
var authzContext acl.AuthorizerContext
|
var authzContext acl.AuthorizerContext
|
||||||
entry.GetEnterpriseMeta().FillAuthzContext(&authzContext)
|
entryID.FillAuthzContext(&authzContext)
|
||||||
|
|
||||||
name := entry.GetName()
|
name := entry.GetName()
|
||||||
|
|
||||||
|
@ -957,7 +969,7 @@ func canWriteDiscoveryChain(entry discoveryChainConfigEntry, rule acl.Authorizer
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, svc := range entry.ListRelatedServices() {
|
for _, svc := range entry.ListRelatedServices() {
|
||||||
if svc.ID == name {
|
if entryID == svc {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1193,3 +1205,10 @@ func validateServiceSubset(subset string) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func defaultIfEmpty(val, defaultVal string) string {
|
||||||
|
if val != "" {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
return defaultVal
|
||||||
|
}
|
||||||
|
|
|
@ -356,13 +356,15 @@ func (k UpstreamKey) String() string {
|
||||||
// upstream in a canonical but human readable way.
|
// upstream in a canonical but human readable way.
|
||||||
func (u *Upstream) Identifier() string {
|
func (u *Upstream) Identifier() string {
|
||||||
name := u.DestinationName
|
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
|
name = u.DestinationNamespace + "/" + u.DestinationName
|
||||||
}
|
}
|
||||||
if u.Datacenter != "" {
|
if u.Datacenter != "" {
|
||||||
name += "?dc=" + u.Datacenter
|
name += "?dc=" + u.Datacenter
|
||||||
}
|
}
|
||||||
typ := u.DestinationType
|
|
||||||
// Service is default type so never prefix it. This is more readable and long
|
// 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
|
// term it is the only type that matters so we can drop the prefix and have
|
||||||
// nicer naming in metrics etc.
|
// nicer naming in metrics etc.
|
||||||
|
|
|
@ -85,7 +85,7 @@ func (c *CompiledDiscoveryChain) IsDefault() bool {
|
||||||
|
|
||||||
target := c.Targets[node.Resolver.Target]
|
target := c.Targets[node.Resolver.Target]
|
||||||
|
|
||||||
return target.Service == c.ServiceName
|
return target.Service == c.ServiceName && target.Namespace == c.Namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -71,6 +71,8 @@ func (s *ServiceDefinition) NodeService() *NodeService {
|
||||||
EnableTagOverride: s.EnableTagOverride,
|
EnableTagOverride: s.EnableTagOverride,
|
||||||
EnterpriseMeta: s.EnterpriseMeta,
|
EnterpriseMeta: s.EnterpriseMeta,
|
||||||
}
|
}
|
||||||
|
ns.EnterpriseMeta.Normalize()
|
||||||
|
|
||||||
if s.Connect != nil {
|
if s.Connect != nil {
|
||||||
ns.Connect = *s.Connect
|
ns.Connect = *s.Connect
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue