Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TT-12566/TT-12851] Add client endpoint rate limiter #6462

Merged
merged 32 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a86e9e3
add endpoint rate limiter
jeffy-mathew Aug 14, 2024
fe6bb60
task lint
jeffy-mathew Aug 14, 2024
7f36772
split test functions
jeffy-mathew Aug 14, 2024
5dcd347
add endpoints to dbaccessdefinition
jeffy-mathew Aug 14, 2024
26b398e
improve tests
jeffy-mathew Aug 14, 2024
9d321cd
call ts.close without closure
jeffy-mathew Aug 14, 2024
23163e3
lint
jeffy-mathew Aug 14, 2024
6633f79
test refactoring
jeffy-mathew Aug 14, 2024
a23d589
exp: remove test runner provider helper
jeffy-mathew Aug 14, 2024
3808e3a
init config in gen func
jeffy-mathew Aug 14, 2024
bc021af
revert test setup
jeffy-mathew Aug 16, 2024
48b1b97
exp-test
jeffy-mathew Aug 16, 2024
cac7968
use module name as coverpkg prefix
jeffy-mathew Aug 16, 2024
efbda2b
review comments on clone
jeffy-mathew Aug 19, 2024
ebf2161
refactor tests to tests/rate
jeffy-mathew Aug 19, 2024
ab21e0b
update swagger.yml
jeffy-mathew Aug 19, 2024
8570fa7
smoothing clone
jeffy-mathew Aug 19, 2024
349875e
Rename tests
jeffy-mathew Aug 19, 2024
307863c
refactor ratelimit to separate struct
jeffy-mathew Aug 20, 2024
932e7aa
update swagger.yml
jeffy-mathew Aug 20, 2024
adcae95
update ref in APILimitDuration
jeffy-mathew Aug 20, 2024
59dd33b
add ./... as coverpkg
jeffy-mathew Aug 20, 2024
0d7bc39
update clone tests
jeffy-mathew Aug 20, 2024
e8bd029
Remove msg tag in DBAccessDef
jeffy-mathew Aug 20, 2024
95866ca
update swagger.yml
jeffy-mathew Aug 20, 2024
c0df1bf
usage renames
jeffy-mathew Aug 20, 2024
7151951
refactor EndpointsRateLimitInfo
jeffy-mathew Aug 20, 2024
89b5794
add empty case to Endpoints.RateLimitInfo
jeffy-mathew Aug 20, 2024
49c447c
Flatten Endpoints.RateLimitInfo
jeffy-mathew Aug 20, 2024
95d320f
remove redundant ts.close
jeffy-mathew Aug 20, 2024
66241f4
Add fixed window rate limiter tests
jeffy-mathew Aug 20, 2024
9ca0799
sonarcloud issues
jeffy-mathew Aug 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .taskfiles/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ vars:
tags: '{{ .tags | default "goplugin dev" }}'
args: '{{ .args | default "-timeout=15m" }}'
buildArgs: -cover -tags "{{.tags}}"
testArgs: -failfast -coverpkg=./... {{.buildArgs}}
testArgs: -failfast -coverpkg=github.com/TykTechnologies/tyk/...,./... {{.buildArgs}}
python:
sh: python3 -c 'import sys; print("%d.%d" % (sys.version_info[0], sys.version_info[1]))'

