Skip to content

Commit dc80468

Browse files
authored
Rate limit zone sync (#7468)
1 parent 1aa4c66 commit dc80468

20 files changed

+1238
-28
lines changed

internal/configs/ingress.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type IngressEx struct {
4646
AppProtectLogs []AppProtectLog
4747
DosEx *DosEx
4848
SecretRefs map[string]*secrets.SecretReference
49+
ZoneSync bool
4950
}
5051

5152
// DosEx holds a DosProtectedResource and the dos policy and log confs it references.
@@ -290,6 +291,7 @@ func generateNginxCfg(p NginxCfgParams) (version1.IngressNginxConfig, Warnings)
290291
Key: cfgParams.LimitReqKey,
291292
Size: cfgParams.LimitReqZoneSize,
292293
Rate: rate,
294+
Sync: p.ingEx.ZoneSync,
293295
})
294296
}
295297
}

internal/configs/ingress_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,47 @@ func TestGenerateNginxCfgForLimitReqDefaults(t *testing.T) {
11591159
}
11601160
}
11611161

1162+
func TestGenerateNginxCfgForLimitReqZoneSync(t *testing.T) {
1163+
t.Parallel()
1164+
cafeIngressEx := createCafeIngressEx()
1165+
cafeIngressEx.Ingress.Annotations["nginx.org/limit-req-rate"] = "200r/s"
1166+
cafeIngressEx.Ingress.Annotations["nginx.org/limit-req-key"] = "${request_uri}"
1167+
cafeIngressEx.Ingress.Annotations["nginx.org/limit-req-zone-size"] = "11m"
1168+
1169+
cafeIngressEx.ZoneSync = true
1170+
isPlus := true
1171+
1172+
configParams := NewDefaultConfigParams(context.Background(), isPlus)
1173+
1174+
expectedZones := []version1.LimitReqZone{
1175+
{
1176+
Name: "default/cafe-ingress",
1177+
Key: "${request_uri}",
1178+
Size: "11m",
1179+
Rate: "200r/s",
1180+
Sync: true,
1181+
},
1182+
}
1183+
1184+
result, warnings := generateNginxCfg(NginxCfgParams{
1185+
ingEx: &cafeIngressEx,
1186+
BaseCfgParams: configParams,
1187+
staticParams: &StaticConfigParams{},
1188+
isPlus: isPlus,
1189+
})
1190+
1191+
if !reflect.DeepEqual(result.LimitReqZones, expectedZones) {
1192+
t.Errorf("generateNginxCfg returned \n%v, but expected \n%v", result.LimitReqZones, expectedZones)
1193+
}
1194+
1195+
if !reflect.DeepEqual(result.LimitReqZones, expectedZones) {
1196+
t.Errorf("generateNginxCfg returned \n%v, but expected \n%v", result.LimitReqZones, expectedZones)
1197+
}
1198+
if len(warnings) != 0 {
1199+
t.Errorf("generateNginxCfg returned warnings: %v", warnings)
1200+
}
1201+
}
1202+
11621203
func TestGenerateNginxCfgForMergeableIngressesForLimitReq(t *testing.T) {
11631204
t.Parallel()
11641205
mergeableIngresses := createMergeableCafeIngress()

internal/configs/version1/__snapshots__/template_test.snap

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,32 @@ server {
12091209
12101210
}
12111211
1212+
}
1213+
1214+
---
1215+
1216+
[TestExecuteTemplate_ForIngressForNGINXPlusWithRequestRateLimitZoneSync - 1]
1217+
# configuration for default/myingress
1218+
1219+
1220+
limit_req_zone ${binary_remote_addr} zone=default/zone1:10m rate=200r/s sync;
1221+
1222+
1223+
1224+
server {
1225+
1226+
server_tokens "";
1227+
1228+
server_name test.example.com;
1229+
1230+
status_zone ;
1231+
set $resource_type "ingress";
1232+
set $resource_name "myingress";
1233+
set $resource_namespace "default";
1234+
1235+
1236+
1237+
12121238
}
12131239
12141240
---

internal/configs/version1/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ type LimitReqZone struct {
7373
Key string
7474
Size string
7575
Rate string
76+
Sync bool
7677
}
7778

7879
// Server describes an NGINX server.

