Skip to content

Commit

Permalink
feat: Implement ListTags for all taggable Lightsail resources
Browse files Browse the repository at this point in the history
  • Loading branch information
acwwat committed May 26, 2024
1 parent 250de7d commit 7fb48bd
Show file tree
Hide file tree
Showing 24 changed files with 725 additions and 78 deletions.
39 changes: 39 additions & 0 deletions .changelog/37711.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
```release-note:bug
resource/aws_lightsail_database: Prevent destroy failure when resource is already deleted outside Terraform
```

```release-note:bug
resource/aws_lightsail_key_pair: Prevent destroy failure when resource is already deleted outside Terraform
```

```release-note:bug
resource/aws_lightsail_lb: Prevent destroy failure when resource is already deleted outside Terraform
```

```release-note:enhancement
resource/aws_lightsail_bucket: Add support to `ListTags` function for proper key-only tag handling
```

```release-note:enhancement
resource/aws_lightsail_certificate: Add support to `ListTags` function for proper key-only tag handling
```

```release-note:enhancement
resource/aws_lightsail_container_service: Add support to `ListTags` function for proper key-only tag handling
```

```release-note:enhancement
resource/aws_lightsail_database: Add support to `ListTags` function for proper key-only tag handling
```

```release-note:enhancement
resource/aws_lightsail_distribution: Add support to `ListTags` function for proper key-only tag handling
```

```release-note:enhancement
resource/aws_lightsail_key_pair: Add support to `ListTags` function for proper key-only tag handling
```

```release-note:enhancement
resource/aws_lightsail_lb: Add support to `ListTags` function for proper key-only tag handling
```
2 changes: 1 addition & 1 deletion internal/service/lightsail/bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
)

// @SDKResource("aws_lightsail_bucket", name="Bucket")
// @Tags(identifierAttribute="id")
// @Tags(identifierAttribute="id", resourceType="Bucket")
func ResourceBucket() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourceBucketCreate,
Expand Down
56 changes: 54 additions & 2 deletions internal/service/lightsail/bucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,58 @@ func TestAccLightsailBucket_tags(t *testing.T) {
})
}

func TestAccLightsailBucket_keyOnlyTags(t *testing.T) {
ctx := acctest.Context(t)
resourceName := "aws_lightsail_bucket.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, strings.ToLower(lightsail.ServiceID))
testAccPreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(lightsail.ServiceID)),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckBucketDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccBucketConfig_tags1(rName, acctest.CtKey1, ""),
Check: resource.ComposeTestCheckFunc(
testAccCheckBucketExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, ""),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
names.AttrForceDelete,
},
},
{
Config: testAccBucketConfig_tags2(rName, acctest.CtKey1, acctest.CtValue1Updated, acctest.CtKey2, ""),
Check: resource.ComposeTestCheckFunc(
testAccCheckBucketExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct2),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1Updated),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, ""),
),
},
{
Config: testAccBucketConfig_tags1(rName, acctest.CtKey2, ""),
Check: resource.ComposeTestCheckFunc(
testAccCheckBucketExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, ""),
),
},
},
})
}

func testAccCheckBucketExists(ctx context.Context, resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
Expand Down Expand Up @@ -285,7 +337,7 @@ resource "aws_lightsail_bucket" "test" {
`, rName)
}

func testAccBucketConfig_bundleId(rName string, rBundleId string) string {
func testAccBucketConfig_bundleId(rName, rBundleId string) string {
return fmt.Sprintf(`
resource "aws_lightsail_bucket" "test" {
name = %[1]q
Expand All @@ -294,7 +346,7 @@ resource "aws_lightsail_bucket" "test" {
`, rName, rBundleId)
}

func testAccBucketConfig_tags1(rName string, tagKey1, tagValue1 string) string {
func testAccBucketConfig_tags1(rName, tagKey1, tagValue1 string) string {
return fmt.Sprintf(`
resource "aws_lightsail_bucket" "test" {
name = %[1]q
Expand Down
2 changes: 1 addition & 1 deletion internal/service/lightsail/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
)

// @SDKResource("aws_lightsail_certificate", name="Certificate")
// @Tags(identifierAttribute="id")
// @Tags(identifierAttribute="id", resourceType="Certificate")
func ResourceCertificate() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourceCertificateCreate,
Expand Down
58 changes: 54 additions & 4 deletions internal/service/lightsail/certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,56 @@ func TestAccLightsailCertificate_tags(t *testing.T) {
})
}

func TestAccLightsailCertificate_keyOnlyTags(t *testing.T) {
ctx := acctest.Context(t)
resourceName := "aws_lightsail_certificate.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
domainName := acctest.ACMCertificateRandomSubDomain(acctest.RandomDomainName())

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, strings.ToLower(lightsail.ServiceID))
testAccPreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(lightsail.ServiceID)),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckCertificateDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccCertificateConfig_tags1(rName, domainName, acctest.CtKey1, ""),
Check: resource.ComposeTestCheckFunc(
testAccCheckCertificateExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, ""),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccCertificateConfig_tags2(rName, domainName, acctest.CtKey1, acctest.CtValue1Updated, acctest.CtKey2, ""),
Check: resource.ComposeTestCheckFunc(
testAccCheckCertificateExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct2),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1Updated),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, ""),
),
},
{
Config: testAccCertificateConfig_tags1(rName, domainName, acctest.CtKey2, ""),
Check: resource.ComposeTestCheckFunc(
testAccCheckCertificateExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, ""),
),
},
},
})
}

func TestAccLightsailCertificate_disappears(t *testing.T) {
ctx := acctest.Context(t)
resourceName := "aws_lightsail_certificate.test"
Expand Down Expand Up @@ -275,7 +325,7 @@ func testAccCheckCertificateExists(ctx context.Context, n string) resource.TestC
}
}