Expand Down
6 changes: 4 additions & 2 deletions gateway/mw_api_rate_limit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,10 @@ func requestThrottlingTest(limiter string, testLevel string) func(t *testing.T)
} else if testLevel == "APILevel" {
a := p.AccessRights[spec.APIID]
a.Limit = user.APILimit{
Rate: rate,
Per: per,
RateLimit: user.RateLimit{
Rate: rate,
Per: per,
},
}

if requestThrottlingEnabled {
Expand Down
24 changes: 16 additions & 8 deletions gateway/mw_jwt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -933,8 +933,10 @@ func TestJWTScopeToPolicyMapping(t *testing.T) {
p.AccessRights = map[string]user.AccessDefinition{
"base-api": {
Limit: user.APILimit{
Rate: 111,
Per: 3600,
RateLimit: user.RateLimit{
Rate: 111,
Per: 3600,
},
QuotaMax: -1,
},
},
Expand All @@ -960,8 +962,10 @@ func TestJWTScopeToPolicyMapping(t *testing.T) {
p.AccessRights = map[string]user.AccessDefinition{
"api1": {
Limit: user.APILimit{
Rate: 100,
Per: 60,
RateLimit: user.RateLimit{
Rate: 100,
Per: 60,
},
QuotaMax: -1,
},
},
Expand All @@ -976,8 +980,10 @@ func TestJWTScopeToPolicyMapping(t *testing.T) {
p.AccessRights = map[string]user.AccessDefinition{
"api2": {
Limit: user.APILimit{
Rate: 500,
Per: 30,
RateLimit: user.RateLimit{
Rate: 500,
Per: 30,
},
QuotaMax: -1,
},
},
Expand Down Expand Up @@ -1191,8 +1197,10 @@ func TestJWTScopeToPolicyMapping(t *testing.T) {
p.AccessRights = map[string]user.AccessDefinition{
spec3.APIID: {
Limit: user.APILimit{
Rate: 500,
Per: 30,
RateLimit: user.RateLimit{
Rate: 500,
Per: 30,
},
QuotaMax: -1,
},
},
Expand Down
12 changes: 8 additions & 4 deletions gateway/mw_rate_limiting_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,10 @@ func providerCustomRatelimitKey(t *testing.T, limiter string) {
APIID: spec.APIID,
APIName: spec.Name,
Limit: user.APILimit{
Rate: 3,
Per: 1000,
RateLimit: user.RateLimit{
Rate: 3,
Per: 1000,
},
},
},
}
Expand All @@ -317,8 +319,10 @@ func providerCustomRatelimitKey(t *testing.T, limiter string) {
APIID: spec.APIID,
APIName: spec.Name,
Limit: user.APILimit{
Rate: 3,
Per: 1000,
RateLimit: user.RateLimit{
Rate: 3,
Per: 1000,
},
},
},
}
Expand Down
4 changes: 4 additions & 0 deletions gateway/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ type DBAccessDefinition struct {
DisableIntrospection bool `json:"disable_introspection"`
FieldAccessRights []user.FieldAccessDefinition `json:"field_access_rights"`
Limit *user.APILimit `json:"limit"`

// Endpoints contains endpoint rate limit settings.
Endpoints []user.Endpoint `json:"endpoints,omitempty" msg:"endpoints,omitempty"`
jeffy-mathew marked this conversation as resolved.
Show resolved Hide resolved
}

func (d *DBAccessDefinition) ToRegularAD() user.AccessDefinition {
Expand All @@ -43,6 +46,7 @@ func (d *DBAccessDefinition) ToRegularAD() user.AccessDefinition {
AllowedTypes: d.AllowedTypes,
DisableIntrospection: d.DisableIntrospection,
FieldAccessRights: d.FieldAccessRights,
Endpoints: d.Endpoints,
}

if d.Limit != nil {
Expand Down
108 changes: 71 additions & 37 deletions gateway/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,10 @@ func (s *Test) TestPrepareApplyPolicies() (*BaseMiddleware, []testApplyPoliciesD
Limit: user.APILimit{
QuotaMax: 1000,
QuotaRenewalRate: 3600,
Rate: 20,
Per: 1,
RateLimit: user.RateLimit{
Rate: 20,
Per: 1,
},
},
}},
},
Expand All @@ -233,8 +235,10 @@ func (s *Test) TestPrepareApplyPolicies() (*BaseMiddleware, []testApplyPoliciesD
Limit: user.APILimit{
QuotaMax: 1000,
QuotaRenewalRate: 3600,
Rate: 20,
Per: 1,
RateLimit: user.RateLimit{
Rate: 20,
Per: 1,
},
},
}},
},
Expand All @@ -251,15 +255,19 @@ func (s *Test) TestPrepareApplyPolicies() (*BaseMiddleware, []testApplyPoliciesD
Limit: user.APILimit{
QuotaMax: 1000,
QuotaRenewalRate: 3600,
Rate: 20,
Per: 1,
RateLimit: user.RateLimit{
Rate: 20,
Per: 1,
},
},
},
"c": {
Limit: user.APILimit{
QuotaMax: -1,
Rate: 2000,
Per: 60,
RateLimit: user.RateLimit{
Rate: 2000,
Per: 60,
},
},
},
},
Expand All @@ -277,8 +285,10 @@ func (s *Test) TestPrepareApplyPolicies() (*BaseMiddleware, []testApplyPoliciesD
Limit: user.APILimit{
QuotaMax: 5000,
QuotaRenewalRate: 3600,
Rate: 200,
Per: 10,
RateLimit: user.RateLimit{
Rate: 200,
Per: 10,
},
},
},
},
Expand All @@ -299,8 +309,10 @@ func (s *Test) TestPrepareApplyPolicies() (*BaseMiddleware, []testApplyPoliciesD
Limit: user.APILimit{
QuotaMax: 5000,
QuotaRenewalRate: 3600,
Rate: 200,
Per: 10,
RateLimit: user.RateLimit{
Rate: 200,
Per: 10,
},
},
},
"e": {},
Expand Down Expand Up @@ -647,16 +659,16 @@ func (s *Test) TestPrepareApplyPolicies() (*BaseMiddleware, []testApplyPoliciesD
{
"Acl for a and rate for a,b", []string{"acl1", "rate-for-a-b"},
"", func(t *testing.T, s *user.SessionState) {
want := map[string]user.AccessDefinition{"a": {Limit: user.APILimit{Rate: 4, Per: 1}}}
want := map[string]user.AccessDefinition{"a": {Limit: user.APILimit{RateLimit: user.RateLimit{Rate: 4, Per: 1}}}}
assert.Equal(t, want, s.AccessRights)
}, nil,
},
{
"Acl for a,b and individual rate for a,b", []string{"acl-for-a-b", "rate-for-a", "rate-for-b"},
"", func(t *testing.T, s *user.SessionState) {
want := map[string]user.AccessDefinition{
"a": {Limit: user.APILimit{Rate: 4, Per: 1}},
"b": {Limit: user.APILimit{Rate: 2, Per: 1}},
"a": {Limit: user.APILimit{RateLimit: user.RateLimit{Rate: 4, Per: 1}}},
"b": {Limit: user.APILimit{RateLimit: user.RateLimit{Rate: 2, Per: 1}}},
}
assert.Equal(t, want, s.AccessRights)
}, nil,
Expand Down Expand Up @@ -699,16 +711,20 @@ func (s *Test) TestPrepareApplyPolicies() (*BaseMiddleware, []testApplyPoliciesD
Limit: user.APILimit{
QuotaMax: 1000,
QuotaRenewalRate: 3600,
Rate: 20,
Per: 1,
RateLimit: user.RateLimit{
Rate: 20,
Per: 1,
},
},
AllowanceScope: "d",
},
"c": {
Limit: user.APILimit{
QuotaMax: -1,
Rate: 2000,
Per: 60,
RateLimit: user.RateLimit{
Rate: 2000,
Per: 60,
},
},
AllowanceScope: "c",
},
Expand Down Expand Up @@ -742,17 +758,21 @@ func (s *Test) TestPrepareApplyPolicies() (*BaseMiddleware, []testApplyPoliciesD
"e": {
Limit: user.APILimit{
QuotaMax: -1,
Rate: 300,
Per: 1,
RateLimit: user.RateLimit{
Rate: 300,
Per: 1,
},
},
AllowanceScope: "per_api_with_limit_set_from_policy",
},
"d": {
Limit: user.APILimit{
QuotaMax: 5000,
QuotaRenewalRate: 3600,
Rate: 200,
Per: 10,
RateLimit: user.RateLimit{
Rate: 200,
Per: 10,
},
},
AllowanceScope: "d",
},
Expand Down Expand Up @@ -996,17 +1016,21 @@ func TestApplyPoliciesQuotaAPILimit(t *testing.T) {
Limit: user.APILimit{
QuotaMax: 100,
QuotaRenewalRate: 3600,
Rate: 1000,
Per: 1,
RateLimit: user.RateLimit{
Rate: 1000,
Per: 1,
},
},
},
"api2": {
Versions: []string{"v1"},
Limit: user.APILimit{
QuotaMax: 200,
QuotaRenewalRate: 3600,
Rate: 1000,
Per: 1,
RateLimit: user.RateLimit{
Rate: 1000,
Per: 1,
},
},
},
"api3": {
Expand Down Expand Up @@ -1121,8 +1145,10 @@ func TestApplyPoliciesQuotaAPILimit(t *testing.T) {
return false
}
api1LimitExpected := user.APILimit{
Rate: 1000,
Per: 1,
RateLimit: user.RateLimit{
Rate: 1000,
Per: 1,
},
QuotaMax: 100,
QuotaRenewalRate: 3600,
QuotaRenews: api1Limit.QuotaRenews,
Expand All @@ -1138,8 +1164,10 @@ func TestApplyPoliciesQuotaAPILimit(t *testing.T) {
return false
}
api2LimitExpected := user.APILimit{
Rate: 1000,
Per: 1,
RateLimit: user.RateLimit{
Rate: 1000,
Per: 1,
},
QuotaMax: 200,
QuotaRenewalRate: 3600,
QuotaRenews: api2Limit.QuotaRenews,
Expand All @@ -1155,8 +1183,10 @@ func TestApplyPoliciesQuotaAPILimit(t *testing.T) {
return false
}
api3LimitExpected := user.APILimit{
Rate: 1000,
Per: 1,
RateLimit: user.RateLimit{
Rate: 1000,
Per: 1,
},
QuotaMax: 50,
QuotaRenewalRate: 3600,
QuotaRenews: api3Limit.QuotaRenews,
Expand Down Expand Up @@ -1346,8 +1376,10 @@ func TestApplyMultiPolicies(t *testing.T) {
json.Unmarshal(data, &sessionData)

policy1Expected := user.APILimit{
Rate: 1000,
Per: 1,
RateLimit: user.RateLimit{
Rate: 1000,
Per: 1,
},
QuotaMax: 50,
QuotaRenewalRate: 3600,
QuotaRenews: sessionData.AccessRights["api1"].Limit.QuotaRenews,
Expand All @@ -1356,8 +1388,10 @@ func TestApplyMultiPolicies(t *testing.T) {
assert.Equal(t, policy1Expected, sessionData.AccessRights["api1"].Limit, "API1 limit do not match")

policy2Expected := user.APILimit{
Rate: 100,
Per: 1,
RateLimit: user.RateLimit{
Rate: 100,
Per: 1,
},
QuotaMax: 100,
QuotaRenewalRate: 3600,
QuotaRenews: sessionData.AccessRights["api2"].Limit.QuotaRenews,
Expand Down
Loading
Loading