internal/configs/version1/nginx-plus.ingress.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ upstream {{$upstream.Name}} {
2222
{{- end}}
2323

2424
{{range $limitReqZone := .LimitReqZones}}
25-
limit_req_zone {{ $limitReqZone.Key }} zone={{ $limitReqZone.Name }}:{{$limitReqZone.Size}} rate={{$limitReqZone.Rate}};
25+
limit_req_zone {{ $limitReqZone.Key }} zone={{ $limitReqZone.Name }}:{{$limitReqZone.Size}} rate={{$limitReqZone.Rate}}{{- if $limitReqZone.Sync }} sync{{- end }};
2626
{{end}}
2727

2828
{{range $server := .Servers}}

internal/configs/version1/template_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,6 +1815,52 @@ func TestExecuteTemplate_ForIngressForNGINXPlusWithRequestRateLimitMinions(t *te
18151815
snaps.MatchSnapshot(t, buf.String())
18161816
}
18171817

1818+
func TestExecuteTemplate_ForIngressForNGINXPlusWithRequestRateLimitZoneSync(t *testing.T) {
1819+
t.Parallel()
1820+
1821+
tmpl := newNGINXPlusIngressTmpl(t)
1822+
buf := &bytes.Buffer{}
1823+
1824+
ingressCfg := IngressNginxConfig{
1825+
Ingress: Ingress{
1826+
Name: "myingress",
1827+
Namespace: "default",
1828+
},
1829+
Servers: []Server{
1830+
{
1831+
Name: "test.example.com",
1832+
},
1833+
},
1834+
LimitReqZones: []LimitReqZone{
1835+
{
1836+
Name: "default/zone1",
1837+
Key: "${binary_remote_addr}",
1838+
Size: "10m",
1839+
Rate: "200r/s",
1840+
Sync: true,
1841+
},
1842+
},
1843+
}
1844+
1845+
err := tmpl.Execute(buf, ingressCfg)
1846+
t.Log(buf.String())
1847+
if err != nil {
1848+
t.Fatal(err)
1849+
}
1850+
ingConf := buf.String()
1851+
1852+
wantDirectives := []string{
1853+
"limit_req_zone ${binary_remote_addr} zone=default/zone1:10m rate=200r/s sync;",
1854+
}
1855+
1856+
for _, want := range wantDirectives {
1857+
if !strings.Contains(ingConf, want) {
1858+
t.Errorf("want %q in generated config", want)
1859+
}
1860+
}
1861+
snaps.MatchSnapshot(t, buf.String())
1862+
}
1863+
18181864
func newNGINXPlusIngressTmpl(t *testing.T) *template.Template {
18191865
t.Helper()
18201866
tmpl, err := template.New("nginx-plus.ingress.tmpl").Funcs(helperFunctions).ParseFiles("nginx-plus.ingress.tmpl")

internal/configs/version2/__snapshots__/templates_test.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2913,7 +2913,7 @@ map $http_x_version $match_0_0 {
29132913
default 0;
29142914
}
29152915
# HTTP snippet
2916-
limit_req_zone $url zone=pol_rl_test_test_test:10m rate=10r/s;
2916+
limit_req_zone $url zone=pol_rl_test_test_test:10m rate=10r/s sync;
29172917

29182918
server {
29192919
listen 80 proxy_protocol;

internal/configs/version2/http.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,11 @@ type LimitReqZone struct {
383383
PolicyResult string
384384
GroupDefault bool
385385
GroupSource string
386+
Sync bool
386387
}
387388

388389
func (rlz LimitReqZone) String() string {
389-
return fmt.Sprintf("{Key %q, ZoneName %q, ZoneSize %v, Rate %q, GroupValue %q, PolicyValue %q, GroupVariable %q, PolicyResult %q, GroupDefault %t, GroupSource %q}",
390+
return fmt.Sprintf("{Key %q, ZoneName %q, ZoneSize %v, Rate %q, GroupValue %q, PolicyValue %q, GroupVariable %q, PolicyResult %q, GroupDefault %t, GroupSource %q, Sync %t}",
390391
rlz.Key,
391392
rlz.ZoneName,
392393
rlz.ZoneSize,
@@ -397,6 +398,7 @@ func (rlz LimitReqZone) String() string {
397398
rlz.PolicyResult,
398399
rlz.GroupDefault,
399400
rlz.GroupSource,
401+
rlz.Sync,
400402
)
401403
}
402404

internal/configs/version2/nginx-plus.virtualserver.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ map {{ $m.Source }} {{ $m.Variable }} {
6767
{{- end }}
6868

6969
{{- range $z := .LimitReqZones }}
70-
limit_req_zone {{ $z.Key }} zone={{ $z.ZoneName }}:{{ $z.ZoneSize }} rate={{ $z.Rate }};
70+
limit_req_zone {{ $z.Key }} zone={{ $z.ZoneName }}:{{ $z.ZoneSize }} rate={{ $z.Rate }}{{- if $z.Sync }} sync{{- end }};
7171
{{- end }}
7272

7373
{{- range $m := .StatusMatches }}

internal/configs/version2/templates_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1147,7 +1147,7 @@ var (
11471147
virtualServerCfg = VirtualServerConfig{
11481148
LimitReqZones: []LimitReqZone{
11491149
{
1150-
ZoneName: "pol_rl_test_test_test", Rate: "10r/s", ZoneSize: "10m", Key: "$url",
1150+
ZoneName: "pol_rl_test_test_test", Rate: "10r/s", ZoneSize: "10m", Key: "$url", Sync: true,
11511151
},
11521152
},
11531153
Upstreams: []Upstream{

0 commit comments

Comments
 (0)