Skip to content

Commit

Permalink
Merge pull request #21219 from jordiprats/main
Browse files Browse the repository at this point in the history
Various data sources: Return empty lists rather than errors when no resources match
  • Loading branch information
ewbankkit authored Jan 26, 2022
2 parents bbfa631 + 9b4b1ca commit 396c6aa
Show file tree
Hide file tree
Showing 39 changed files with 1,303 additions and 854 deletions.
67 changes: 67 additions & 0 deletions .changelog/21219.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
```release-note:note
data-source/aws_security_groups: If no security groups match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_route_tables: The type of the `ids` attribute has changed from Set to List. If no route tables match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_network_interfaces: The type of the `ids` attribute has changed from Set to List. If no network interfaces match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_network_acls: The type of the `ids` attribute has changed from Set to List. If no NACLs match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_ec2_transit_gateway_route_tables: The type of the `ids` attribute has changed from Set to List. If no transit gateway route tables match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_ec2_coip_pools: The type of the `pool_ids` attribute has changed from Set to List. If no COIP pools match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_ec2_local_gateway_route_tables: The type of the `ids` attribute has changed from Set to List. If no local gateway route tables match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_ec2_local_gateway_virtual_interface_groups: The type of the `ids` and `local_gateway_virtual_interface_ids` attributes has changed from Set to List. If no local gateway virtual interface groups match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_ec2_local_gateways: The type of the `ids` attribute has changed from Set to List. If no local gateways match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_ebs_volumes: The type of the `ids` attribute has changed from Set to List. If no volumes match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_cognito_user_pools: The type of the `ids` and `arns` attributes has changed from Set to List. If no volumes match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_ip_ranges: If no ranges match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_efs_access_points: The type of the `ids` and `arns` attributes has changed from Set to List. If no access points match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_emr_release_labels: The type of the `ids` attribute has changed from Set to List. If no release labels match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_inspector_rules_packages: If no rules packages match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_db_event_categories: The type of the `ids` attribute has changed from Set to List. If no event categories match the specified criteria an empty list is returned (previously an error was raised)
```

