Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ AWS Resource Exporter is a Prometheus exporter for AWS resources, built in Go. I
- `aws_resources_exporter_vpc_routesperroutetable_usage` - Usage of routes per route table
- `aws_resources_exporter_vpc_ipv4blockspervpc_quota` - Quota for IPv4 blocks per VPC
- `aws_resources_exporter_vpc_ipv4blockspervpc_usage` - Usage of IPv4 blocks per VPC
- `aws_resources_exporter_vpc_ipv4addressespersubnet_capacity` - Amount of usable IPv4 addresses per subnet (based on CIDR block)
- `aws_resources_exporter_vpc_ipv4addressespersubnet_usage` - Used IPv4 addresses per subnet

### EC2 Metrics
- `aws_resources_exporter_ec2_transitgatewaysperregion_quota` - Quota for transit gateways per region
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ This was made as a complement to [CloudWatch Exporter](https://github.com/promet
| VPC | routetablespervpc | Quota and usage of routetables per VPC |
| VPC | routesperroutetable | Quota and usage of the routes per routetable |
| VPC | ipv4blockspervpc | Quota and usage of ipv4 blocks per VPC |
| VPC | ipv4addressespersubnet | Capacity and usage of IPv4 addresses per subnet |
| EC2 | transitgatewaysperregion | Quota and usage of transitgateways per region |
| Route53 | recordsperhostedzone | Quota and usage of resource records per Hosted Zone |

Expand Down
248 changes: 247 additions & 1 deletion dashboards/aws-resource-exporter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -735,12 +735,258 @@ data:
"type": "alertlist"
},
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 32
},
"id": 17,
"panels": [],
"title": "VPC",
"type": "row"
},
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"description": "Shows IPv4 address utilization per subnet",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 33
},
"id": 18,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "multi",
"sort": "none"
}
},
"pluginVersion": "10.4.1",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"editorMode": "code",
"expr": "aws_resources_exporter_vpc_ipv4addressespersubnet_capacity",
"legendFormat": "{{subnetid}} capacity",
"range": true,
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"editorMode": "code",
"expr": "aws_resources_exporter_vpc_ipv4addressespersubnet_usage",
"legendFormat": "{{subnetid}} used",
"range": true,
"refId": "B"
}
],
"title": "IPv4 Address Usage per Subnet",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"description": "Shows percentage utilization of IPv4 addresses per subnet",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "color-background"
},
"filterable": true,
"inspect": false
},
"mappings": [],
"max": 100,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "yellow",
"value": 70
},
{
"color": "red",
"value": 90
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 33
},
"id": 19,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"enablePagination": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"sortBy": [
{
"desc": true,
"displayName": "Utilization %"
}
]
},
"pluginVersion": "10.4.1",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"editorMode": "code",
"expr": "(aws_resources_exporter_vpc_ipv4addressespersubnet_usage / aws_resources_exporter_vpc_ipv4addressespersubnet_capacity) * 100",
"format": "table",
"legendFormat": "__auto",
"range": true,
"refId": "A"
}
],
"title": "Subnet IPv4 Utilization",
"transformations": [
{
"id": "groupBy",
"options": {
"fields": {
"Value": {
"aggregations": [
"lastNotNull"
],
"operation": "aggregate"
},
"aws_region": {
"aggregations": [],
"operation": "groupby"
},
"subnetid": {
"aggregations": [],
"operation": "groupby"
},
"vpcid": {
"aggregations": [],
"operation": "groupby"
}
}
}
},
{
"id": "organize",
"options": {
"excludeByName": {},
"indexByName": {},
"renameByName": {
"Value (lastNotNull)": "Utilization %",
"aws_region": "Region",
"subnetid": "Subnet ID",
"vpcid": "VPC ID"
}
}
}
],
"type": "table"
},
{
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 41
},
"id": 4,
"title": "Route53",
"type": "row"
Expand Down Expand Up @@ -806,7 +1052,7 @@ data:
"h": 8,
"w": 24,
"x": 0,
"y": 33
"y": 42
},
"id": 2,
"options": {
Expand Down
23 changes: 23 additions & 0 deletions pkg/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pkg

import (
"errors"
"net"
"os"
"sort"
"strconv"
Expand Down Expand Up @@ -61,3 +62,25 @@ func GetEOLStatus(eol string, thresholds []Threshold) (string, error) {
}
return thresholds[len(thresholds)-1].Name, nil
}

// CalculateTotalIPsFromCIDR calculates the total number of IP addresses in a CIDR block using Go's net package
func CalculateTotalIPsFromCIDR(cidrBlock string) (int64, error) {
_, ipNet, err := net.ParseCIDR(cidrBlock)
if err != nil {
return 0, err
}

// Get the prefix length
prefixLength, _ := ipNet.Mask.Size()

// Validate reasonable prefix length for IPv4 subnets (AWS supports /16 to /28)
if prefixLength < 16 || prefixLength > 28 {
return 0, errors.New("invalid subnet prefix length for AWS (must be /16 to /28)")
}

// For IPv4, calculate 2^(32-prefix_length)
hostBits := 32 - prefixLength
totalIPs := int64(1 << hostBits)

return totalIPs, nil
}
Loading