@@ -2,6 +2,7 @@ package main
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"sync"
6
7
"time"
7
8
@@ -153,13 +154,17 @@ func (c *VPCCollector) collectVpcsPerRegionQuota(ch chan<- prometheus.Metric) {
153
154
func (c * VPCCollector ) collectVpcsPerRegionUsage (ch chan <- prometheus.Metric ) {
154
155
ctx , cancelFunc := context .WithTimeout (context .Background (), c .e .timeout )
155
156
defer cancelFunc ()
156
- describeVpcsOutput , err := c .ec2 .DescribeVpcsWithContext (ctx , & ec2.DescribeVpcsInput {})
157
+ var vpcs []* ec2.Vpc
158
+ err := c .ec2 .DescribeVpcsPagesWithContext (ctx , & ec2.DescribeVpcsInput {}, func (page * ec2.DescribeVpcsOutput , lastPage bool ) bool {
159
+ vpcs = append (vpcs , page .Vpcs ... )
160
+ return ! lastPage
161
+ })
157
162
if err != nil {
158
163
level .Error (c .e .logger ).Log ("msg" , "Call to DescribeVpcs failed" , "region" , c .region , "err" , err )
159
164
exporterMetrics .IncrementErrors ()
160
165
return
161
166
}
162
- usage := len (describeVpcsOutput . Vpcs )
167
+ usage := len (vpcs )
163
168
ch <- prometheus .MustNewConstMetric (c .e .VpcsPerRegionUsage , prometheus .GaugeValue , float64 (usage ), * c .region )
164
169
}
165
170
@@ -176,18 +181,21 @@ func (c *VPCCollector) collectSubnetsPerVpcQuota(ch chan<- prometheus.Metric) {
176
181
func (c * VPCCollector ) collectSubnetsPerVpcUsage (ch chan <- prometheus.Metric , vpc * ec2.Vpc ) {
177
182
ctx , cancelFunc := context .WithTimeout (context .Background (), c .e .timeout )
178
183
defer cancelFunc ()
179
- describeSubnetsOutput , err := c .ec2 .DescribeSubnetsWithContext (ctx , & ec2.DescribeSubnetsInput {
180
- Filters : []* ec2.Filter {& ec2.Filter {
184
+ var subnets []* ec2.Subnet
185
+ err := c .ec2 .DescribeSubnetsPagesWithContext (ctx , & ec2.DescribeSubnetsInput {
186
+ Filters : []* ec2.Filter {{
181
187
Name : aws .String ("vpc-id" ),
182
188
Values : []* string {vpc .VpcId },
183
- }},
189
+ }}}, func (page * ec2.DescribeSubnetsOutput , lastPage bool ) bool {
190
+ subnets = append (subnets , page .Subnets ... )
191
+ return ! lastPage
184
192
})
185
193
if err != nil {
186
194
level .Error (c .e .logger ).Log ("msg" , "Call to DescribeSubnets failed" , "region" , c .region , "err" , err )
187
195
exporterMetrics .IncrementErrors ()
188
196
return
189
197
}
190
- usage := len (describeSubnetsOutput . Subnets )
198
+ usage := len (subnets )
191
199
ch <- prometheus .MustNewConstMetric (c .e .SubnetsPerVpcUsage , prometheus .GaugeValue , float64 (usage ), * c .region , * vpc .VpcId )
192
200
}
193
201
@@ -204,15 +212,25 @@ func (c *VPCCollector) collectRoutesPerRouteTableQuota(ch chan<- prometheus.Metr
204
212
func (c * VPCCollector ) collectRoutesPerRouteTableUsage (ch chan <- prometheus.Metric , rtb * ec2.RouteTable ) {
205
213
ctx , cancelFunc := context .WithTimeout (context .Background (), c .e .timeout )
206
214
defer cancelFunc ()
207
- descRouteTableOutput , err := c .ec2 .DescribeRouteTablesWithContext (ctx , & ec2.DescribeRouteTablesInput {
215
+ var routes []* ec2.Route
216
+ var unexpectedNumberOfRouteTables error
217
+ err := c .ec2 .DescribeRouteTablesPagesWithContext (ctx , & ec2.DescribeRouteTablesInput {
208
218
RouteTableIds : []* string {rtb .RouteTableId },
219
+ }, func (page * ec2.DescribeRouteTablesOutput , lastPage bool ) bool {
220
+ if len (page .RouteTables ) != 1 {
221
+ // Indicate that one of the calls return too many routetables making data invalid
222
+ unexpectedNumberOfRouteTables = errors .New ("Unexpected number of routetables returned" )
223
+ return false
224
+ }
225
+ routes = append (routes , page .RouteTables [0 ].Routes ... )
226
+ return ! lastPage
209
227
})
210
- if err != nil {
228
+ if err != nil || unexpectedNumberOfRouteTables != nil {
211
229
level .Error (c .e .logger ).Log ("msg" , "Call to DescribeRouteTables failed" , "region" , c .region , "err" , err )
212
230
exporterMetrics .IncrementErrors ()
213
231
return
214
232
}
215
- quota := len (descRouteTableOutput . RouteTables )
233
+ quota := len (routes )
216
234
ch <- prometheus .MustNewConstMetric (c .e .RoutesPerRouteTableUsage , prometheus .GaugeValue , float64 (quota ), * c .region , * rtb .VpcId , * rtb .RouteTableId )
217
235
}
218
236
@@ -229,19 +247,27 @@ func (c *VPCCollector) collectInterfaceVpcEndpointsPerVpcQuota(ch chan<- prometh
229
247
func (c * VPCCollector ) collectInterfaceVpcEndpointsPerVpcUsage (ch chan <- prometheus.Metric , vpc * ec2.Vpc ) {
230
248
ctx , cancelFunc := context .WithTimeout (context .Background (), c .e .timeout )
231
249
defer cancelFunc ()
232
- descVpcEndpoints , err := c .ec2 .DescribeVpcEndpointsWithContext (ctx , & ec2.DescribeVpcEndpointsInput {
233
- Filters : []* ec2.Filter {{
234
- Name : aws .String ("vpc-id" ),
235
- Values : []* string {vpc .VpcId },
236
- }},
250
+
251
+ numEndpoints := 0
252
+ descEndpointsInput := & ec2.DescribeVpcEndpointsInput {
253
+ Filters : []* ec2.Filter {{Name : aws .String ("vpc-id" ), Values : []* string {vpc .VpcId }}},
254
+ MaxResults : aws .Int64 (1000 ),
255
+ }
256
+
257
+ var vpcEndpoints []* ec2.VpcEndpoint
258
+ err := c .ec2 .DescribeVpcEndpointsPagesWithContext (ctx , descEndpointsInput , func (page * ec2.DescribeVpcEndpointsOutput , lastPage bool ) bool {
259
+ vpcEndpoints = append (vpcEndpoints , page .VpcEndpoints ... )
260
+ return ! lastPage
237
261
})
262
+
238
263
if err != nil {
239
264
level .Error (c .e .logger ).Log ("msg" , "Call to DescribeVpcEndpoints failed" , "region" , c .region , "err" , err )
240
265
exporterMetrics .IncrementErrors ()
241
266
return
242
267
}
243
- quota := len (descVpcEndpoints .VpcEndpoints )
244
- ch <- prometheus .MustNewConstMetric (c .e .InterfaceVpcEndpointsPerVpcUsage , prometheus .GaugeValue , float64 (quota ), * c .region , * vpc .VpcId )
268
+ numEndpoints += len (vpcEndpoints )
269
+
270
+ ch <- prometheus .MustNewConstMetric (c .e .InterfaceVpcEndpointsPerVpcUsage , prometheus .GaugeValue , float64 (numEndpoints ), * c .region , * vpc .VpcId )
245
271
}
246
272
247
273
func (c * VPCCollector ) collectRoutesTablesPerVpcQuota (ch chan <- prometheus.Metric ) {
@@ -257,18 +283,22 @@ func (c *VPCCollector) collectRoutesTablesPerVpcQuota(ch chan<- prometheus.Metri
257
283
func (c * VPCCollector ) collectRoutesTablesPerVpcUsage (ch chan <- prometheus.Metric , vpc * ec2.Vpc ) {
258
284
ctx , cancelFunc := context .WithTimeout (context .Background (), c .e .timeout )
259
285
defer cancelFunc ()
260
- descRouteTables , err := c .ec2 .DescribeRouteTablesWithContext (ctx , & ec2.DescribeRouteTablesInput {
286
+ var routeTables []* ec2.RouteTable
287
+ input := & ec2.DescribeRouteTablesInput {
261
288
Filters : []* ec2.Filter {{
262
289
Name : aws .String ("vpc-id" ),
263
290
Values : []* string {vpc .VpcId },
264
- }},
291
+ }}}
292
+ err := c .ec2 .DescribeRouteTablesPagesWithContext (ctx , input , func (page * ec2.DescribeRouteTablesOutput , lastPage bool ) bool {
293
+ routeTables = append (routeTables , page .RouteTables ... )
294
+ return ! lastPage
265
295
})
266
296
if err != nil {
267
297
level .Error (c .e .logger ).Log ("msg" , "Call to DescribeRouteTables failed" , "region" , c .region , "err" , err )
268
298
exporterMetrics .IncrementErrors ()
269
299
return
270
300
}
271
- quota := len (descRouteTables . RouteTables )
301
+ quota := len (routeTables )
272
302
ch <- prometheus .MustNewConstMetric (c .e .RouteTablesPerVpcUsage , prometheus .GaugeValue , float64 (quota ), * c .region , * vpc .VpcId )
273
303
}
274
304
@@ -285,18 +315,28 @@ func (c *VPCCollector) collectIPv4BlocksPerVpcQuota(ch chan<- prometheus.Metric)
285
315
func (c * VPCCollector ) collectIPv4BlocksPerVpcUsage (ch chan <- prometheus.Metric , vpc * ec2.Vpc ) {
286
316
ctx , cancelFunc := context .WithTimeout (context .Background (), c .e .timeout )
287
317
defer cancelFunc ()
288
- descVpcs , err := c . ec2 . DescribeVpcsWithContext ( ctx , & ec2.DescribeVpcsInput {
318
+ input := & ec2.DescribeVpcsInput {
289
319
VpcIds : []* string {vpc .VpcId },
320
+ }
321
+ var unexpectedNumberOfVpcs error
322
+ var cidrBlockAssociations []* ec2.VpcCidrBlockAssociation
323
+ err := c .ec2 .DescribeVpcsPagesWithContext (ctx , input , func (page * ec2.DescribeVpcsOutput , lastPage bool ) bool {
324
+ if len (page .Vpcs ) != 1 {
325
+ unexpectedNumberOfVpcs = errors .New ("Unexpected number of vpcs received" )
326
+ return false
327
+ }
328
+ cidrBlockAssociations = append (cidrBlockAssociations , page .Vpcs [0 ].CidrBlockAssociationSet ... )
329
+ return ! lastPage
290
330
})
291
331
if err != nil {
292
332
level .Error (c .e .logger ).Log ("msg" , "Call to DescribeVpcs failed" , "region" , c .region , "err" , err )
293
333
exporterMetrics .IncrementErrors ()
294
334
return
295
335
}
296
- if len ( descVpcs . Vpcs ) != 1 {
336
+ if unexpectedNumberOfVpcs != nil {
297
337
level .Error (c .e .logger ).Log ("msg" , "Unexpected numbers of VPCs (!= 1) returned" , "region" , c .region , "vpcId" , vpc .VpcId )
298
338
}
299
- quota := len (descVpcs . Vpcs [ 0 ]. CidrBlockAssociationSet )
339
+ quota := len (cidrBlockAssociations )
300
340
ch <- prometheus .MustNewConstMetric (c .e .IPv4BlocksPerVpcUsage , prometheus .GaugeValue , float64 (quota ), * c .region , * vpc .VpcId )
301
341
}
302
342
0 commit comments