terraform/builtin/providers/aws/data_source_aws_ip_ranges.go

152 lines
3.0 KiB
Go

package aws
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"sort"
"strconv"
"strings"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/terraform/helper/schema"
)
type dataSourceAwsIPRangesResult struct {
CreateDate string
Prefixes []dataSourceAwsIPRangesPrefix
SyncToken string
}
type dataSourceAwsIPRangesPrefix struct {
IpPrefix string `json:"ip_prefix"`
Region string
Service string
}
func dataSourceAwsIPRanges() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsIPRangesRead,
Schema: map[string]*schema.Schema{
"cidr_blocks": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"create_date": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"regions": &schema.Schema{
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},
"services": &schema.Schema{
Type: schema.TypeSet,
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"sync_token": &schema.Schema{
Type: schema.TypeInt,
Computed: true,
},
},
}
}
func dataSourceAwsIPRangesRead(d *schema.ResourceData, meta interface{}) error {
conn := cleanhttp.DefaultClient()
log.Printf("[DEBUG] Reading IP ranges")
res, err := conn.Get("https://ip-ranges.amazonaws.com/ip-ranges.json")
if err != nil {
return fmt.Errorf("Error listing IP ranges: %s", err)
}
defer res.Body.Close()
data, err := ioutil.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("Error reading response body: %s", err)
}
result := new(dataSourceAwsIPRangesResult)
if err := json.Unmarshal(data, result); err != nil {
return fmt.Errorf("Error parsing result: %s", err)
}
if err := d.Set("create_date", result.CreateDate); err != nil {
return fmt.Errorf("Error setting create date: %s", err)
}
syncToken, err := strconv.Atoi(result.SyncToken)
if err != nil {
return fmt.Errorf("Error while converting sync token: %s", err)
}
d.SetId(result.SyncToken)
if err := d.Set("sync_token", syncToken); err != nil {
return fmt.Errorf("Error setting sync token: %s", err)
}
get := func(key string) *schema.Set {
set := d.Get(key).(*schema.Set)
for _, e := range set.List() {
s := e.(string)
set.Remove(s)
set.Add(strings.ToLower(s))
}
return set
}
var (
regions = get("regions")
services = get("services")
noRegionFilter = regions.Len() == 0
prefixes []string
)
for _, e := range result.Prefixes {
var (
matchRegion = noRegionFilter || regions.Contains(strings.ToLower(e.Region))
matchService = services.Contains(strings.ToLower(e.Service))
)
if matchRegion && matchService {
prefixes = append(prefixes, e.IpPrefix)
}
}
if len(prefixes) == 0 {
return fmt.Errorf(" No IP ranges result from filters")
}
sort.Strings(prefixes)
if err := d.Set("cidr_blocks", prefixes); err != nil {
return fmt.Errorf("Error setting ip ranges: %s", err)
}
return nil
}