VictoriaMetrics/lib/promscrape/discovery/ec2/az.go

82 lines
2.6 KiB
Go
Raw Normal View History

package ec2
import (
"encoding/xml"
"fmt"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/awsapi"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
)
func getAZMap(cfg *apiConfig) map[string]string {
cfg.azMapLock.Lock()
defer cfg.azMapLock.Unlock()
if cfg.azMap != nil {
return cfg.azMap
}
azs, err := getAvailabilityZones(cfg)
cfg.azMap = make(map[string]string, len(azs))
if err != nil {
logger.Warnf("couldn't load availability zones map, so __meta_ec2_availability_zone_id label isn't set: %s", err)
return cfg.azMap
}
for _, az := range azs {
cfg.azMap[az.ZoneName] = az.ZoneID
}
return cfg.azMap
}
func getAvailabilityZones(cfg *apiConfig) ([]AvailabilityZone, error) {
// See https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeAvailabilityZones.html
azFilters := awsapi.GetFiltersQueryString(cfg.azFilters, azFiltersWhitelist)
data, err := cfg.awsConfig.GetEC2APIResponse("DescribeAvailabilityZones", azFilters, "")
if err != nil {
return nil, fmt.Errorf("cannot obtain availability zones: %w", err)
}
azr, err := parseAvailabilityZonesResponse(data)
if err != nil {
return nil, fmt.Errorf("cannot parse availability zones list: %w", err)
}
return azr.AvailabilityZoneInfo.Items, nil
}
// See https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeAvailabilityZones.html
var azFiltersWhitelist = map[string]bool{
"group-name": true,
"message": true,
"opt-in-status": true,
"parent-zoneID": true,
"parent-zoneName": true,
"region-name": true,
"state": true,
"zone-id": true,
"zone-type": true,
"zone-name": true,
}
// AvailabilityZonesResponse represents the response for https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeAvailabilityZones.html
type AvailabilityZonesResponse struct {
AvailabilityZoneInfo AvailabilityZoneInfo `xml:"availabilityZoneInfo"`
}
// AvailabilityZoneInfo represents availabilityZoneInfo for https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeAvailabilityZones.html
type AvailabilityZoneInfo struct {
Items []AvailabilityZone `xml:"item"`
}
// AvailabilityZone represents availabilityZone for https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AvailabilityZone.html
type AvailabilityZone struct {
ZoneName string `xml:"zoneName"`
ZoneID string `xml:"zoneId"`
}
func parseAvailabilityZonesResponse(data []byte) (*AvailabilityZonesResponse, error) {
var v AvailabilityZonesResponse
if err := xml.Unmarshal(data, &v); err != nil {
return nil, fmt.Errorf("cannot unmarshal DescribeAvailabilityZonesResponse from %q: %w", data, err)
}
return &v, nil
}