From ccd00bf1ec35e7815beabc0ee4c2f3ba99f9274f Mon Sep 17 00:00:00 2001 From: Roberth Kulbin Date: Tue, 21 Jul 2020 22:49:00 +0100 Subject: [PATCH] d/aws_prefix_list: add managed prefix list support --- aws/data_source_aws_prefix_list.go | 55 +++++++++++++++++- aws/data_source_aws_prefix_list_test.go | 74 ++++++++++++++++++++++++ website/docs/d/prefix_list.html.markdown | 35 ++++++++++- 3 files changed, 158 insertions(+), 6 deletions(-) diff --git a/aws/data_source_aws_prefix_list.go b/aws/data_source_aws_prefix_list.go index fdb0fe24a39..eea2f8af8c2 100644 --- a/aws/data_source_aws_prefix_list.go +++ b/aws/data_source_aws_prefix_list.go @@ -8,6 +8,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) func dataSourceAwsPrefixList() *schema.Resource { @@ -30,16 +32,34 @@ func dataSourceAwsPrefixList() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, "filter": dataSourceFiltersSchema(), + "owner_id": { + Type: schema.TypeString, + Computed: true, + }, + "address_family": { + Type: schema.TypeString, + Computed: true, + }, + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "max_entries": { + Type: schema.TypeInt, + Computed: true, + }, + "tags": tagsSchemaComputed(), }, } } func dataSourceAwsPrefixListRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig filters, filtersOk := d.GetOk("filter") - req := &ec2.DescribePrefixListsInput{} + req := &ec2.DescribeManagedPrefixListsInput{} if filtersOk { req.Filters = buildAwsDataSourceFilters(filters.(*schema.Set)) } @@ -54,7 +74,7 @@ func dataSourceAwsPrefixListRead(d *schema.ResourceData, meta interface{}) error } log.Printf("[DEBUG] Reading Prefix List: %s", req) - resp, err := conn.DescribePrefixLists(req) + resp, err := conn.DescribeManagedPrefixLists(req) switch { case err != nil: return err @@ -69,11 +89,40 @@ func dataSourceAwsPrefixListRead(d *schema.ResourceData, meta interface{}) error d.SetId(*pl.PrefixListId) d.Set("name", pl.PrefixListName) - cidrs := aws.StringValueSlice(pl.Cidrs) + getEntriesInput := ec2.GetManagedPrefixListEntriesInput{ + PrefixListId: pl.PrefixListId, + } + + cidrs := []string(nil) + + err = conn.GetManagedPrefixListEntriesPages( + &getEntriesInput, func(output *ec2.GetManagedPrefixListEntriesOutput, last bool) bool { + for _, entry := range output.Entries { + cidrs = append(cidrs, aws.StringValue(entry.Cidr)) + } + return true + }) + if err != nil { + return fmt.Errorf("failed to get entries of prefix list %s: %s", *pl.PrefixListId, err) + } + sort.Strings(cidrs) + if err := d.Set("cidr_blocks", cidrs); err != nil { return fmt.Errorf("failed to set cidr blocks of prefix list %s: %s", d.Id(), err) } + d.Set("owner_id", pl.OwnerId) + d.Set("address_family", pl.AddressFamily) + d.Set("arn", pl.PrefixListArn) + + if actual := aws.Int64Value(pl.MaxEntries); actual > 0 { + d.Set("max_entries", actual) + } + + if err := d.Set("tags", keyvaluetags.Ec2KeyValueTags(pl.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("failed to set tags of prefix list %s: %s", d.Id(), err) + } + return nil } diff --git a/aws/data_source_aws_prefix_list_test.go b/aws/data_source_aws_prefix_list_test.go index ae351ae06b0..501b1ad5dd4 100644 --- a/aws/data_source_aws_prefix_list_test.go +++ b/aws/data_source_aws_prefix_list_test.go @@ -70,6 +70,26 @@ func testAccDataSourceAwsPrefixListCheck(name string) resource.TestCheckFunc { return fmt.Errorf("cidr_blocks seem suspiciously low: %d", cidrBlockSize) } + if actual := attr["owner_id"]; actual != "AWS" { + return fmt.Errorf("bad owner_id %s", actual) + } + + if actual := attr["address_family"]; actual != "IPv4" { + return fmt.Errorf("bad address_family %s", actual) + } + + if actual := attr["arn"]; actual != "arn:aws:ec2:us-west-2:aws:prefix-list/pl-68a54001" { + return fmt.Errorf("bad arn %s", actual) + } + + if actual := attr["max_entries"]; actual != "" { + return fmt.Errorf("unexpected max_entries %s", actual) + } + + if attr["tags.%"] != "0" { + return fmt.Errorf("expected 0 tags") + } + return nil } } @@ -143,3 +163,57 @@ data "aws_prefix_list" "test" { } } ` + +func TestAccDataSourceAwsPrefixList_managedPrefixList(t *testing.T) { + resourceName := "aws_prefix_list.test" + dataSourceName := "data.aws_prefix_list.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSPrefixListDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsPrefixListConfig_managedPrefixList, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair(resourceName, "id", dataSourceName, "id"), + resource.TestCheckResourceAttrPair(resourceName, "name", dataSourceName, "name"), + resource.TestCheckResourceAttrPair(resourceName, "arn", dataSourceName, "arn"), + resource.TestCheckResourceAttrPair(resourceName, "owner_id", dataSourceName, "owner_id"), + testAccCheckResourceAttrAccountID(dataSourceName, "owner_id"), + resource.TestCheckResourceAttrPair(resourceName, "name", dataSourceName, "name"), + resource.TestCheckResourceAttrPair(resourceName, "address_family", dataSourceName, "address_family"), + resource.TestCheckResourceAttrPair(resourceName, "max_entries", dataSourceName, "max_entries"), + resource.TestCheckResourceAttr(dataSourceName, "cidr_blocks.#", "2"), + resource.TestCheckResourceAttr(dataSourceName, "cidr_blocks.0", "1.0.0.0/8"), + resource.TestCheckResourceAttr(dataSourceName, "cidr_blocks.1", "2.0.0.0/8"), + resource.TestCheckResourceAttr(dataSourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(dataSourceName, "tags.Key1", "Value1"), + resource.TestCheckResourceAttr(dataSourceName, "tags.Key2", "Value2"), + ), + }, + }, + }) +} + +const testAccDataSourceAwsPrefixListConfig_managedPrefixList = ` +resource "aws_prefix_list" "test" { + name = "tf-test-acc" + max_entries = 5 + address_family = "IPv4" + entry { + cidr_block = "1.0.0.0/8" + } + entry { + cidr_block = "2.0.0.0/8" + } + tags = { + Key1 = "Value1" + Key2 = "Value2" + } +} + +data "aws_prefix_list" "test" { + prefix_list_id = aws_prefix_list.test.id +} +` diff --git a/website/docs/d/prefix_list.html.markdown b/website/docs/d/prefix_list.html.markdown index b2b5c8ff356..20372f4c78a 100644 --- a/website/docs/d/prefix_list.html.markdown +++ b/website/docs/d/prefix_list.html.markdown @@ -8,8 +8,8 @@ description: |- # Data Source: aws_prefix_list -`aws_prefix_list` provides details about a specific prefix list (PL) -in the current region. +`aws_prefix_list` provides details about a specific AWS prefix list (PL) +or a customer-managed prefix list in the current region. This can be used both to validate a prefix list given in a variable and to obtain the CIDR blocks (IP address ranges) for the associated @@ -64,6 +64,30 @@ data "aws_prefix_list" "test" { } ``` +### Find a managed prefix list + +```hcl +resource "aws_prefix_list" "example" { + name = "example" + max_entries = 5 + address_family = "IPv4" + entry { + cidr_block = "1.0.0.0/8" + } + entry { + cidr_block = "2.0.0.0/8" + } + tags = { + Key1 = "Value1" + Key2 = "Value2" + } +} + +data "aws_prefix_list" "example" { + prefix_list_id = aws_prefix_list.example.id +} +``` + ## Argument Reference The arguments of this data source act as filters for querying the available @@ -78,7 +102,7 @@ whose data will be exported as attributes. The following arguments are supported by the `filter` configuration block: -* `name` - (Required) The name of the filter field. Valid values can be found in the [EC2 DescribePrefixLists API Reference](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribePrefixLists.html). +* `name` - (Required) The name of the filter field. Valid values can be found in the EC2 [DescribeManagedPrefixLists](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeManagedPrefixLists.html) API Reference. * `values` - (Required) Set of values that are accepted for the given filter field. Results will be selected if any given value matches. ## Attributes Reference @@ -86,5 +110,10 @@ The following arguments are supported by the `filter` configuration block: In addition to all arguments above, the following attributes are exported: * `id` - The ID of the selected prefix list. +* `arn` - The ARN of the selected prefix list. * `name` - The name of the selected prefix list. * `cidr_blocks` - The list of CIDR blocks for the AWS service associated with the prefix list. +* `owner_id` - The Account ID of the owner of a customer-managed prefix list, or `AWS` otherwise. +* `address_family` - The address family of the prefix list. Valid values are `IPv4` and `IPv6`. +* `max_entries` - When then prefix list is managed, the maximum number of entries it supports, or null otherwise. +* `tags` - A map of tags assigned to the resource.