Skip to content

Commit

Permalink
Backport of [API Gateway] Fix rate limiting for API gateways into rel…
Browse files Browse the repository at this point in the history
…ease/1.15.x (#17634)

* backport of commit fb2f3b6

* backport of commit 178abb8

* backport of commit 77b3998

* backport of commit a245b32

---------

Co-authored-by: Andrew Stucki <andrew.stucki@hashicorp.com>
  • Loading branch information
hc-github-team-consul-core and andrewstucki committed Jun 9, 2023
1 parent 082de09 commit 08a106c
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .changelog/17631.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
gateways: Fixed a bug where API gateways were not being taken into account in determining xDS rate limits.
```
19 changes: 18 additions & 1 deletion agent/consul/state/state_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,27 @@ func testRegisterConnectService(t *testing.T, s *Store, idx uint64, nodeID, serv
})
}

func testRegisterAPIService(t *testing.T, s *Store, idx uint64, nodeID, serviceID string) {
testRegisterGatewayService(t, s, structs.ServiceKindAPIGateway, idx, nodeID, serviceID)
}

func testRegisterTerminatingService(t *testing.T, s *Store, idx uint64, nodeID, serviceID string) {
testRegisterGatewayService(t, s, structs.ServiceKindTerminatingGateway, idx, nodeID, serviceID)
}

func testRegisterIngressService(t *testing.T, s *Store, idx uint64, nodeID, serviceID string) {
testRegisterGatewayService(t, s, structs.ServiceKindIngressGateway, idx, nodeID, serviceID)
}

func testRegisterMeshService(t *testing.T, s *Store, idx uint64, nodeID, serviceID string) {
testRegisterGatewayService(t, s, structs.ServiceKindMeshGateway, idx, nodeID, serviceID)
}

func testRegisterGatewayService(t *testing.T, s *Store, kind structs.ServiceKind, idx uint64, nodeID, serviceID string) {
svc := &structs.NodeService{
ID: serviceID,
Service: serviceID,
Kind: structs.ServiceKindIngressGateway,
Kind: kind,
Address: "1.1.1.1",
Port: 1111,
}
Expand All @@ -224,6 +240,7 @@ func testRegisterIngressService(t *testing.T, s *Store, idx uint64, nodeID, serv
t.Fatalf("bad service: %#v", result)
}
}

func testRegisterCheck(t *testing.T, s *Store, idx uint64,
nodeID string, serviceID string, checkID types.CheckID, state string) {
testRegisterCheckWithPartition(t, s, idx,
Expand Down
1 change: 1 addition & 0 deletions agent/consul/state/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var allConnectKind = []string{
string(structs.ServiceKindIngressGateway),
string(structs.ServiceKindMeshGateway),
string(structs.ServiceKindTerminatingGateway),
string(structs.ServiceKindAPIGateway),
connectNativeInstancesTable,
}

Expand Down
15 changes: 12 additions & 3 deletions agent/consul/state/usage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,25 @@ func TestStateStore_Usage_ServiceUsage(t *testing.T) {
testRegisterConnectNativeService(t, s, 13, "node1", "service-native")
testRegisterConnectNativeService(t, s, 14, "node2", "service-native")
testRegisterConnectNativeService(t, s, 15, "node2", "service-native-1")
testRegisterIngressService(t, s, 16, "node1", "ingress")
testRegisterMeshService(t, s, 17, "node1", "mesh")
testRegisterTerminatingService(t, s, 18, "node1", "terminating")
testRegisterAPIService(t, s, 19, "node1", "api")
testRegisterAPIService(t, s, 20, "node2", "api")

ws := memdb.NewWatchSet()
idx, usage, err := s.ServiceUsage(ws)
require.NoError(t, err)
require.Equal(t, idx, uint64(15))
require.Equal(t, 5, usage.Services)
require.Equal(t, 8, usage.ServiceInstances)
require.Equal(t, idx, uint64(20))
require.Equal(t, 9, usage.Services)
require.Equal(t, 13, usage.ServiceInstances)
require.Equal(t, 2, usage.ConnectServiceInstances[string(structs.ServiceKindConnectProxy)])
require.Equal(t, 3, usage.ConnectServiceInstances[connectNativeInstancesTable])
require.Equal(t, 6, usage.BillableServiceInstances)
require.Equal(t, 2, usage.ConnectServiceInstances[string(structs.ServiceKindAPIGateway)])
require.Equal(t, 1, usage.ConnectServiceInstances[string(structs.ServiceKindIngressGateway)])
require.Equal(t, 1, usage.ConnectServiceInstances[string(structs.ServiceKindTerminatingGateway)])
require.Equal(t, 1, usage.ConnectServiceInstances[string(structs.ServiceKindMeshGateway)])

testRegisterSidecarProxy(t, s, 16, "node2", "service2")

Expand Down
68 changes: 60 additions & 8 deletions agent/consul/usagemetrics/usagemetrics_oss_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,22 @@ var baseCases = map[string]testCase{
{Name: "kind", Value: "ingress-gateway"},
},
},
"consul.usage.test.consul.state.connect_instances;datacenter=dc1;kind=api-gateway": { // Legacy
Name: "consul.usage.test.consul.state.connect_instances",
Value: 0,
Labels: []metrics.Label{
{Name: "datacenter", Value: "dc1"},
{Name: "kind", Value: "api-gateway"},
},
},
"consul.usage.test.state.connect_instances;datacenter=dc1;kind=api-gateway": {
Name: "consul.usage.test.state.connect_instances",
Value: 0,
Labels: []metrics.Label{
{Name: "datacenter", Value: "dc1"},
{Name: "kind", Value: "api-gateway"},
},
},
"consul.usage.test.consul.state.connect_instances;datacenter=dc1;kind=mesh-gateway": { // Legacy
Name: "consul.usage.test.consul.state.connect_instances",
Value: 0,
Expand Down Expand Up @@ -573,6 +589,22 @@ var baseCases = map[string]testCase{
{Name: "kind", Value: "ingress-gateway"},
},
},
"consul.usage.test.consul.state.connect_instances;datacenter=dc1;kind=api-gateway": { // Legacy
Name: "consul.usage.test.consul.state.connect_instances",
Value: 0,
Labels: []metrics.Label{
{Name: "datacenter", Value: "dc1"},
{Name: "kind", Value: "api-gateway"},
},
},
"consul.usage.test.state.connect_instances;datacenter=dc1;kind=api-gateway": {
Name: "consul.usage.test.state.connect_instances",
Value: 0,
Labels: []metrics.Label{
{Name: "datacenter", Value: "dc1"},
{Name: "kind", Value: "api-gateway"},
},
},
"consul.usage.test.consul.state.connect_instances;datacenter=dc1;kind=mesh-gateway": { // Legacy
Name: "consul.usage.test.consul.state.connect_instances",
Value: 0,
Expand Down Expand Up @@ -1028,6 +1060,9 @@ func TestUsageReporter_emitServiceUsage_OSS(t *testing.T) {
require.NoError(t, s.EnsureNode(3, &structs.Node{Node: "baz", Address: "127.0.0.2"}))
require.NoError(t, s.EnsureNode(4, &structs.Node{Node: "qux", Address: "127.0.0.3"}))

apigw := structs.TestNodeServiceAPIGateway(t)
apigw.ID = "api-gateway"

mgw := structs.TestNodeServiceMeshGateway(t)
mgw.ID = "mesh-gateway"

Expand All @@ -1042,16 +1077,17 @@ func TestUsageReporter_emitServiceUsage_OSS(t *testing.T) {
require.NoError(t, s.EnsureRegistration(10, structs.TestRegisterIngressGateway(t)))
require.NoError(t, s.EnsureService(11, "foo", mgw))
require.NoError(t, s.EnsureService(12, "foo", tgw))
require.NoError(t, s.EnsureService(13, "bar", &structs.NodeService{ID: "db-native", Service: "db", Tags: nil, Address: "", Port: 5000, Connect: structs.ServiceConnect{Native: true}}))
require.NoError(t, s.EnsureConfigEntry(14, &structs.IngressGatewayConfigEntry{
require.NoError(t, s.EnsureService(13, "foo", apigw))
require.NoError(t, s.EnsureService(14, "bar", &structs.NodeService{ID: "db-native", Service: "db", Tags: nil, Address: "", Port: 5000, Connect: structs.ServiceConnect{Native: true}}))
require.NoError(t, s.EnsureConfigEntry(15, &structs.IngressGatewayConfigEntry{
Kind: structs.IngressGateway,
Name: "foo",
}))
require.NoError(t, s.EnsureConfigEntry(15, &structs.IngressGatewayConfigEntry{
require.NoError(t, s.EnsureConfigEntry(16, &structs.IngressGatewayConfigEntry{
Kind: structs.IngressGateway,
Name: "bar",
}))
require.NoError(t, s.EnsureConfigEntry(16, &structs.IngressGatewayConfigEntry{
require.NoError(t, s.EnsureConfigEntry(17, &structs.IngressGatewayConfigEntry{
Kind: structs.IngressGateway,
Name: "baz",
}))
Expand Down Expand Up @@ -1092,22 +1128,22 @@ func TestUsageReporter_emitServiceUsage_OSS(t *testing.T) {
}
nodesAndSvcsCase.expectedGauges["consul.usage.test.consul.state.services;datacenter=dc1"] = metrics.GaugeValue{ // Legacy
Name: "consul.usage.test.consul.state.services",
Value: 7,
Value: 8,
Labels: []metrics.Label{{Name: "datacenter", Value: "dc1"}},
}
nodesAndSvcsCase.expectedGauges["consul.usage.test.state.services;datacenter=dc1"] = metrics.GaugeValue{
Name: "consul.usage.test.state.services",
Value: 7,
Value: 8,
Labels: []metrics.Label{{Name: "datacenter", Value: "dc1"}},
}
nodesAndSvcsCase.expectedGauges["consul.usage.test.consul.state.service_instances;datacenter=dc1"] = metrics.GaugeValue{ // Legacy
Name: "consul.usage.test.consul.state.service_instances",
Value: 9,
Value: 10,
Labels: []metrics.Label{{Name: "datacenter", Value: "dc1"}},
}
nodesAndSvcsCase.expectedGauges["consul.usage.test.state.service_instances;datacenter=dc1"] = metrics.GaugeValue{
Name: "consul.usage.test.state.service_instances",
Value: 9,
Value: 10,
Labels: []metrics.Label{{Name: "datacenter", Value: "dc1"}},
}
nodesAndSvcsCase.expectedGauges["consul.usage.test.consul.state.connect_instances;datacenter=dc1;kind=connect-proxy"] = metrics.GaugeValue{ // Legacy
Expand Down Expand Up @@ -1158,6 +1194,22 @@ func TestUsageReporter_emitServiceUsage_OSS(t *testing.T) {
{Name: "kind", Value: "ingress-gateway"},
},
}
nodesAndSvcsCase.expectedGauges["consul.usage.test.consul.state.connect_instances;datacenter=dc1;kind=api-gateway"] = metrics.GaugeValue{ // Legacy
Name: "consul.usage.test.consul.state.connect_instances",
Value: 1,
Labels: []metrics.Label{
{Name: "datacenter", Value: "dc1"},
{Name: "kind", Value: "api-gateway"},
},
}
nodesAndSvcsCase.expectedGauges["consul.usage.test.state.connect_instances;datacenter=dc1;kind=api-gateway"] = metrics.GaugeValue{
Name: "consul.usage.test.state.connect_instances",
Value: 1,
Labels: []metrics.Label{
{Name: "datacenter", Value: "dc1"},
{Name: "kind", Value: "api-gateway"},
},
}
nodesAndSvcsCase.expectedGauges["consul.usage.test.consul.state.connect_instances;datacenter=dc1;kind=mesh-gateway"] = metrics.GaugeValue{ // Legacy
Name: "consul.usage.test.consul.state.connect_instances",
Value: 1,
Expand Down
1 change: 1 addition & 0 deletions agent/operator_endpoint_oss_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func TestOperator_Usage(t *testing.T) {
Services: 5,
ServiceInstances: 6,
ConnectServiceInstances: map[string]int{
"api-gateway": 0,
"connect-native": 1,
"connect-proxy": 1,
"ingress-gateway": 0,
Expand Down
8 changes: 8 additions & 0 deletions agent/structs/testing_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ func TestNodeServiceMeshGateway(t testing.T) *NodeService {
ServiceAddress{Address: "198.18.4.5", Port: 443})
}

func TestNodeServiceAPIGateway(t testing.T) *NodeService {
return &NodeService{
Kind: ServiceKindAPIGateway,
Service: "api-gateway",
Address: "1.1.1.1",
}
}

func TestNodeServiceTerminatingGateway(t testing.T, address string) *NodeService {
return &NodeService{
Kind: ServiceKindTerminatingGateway,
Expand Down
1 change: 1 addition & 0 deletions api/operator_usage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func TestAPI_OperatorUsage(t *testing.T) {
require.Equal(t, 4, usage.Usage["dc1"].Services)
require.Equal(t, 5, usage.Usage["dc1"].ServiceInstances)
require.Equal(t, map[string]int{
"api-gateway": 0,
"connect-native": 1,
"connect-proxy": 1,
"ingress-gateway": 0,
Expand Down

0 comments on commit 08a106c

Please sign in to comment.