Remove deprecated service-defaults upstream behavior. (#16957)

Prior to this change, peer services would be targeted by service-default
overrides as long as the new `peer` field was not found in the config entry.
This commit removes that deprecated backwards-compatibility behavior. Now
it is necessary to specify the `peer` field in order for upstream overrides
to apply to a peer upstream.
This commit is contained in:
Derek Menteer 2023-04-11 10:20:33 -05:00 committed by GitHub
parent 317240fca7
commit 1bcaeabfc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 64 additions and 259 deletions

5
.changelog/16957.txt Normal file
View File

@ -0,0 +1,5 @@
```release-note:breaking-change
peering: Removed deprecated backward-compatibility behavior.
Upstream overrides in service-defaults will now only apply to peer upstreams when the `peer` field is provided.
Visit the 1.16.x [upgrade instructions](https://developer.hashicorp.com/consul/docs/upgrading/upgrade-specific) for more information.
```

View File

@ -157,44 +157,20 @@ func MergeServiceConfig(defaults *structs.ServiceConfigResponse, service *struct
// remoteUpstreams contains synthetic Upstreams generated from central config (service-defaults.UpstreamConfigs). // remoteUpstreams contains synthetic Upstreams generated from central config (service-defaults.UpstreamConfigs).
remoteUpstreams := make(map[structs.PeeredServiceName]structs.Upstream) remoteUpstreams := make(map[structs.PeeredServiceName]structs.Upstream)
if len(defaults.UpstreamIDConfigs) > 0 { for _, us := range defaults.UpstreamConfigs {
// Handle legacy upstreams. This should be removed in Consul 1.16. parsed, err := structs.ParseUpstreamConfigNoDefaults(us.Config)
for _, us := range defaults.UpstreamIDConfigs { if err != nil {
parsed, err := structs.ParseUpstreamConfigNoDefaults(us.Config) return nil, fmt.Errorf("failed to parse upstream config map for %s: %v", us.Upstream.String(), err)
if err != nil {
return nil, fmt.Errorf("failed to parse upstream config map for %s: %v", us.Upstream.String(), err)
}
psn := structs.PeeredServiceName{
Peer: "",
ServiceName: structs.NewServiceName(us.Upstream.ID, &us.Upstream.EnterpriseMeta),
}
remoteUpstreams[psn] = structs.Upstream{
DestinationNamespace: us.Upstream.NamespaceOrDefault(),
DestinationPartition: us.Upstream.PartitionOrDefault(),
DestinationName: us.Upstream.ID,
DestinationPeer: "",
Config: us.Config,
MeshGateway: parsed.MeshGateway,
CentrallyConfigured: true,
}
} }
} else {
for _, us := range defaults.UpstreamConfigs {
parsed, err := structs.ParseUpstreamConfigNoDefaults(us.Config)
if err != nil {
return nil, fmt.Errorf("failed to parse upstream config map for %s: %v", us.Upstream.String(), err)
}
remoteUpstreams[us.Upstream] = structs.Upstream{ remoteUpstreams[us.Upstream] = structs.Upstream{
DestinationNamespace: us.Upstream.ServiceName.NamespaceOrDefault(), DestinationNamespace: us.Upstream.ServiceName.NamespaceOrDefault(),
DestinationPartition: us.Upstream.ServiceName.PartitionOrDefault(), DestinationPartition: us.Upstream.ServiceName.PartitionOrDefault(),
DestinationName: us.Upstream.ServiceName.Name, DestinationName: us.Upstream.ServiceName.Name,
DestinationPeer: us.Upstream.Peer, DestinationPeer: us.Upstream.Peer,
Config: us.Config, Config: us.Config,
MeshGateway: parsed.MeshGateway, MeshGateway: parsed.MeshGateway,
CentrallyConfigured: true, CentrallyConfigured: true,
}
} }
} }

View File

@ -133,7 +133,7 @@ func ComputeResolvedServiceConfig(
seenUpstreams := map[structs.PeeredServiceName]struct{}{} seenUpstreams := map[structs.PeeredServiceName]struct{}{}
var ( var (
noUpstreamArgs = len(args.UpstreamServiceNames) == 0 && len(args.UpstreamIDs) == 0 noUpstreamArgs = len(args.UpstreamServiceNames) == 0
// Check the args and the resolved value. If it was exclusively set via a config entry, then args.Mode // Check the args and the resolved value. If it was exclusively set via a config entry, then args.Mode
// will never be transparent because the service config request does not use the resolved value. // will never be transparent because the service config request does not use the resolved value.
@ -153,15 +153,6 @@ func ComputeResolvedServiceConfig(
seenUpstreams[psn] = struct{}{} seenUpstreams[psn] = struct{}{}
} }
} }
// For 1.14, service-defaults overrides would apply to peer upstreams incorrectly
// because the config merging logic was oblivious to the concept of a peer.
// We replicate this behavior on legacy calls for backwards-compatibility.
for _, sid := range args.UpstreamIDs {
psn := structs.PeeredServiceName{
ServiceName: structs.NewServiceName(sid.ID, &sid.EnterpriseMeta),
}
seenUpstreams[psn] = struct{}{}
}
// Then store upstreams inferred from service-defaults and mapify the overrides. // Then store upstreams inferred from service-defaults and mapify the overrides.
var ( var (
@ -206,22 +197,6 @@ func ComputeResolvedServiceConfig(
resolvedConfigs[wildcard] = wildcardUpstreamDefaults resolvedConfigs[wildcard] = wildcardUpstreamDefaults
} }
// For Consul 1.14.x, service-defaults would apply to either local or peer services as long
// as the `name` matched. We introduce `legacyUpstreams` as a compatibility mode for:
// 1. old agents, that are using the deprecated UpstreamIDs api
// 2. Migrations to 1.15 that do not specify the "peer" field. The behavior should remain the same
// until the config entries are updates.
//
// This should be remove in Consul 1.16
var hasPeerUpstream bool
for _, override := range upstreamOverrides {
if override.Peer != "" {
hasPeerUpstream = true
break
}
}
legacyUpstreams := len(args.UpstreamIDs) > 0 || !hasPeerUpstream
for upstream := range seenUpstreams { for upstream := range seenUpstreams {
resolvedCfg := make(map[string]interface{}) resolvedCfg := make(map[string]interface{})
@ -273,16 +248,6 @@ func ComputeResolvedServiceConfig(
} }
// Merge in Overrides for the upstream (step 5). // Merge in Overrides for the upstream (step 5).
// In the legacy case, overrides only match on name. We remove the peer and try to match against
// our map of overrides. We still want to check the full PSN in the map in case there is a specific
// override that applies to peers.
if legacyUpstreams {
peerlessUpstream := upstream
peerlessUpstream.Peer = ""
if upstreamOverrides[peerlessUpstream] != nil {
upstreamOverrides[peerlessUpstream].MergeInto(resolvedCfg)
}
}
if upstreamOverrides[upstream] != nil { if upstreamOverrides[upstream] != nil {
upstreamOverrides[upstream].MergeInto(resolvedCfg) upstreamOverrides[upstream].MergeInto(resolvedCfg)
} }
@ -297,21 +262,11 @@ func ComputeResolvedServiceConfig(
return &thisReply, nil return &thisReply, nil
} }
if len(args.UpstreamIDs) > 0 { thisReply.UpstreamConfigs = make(structs.OpaqueUpstreamConfigs, 0, len(resolvedConfigs))
// DEPRECATED: Remove these legacy upstreams in Consul v1.16
thisReply.UpstreamIDConfigs = make(structs.OpaqueUpstreamConfigsDeprecated, 0, len(resolvedConfigs))
for us, conf := range resolvedConfigs { for us, conf := range resolvedConfigs {
thisReply.UpstreamIDConfigs = append(thisReply.UpstreamIDConfigs, thisReply.UpstreamConfigs = append(thisReply.UpstreamConfigs,
structs.OpaqueUpstreamConfigDeprecated{Upstream: us.ServiceName.ToServiceID(), Config: conf}) structs.OpaqueUpstreamConfig{Upstream: us, Config: conf})
}
} else {
thisReply.UpstreamConfigs = make(structs.OpaqueUpstreamConfigs, 0, len(resolvedConfigs))
for us, conf := range resolvedConfigs {
thisReply.UpstreamConfigs = append(thisReply.UpstreamConfigs,
structs.OpaqueUpstreamConfig{Upstream: us, Config: conf})
}
} }
return &thisReply, nil return &thisReply, nil

View File

@ -1344,66 +1344,6 @@ func TestConfigEntry_ResolveServiceConfig_Upstreams(t *testing.T) {
}, },
}, },
}, },
{
name: "upstream config entries from UpstreamIDs and service-defaults",
entries: []structs.ConfigEntry{
&structs.ProxyConfigEntry{
Kind: structs.ProxyDefaults,
Name: structs.ProxyConfigGlobal,
Config: map[string]interface{}{
"protocol": "grpc",
},
},
&structs.ServiceConfigEntry{
Kind: structs.ServiceDefaults,
Name: "api",
UpstreamConfig: &structs.UpstreamConfiguration{
Overrides: []*structs.UpstreamConfig{
{
Name: "mysql",
Peer: "peer1", // This should be ignored for legacy UpstreamIDs mode
Protocol: "http",
},
},
},
},
},
request: structs.ServiceConfigRequest{
Name: "api",
Datacenter: "dc1",
UpstreamIDs: []structs.ServiceID{
structs.NewServiceID("cache", nil),
},
},
expect: structs.ServiceConfigResponse{
ProxyConfig: map[string]interface{}{
"protocol": "grpc",
},
UpstreamIDConfigs: structs.OpaqueUpstreamConfigsDeprecated{
{
Upstream: structs.NewServiceID(
structs.WildcardSpecifier,
acl.DefaultEnterpriseMeta().WithWildcardNamespace(),
),
Config: map[string]interface{}{
"protocol": "grpc",
},
},
{
Upstream: structs.NewServiceID("cache", nil),
Config: map[string]interface{}{
"protocol": "grpc",
},
},
{
Upstream: structs.NewServiceID("mysql", nil),
Config: map[string]interface{}{
"protocol": "http",
},
},
},
},
},
{ {
name: "upstream config entries from UpstreamServiceNames and service-defaults", name: "upstream config entries from UpstreamServiceNames and service-defaults",
entries: []structs.ConfigEntry{ entries: []structs.ConfigEntry{
@ -1764,9 +1704,6 @@ func TestConfigEntry_ResolveServiceConfig_Upstreams(t *testing.T) {
sort.SliceStable(out.UpstreamConfigs, func(i, j int) bool { sort.SliceStable(out.UpstreamConfigs, func(i, j int) bool {
return out.UpstreamConfigs[i].Upstream.String() < out.UpstreamConfigs[j].Upstream.String() return out.UpstreamConfigs[i].Upstream.String() < out.UpstreamConfigs[j].Upstream.String()
}) })
sort.SliceStable(out.UpstreamIDConfigs, func(i, j int) bool {
return out.UpstreamIDConfigs[i].Upstream.String() < out.UpstreamIDConfigs[j].Upstream.String()
})
require.Equal(t, tc.expect, out) require.Equal(t, tc.expect, out)
}) })
@ -2037,9 +1974,9 @@ func TestConfigEntry_ResolveServiceConfig_Upstreams_Blocking(t *testing.T) {
&structs.ServiceConfigRequest{ &structs.ServiceConfigRequest{
Name: "foo", Name: "foo",
Datacenter: "dc1", Datacenter: "dc1",
UpstreamIDs: []structs.ServiceID{ UpstreamServiceNames: []structs.PeeredServiceName{
structs.NewServiceID("bar", nil), {ServiceName: structs.NewServiceName("bar", nil)},
structs.NewServiceID("other", nil), {ServiceName: structs.NewServiceName("other", nil)},
}, },
QueryOptions: structs.QueryOptions{ QueryOptions: structs.QueryOptions{
MinQueryIndex: index, MinQueryIndex: index,
@ -2073,9 +2010,9 @@ func TestConfigEntry_ResolveServiceConfig_Upstreams_Blocking(t *testing.T) {
&structs.ServiceConfigRequest{ &structs.ServiceConfigRequest{
Name: "foo", Name: "foo",
Datacenter: "dc1", Datacenter: "dc1",
UpstreamIDs: []structs.ServiceID{ UpstreamServiceNames: []structs.PeeredServiceName{
structs.NewServiceID("bar", nil), {ServiceName: structs.NewServiceName("bar", nil)},
structs.NewServiceID("other", nil), {ServiceName: structs.NewServiceName("other", nil)},
}, },
}, },
&out, &out,
@ -2116,9 +2053,9 @@ func TestConfigEntry_ResolveServiceConfig_Upstreams_Blocking(t *testing.T) {
&structs.ServiceConfigRequest{ &structs.ServiceConfigRequest{
Name: "foo", Name: "foo",
Datacenter: "dc1", Datacenter: "dc1",
UpstreamIDs: []structs.ServiceID{ UpstreamServiceNames: []structs.PeeredServiceName{
structs.NewServiceID("bar", nil), {ServiceName: structs.NewServiceName("bar", nil)},
structs.NewServiceID("other", nil), {ServiceName: structs.NewServiceName("other", nil)},
}, },
QueryOptions: structs.QueryOptions{ QueryOptions: structs.QueryOptions{
MinQueryIndex: index, MinQueryIndex: index,
@ -2355,8 +2292,8 @@ func TestConfigEntry_ResolveServiceConfig_BlockOnNoChange(t *testing.T) {
func(minQueryIndex uint64) (*structs.QueryMeta, <-chan error) { func(minQueryIndex uint64) (*structs.QueryMeta, <-chan error) {
args := structs.ServiceConfigRequest{ args := structs.ServiceConfigRequest{
Name: "foo", Name: "foo",
UpstreamIDs: []structs.ServiceID{ UpstreamServiceNames: []structs.PeeredServiceName{
structs.NewServiceID("bar", nil), {ServiceName: structs.NewServiceName("bar", nil)},
}, },
} }
args.QueryOptions.MinQueryIndex = minQueryIndex args.QueryOptions.MinQueryIndex = minQueryIndex

View File

@ -5,7 +5,6 @@ package proxycfgglue
import ( import (
"context" "context"
"errors"
"github.com/hashicorp/go-memdb" "github.com/hashicorp/go-memdb"
@ -40,10 +39,6 @@ func (s *serverResolvedServiceConfig) Notify(ctx context.Context, req *structs.S
return s.remoteSource.Notify(ctx, req, correlationID, ch) return s.remoteSource.Notify(ctx, req, correlationID, ch)
} }
if len(req.UpstreamIDs) != 0 {
return errors.New("ServerResolvedServiceConfig does not support the legacy UpstreamIDs parameter")
}
return watch.ServerLocalNotify(ctx, correlationID, s.deps.GetStore, return watch.ServerLocalNotify(ctx, correlationID, s.deps.GetStore,
func(ws memdb.WatchSet, store Store) (uint64, *structs.ServiceConfigResponse, error) { func(ws memdb.WatchSet, store Store) (uint64, *structs.ServiceConfigResponse, error) {
authz, err := s.deps.ACLResolver.ResolveTokenAndDefaultMeta(req.Token, &req.EnterpriseMeta, nil) authz, err := s.deps.ACLResolver.ResolveTokenAndDefaultMeta(req.Token, &req.EnterpriseMeta, nil)

View File

@ -829,9 +829,6 @@ func fixPersistedServiceConfigForTest(content []byte) ([]byte, error) {
return nil, err return nil, err
} }
// Sort the output, since it's randomized and causes flaky tests otherwise. // Sort the output, since it's randomized and causes flaky tests otherwise.
sort.Slice(parsed.Defaults.UpstreamIDConfigs, func(i, j int) bool {
return parsed.Defaults.UpstreamIDConfigs[i].Upstream.ID < parsed.Defaults.UpstreamIDConfigs[j].Upstream.ID
})
sort.Slice(parsed.Defaults.UpstreamConfigs, func(i, j int) bool { sort.Slice(parsed.Defaults.UpstreamConfigs, func(i, j int) bool {
return parsed.Defaults.UpstreamConfigs[i].Upstream.String() < parsed.Defaults.UpstreamConfigs[j].Upstream.String() return parsed.Defaults.UpstreamConfigs[i].Upstream.String() < parsed.Defaults.UpstreamConfigs[j].Upstream.String()
}) })

View File

@ -775,11 +775,6 @@ type ServiceConfigRequest struct {
// UpstreamServiceNames is a list of upstream service names to use for resolving the service config. // UpstreamServiceNames is a list of upstream service names to use for resolving the service config.
UpstreamServiceNames []PeeredServiceName UpstreamServiceNames []PeeredServiceName
// DEPRECATED
// UpstreamIDs is a list of upstream service names to use for resolving the service config.
// This field does not take the peer name into consideration, so it is deprecated.
UpstreamIDs []ServiceID
acl.EnterpriseMeta `hcl:",squash" mapstructure:",squash"` acl.EnterpriseMeta `hcl:",squash" mapstructure:",squash"`
QueryOptions QueryOptions
} }
@ -792,12 +787,6 @@ func (s *ServiceConfigRequest) RequestDatacenter() string {
// This is often used for fetching service-defaults config entries. // This is often used for fetching service-defaults config entries.
func (s *ServiceConfigRequest) GetLocalUpstreamIDs() []ServiceID { func (s *ServiceConfigRequest) GetLocalUpstreamIDs() []ServiceID {
var upstreams []ServiceID var upstreams []ServiceID
if len(s.UpstreamIDs) > 0 {
// The legacy mode is mutually exclusive with the new mode, so we don't need
// to join the two lists together.
upstreams = append(upstreams, s.UpstreamIDs...)
return upstreams
}
for i := range s.UpstreamServiceNames { for i := range s.UpstreamServiceNames {
u := &s.UpstreamServiceNames[i] u := &s.UpstreamServiceNames[i]
if u.Peer == "" { if u.Peer == "" {
@ -826,7 +815,6 @@ func (r *ServiceConfigRequest) CacheInfo() cache.RequestInfo {
Name string Name string
EnterpriseMeta acl.EnterpriseMeta EnterpriseMeta acl.EnterpriseMeta
UpstreamServiceNames []PeeredServiceName `hash:"set"` UpstreamServiceNames []PeeredServiceName `hash:"set"`
UpstreamIDs []ServiceID `hash:"set"`
MeshGatewayConfig MeshGatewayConfig MeshGatewayConfig MeshGatewayConfig
ProxyMode ProxyMode ProxyMode ProxyMode
Filter string Filter string
@ -834,7 +822,6 @@ func (r *ServiceConfigRequest) CacheInfo() cache.RequestInfo {
Name: r.Name, Name: r.Name,
EnterpriseMeta: r.EnterpriseMeta, EnterpriseMeta: r.EnterpriseMeta,
UpstreamServiceNames: r.UpstreamServiceNames, UpstreamServiceNames: r.UpstreamServiceNames,
UpstreamIDs: r.UpstreamIDs,
ProxyMode: r.Mode, ProxyMode: r.Mode,
MeshGatewayConfig: r.MeshGateway, MeshGatewayConfig: r.MeshGateway,
Filter: r.QueryOptions.Filter, Filter: r.QueryOptions.Filter,
@ -1153,12 +1140,6 @@ func (ul UpstreamLimits) Validate() error {
return nil return nil
} }
type OpaqueUpstreamConfigDeprecated struct {
Upstream ServiceID
Config map[string]interface{}
}
type OpaqueUpstreamConfigsDeprecated []OpaqueUpstreamConfigDeprecated
type OpaqueUpstreamConfig struct { type OpaqueUpstreamConfig struct {
Upstream PeeredServiceName Upstream PeeredServiceName
Config map[string]interface{} Config map[string]interface{}
@ -1166,19 +1147,16 @@ type OpaqueUpstreamConfig struct {
type OpaqueUpstreamConfigs []OpaqueUpstreamConfig type OpaqueUpstreamConfigs []OpaqueUpstreamConfig
type ServiceConfigResponse struct { type ServiceConfigResponse struct {
ProxyConfig map[string]interface{} ProxyConfig map[string]interface{}
// DEPRECATED: UpstreamIDConfigs field exists only for backwards-compatibility UpstreamConfigs OpaqueUpstreamConfigs
// during upgrades and should be removed in Consul 1.16. MeshGateway MeshGatewayConfig `json:",omitempty"`
UpstreamIDConfigs OpaqueUpstreamConfigsDeprecated Expose ExposeConfig `json:",omitempty"`
UpstreamConfigs OpaqueUpstreamConfigs TransparentProxy TransparentProxyConfig `json:",omitempty"`
MeshGateway MeshGatewayConfig `json:",omitempty"` Mode ProxyMode `json:",omitempty"`
Expose ExposeConfig `json:",omitempty"` Destination DestinationConfig `json:",omitempty"`
TransparentProxy TransparentProxyConfig `json:",omitempty"` AccessLogs AccessLogsConfig `json:",omitempty"`
Mode ProxyMode `json:",omitempty"` Meta map[string]string `json:",omitempty"`
Destination DestinationConfig `json:",omitempty"` EnvoyExtensions []EnvoyExtension `json:",omitempty"`
AccessLogs AccessLogsConfig `json:",omitempty"`
Meta map[string]string `json:",omitempty"`
EnvoyExtensions []EnvoyExtension `json:",omitempty"`
QueryMeta QueryMeta
} }
@ -1222,13 +1200,6 @@ func (r *ServiceConfigResponse) UnmarshalBinary(data []byte) error {
return err return err
} }
for k := range r.UpstreamIDConfigs {
r.UpstreamIDConfigs[k].Config, err = lib.MapWalk(r.UpstreamIDConfigs[k].Config)
if err != nil {
return err
}
}
for k := range r.UpstreamConfigs { for k := range r.UpstreamConfigs {
r.UpstreamConfigs[k].Config, err = lib.MapWalk(r.UpstreamConfigs[k].Config) r.UpstreamConfigs[k].Config, err = lib.MapWalk(r.UpstreamConfigs[k].Config)
if err != nil { if err != nil {

View File

@ -2146,13 +2146,6 @@ func TestDecodeConfigEntry(t *testing.T) {
func TestServiceConfigRequest(t *testing.T) { func TestServiceConfigRequest(t *testing.T) {
makeLegacyUpstreamIDs := func(services ...string) []ServiceID {
u := make([]ServiceID, 0, len(services))
for _, s := range services {
u = append(u, NewServiceID(s, acl.DefaultEnterpriseMeta()))
}
return u
}
tests := []struct { tests := []struct {
name string name string
req ServiceConfigRequest req ServiceConfigRequest
@ -2182,40 +2175,18 @@ func TestServiceConfigRequest(t *testing.T) {
}, },
wantSame: false, wantSame: false,
}, },
{
name: "legacy upstreams should be different",
req: ServiceConfigRequest{
Name: "web",
UpstreamIDs: makeLegacyUpstreamIDs("foo"),
},
mutate: func(req *ServiceConfigRequest) {
req.UpstreamIDs = makeLegacyUpstreamIDs("foo", "bar")
},
wantSame: false,
},
{
name: "legacy upstreams should not depend on order",
req: ServiceConfigRequest{
Name: "web",
UpstreamIDs: makeLegacyUpstreamIDs("bar", "foo"),
},
mutate: func(req *ServiceConfigRequest) {
req.UpstreamIDs = makeLegacyUpstreamIDs("foo", "bar")
},
wantSame: true,
},
{ {
name: "upstreams should be different", name: "upstreams should be different",
req: ServiceConfigRequest{ req: ServiceConfigRequest{
Name: "web", Name: "web",
UpstreamIDs: []ServiceID{ UpstreamServiceNames: []PeeredServiceName{
NewServiceID("foo", nil), {ServiceName: NewServiceName("foo", nil)},
}, },
}, },
mutate: func(req *ServiceConfigRequest) { mutate: func(req *ServiceConfigRequest) {
req.UpstreamIDs = []ServiceID{ req.UpstreamServiceNames = []PeeredServiceName{
NewServiceID("foo", nil), {ServiceName: NewServiceName("foo", nil)},
NewServiceID("bar", nil), {ServiceName: NewServiceName("bar", nil)},
} }
}, },
wantSame: false, wantSame: false,
@ -2224,15 +2195,15 @@ func TestServiceConfigRequest(t *testing.T) {
name: "upstreams should not depend on order", name: "upstreams should not depend on order",
req: ServiceConfigRequest{ req: ServiceConfigRequest{
Name: "web", Name: "web",
UpstreamIDs: []ServiceID{ UpstreamServiceNames: []PeeredServiceName{
NewServiceID("bar", nil), {ServiceName: NewServiceName("foo", nil)},
NewServiceID("foo", nil), {ServiceName: NewServiceName("bar", nil)},
}, },
}, },
mutate: func(req *ServiceConfigRequest) { mutate: func(req *ServiceConfigRequest) {
req.UpstreamIDs = []ServiceID{ req.UpstreamServiceNames = []PeeredServiceName{
NewServiceID("foo", nil), {ServiceName: NewServiceName("foo", nil)},
NewServiceID("bar", nil), {ServiceName: NewServiceName("bar", nil)},
} }
}, },
wantSame: true, wantSame: true,

View File

@ -783,18 +783,6 @@ func (o *ServiceConfigResponse) DeepCopy() *ServiceConfigResponse {
cp.ProxyConfig[k2] = v2 cp.ProxyConfig[k2] = v2
} }
} }
if o.UpstreamIDConfigs != nil {
cp.UpstreamIDConfigs = make([]OpaqueUpstreamConfigDeprecated, len(o.UpstreamIDConfigs))
copy(cp.UpstreamIDConfigs, o.UpstreamIDConfigs)
for i2 := range o.UpstreamIDConfigs {
if o.UpstreamIDConfigs[i2].Config != nil {
cp.UpstreamIDConfigs[i2].Config = make(map[string]interface{}, len(o.UpstreamIDConfigs[i2].Config))
for k4, v4 := range o.UpstreamIDConfigs[i2].Config {
cp.UpstreamIDConfigs[i2].Config[k4] = v4
}
}
}
}
if o.UpstreamConfigs != nil { if o.UpstreamConfigs != nil {
cp.UpstreamConfigs = make([]OpaqueUpstreamConfig, len(o.UpstreamConfigs)) cp.UpstreamConfigs = make([]OpaqueUpstreamConfig, len(o.UpstreamConfigs))
copy(cp.UpstreamConfigs, o.UpstreamConfigs) copy(cp.UpstreamConfigs, o.UpstreamConfigs)

View File

@ -14,6 +14,16 @@ provided for their upgrades as a result of new features or changed behavior.
This page is used to document those details separately from the standard This page is used to document those details separately from the standard
upgrade flow. upgrade flow.
## Consul 1.16.x
#### Remove deprecated service-defaults peer upstream override behavior
In Consul 1.16.x, `service-defaults` upstream [`overrides`](/consul/docs/connect/config-entries/service-defaults#overrides)
will not apply to peer upstreams, unless the [`peer`](/consul/docs/connect/config-entries/service-defaults#peer) field is explicitly provided.
Consul 1.15.x introduced a backward-compatibility behavior to allow for a smoother transition during the upgrade. This behavior will be removed in Consul 1.16.x.
Visit the [upgrade instructions for 1.15.x](#service-defaults-overrides-for-upstream-peered-services) for more info.
## Consul 1.15.x ## Consul 1.15.x
#### Service mesh known issue #### Service mesh known issue