diff --git a/agent/consul/config_endpoint.go b/agent/consul/config_endpoint.go index 354fb05a47..382b5c2974 100644 --- a/agent/consul/config_endpoint.go +++ b/agent/consul/config_endpoint.go @@ -469,7 +469,7 @@ func (c *ConfigEntry) ResolveServiceConfig(args *structs.ServiceConfigRequest, r // usConfigs stores the opaque config map for each upstream and is keyed on the upstream's ID. usConfigs := make(map[structs.ServiceID]map[string]interface{}) - for upstream, _ := range seenUpstreams { + for upstream := range seenUpstreams { resolvedCfg := make(map[string]interface{}) // The protocol of an upstream is resolved in this order: diff --git a/agent/consul/config_endpoint_test.go b/agent/consul/config_endpoint_test.go index a10112834f..8f2bcf6aa7 100644 --- a/agent/consul/config_endpoint_test.go +++ b/agent/consul/config_endpoint_test.go @@ -1069,7 +1069,7 @@ func TestConfigEntry_ResolveServiceConfig_Upstreams(t *testing.T) { UpstreamDefaults: &structs.UpstreamConfig{ Protocol: "http", MeshGateway: structs.MeshGatewayConfig{Mode: structs.MeshGatewayModeRemote}, - PassiveHealthCheck: structs.PassiveHealthCheck{ + PassiveHealthCheck: &structs.PassiveHealthCheck{ Interval: 10, MaxFailures: 2, }, diff --git a/agent/structs/config_entry.go b/agent/structs/config_entry.go index 158264c13e..c6fe9ada51 100644 --- a/agent/structs/config_entry.go +++ b/agent/structs/config_entry.go @@ -660,11 +660,11 @@ type UpstreamConfig struct { // Limits are the set of limits that are applied to the proxy for a specific upstream of a // service instance. - Limits UpstreamLimits + Limits *UpstreamLimits `json:",omitempty"` // PassiveHealthCheck configuration determines how upstream proxy instances will // be monitored for removal from the load balancing pool. - PassiveHealthCheck PassiveHealthCheck `json:",omitempty" alias:"passive_health_check"` + PassiveHealthCheck *PassiveHealthCheck `json:",omitempty" alias:"passive_health_check"` // MeshGatewayConfig controls how Mesh Gateways are configured and used MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway" ` @@ -697,10 +697,10 @@ func (cfg UpstreamConfig) MergeInto(dst map[string]interface{}, legacy bool) { if !cfg.MeshGateway.IsZero() { dst["mesh_gateway"] = cfg.MeshGateway } - if !cfg.Limits.IsZero() { + if cfg.Limits != nil { dst["limits"] = cfg.Limits } - if !cfg.PassiveHealthCheck.IsZero() { + if cfg.PassiveHealthCheck != nil { dst["passive_health_check"] = cfg.PassiveHealthCheck } } @@ -720,11 +720,18 @@ func (cfg *UpstreamConfig) Normalize() { func (cfg UpstreamConfig) Validate() error { var validationErr error - if err := cfg.PassiveHealthCheck.Validate(); err != nil { - validationErr = multierror.Append(validationErr, err) + if cfg.PassiveHealthCheck != nil { + err := cfg.PassiveHealthCheck.Validate() + if err != nil { + validationErr = multierror.Append(validationErr, err) + } } - if err := cfg.Limits.Validate(); err != nil { - validationErr = multierror.Append(validationErr, err) + + if cfg.Limits != nil { + err := cfg.Limits.Validate() + if err != nil { + validationErr = multierror.Append(validationErr, err) + } } return validationErr diff --git a/agent/structs/config_entry_test.go b/agent/structs/config_entry_test.go index 36edcaef62..9e79d8f142 100644 --- a/agent/structs/config_entry_test.go +++ b/agent/structs/config_entry_test.go @@ -196,7 +196,7 @@ func TestDecodeConfigEntry(t *testing.T) { Connect: &ConnectConfiguration{ UpstreamConfigs: map[string]*UpstreamConfig{ "redis": { - PassiveHealthCheck: PassiveHealthCheck{ + PassiveHealthCheck: &PassiveHealthCheck{ MaxFailures: 3, Interval: 2 * time.Second, }, @@ -210,7 +210,7 @@ func TestDecodeConfigEntry(t *testing.T) { ClusterJSON: "bar", ConnectTimeoutMs: 5, Protocol: "http", - Limits: UpstreamLimits{ + Limits: &UpstreamLimits{ MaxConnections: intPointer(3), MaxPendingRequests: intPointer(4), MaxConcurrentRequests: intPointer(5), @@ -1613,12 +1613,12 @@ func TestUpstreamConfig_MergeInto(t *testing.T) { ClusterJSON: "bar", ConnectTimeoutMs: 5, Protocol: "http", - Limits: UpstreamLimits{ + Limits: &UpstreamLimits{ MaxConnections: intPointer(3), MaxPendingRequests: intPointer(4), MaxConcurrentRequests: intPointer(5), }, - PassiveHealthCheck: PassiveHealthCheck{ + PassiveHealthCheck: &PassiveHealthCheck{ MaxFailures: 3, Interval: 2 * time.Second, }, @@ -1630,12 +1630,12 @@ func TestUpstreamConfig_MergeInto(t *testing.T) { "cluster_json": "bar", "connect_timeout_ms": 5, "protocol": "http", - "limits": UpstreamLimits{ + "limits": &UpstreamLimits{ MaxConnections: intPointer(3), MaxPendingRequests: intPointer(4), MaxConcurrentRequests: intPointer(5), }, - "passive_health_check": PassiveHealthCheck{ + "passive_health_check": &PassiveHealthCheck{ MaxFailures: 3, Interval: 2 * time.Second, }, @@ -1650,12 +1650,12 @@ func TestUpstreamConfig_MergeInto(t *testing.T) { ClusterJSON: "bar", ConnectTimeoutMs: 5, Protocol: "http", - Limits: UpstreamLimits{ + Limits: &UpstreamLimits{ MaxConnections: intPointer(3), MaxPendingRequests: intPointer(4), MaxConcurrentRequests: intPointer(5), }, - PassiveHealthCheck: PassiveHealthCheck{ + PassiveHealthCheck: &PassiveHealthCheck{ MaxFailures: 3, Interval: 2 * time.Second, }, @@ -1666,12 +1666,12 @@ func TestUpstreamConfig_MergeInto(t *testing.T) { "cluster_json": "zap", "connect_timeout_ms": 10, "protocol": "grpc", - "limits": UpstreamLimits{ + "limits": &UpstreamLimits{ MaxConnections: intPointer(10), MaxPendingRequests: intPointer(11), MaxConcurrentRequests: intPointer(12), }, - "passive_health_check": PassiveHealthCheck{ + "passive_health_check": &PassiveHealthCheck{ MaxFailures: 13, Interval: 14 * time.Second, }, @@ -1682,12 +1682,12 @@ func TestUpstreamConfig_MergeInto(t *testing.T) { "cluster_json": "bar", "connect_timeout_ms": 5, "protocol": "http", - "limits": UpstreamLimits{ + "limits": &UpstreamLimits{ MaxConnections: intPointer(3), MaxPendingRequests: intPointer(4), MaxConcurrentRequests: intPointer(5), }, - "passive_health_check": PassiveHealthCheck{ + "passive_health_check": &PassiveHealthCheck{ MaxFailures: 3, Interval: 2 * time.Second, }, @@ -1716,12 +1716,12 @@ func TestUpstreamConfig_MergeInto(t *testing.T) { "cluster_json": "zap", "connect_timeout_ms": 10, "protocol": "grpc", - "limits": UpstreamLimits{ + "limits": &UpstreamLimits{ MaxConnections: intPointer(10), MaxPendingRequests: intPointer(11), MaxConcurrentRequests: intPointer(12), }, - "passive_health_check": PassiveHealthCheck{ + "passive_health_check": &PassiveHealthCheck{ MaxFailures: 13, Interval: 14 * time.Second, }, @@ -1732,12 +1732,12 @@ func TestUpstreamConfig_MergeInto(t *testing.T) { "cluster_json": "zap", "connect_timeout_ms": 10, "protocol": "grpc", - "limits": UpstreamLimits{ + "limits": &UpstreamLimits{ MaxConnections: intPointer(10), MaxPendingRequests: intPointer(11), MaxConcurrentRequests: intPointer(12), }, - "passive_health_check": PassiveHealthCheck{ + "passive_health_check": &PassiveHealthCheck{ MaxFailures: 13, Interval: 14 * time.Second, }, @@ -1845,7 +1845,7 @@ func TestParseUpstreamConfig(t *testing.T) { want: UpstreamConfig{ ConnectTimeoutMs: 5000, Protocol: "tcp", - Limits: UpstreamLimits{ + Limits: &UpstreamLimits{ MaxConnections: intPointer(50), MaxPendingRequests: intPointer(60), MaxConcurrentRequests: intPointer(70), @@ -1864,7 +1864,7 @@ func TestParseUpstreamConfig(t *testing.T) { want: UpstreamConfig{ ConnectTimeoutMs: 5000, Protocol: "tcp", - Limits: UpstreamLimits{ + Limits: &UpstreamLimits{ MaxConnections: intPointer(0), MaxPendingRequests: intPointer(0), MaxConcurrentRequests: intPointer(0), @@ -1882,7 +1882,7 @@ func TestParseUpstreamConfig(t *testing.T) { want: UpstreamConfig{ ConnectTimeoutMs: 5000, Protocol: "tcp", - PassiveHealthCheck: PassiveHealthCheck{ + PassiveHealthCheck: &PassiveHealthCheck{ Interval: 22 * time.Second, MaxFailures: 7, }, diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index 21b3c23240..bfafb4d6dd 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -734,11 +734,8 @@ func (s *Server) makeGatewayCluster(snap *proxycfg.ConfigSnapshot, opts gatewayC return cluster } -func makeThresholdsIfNeeded(limits structs.UpstreamLimits) []*envoy_cluster_v3.CircuitBreakers_Thresholds { - var empty structs.UpstreamLimits - // Make sure to not create any thresholds when passed the zero-value in order - // to rely on Envoy defaults - if limits == empty { +func makeThresholdsIfNeeded(limits *structs.UpstreamLimits) []*envoy_cluster_v3.CircuitBreakers_Thresholds { + if limits == nil { return nil } diff --git a/agent/xds/config.go b/agent/xds/config.go index 9f796ab6df..8f6748b75d 100644 --- a/agent/xds/config.go +++ b/agent/xds/config.go @@ -151,8 +151,12 @@ func ParseGatewayConfig(m map[string]interface{}) (GatewayConfig, error) { // Return an envoy.OutlierDetection populated by the values from this struct. // If all values are zero a default empty OutlierDetection will be returned to // enable outlier detection with default values. -func ToOutlierDetection(p structs.PassiveHealthCheck) *envoy_cluster_v3.OutlierDetection { +func ToOutlierDetection(p *structs.PassiveHealthCheck) *envoy_cluster_v3.OutlierDetection { od := &envoy_cluster_v3.OutlierDetection{} + if p == nil { + return od + } + if p.Interval != 0 { od.Interval = ptypes.DurationProto(p.Interval) } diff --git a/api/config_entry.go b/api/config_entry.go index a6bace0a98..272635c78c 100644 --- a/api/config_entry.go +++ b/api/config_entry.go @@ -127,11 +127,11 @@ type UpstreamConfig struct { // Limits are the set of limits that are applied to the proxy for a specific upstream of a // service instance. - Limits UpstreamLimits + Limits *UpstreamLimits // PassiveHealthCheck configuration determines how upstream proxy instances will // be monitored for removal from the load balancing pool. - PassiveHealthCheck PassiveHealthCheck `json:",omitempty" alias:"passive_health_check"` + PassiveHealthCheck *PassiveHealthCheck `json:",omitempty" alias:"passive_health_check"` // MeshGatewayConfig controls how Mesh Gateways are configured and used MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway" ` diff --git a/api/config_entry_test.go b/api/config_entry_test.go index 62b0d79664..aa3e3b45f2 100644 --- a/api/config_entry_test.go +++ b/api/config_entry_test.go @@ -380,7 +380,7 @@ func TestDecodeConfigEntry(t *testing.T) { Connect: ConnectConfiguration{ UpstreamConfigs: map[string]UpstreamConfig{ "redis": { - PassiveHealthCheck: PassiveHealthCheck{ + PassiveHealthCheck: &PassiveHealthCheck{ MaxFailures: 3, Interval: 2 * time.Second, }, @@ -394,12 +394,12 @@ func TestDecodeConfigEntry(t *testing.T) { ListenerJSON: "zop", Protocol: "http", ConnectTimeoutMs: 5000, - Limits: UpstreamLimits{ + Limits: &UpstreamLimits{ MaxConnections: 3, MaxPendingRequests: 4, MaxConcurrentRequests: 5, }, - PassiveHealthCheck: PassiveHealthCheck{ + PassiveHealthCheck: &PassiveHealthCheck{ MaxFailures: 5, Interval: 4 * time.Second, }, diff --git a/command/config/write/config_write_test.go b/command/config/write/config_write_test.go index bc8a1ff799..701d2dd0f5 100644 --- a/command/config/write/config_write_test.go +++ b/command/config/write/config_write_test.go @@ -615,7 +615,7 @@ func TestParseConfigEntry(t *testing.T) { Connect: api.ConnectConfiguration{ UpstreamConfigs: map[string]api.UpstreamConfig{ "redis": { - PassiveHealthCheck: api.PassiveHealthCheck{ + PassiveHealthCheck: &api.PassiveHealthCheck{ MaxFailures: 3, Interval: 2 * time.Second, }, @@ -631,12 +631,12 @@ func TestParseConfigEntry(t *testing.T) { ListenerJSON: "zop", Protocol: "http", ConnectTimeoutMs: 5000, - Limits: api.UpstreamLimits{ + Limits: &api.UpstreamLimits{ MaxConnections: 3, MaxPendingRequests: 4, MaxConcurrentRequests: 5, }, - PassiveHealthCheck: api.PassiveHealthCheck{ + PassiveHealthCheck: &api.PassiveHealthCheck{ MaxFailures: 5, Interval: 4 * time.Second, },