Skip to content

Commit

Permalink
Merge pull request #24906 from DrFaust92/redshift-hsm-client-cert
Browse files Browse the repository at this point in the history
r/redshift_hsm_client_certificate - new resource
  • Loading branch information
ewbankkit authored May 23, 2022
2 parents 0cb2a49 + 35a1217 commit 63ac5cd
Show file tree
Hide file tree
Showing 7 changed files with 463 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/24906.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_redshift_hsm_client_certificate
```
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1763,6 +1763,7 @@ func Provider() *schema.Provider {

"aws_redshift_cluster": redshift.ResourceCluster(),
"aws_redshift_event_subscription": redshift.ResourceEventSubscription(),
"aws_redshift_hsm_client_certificate": redshift.ResourceHsmClientCertificate(),
"aws_redshift_parameter_group": redshift.ResourceParameterGroup(),
"aws_redshift_scheduled_action": redshift.ResourceScheduledAction(),
"aws_redshift_security_group": redshift.ResourceSecurityGroup(),
Expand Down
28 changes: 28 additions & 0 deletions internal/service/redshift/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,31 @@ func FindScheduleAssociationById(conn *redshift.Redshift, id string) (string, *r

return aws.StringValue(snapshotSchedule.ScheduleIdentifier), associatedCluster, nil
}

func FindHsmClientCertificateByID(conn *redshift.Redshift, id string) (*redshift.HsmClientCertificate, error) {
input := redshift.DescribeHsmClientCertificatesInput{
HsmClientCertificateIdentifier: aws.String(id),
}

out, err := conn.DescribeHsmClientCertificates(&input)
if tfawserr.ErrCodeEquals(err, redshift.ErrCodeHsmClientCertificateNotFoundFault) {
return nil, &resource.NotFoundError{
LastError: err,
LastRequest: input,
}
}

if err != nil {
return nil, err
}

if out == nil || len(out.HsmClientCertificates) == 0 {
return nil, tfresource.NewEmptyResultError(input)
}

if count := len(out.HsmClientCertificates); count > 1 {
return nil, tfresource.NewTooManyResultsError(count, input)
}

return out.HsmClientCertificates[0], nil
}
149 changes: 149 additions & 0 deletions internal/service/redshift/hsm_client_certificate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package redshift

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/redshift"
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
"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"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
)

func ResourceHsmClientCertificate() *schema.Resource {
return &schema.Resource{
Create: resourceHsmClientCertificateCreate,
Read: resourceHsmClientCertificateRead,
Update: resourceHsmClientCertificateUpdate,
Delete: resourceHsmClientCertificateDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"hsm_client_certificate_identifier": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"hsm_client_certificate_public_key": {
Type: schema.TypeString,
Computed: true,
},
"tags": tftags.TagsSchema(),
"tags_all": tftags.TagsSchemaComputed(),
},

CustomizeDiff: verify.SetTagsDiff,
}
}

func resourceHsmClientCertificateCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).RedshiftConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{})))

certIdentifier := d.Get("hsm_client_certificate_identifier").(string)

input := redshift.CreateHsmClientCertificateInput{
HsmClientCertificateIdentifier: aws.String(certIdentifier),
}

input.Tags = Tags(tags.IgnoreAWS())

out, err := conn.CreateHsmClientCertificate(&input)
if err != nil {
return fmt.Errorf("error creating Redshift Hsm Client Certificate (%s): %s", certIdentifier, err)
}

d.SetId(aws.StringValue(out.HsmClientCertificate.HsmClientCertificateIdentifier))

return resourceHsmClientCertificateRead(d, meta)
}

func resourceHsmClientCertificateRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).RedshiftConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig

out, err := FindHsmClientCertificateByID(conn, d.Id())
if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] Redshift Hsm Client Certificate (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return fmt.Errorf("error reading Redshift Hsm Client Certificate (%s): %w", d.Id(), err)
}

arn := arn.ARN{
Partition: meta.(*conns.AWSClient).Partition,
Service: "redshift",
Region: meta.(*conns.AWSClient).Region,
AccountID: meta.(*conns.AWSClient).AccountID,
Resource: fmt.Sprintf("hsmclientcertificate:%s", d.Id()),
}.String()

d.Set("arn", arn)

d.Set("hsm_client_certificate_identifier", out.HsmClientCertificateIdentifier)
d.Set("hsm_client_certificate_public_key", out.HsmClientCertificatePublicKey)

tags := KeyValueTags(out.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig)

//lintignore:AWSR002
if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil {
return fmt.Errorf("error setting tags: %w", err)
}

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

return nil
}

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

if d.HasChange("tags_all") {
o, n := d.GetChange("tags_all")

if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
return fmt.Errorf("error updating Redshift Hsm Client Certificate (%s) tags: %s", d.Get("arn").(string), err)
}
}

return resourceHsmClientCertificateRead(d, meta)
}

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

deleteInput := redshift.DeleteHsmClientCertificateInput{
HsmClientCertificateIdentifier: aws.String(d.Id()),
}

log.Printf("[DEBUG] Deleting Redshift Hsm Client Certificate: %s", d.Id())
_, err := conn.DeleteHsmClientCertificate(&deleteInput)

if err != nil {
if tfawserr.ErrCodeEquals(err, redshift.ErrCodeHsmClientCertificateNotFoundFault) {
return nil
}
return err
}

return err
}
190 changes: 190 additions & 0 deletions internal/service/redshift/hsm_client_certificate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package redshift_test

import (
"fmt"
"regexp"
"testing"

"github.com/aws/aws-sdk-go/service/redshift"
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tfredshift "github.com/hashicorp/terraform-provider-aws/internal/service/redshift"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
)

func TestAccRedshiftHsmClientCertificate_basic(t *testing.T) {
resourceName := "aws_redshift_hsm_client_certificate.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, redshift.EndpointsID),
ProviderFactories: acctest.ProviderFactories,
CheckDestroy: testAccCheckHsmClientCertificateDestroy,
Steps: []resource.TestStep{
{
Config: testAccHsmClientCertificate_Basic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckHsmClientCertificateExists(resourceName),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "redshift", regexp.MustCompile(`hsmclientcertificate:.+`)),
resource.TestCheckResourceAttr(resourceName, "hsm_client_certificate_identifier", rName),
resource.TestCheckResourceAttrSet(resourceName, "hsm_client_certificate_public_key"),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccRedshiftHsmClientCertificate_tags(t *testing.T) {
resourceName := "aws_redshift_hsm_client_certificate.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, redshift.EndpointsID),
ProviderFactories: acctest.ProviderFactories,
CheckDestroy: testAccCheckHsmClientCertificateDestroy,
Steps: []resource.TestStep{
{
Config: testAccHsmClientCertificateConfigTags1(rName, "key1", "value1"),
Check: resource.ComposeTestCheckFunc(
testAccCheckHsmClientCertificateExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccHsmClientCertificateConfigTags2(rName, "key1", "value1updated", "key2", "value2"),
Check: resource.ComposeTestCheckFunc(
testAccCheckHsmClientCertificateExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"),
resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"),
),
}, {
Config: testAccHsmClientCertificateConfigTags1(rName, "key2", "value2"),
Check: resource.ComposeTestCheckFunc(
testAccCheckHsmClientCertificateExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"),
),
},
},
})
}

func TestAccRedshiftHsmClientCertificate_disappears(t *testing.T) {
resourceName := "aws_redshift_hsm_client_certificate.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, redshift.EndpointsID),
ProviderFactories: acctest.ProviderFactories,
CheckDestroy: testAccCheckHsmClientCertificateDestroy,
Steps: []resource.TestStep{
{
Config: testAccHsmClientCertificate_Basic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckHsmClientCertificateExists(resourceName),
acctest.CheckResourceDisappears(acctest.Provider, tfredshift.ResourceHsmClientCertificate(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccCheckHsmClientCertificateDestroy(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).RedshiftConn

for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_redshift_hsm_client_certificate" {
continue
}

_, err := tfredshift.FindHsmClientCertificateByID(conn, rs.Primary.ID)

if tfresource.NotFound(err) {
continue
}

if err != nil {
return err
}

return fmt.Errorf("Redshift Hsm Client Certificate %s still exists", rs.Primary.ID)
}

return nil
}

func testAccCheckHsmClientCertificateExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("not found: %s", name)
}

if rs.Primary.ID == "" {
return fmt.Errorf("Snapshot Copy Grant ID (HsmClientCertificateName) is not set")
}

conn := acctest.Provider.Meta().(*conns.AWSClient).RedshiftConn

_, err := tfredshift.FindHsmClientCertificateByID(conn, rs.Primary.ID)

if err != nil {
return err
}

return nil
}
}

func testAccHsmClientCertificate_Basic(rName string) string {
return fmt.Sprintf(`
resource "aws_redshift_hsm_client_certificate" "test" {
hsm_client_certificate_identifier = %[1]q
}
`, rName)
}

func testAccHsmClientCertificateConfigTags1(rName, tagKey1, tagValue1 string) string {
return fmt.Sprintf(`
resource "aws_redshift_hsm_client_certificate" "test" {
hsm_client_certificate_identifier = %[1]q
tags = {
%[2]q = %[3]q
}
}
`, rName, tagKey1, tagValue1)
}

func testAccHsmClientCertificateConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string {
return fmt.Sprintf(`
resource "aws_redshift_hsm_client_certificate" "test" {
hsm_client_certificate_identifier = %[1]q
tags = {
%[2]q = %[3]q
%[4]q = %[5]q
}
}
`, rName, tagKey1, tagValue1, tagKey2, tagValue2)
}
Loading

0 comments on commit 63ac5cd

Please sign in to comment.