Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r/redshift_event_subscription - use finder + validations #24909

Merged
merged 10 commits into from
May 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/24909.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_redshift_event_subscription: Add plan time validations for `event_categories`, `source_type`, and `severity`.
```
198 changes: 97 additions & 101 deletions internal/service/redshift/event_subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"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/resource"
"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/flex"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
Expand All @@ -24,60 +24,81 @@ func ResourceEventSubscription() *schema.Resource {
Read: resourceEventSubscriptionRead,
Update: resourceEventSubscriptionUpdate,
Delete: resourceEventSubscriptionDelete,

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

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(40 * time.Minute),
Delete: schema.DefaultTimeout(40 * time.Minute),
Update: schema.DefaultTimeout(40 * time.Minute),
},

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},

"customer_aws_id": {
Type: schema.TypeString,
Computed: true,
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"event_categories": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice([]string{
"configuration",
"management",
"monitoring",
"security",
"pending",
}, false),
},
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"severity": {
Type: schema.TypeString,
Optional: true,
Default: "INFO",
ValidateFunc: validation.StringInSlice([]string{
"ERROR",
"INFO",
}, false),
},
"sns_topic_arn": {
Type: schema.TypeString,
Required: true,
ValidateFunc: verify.ValidARN,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"event_categories": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"source_ids": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"source_type": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
"cluster",
"cluster-parameter-group",
"cluster-security-group",
"cluster-snapshot",
"scheduled-action",
}, false),
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"severity": {
Type: schema.TypeString,
Optional: true,
},
"customer_aws_id": {
"status": {
Type: schema.TypeString,
Computed: true,
},
Expand All @@ -98,13 +119,25 @@ func resourceEventSubscriptionCreate(d *schema.ResourceData, meta interface{}) e
SubscriptionName: aws.String(d.Get("name").(string)),
SnsTopicArn: aws.String(d.Get("sns_topic_arn").(string)),
Enabled: aws.Bool(d.Get("enabled").(bool)),
SourceIds: flex.ExpandStringSet(d.Get("source_ids").(*schema.Set)),
SourceType: aws.String(d.Get("source_type").(string)),
Severity: aws.String(d.Get("severity").(string)),
EventCategories: flex.ExpandStringSet(d.Get("event_categories").(*schema.Set)),
Tags: Tags(tags.IgnoreAWS()),
}

if v, ok := d.GetOk("event_categories"); ok && v.(*schema.Set).Len() > 0 {
request.EventCategories = flex.ExpandStringSet(v.(*schema.Set))
}

if v, ok := d.GetOk("source_ids"); ok && v.(*schema.Set).Len() > 0 {
request.SourceIds = flex.ExpandStringSet(v.(*schema.Set))
}

if v, ok := d.GetOk("severity"); ok {
request.Severity = aws.String(v.(string))
}

if v, ok := d.GetOk("source_type"); ok {
request.SourceType = aws.String(v.(string))
}

log.Println("[DEBUG] Create Redshift Event Subscription:", request)

output, err := conn.CreateEventSubscription(request)
Expand All @@ -122,17 +155,8 @@ func resourceEventSubscriptionRead(d *schema.ResourceData, meta interface{}) err
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig

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

d.Set("arn", arn)
sub, err := FindEventSubscriptionByName(conn, d.Id())

sub, err := findEventSubscription(conn, d.Id())
if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] Redshift Event Subscription (%s) not found, removing from state", d.Id())
d.SetId("")
Expand All @@ -142,33 +166,28 @@ func resourceEventSubscriptionRead(d *schema.ResourceData, meta interface{}) err
return fmt.Errorf("error retrieving Redshift Event Subscription %s: %w", d.Id(), err)
}

if err := d.Set("name", sub.CustSubscriptionId); err != nil {
return err
}
if err := d.Set("sns_topic_arn", sub.SnsTopicArn); err != nil {
return err
}
if err := d.Set("status", sub.Status); err != nil {
return err
}
if err := d.Set("source_type", sub.SourceType); err != nil {
return err
}
if err := d.Set("severity", sub.Severity); err != nil {
return err
}
if err := d.Set("enabled", sub.Enabled); err != nil {
return err
}
if err := d.Set("source_ids", flex.FlattenStringList(sub.SourceIdsList)); err != nil {
return err
}
if err := d.Set("event_categories", flex.FlattenStringList(sub.EventCategoriesList)); err != nil {
return err
}
if err := d.Set("customer_aws_id", sub.CustomerAwsId); err != nil {
return err
if err != nil {
return fmt.Errorf("error reading Redshift Event Subscription (%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("eventsubscription:%s", d.Id()),
}.String()
d.Set("arn", arn)
d.Set("customer_aws_id", sub.CustomerAwsId)
d.Set("enabled", sub.Enabled)
d.Set("event_categories", aws.StringValueSlice(sub.EventCategoriesList))
d.Set("name", sub.CustSubscriptionId)
d.Set("severity", sub.Severity)
d.Set("sns_topic_arn", sub.SnsTopicArn)
d.Set("source_ids", aws.StringValueSlice(sub.SourceIdsList))
d.Set("source_type", sub.SourceType)
d.Set("status", sub.Status)

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

//lintignore:AWSR002
Expand All @@ -183,48 +202,25 @@ func resourceEventSubscriptionRead(d *schema.ResourceData, meta interface{}) err
return nil
}

func findEventSubscription(conn *redshift.Redshift, name string) (*redshift.EventSubscription, error) {
input := &redshift.DescribeEventSubscriptionsInput{
SubscriptionName: aws.String(name),
}
out, err := conn.DescribeEventSubscriptions(input)
if tfawserr.ErrCodeEquals(err, redshift.ErrCodeSubscriptionNotFoundFault) {
return nil, &resource.NotFoundError{
LastError: err,
LastRequest: input,
}
}
if err != nil {
return nil, err
}

switch count := len(out.EventSubscriptionsList); count {
case 0:
return nil, tfresource.NewEmptyResultError(input)
case 1:
return out.EventSubscriptionsList[0], nil
default:
return nil, tfresource.NewTooManyResultsError(count, input)
}
}

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

req := &redshift.ModifyEventSubscriptionInput{
SubscriptionName: aws.String(d.Id()),
SnsTopicArn: aws.String(d.Get("sns_topic_arn").(string)),
Enabled: aws.Bool(d.Get("enabled").(bool)),
SourceIds: flex.ExpandStringSet(d.Get("source_ids").(*schema.Set)),
SourceType: aws.String(d.Get("source_type").(string)),
Severity: aws.String(d.Get("severity").(string)),
EventCategories: flex.ExpandStringSet(d.Get("event_categories").(*schema.Set)),
}
if d.HasChangesExcept("tags", "tags_all") {
req := &redshift.ModifyEventSubscriptionInput{
SubscriptionName: aws.String(d.Id()),
SnsTopicArn: aws.String(d.Get("sns_topic_arn").(string)),
Enabled: aws.Bool(d.Get("enabled").(bool)),
SourceIds: flex.ExpandStringSet(d.Get("source_ids").(*schema.Set)),
SourceType: aws.String(d.Get("source_type").(string)),
Severity: aws.String(d.Get("severity").(string)),
EventCategories: flex.ExpandStringSet(d.Get("event_categories").(*schema.Set)),
}

log.Printf("[DEBUG] Redshift Event Subscription modification request: %#v", req)
_, err := conn.ModifyEventSubscription(req)
if err != nil {
return fmt.Errorf("Modifying Redshift Event Subscription %s failed: %s", d.Id(), err)
log.Printf("[DEBUG] Redshift Event Subscription modification request: %#v", req)
_, err := conn.ModifyEventSubscription(req)
if err != nil {
return fmt.Errorf("Modifying Redshift Event Subscription %s failed: %s", d.Id(), err)
}
}

if d.HasChange("tags_all") {
Expand Down
Loading