package ec2 import ( "encoding/xml" "fmt" "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 data, err := cfg.awsConfig.GetEC2APIResponse("DescribeAvailabilityZones", "", "") 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 } // 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 }