@@ -118,58 +118,55 @@ function addThrottleAndBanRules(
118118 preview : boolean ,
119119 opts : pulumi . ResourceOptions
120120) : void {
121- apiThrottles . reduce ( ( priority , apiConfig ) => {
122- if ( priority >= THROTTLE_BAN_RULE_MAX ) {
123- throw new Error (
124- `Throttle rule priority ${ priority } exceeds maximum ${ THROTTLE_BAN_RULE_MAX } `
125- ) ;
126- }
127-
128- const { endpoint, throttle, action } = apiConfig ;
129- const ruleName = `${ action } ${ throttle . perIp ? '-per-ip' : '' } -${ endpoint . name } ` ;
121+ _ . sortBy ( Object . entries ( throttles ) , e => e [ 0 ] ) . reduce (
122+ ( priority , [ confEntryHead , singleServiceThrottle ] ) => {
123+ if ( priority >= THROTTLE_BAN_RULE_MAX ) {
124+ throw new Error (
125+ `Throttle rule priority ${ priority } exceeds maximum ${ THROTTLE_BAN_RULE_MAX } `
126+ ) ;
127+ }
128+
129+ const { hostname, pathPrefix, throttleAcrossAllEndpointsAllIps } = singleServiceThrottle ;
130+ // leave out the rule but consume the priority number if max is 0
131+ // this makes the pulumi update cleaner if toggling just one service
132+ if ( throttleAcrossAllEndpointsAllIps . maxRequestsBeforeHttp429 > 0 ) {
133+ const ruleName = `throttle-all-endpoints-all-ips-${ confEntryHead } ` ;
130134
131135 // Build the expression for path and hostname matching
132136 const pathExpr = `request.path.matches('${ endpoint . path } ')` ;
133137 const hostExpr = `request.headers['host'].matches('${ endpoint . hostname } ')` ;
134138 const matchExpr = `${ pathExpr } && ${ hostExpr } ` ;
135139
136- new gcp . compute . SecurityPolicyRule (
137- ruleName ,
138- {
139- securityPolicy : securityPolicy . name ,
140- description : `${ action === 'throttle' ? 'Throttle' : 'Ban' } rule${ throttle . perIp ? ' per-IP' : '' } for ${ endpoint . name } API endpoint` ,
141- priority,
142- preview,
143- action : action === 'ban' ? 'rate_based_ban' : 'throttle' ,
144- match : {
145- expr : {
146- expression : matchExpr ,
147- } ,
148- } ,
149- rateLimitOptions : {
150- // ban point is banThreshold + ratelimit count; consider splitting up rather than doubling
151- ...( action === 'ban'
152- ? {
153- banDurationSec : 600 ,
154- banThreshold : {
155- count : throttle . rate ,
156- intervalSec : throttle . interval ,
157- } ,
158- }
159- : { } ) ,
160- enforceOnKey : throttle . perIp ? 'IP' : 'ALL' ,
161- rateLimitThreshold : {
162- count : throttle . rate ,
163- intervalSec : throttle . interval ,
140+ new gcp . compute . SecurityPolicyRule (
141+ ruleName ,
142+ {
143+ securityPolicy : securityPolicy . name ,
144+ description : `Throttle rule for all ${ confEntryHead } API endpoints` ,
145+ priority,
146+ preview : preview || singleServiceThrottle . rulePreviewOnly ,
147+ action : 'throttle' ,
148+ match : {
149+ expr : {
150+ expression : matchExpr ,
151+ } ,
152+ } ,
153+ rateLimitOptions : {
154+ enforceOnKey : 'ALL' ,
155+ rateLimitThreshold : {
156+ count : throttleAcrossAllEndpointsAllIps . maxRequestsBeforeHttp429 ,
157+ intervalSec : throttleAcrossAllEndpointsAllIps . withinIntervalSeconds ,
158+ } ,
159+ conformAction : 'allow' ,
160+ exceedAction : 'deny(429)' , // 429 Too Many Requests
161+ } ,
164162 } ,
165- conformAction : 'allow' ,
166- exceedAction : 'deny(429)' , // 429 Too Many Requests
167- } ,
168- } ,
169- opts
170- ) ;
171- return priority + RULE_SPACING ;
172- } , THROTTLE_BAN_RULE_MIN ) ;
163+ opts
164+ ) ;
165+ }
166+ return priority + RULE_SPACING ;
167+ } ,
168+ THROTTLE_BAN_RULE_MIN
169+ ) ;
173170}
174171
175172/**
0 commit comments