func testAccCertificateConfig_basic(rName string, domainName string) string {
func testAccCertificateConfig_basic(rName, domainName string) string {
return fmt.Sprintf(`
resource "aws_lightsail_certificate" "test" {
name = %[1]q
Expand All @@ -284,7 +334,7 @@ resource "aws_lightsail_certificate" "test" {
`, rName, domainName)
}

func testAccCertificateConfig_subjectAlternativeNames(rName string, domainName string, san string) string {
func testAccCertificateConfig_subjectAlternativeNames(rName, domainName, san string) string {
return fmt.Sprintf(`
resource "aws_lightsail_certificate" "test" {
name = %[1]q
Expand All @@ -294,7 +344,7 @@ resource "aws_lightsail_certificate" "test" {
`, rName, domainName, san)
}

func testAccCertificateConfig_tags1(resourceName string, domainName string, tagKey1, tagValue1 string) string {
func testAccCertificateConfig_tags1(resourceName, domainName, tagKey1, tagValue1 string) string {
return fmt.Sprintf(`
resource "aws_lightsail_certificate" "test" {
name = %[1]q
Expand All @@ -306,7 +356,7 @@ resource "aws_lightsail_certificate" "test" {
`, resourceName, domainName, tagKey1, tagValue1)
}

func testAccCertificateConfig_tags2(resourceName, domainName string, tagKey1, tagValue1, tagKey2, tagValue2 string) string {
func testAccCertificateConfig_tags2(resourceName, domainName, tagKey1, tagValue1, tagKey2, tagValue2 string) string {
return fmt.Sprintf(`
resource "aws_lightsail_certificate" "test" {
name = %[1]q
Expand Down
2 changes: 1 addition & 1 deletion internal/service/lightsail/container_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
)

// @SDKResource("aws_lightsail_container_service", name="Container Service")
// @Tags(identifierAttribute="id")
// @Tags(identifierAttribute="id", resourceType="Container Service")
func ResourceContainerService() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourceContainerServiceCreate,
Expand Down
49 changes: 49 additions & 0 deletions internal/service/lightsail/container_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,55 @@ func TestAccLightsailContainerService_tags(t *testing.T) {
})
}

func TestAccLightsailContainerService_keyOnlyTags(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_lightsail_container_service.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, strings.ToLower(lightsail.ServiceID))
testAccPreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(lightsail.ServiceID)),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckContainerServiceDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccContainerServiceConfig_tags1(rName, acctest.CtKey1, ""),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckContainerServiceExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, ""),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccContainerServiceConfig_tags2(rName, acctest.CtKey1, acctest.CtValue1Updated, acctest.CtKey2, ""),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckContainerServiceExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct2),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1Updated),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, ""),
),
},
{
Config: testAccContainerServiceConfig_tags1(rName, acctest.CtKey2, ""),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckContainerServiceExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, ""),
),
},
},
})
}

func testAccCheckContainerServiceDestroy(ctx context.Context) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).LightsailClient(ctx)
Expand Down
39 changes: 37 additions & 2 deletions internal/service/lightsail/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import (
"github.com/aws/aws-sdk-go-v2/service/lightsail"
"github.com/aws/aws-sdk-go-v2/service/lightsail/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
"github.com/hashicorp/terraform-provider-aws/names"
)
Expand All @@ -27,7 +29,7 @@ const (
)

// @SDKResource("aws_lightsail_database", name="Database")
// @Tags(identifierAttribute="id")
// @Tags(identifierAttribute="id", resourceType="Database")
func ResourceDatabase() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourceDatabaseCreate,
Expand Down Expand Up @@ -400,7 +402,11 @@ func resourceDatabaseDelete(ctx context.Context, d *schema.ResourceData, meta in

// Some Operations can complete before the Database enters the Available state. Added a waiter to make sure the Database is available before continuing.
if _, err := waitDatabaseModified(ctx, conn, aws.String(d.Id())); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for Lightsail Relational Database (%s) to become available: %s", d.Id(), err)
if err != nil && IsANotFoundError(err) {
return diags
} else {
return sdkdiag.AppendErrorf(diags, "waiting for Lightsail Relational Database (%s) to become available: %s", d.Id(), err)
}
}

skipFinalSnapshot := d.Get("skip_final_snapshot").(bool)
Expand All @@ -420,6 +426,10 @@ func resourceDatabaseDelete(ctx context.Context, d *schema.ResourceData, meta in

output, err := conn.DeleteRelationalDatabase(ctx, input)

if err != nil && IsANotFoundError(err) {
return diags
}

if err != nil {
return sdkdiag.AppendErrorf(diags, "deleting Lightsail Relational Database (%s): %s", d.Id(), err)
}
Expand All @@ -440,3 +450,28 @@ func resourceDatabaseImport(ctx context.Context, d *schema.ResourceData, meta in
d.Set("skip_final_snapshot", true)
return []*schema.ResourceData{d}, nil
}

func FindDatabaseById(ctx context.Context, conn *lightsail.Client, id string) (*types.RelationalDatabase, error) {
in := &lightsail.GetRelationalDatabaseInput{
RelationalDatabaseName: aws.String(id),
}

out, err := conn.GetRelationalDatabase(ctx, in)

if IsANotFoundError(err) {
return nil, &retry.NotFoundError{
LastError: err,
LastRequest: in,
}
}

if err != nil {
return nil, err
}

if out == nil || out.RelationalDatabase == nil {
return nil, tfresource.NewEmptyResultError(in)
}

return out.RelationalDatabase, nil
}
Loading

0 comments on commit 7fb48bd

Please sign in to comment.