-
Notifications
You must be signed in to change notification settings - Fork 9.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
590 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
326 changes: 326 additions & 0 deletions
326
builtin/providers/aws/resource_aws_db_event_subscription.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,326 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/awserr" | ||
"github.com/aws/aws-sdk-go/service/rds" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsDbEventSubscription() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsDbEventSubscriptionCreate, | ||
Read: resourceAwsDbEventSubscriptionRead, | ||
Update: resourceAwsDbEventSubscriptionUpdate, | ||
Delete: resourceAwsDbEventSubscriptionDelete, | ||
Schema: map[string]*schema.Schema{ | ||
"name": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validateDbEventSubscriptionName, | ||
}, | ||
"sns_topic": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"event_categories": &schema.Schema{ | ||
Type: schema.TypeSet, | ||
Optional: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Set: schema.HashString, | ||
}, | ||
"source_ids": &schema.Schema{ | ||
Type: schema.TypeSet, | ||
Optional: true, | ||
ForceNew: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Set: schema.HashString, | ||
// ValidateFunc: validateDbEventSubscriptionSourceIds, | ||
// requires source_type to be set, does not seem to be a way to validate this | ||
}, | ||
"source_type": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"enabled": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Default: true, | ||
}, | ||
"customer_aws_id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"tags": tagsSchema(), | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsDbEventSubscriptionCreate(d *schema.ResourceData, meta interface{}) error { | ||
rdsconn := meta.(*AWSClient).rdsconn | ||
name := d.Get("name").(string) | ||
tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{})) | ||
|
||
sourceIdsSet := d.Get("source_ids").(*schema.Set) | ||
sourceIds := make([]*string, sourceIdsSet.Len()) | ||
for i, sourceId := range sourceIdsSet.List() { | ||
sourceIds[i] = aws.String(sourceId.(string)) | ||
} | ||
|
||
eventCategoriesSet := d.Get("event_categories").(*schema.Set) | ||
eventCategories := make([]*string, eventCategoriesSet.Len()) | ||
for i, eventCategory := range eventCategoriesSet.List() { | ||
eventCategories[i] = aws.String(eventCategory.(string)) | ||
} | ||
|
||
request := &rds.CreateEventSubscriptionInput{ | ||
SubscriptionName: aws.String(name), | ||
SnsTopicArn: aws.String(d.Get("sns_topic").(string)), | ||
Enabled: aws.Bool(d.Get("enabled").(bool)), | ||
SourceIds: sourceIds, | ||
SourceType: aws.String(d.Get("source_type").(string)), | ||
EventCategories: eventCategories, | ||
Tags: tags, | ||
} | ||
|
||
log.Println("[DEBUG] Create RDS Event Subscription:", request) | ||
|
||
_, err := rdsconn.CreateEventSubscription(request) | ||
if err != nil { | ||
return fmt.Errorf("Error creating RDS Event Subscription %s: %s", name, err) | ||
} | ||
|
||
log.Println( | ||
"[INFO] Waiting for RDS Event Subscription to be ready") | ||
|
||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"creating"}, | ||
Target: []string{"active"}, | ||
Refresh: resourceAwsDbEventSubscriptionRefreshFunc(d, meta.(*AWSClient).rdsconn), | ||
Timeout: 40 * time.Minute, | ||
MinTimeout: 10 * time.Second, | ||
Delay: 30 * time.Second, // Wait 30 secs before starting | ||
} | ||
|
||
// Wait, catching any errors | ||
_, err = stateConf.WaitForState() | ||
if err != nil { | ||
return fmt.Errorf("Creating RDS Event Subscription %s failed: %s", d.Id(), err) | ||
} | ||
|
||
return resourceAwsDbEventSubscriptionRead(d, meta) | ||
} | ||
|
||
func resourceAwsDbEventSubscriptionRead(d *schema.ResourceData, meta interface{}) error { | ||
sub, err := resourceAwsDbEventSubscriptionRetrieve(d, meta.(*AWSClient).rdsconn) | ||
if err != nil { | ||
return fmt.Errorf("Error retrieving RDS Event Subscription %s: %s", d.Id(), err) | ||
} | ||
if sub == nil { | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
d.SetId(*sub.CustSubscriptionId) | ||
if err := d.Set("name", sub.CustSubscriptionId); err != nil { | ||
return err | ||
} | ||
if err := d.Set("sns_topic", sub.SnsTopicArn); err != nil { | ||
return err | ||
} | ||
if err := d.Set("source_type", sub.SourceType); err != nil { | ||
return err | ||
} | ||
if err := d.Set("enabled", sub.Enabled); err != nil { | ||
return err | ||
} | ||
if err := d.Set("source_ids", flattenStringList(sub.SourceIdsList)); err != nil { | ||
return err | ||
} | ||
if err := d.Set("event_categories", flattenStringList(sub.EventCategoriesList)); err != nil { | ||
return err | ||
} | ||
if err := d.Set("customer_aws_id", sub.CustomerAwsId); err != nil { | ||
return err | ||
} | ||
|
||
// list tags for resource | ||
// set tags | ||
conn := meta.(*AWSClient).rdsconn | ||
arn, err := buildRDSEventSubscriptionARN(d, meta) | ||
if err != nil { | ||
name := "<empty>" | ||
if sub.CustSubscriptionId != nil && *sub.CustSubscriptionId != "" { | ||
name = *sub.CustSubscriptionId | ||
} | ||
log.Printf("[DEBUG] Error building ARN for RDS Event Subscription, not setting Tags for RDS Event Subscription %s: %s", name, err) | ||
} else { | ||
d.Set("arn", arn) | ||
resp, err := conn.ListTagsForResource(&rds.ListTagsForResourceInput{ | ||
ResourceName: aws.String(arn), | ||
}) | ||
|
||
if err != nil { | ||
log.Printf("[DEBUG] Error retrieving tags for ARN: %s", arn) | ||
} | ||
|
||
var dt []*rds.Tag | ||
if len(resp.TagList) > 0 { | ||
dt = resp.TagList | ||
} | ||
d.Set("tags", tagsToMapRDS(dt)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsDbEventSubscriptionRetrieve( | ||
d *schema.ResourceData, rdsconn *rds.RDS) (*rds.EventSubscription, error) { | ||
|
||
name := d.Get("name").(string) | ||
request := &rds.DescribeEventSubscriptionsInput{ | ||
SubscriptionName: aws.String(name), | ||
} | ||
|
||
describeResp, err := rdsconn.DescribeEventSubscriptions(request) | ||
if err != nil { | ||
if rdserr, ok := err.(awserr.Error); ok && rdserr.Code() == "SubscriptionNotFound" { | ||
log.Printf("[WARN] No RDS Event Subscription by name (%s) found", name) | ||
d.SetId("") | ||
return nil, nil | ||
} | ||
return nil, fmt.Errorf("Error reading RDS Event Subscription %s: %s", name, err) | ||
} | ||
|
||
if len(describeResp.EventSubscriptionsList) != 1 { | ||
return nil, fmt.Errorf("Unable to find RDS Event Subscription: %#v", describeResp.EventSubscriptionsList) | ||
} | ||
|
||
return describeResp.EventSubscriptionsList[0], nil | ||
} | ||
|
||
func resourceAwsDbEventSubscriptionUpdate(d *schema.ResourceData, meta interface{}) error { | ||
rdsconn := meta.(*AWSClient).rdsconn | ||
|
||
d.Partial(true) | ||
|
||
// check/update tags, missing from go-aws-sdk? | ||
if d.HasChange("enabled") || d.HasChange("event_categories") || | ||
d.HasChange("sns_topic") || d.HasChange("source_type") { | ||
|
||
eventCategoriesSet := d.Get("event_categories").(*schema.Set) | ||
eventCategories := make([]*string, eventCategoriesSet.Len()) | ||
for _, eventCategory := range eventCategoriesSet.List() { | ||
eventCategories = append(eventCategories, aws.String(eventCategory.(string))) | ||
} | ||
|
||
_, err := rdsconn.ModifyEventSubscription(&rds.ModifyEventSubscriptionInput{ | ||
SubscriptionName: aws.String(d.Id()), | ||
Enabled: aws.Bool(d.Get("enabled").(bool)), | ||
SnsTopicArn: aws.String(d.Get("sns_topic").(string)), | ||
SourceType: aws.String(d.Get("source_type").(string)), | ||
EventCategories: eventCategories, | ||
}) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Modifying RDS Event Subscription %s failed: %s", d.Id(), err) | ||
} | ||
|
||
log.Println( | ||
"[INFO] Waiting for RDS Event Subscription modification to finish") | ||
|
||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"modifying"}, | ||
Target: []string{"active"}, | ||
Refresh: resourceAwsDbEventSubscriptionRefreshFunc(d, meta.(*AWSClient).rdsconn), | ||
Timeout: 40 * time.Minute, | ||
MinTimeout: 10 * time.Second, | ||
Delay: 30 * time.Second, // Wait 30 secs before starting | ||
} | ||
|
||
// Wait, catching any errors | ||
_, err = stateConf.WaitForState() | ||
if err != nil { | ||
return fmt.Errorf("Modifying RDS Event Subscription %s failed: %s", d.Id(), err) | ||
} | ||
} | ||
|
||
if arn, err := buildRDSEventSubscriptionARN(d, meta); err == nil { | ||
if err := setTagsRDS(rdsconn, d, arn); err != nil { | ||
return err | ||
} else { | ||
d.SetPartial("tags") | ||
} | ||
} | ||
d.Partial(false) | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsDbEventSubscriptionDelete(d *schema.ResourceData, meta interface{}) error { | ||
rdsconn := meta.(*AWSClient).rdsconn | ||
deleteOpts := rds.DeleteEventSubscriptionInput{ | ||
SubscriptionName: aws.String(d.Id()), | ||
} | ||
|
||
if _, err := rdsconn.DeleteEventSubscription(&deleteOpts); err != nil { | ||
rdserr, ok := err.(awserr.Error) | ||
if !ok { | ||
return fmt.Errorf("Error deleting RDS Event Subscription %s: %s", d.Id(), err) | ||
} | ||
|
||
if rdserr.Code() != "DBEventSubscriptionNotFoundFault" { | ||
return fmt.Errorf("Error deleting RDS Event Subscription %s: %s", d.Id(), err) | ||
} | ||
} | ||
|
||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"deleting"}, | ||
Target: []string{}, | ||
Refresh: resourceAwsDbEventSubscriptionRefreshFunc(d, meta.(*AWSClient).rdsconn), | ||
Timeout: 40 * time.Minute, | ||
MinTimeout: 10 * time.Second, | ||
Delay: 30 * time.Second, // Wait 30 secs before starting | ||
} | ||
_, err := stateConf.WaitForState() | ||
if err != nil { | ||
return fmt.Errorf("Error deleting RDS Event Subscription %s: %s", d.Id(), err) | ||
} | ||
return err | ||
} | ||
|
||
func resourceAwsDbEventSubscriptionRefreshFunc( | ||
d *schema.ResourceData, | ||
rdsconn *rds.RDS) resource.StateRefreshFunc { | ||
|
||
return func() (interface{}, string, error) { | ||
sub, err := resourceAwsDbEventSubscriptionRetrieve(d, rdsconn) | ||
|
||
if err != nil { | ||
log.Printf("Error on retrieving DB Event Subscription when waiting: %s", err) | ||
return nil, "", err | ||
} | ||
|
||
if sub == nil { | ||
return nil, "", nil | ||
} | ||
|
||
if sub.Status != nil { | ||
log.Printf("[DEBUG] DB Event Subscription status for %s: %s", d.Id(), *sub.Status) | ||
} | ||
|
||
return sub, *sub.Status, nil | ||
} | ||
} | ||
|
||
func buildRDSEventSubscriptionARN(d *schema.ResourceData, meta interface{}) (string, error) { | ||
region := meta.(*AWSClient).region | ||
arn := fmt.Sprintf("arn:aws:rds:%s:%s:es:%s", region, d.Get("customer_aws_id"), d.Id()) | ||
return arn, nil | ||
} |
Oops, something went wrong.