Skip to content

Commit

Permalink
Merge pull request #27101 from drewmullen/f-data_vpc_ipam_pools
Browse files Browse the repository at this point in the history
[New Data Source] data vpc ipam pools
  • Loading branch information
ewbankkit authored Oct 11, 2022
2 parents ec68e36 + 406b379 commit 2bd8ae2
Show file tree
Hide file tree
Showing 6 changed files with 434 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/27101.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-data-source
aws_vpc_ipam_pools
```
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ func New(_ context.Context) (*schema.Provider, error) {
"aws_vpc_endpoint_service": ec2.DataSourceVPCEndpointService(),
"aws_vpc_endpoint": ec2.DataSourceVPCEndpoint(),
"aws_vpc_ipam_pool": ec2.DataSourceIPAMPool(),
"aws_vpc_ipam_pools": ec2.DataSourceIPAMPools(),
"aws_vpc_ipam_pool_cidrs": ec2.DataSourceIPAMPoolCIDRs(),
"aws_vpc_ipam_preview_next_cidr": ec2.DataSourceIPAMPreviewNextCIDR(),
"aws_vpc_peering_connection": ec2.DataSourceVPCPeeringConnection(),
Expand Down
24 changes: 24 additions & 0 deletions internal/service/ec2/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -4970,6 +4970,30 @@ func FindIPAMPoolCIDRs(conn *ec2.EC2, input *ec2.GetIpamPoolCidrsInput) ([]*ec2.
return output, nil
}

func FindIPAMPools(conn *ec2.EC2, input *ec2.DescribeIpamPoolsInput) ([]*ec2.IpamPool, error) {
var output []*ec2.IpamPool

err := conn.DescribeIpamPoolsPages(input, func(page *ec2.DescribeIpamPoolsOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}

for _, v := range page.IpamPools {
if v != nil {
output = append(output, v)
}
}

return !lastPage
})

if err != nil {
return nil, err
}

return output, nil
}

func FindKeyPair(conn *ec2.EC2, input *ec2.DescribeKeyPairsInput) (*ec2.KeyPairInfo, error) {
output, err := FindKeyPairs(conn, input)

Expand Down
176 changes: 176 additions & 0 deletions internal/service/ec2/ipam_pools_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package ec2

import (
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
)

func DataSourceIPAMPools() *schema.Resource {
return &schema.Resource{
Read: dataSourceIPAMPoolsRead,

Schema: map[string]*schema.Schema{
"filter": DataSourceFiltersSchema(),

"ipam_pools": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},

"address_family": {
Type: schema.TypeString,
Computed: true,
},

"allocation_default_netmask_length": {
Type: schema.TypeInt,
Computed: true,
},

"allocation_max_netmask_length": {
Type: schema.TypeInt,
Computed: true,
},

"allocation_min_netmask_length": {
Type: schema.TypeInt,
Computed: true,
},

"allocation_resource_tags": tftags.TagsSchemaComputed(),

"auto_import": {
Type: schema.TypeBool,
Computed: true,
},

"aws_service": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},

"id": {
Type: schema.TypeString,
Optional: true,
},

"ipam_scope_id": {
Type: schema.TypeString,
Computed: true,
},

"ipam_scope_type": {
Type: schema.TypeString,
Computed: true,
},

"ipam_pool_id": {
Type: schema.TypeString,
Computed: true,
},

"locale": {
Type: schema.TypeString,
Computed: true,
},

"publicly_advertisable": {
Type: schema.TypeBool,
Computed: true,
},

"pool_depth": {
Type: schema.TypeInt,
Computed: true,
},

"source_ipam_pool_id": {
Type: schema.TypeString,
Computed: true,
},

"state": {
Type: schema.TypeString,
Computed: true,
},

"tags": tftags.TagsSchemaComputed(),
},
},
},
},
}
}

func dataSourceIPAMPoolsRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).EC2Conn
ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig

input := &ec2.DescribeIpamPoolsInput{}

filters, filtersOk := d.GetOk("filter")
if filtersOk {
input.Filters = BuildFiltersDataSource(filters.(*schema.Set))
}

pools, err := FindIPAMPools(conn, input)

if err != nil {
return err
}

d.Set("ipam_pools", flattenIPAMPools(pools, ignoreTagsConfig))

d.SetId(meta.(*conns.AWSClient).Region)

return nil
}

func flattenIPAMPools(c []*ec2.IpamPool, ignoreTagsConfig *tftags.IgnoreConfig) []interface{} {
pools := []interface{}{}
for _, pool := range c {
pools = append(pools, flattenIPAMPool(pool, ignoreTagsConfig))
}
return pools
}

func flattenIPAMPool(p *ec2.IpamPool, ignoreTagsConfig *tftags.IgnoreConfig) map[string]interface{} {
pool := make(map[string]interface{})

pool["address_family"] = aws.StringValue(p.AddressFamily)
pool["allocation_default_netmask_length"] = aws.Int64Value(p.AllocationDefaultNetmaskLength)
pool["allocation_max_netmask_length"] = aws.Int64Value(p.AllocationMaxNetmaskLength)
pool["allocation_min_netmask_length"] = aws.Int64Value(p.AllocationMinNetmaskLength)
pool["allocation_resource_tags"] = KeyValueTags(tagsFromIPAMAllocationTags(p.AllocationResourceTags)).Map()
pool["arn"] = aws.StringValue(p.IpamPoolArn)
pool["auto_import"] = aws.BoolValue(p.AutoImport)
pool["aws_service"] = aws.StringValue(p.AwsService)
pool["description"] = aws.StringValue(p.Description)
pool["ipam_scope_id"] = strings.Split(aws.StringValue(p.IpamScopeArn), "/")[1]
pool["ipam_scope_type"] = aws.StringValue(p.IpamScopeType)
pool["locale"] = aws.StringValue(p.Locale)
pool["pool_depth"] = aws.Int64Value(p.PoolDepth)
pool["publicly_advertisable"] = aws.BoolValue(p.PubliclyAdvertisable)
pool["source_ipam_pool_id"] = aws.StringValue(p.SourceIpamPoolId)
pool["state"] = aws.StringValue(p.State)

if v := p.Tags; v != nil {
pool["tags"] = KeyValueTags(v).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()
}

return pool
}
166 changes: 166 additions & 0 deletions internal/service/ec2/ipam_pools_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package ec2_test

import (
"testing"

"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
)

func TestAccIPAMPoolsDataSource_basic(t *testing.T) {
dataSourceName := "data.aws_vpc_ipam_pools.test"
dataSourceNameTwo := "data.aws_vpc_ipam_pools.testtwo"
resourceName := "aws_vpc_ipam_pool.testthree"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t); testAccIPAMPreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccIPAMPoolsDataSourceConfig_basic,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "ipam_pools.#", "1"),
),
},
{
Config: testAccIPAMPoolsDataSourceConfig_basicTwoPools,
Check: resource.ComposeAggregateTestCheckFunc(
// DS 1 finds all 3 pools
resource.TestCheckResourceAttr(dataSourceName, "ipam_pools.#", "3"),

// DS 2 filters on 1 specific pool to validate attributes
resource.TestCheckResourceAttr(dataSourceNameTwo, "ipam_pools.#", "1"),

resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.address_family", resourceName, "address_family"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.allocation_default_netmask_length", resourceName, "allocation_default_netmask_length"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.allocation_max_netmask_length", resourceName, "allocation_max_netmask_length"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.allocation_min_netmask_length", resourceName, "allocation_min_netmask_length"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.allocation_resource_tags.%", resourceName, "allocation_resource_tags.%"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.auto_import", resourceName, "auto_import"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.description", resourceName, "description"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.aws_service", resourceName, "aws_service"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.ipam_scope_id", resourceName, "ipam_scope_id"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.ipam_scope_type", resourceName, "ipam_scope_type"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.locale", resourceName, "locale"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.pool_depth", resourceName, "pool_depth"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.publicly_advertisable", resourceName, "publicly_advertisable"),
resource.TestCheckResourceAttrPair(dataSourceNameTwo, "ipam_pools.0.source_ipam_pool_id", resourceName, "source_ipam_pool_id"),

resource.TestCheckResourceAttr(dataSourceNameTwo, "ipam_pools.0.tags.tagtest", "3"),
),
},
},
})
}

func TestAccIPAMPoolsDataSource_empty(t *testing.T) {
dataSourceName := "data.aws_vpc_ipam_pools.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t); testAccIPAMPreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccIPAMPoolsDataSourceConfig_empty,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "ipam_pools.#", "0"),
),
},
},
})
}

var testAccIPAMPoolsDataSourceConfig_basic = acctest.ConfigCompose(testAccIPAMPoolConfig_base, `
resource "aws_vpc_ipam_pool" "test" {
address_family = "ipv4"
ipam_scope_id = aws_vpc_ipam.test.private_default_scope_id
auto_import = true
allocation_default_netmask_length = 32
allocation_max_netmask_length = 32
allocation_min_netmask_length = 32
allocation_resource_tags = {
test = "1"
}
description = "test"
}
data "aws_vpc_ipam_pools" "test" {
depends_on = [
aws_vpc_ipam_pool.test
]
}
`)

var testAccIPAMPoolsDataSourceConfig_basicTwoPools = acctest.ConfigCompose(testAccIPAMPoolConfig_base, `
resource "aws_vpc_ipam_pool" "test" {
address_family = "ipv4"
ipam_scope_id = aws_vpc_ipam.test.private_default_scope_id
auto_import = true
allocation_default_netmask_length = 32
allocation_max_netmask_length = 32
allocation_min_netmask_length = 32
allocation_resource_tags = {
test = "1"
}
description = "test"
}
resource "aws_vpc_ipam_pool" "testtwo" {
address_family = "ipv4"
ipam_scope_id = aws_vpc_ipam.test.private_default_scope_id
allocation_resource_tags = {
test = "2"
}
description = "testtwo"
}
resource "aws_vpc_ipam_pool" "testthree" {
address_family = "ipv4"
ipam_scope_id = aws_vpc_ipam.test.private_default_scope_id
allocation_default_netmask_length = 32
allocation_max_netmask_length = 32
allocation_min_netmask_length = 32
auto_import = true
allocation_resource_tags = {
test = "3"
}
description = "testthree"
tags = {
tagtest = 3
}
}
data "aws_vpc_ipam_pools" "test" {
depends_on = [
aws_vpc_ipam_pool.test,
aws_vpc_ipam_pool.testtwo,
aws_vpc_ipam_pool.testthree
]
}
data "aws_vpc_ipam_pools" "testtwo" {
filter {
name = "description"
values = ["*three*"]
}
depends_on = [
aws_vpc_ipam_pool.test,
aws_vpc_ipam_pool.testtwo,
aws_vpc_ipam_pool.testthree
]
}
`)

var testAccIPAMPoolsDataSourceConfig_empty = acctest.ConfigCompose(`
data "aws_vpc_ipam_pools" "test" {
filter {
name = "description"
values = ["*none*"]
}
}
`)
Loading

0 comments on commit 2bd8ae2

Please sign in to comment.