```release-note:note
data-source/aws_ssoadmin_instances: The type of the `identity_store_ids` and `arns` attributes has changed from Set to List. If no instances match the specified criteria an empty list is returned (previously an error was raised)
```
3 changes: 3 additions & 0 deletions .changelog/5055.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:note
data-source/aws_instances: If no instances match the specified criteria an empty list is returned (previously an error was raised)
```
99 changes: 50 additions & 49 deletions internal/service/cognitoidp/user_pools_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,85 +13,86 @@ import (
func DataSourceUserPools() *schema.Resource {
return &schema.Resource{
Read: dataSourceUserPoolsRead,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"ids": {
Type: schema.TypeSet,
"arns": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"arns": {
Type: schema.TypeSet,
"ids": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"name": {
Type: schema.TypeString,
Required: true,
},
},
}
}

func dataSourceUserPoolsRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).CognitoIDPConn
name := d.Get("name").(string)
var ids []string
var arns []string

pools, err := getAllCognitoUserPools(conn)
output, err := findUserPoolDescriptionTypes(conn)

if err != nil {
return fmt.Errorf("Error listing cognito user pools: %w", err)
return fmt.Errorf("error reading Cognito User Pools: %w", err)
}
for _, pool := range pools {
if name == aws.StringValue(pool.Name) {
id := aws.StringValue(pool.Id)
arn := arn.ARN{
Partition: meta.(*conns.AWSClient).Partition,
Service: "cognito-idp",
Region: meta.(*conns.AWSClient).Region,
AccountID: meta.(*conns.AWSClient).AccountID,
Resource: fmt.Sprintf("userpool/%s", id),
}.String()

ids = append(ids, id)
arns = append(arns, arn)

name := d.Get("name").(string)
var arns, userPoolIDs []string

for _, v := range output {
if name != aws.StringValue(v.Name) {
continue
}
}

if len(ids) == 0 {
return fmt.Errorf("No cognito user pool found with name: %s", name)
userPoolID := aws.StringValue(v.Id)
arn := arn.ARN{
Partition: meta.(*conns.AWSClient).Partition,
Service: cognitoidentityprovider.ServiceName,
Region: meta.(*conns.AWSClient).Region,
AccountID: meta.(*conns.AWSClient).AccountID,
Resource: fmt.Sprintf("userpool/%s", userPoolID),
}.String()

userPoolIDs = append(userPoolIDs, userPoolID)
arns = append(arns, arn)
}

d.SetId(name)
d.Set("ids", ids)
d.Set("ids", userPoolIDs)
d.Set("arns", arns)

return nil
}

func getAllCognitoUserPools(conn *cognitoidentityprovider.CognitoIdentityProvider) ([]*cognitoidentityprovider.UserPoolDescriptionType, error) {
var pools []*cognitoidentityprovider.UserPoolDescriptionType
var nextToken string
func findUserPoolDescriptionTypes(conn *cognitoidentityprovider.CognitoIdentityProvider) ([]*cognitoidentityprovider.UserPoolDescriptionType, error) {
input := &cognitoidentityprovider.ListUserPoolsInput{
MaxResults: aws.Int64(60),
}
var output []*cognitoidentityprovider.UserPoolDescriptionType

for {
input := &cognitoidentityprovider.ListUserPoolsInput{
// MaxResults Valid Range: Minimum value of 1. Maximum value of 60
MaxResults: aws.Int64(60),
}
if nextToken != "" {
input.NextToken = aws.String(nextToken)
}
out, err := conn.ListUserPools(input)
if err != nil {
return pools, err
err := conn.ListUserPoolsPages(input, func(page *cognitoidentityprovider.ListUserPoolsOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}
pools = append(pools, out.UserPools...)

if out.NextToken == nil {
break
for _, v := range page.UserPools {
if v != nil {
output = append(output, v)
}
}
nextToken = aws.StringValue(out.NextToken)

return !lastPage
})

if err != nil {
return nil, err
}

return pools, nil
return output, nil
}
38 changes: 18 additions & 20 deletions internal/service/cognitoidp/user_pools_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package cognitoidp_test

import (
"fmt"
"regexp"
"testing"

"github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
Expand All @@ -12,44 +11,43 @@ import (
)

func TestAccCognitoIDPUserPoolsDataSource_basic(t *testing.T) {
rName := fmt.Sprintf("tf_acc_ds_cognito_user_pools_%s", sdkacctest.RandString(7))
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIdentityProvider(t) },
ErrorCheck: acctest.ErrorCheck(t, cognitoidentityprovider.EndpointsID),
Providers: acctest.Providers,
Steps: []resource.TestStep{
{
Config: testAccUserPoolsDataSourceConfig_basic(rName),
Config: testAccUserPoolsDataSourceConfig(rName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.aws_cognito_user_pools.selected", "ids.#", "2"),
resource.TestCheckResourceAttr("data.aws_cognito_user_pools.selected", "arns.#", "2"),
resource.TestCheckResourceAttr("data.aws_cognito_user_pools.test", "arns.#", "2"),
resource.TestCheckResourceAttr("data.aws_cognito_user_pools.test", "ids.#", "2"),
resource.TestCheckResourceAttr("data.aws_cognito_user_pools.empty", "arns.#", "0"),
resource.TestCheckResourceAttr("data.aws_cognito_user_pools.empty", "ids.#", "0"),
),
},
{
Config: testAccUserPoolsDataSourceConfig_notFound(rName),
ExpectError: regexp.MustCompile(`No cognito user pool found with name:`),
},
},
})
}

func testAccUserPoolsDataSourceConfig_basic(rName string) string {
func testAccUserPoolsDataSourceConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_cognito_user_pool" "main" {
resource "aws_cognito_user_pool" "test" {
count = 2
name = "%s"
name = %[1]q
}
data "aws_cognito_user_pools" "selected" {
name = aws_cognito_user_pool.main.*.name[0]
}
`, rName)
data "aws_cognito_user_pools" "test" {
name = %[1]q
depends_on = [aws_cognito_user_pool.test[0], aws_cognito_user_pool.test[1]]
}
func testAccUserPoolsDataSourceConfig_notFound(rName string) string {
return fmt.Sprintf(`
data "aws_cognito_user_pools" "selected" {
name = "%s-not-found"
data "aws_cognito_user_pools" "empty" {
name = "not.%[1]s"
depends_on = [aws_cognito_user_pool.test[0], aws_cognito_user_pool.test[1]]
}
`, rName)
}
65 changes: 19 additions & 46 deletions internal/service/ec2/coip_pools_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,77 +13,50 @@ import (
func DataSourceCoIPPools() *schema.Resource {
return &schema.Resource{
Read: dataSourceCoIPPoolsRead,
Schema: map[string]*schema.Schema{
"filter": CustomFiltersSchema(),

"tags": tftags.TagsSchemaComputed(),

Schema: map[string]*schema.Schema{
"filter": DataSourceFiltersSchema(),
"pool_ids": {
Type: schema.TypeSet,
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"tags": tftags.TagsSchemaComputed(),
},
}
}

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

req := &ec2.DescribeCoipPoolsInput{}

if tags, tagsOk := d.GetOk("tags"); tagsOk {
req.Filters = append(req.Filters, BuildTagFilterList(
Tags(tftags.New(tags.(map[string]interface{}))),
)...)
}

if filters, filtersOk := d.GetOk("filter"); filtersOk {
req.Filters = append(req.Filters, BuildCustomFilterList(
filters.(*schema.Set),
)...)
}
if len(req.Filters) == 0 {
// Don't send an empty filters list; the EC2 API won't accept it.
req.Filters = nil
}
input := &ec2.DescribeCoipPoolsInput{}

var coipPools []*ec2.CoipPool
input.Filters = append(input.Filters, BuildTagFilterList(
Tags(tftags.New(d.Get("tags").(map[string]interface{}))),
)...)

err := conn.DescribeCoipPoolsPages(req, func(page *ec2.DescribeCoipPoolsOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}
input.Filters = append(input.Filters, BuildFiltersDataSource(
d.Get("filter").(*schema.Set),
)...)

coipPools = append(coipPools, page.CoipPools...)
if len(input.Filters) == 0 {
input.Filters = nil
}

return !lastPage
})
output, err := FindCOIPPools(conn, input)

if err != nil {
return fmt.Errorf("error describing EC2 COIP Pools: %w", err)
}

if len(coipPools) == 0 {
return fmt.Errorf("no matching EC2 COIP Pools found")
return fmt.Errorf("error reading EC2 COIP Pools: %w", err)
}

var poolIDs []string

for _, coipPool := range coipPools {
if coipPool == nil {
continue
}

poolIDs = append(poolIDs, aws.StringValue(coipPool.PoolId))
for _, v := range output {
poolIDs = append(poolIDs, aws.StringValue(v.PoolId))
}

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

if err := d.Set("pool_ids", poolIDs); err != nil {
return fmt.Errorf("error setting pool_ids: %w", err)
}
d.Set("pool_ids", poolIDs)

return nil
}
Loading

0 comments on commit 396c6aa

Please sign in to comment.