2015-05-15 01:17:18 +02:00
|
|
|
package aws
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
2016-01-11 22:54:57 +01:00
|
|
|
"strings"
|
2015-05-15 01:17:18 +02:00
|
|
|
|
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
|
|
|
2015-06-03 20:36:57 +02:00
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
|
|
"github.com/aws/aws-sdk-go/service/sns"
|
2015-05-15 01:17:18 +02:00
|
|
|
)
|
|
|
|
|
2016-01-11 22:54:57 +01:00
|
|
|
const awsSNSPendingConfirmationMessage = "pending confirmation"
|
|
|
|
|
2015-05-15 01:17:18 +02:00
|
|
|
func resourceAwsSnsTopicSubscription() *schema.Resource {
|
|
|
|
return &schema.Resource{
|
|
|
|
Create: resourceAwsSnsTopicSubscriptionCreate,
|
|
|
|
Read: resourceAwsSnsTopicSubscriptionRead,
|
|
|
|
Update: resourceAwsSnsTopicSubscriptionUpdate,
|
|
|
|
Delete: resourceAwsSnsTopicSubscriptionDelete,
|
|
|
|
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"protocol": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: false,
|
2016-01-11 22:54:57 +01:00
|
|
|
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
|
|
|
value := v.(string)
|
|
|
|
forbidden := []string{"email", "sms", "http"}
|
|
|
|
for _, f := range forbidden {
|
|
|
|
if strings.Contains(value, f) {
|
|
|
|
errors = append(
|
|
|
|
errors,
|
|
|
|
fmt.Errorf("Unsupported protocol (%s) for SNS Topic", value),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
},
|
2015-05-15 01:17:18 +02:00
|
|
|
},
|
|
|
|
"endpoint": &schema.Schema{
|
2015-06-03 15:46:03 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: false,
|
2015-05-15 01:17:18 +02:00
|
|
|
},
|
|
|
|
"topic_arn": &schema.Schema{
|
2015-06-03 15:46:03 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: false,
|
2015-05-15 01:17:18 +02:00
|
|
|
},
|
|
|
|
"delivery_policy": &schema.Schema{
|
2015-06-03 15:46:03 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
ForceNew: false,
|
2015-05-15 01:17:18 +02:00
|
|
|
},
|
|
|
|
"raw_message_delivery": &schema.Schema{
|
2015-06-03 15:46:03 +02:00
|
|
|
Type: schema.TypeBool,
|
|
|
|
Optional: true,
|
|
|
|
ForceNew: false,
|
|
|
|
Default: false,
|
2015-05-15 01:17:18 +02:00
|
|
|
},
|
2015-05-23 06:12:25 +02:00
|
|
|
"arn": &schema.Schema{
|
2015-06-03 15:46:03 +02:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Computed: true,
|
2015-05-23 06:12:25 +02:00
|
|
|
},
|
2015-05-15 01:17:18 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceAwsSnsTopicSubscriptionCreate(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
snsconn := meta.(*AWSClient).snsconn
|
|
|
|
|
|
|
|
output, err := subscribeToSNSTopic(d, snsconn)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2016-01-11 22:54:57 +01:00
|
|
|
if output.SubscriptionArn != nil && *output.SubscriptionArn == awsSNSPendingConfirmationMessage {
|
|
|
|
log.Printf("[WARN] Invalid SNS Subscription, received a \"%s\" ARN", awsSNSPendingConfirmationMessage)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-08-17 20:27:16 +02:00
|
|
|
log.Printf("New subscription ARN: %s", *output.SubscriptionArn)
|
|
|
|
d.SetId(*output.SubscriptionArn)
|
2015-05-15 01:17:18 +02:00
|
|
|
|
2015-05-23 06:12:25 +02:00
|
|
|
// Write the ARN to the 'arn' field for export
|
2015-08-17 20:27:16 +02:00
|
|
|
d.Set("arn", *output.SubscriptionArn)
|
2015-05-23 06:12:25 +02:00
|
|
|
|
2015-05-15 01:17:18 +02:00
|
|
|
return resourceAwsSnsTopicSubscriptionUpdate(d, meta)
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceAwsSnsTopicSubscriptionUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
snsconn := meta.(*AWSClient).snsconn
|
|
|
|
|
|
|
|
// If any changes happened, un-subscribe and re-subscribe
|
|
|
|
if d.HasChange("protocol") || d.HasChange("endpoint") || d.HasChange("topic_arn") {
|
|
|
|
log.Printf("[DEBUG] Updating subscription %s", d.Id())
|
|
|
|
// Unsubscribe
|
|
|
|
_, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{
|
2015-08-17 20:27:16 +02:00
|
|
|
SubscriptionArn: aws.String(d.Id()),
|
2015-05-15 01:17:18 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error unsubscribing from SNS topic: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Re-subscribe and set id
|
|
|
|
output, err := subscribeToSNSTopic(d, snsconn)
|
2015-08-17 20:27:16 +02:00
|
|
|
d.SetId(*output.SubscriptionArn)
|
2016-01-11 22:54:57 +01:00
|
|
|
d.Set("arn", *output.SubscriptionArn)
|
2015-05-15 01:17:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if d.HasChange("raw_message_delivery") {
|
|
|
|
_, n := d.GetChange("raw_message_delivery")
|
|
|
|
|
|
|
|
attrValue := "false"
|
|
|
|
|
|
|
|
if n.(bool) {
|
|
|
|
attrValue = "true"
|
|
|
|
}
|
|
|
|
|
|
|
|
req := &sns.SetSubscriptionAttributesInput{
|
2015-08-17 20:27:16 +02:00
|
|
|
SubscriptionArn: aws.String(d.Id()),
|
2015-06-03 15:46:03 +02:00
|
|
|
AttributeName: aws.String("RawMessageDelivery"),
|
|
|
|
AttributeValue: aws.String(attrValue),
|
2015-05-15 01:17:18 +02:00
|
|
|
}
|
|
|
|
_, err := snsconn.SetSubscriptionAttributes(req)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Unable to set raw message delivery attribute on subscription")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return resourceAwsSnsTopicSubscriptionRead(d, meta)
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceAwsSnsTopicSubscriptionRead(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
snsconn := meta.(*AWSClient).snsconn
|
|
|
|
|
|
|
|
log.Printf("[DEBUG] Loading subscription %s", d.Id())
|
|
|
|
|
|
|
|
attributeOutput, err := snsconn.GetSubscriptionAttributes(&sns.GetSubscriptionAttributesInput{
|
2015-08-17 20:27:16 +02:00
|
|
|
SubscriptionArn: aws.String(d.Id()),
|
2015-05-15 01:17:18 +02:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2015-06-03 15:46:03 +02:00
|
|
|
if attributeOutput.Attributes != nil && len(attributeOutput.Attributes) > 0 {
|
|
|
|
attrHash := attributeOutput.Attributes
|
2015-05-15 01:17:18 +02:00
|
|
|
log.Printf("[DEBUG] raw message delivery: %s", *attrHash["RawMessageDelivery"])
|
|
|
|
if *attrHash["RawMessageDelivery"] == "true" {
|
|
|
|
d.Set("raw_message_delivery", true)
|
|
|
|
} else {
|
|
|
|
d.Set("raw_message_delivery", false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceAwsSnsTopicSubscriptionDelete(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
snsconn := meta.(*AWSClient).snsconn
|
|
|
|
|
|
|
|
log.Printf("[DEBUG] SNS delete topic subscription: %s", d.Id())
|
|
|
|
_, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{
|
2015-08-17 20:27:16 +02:00
|
|
|
SubscriptionArn: aws.String(d.Id()),
|
2015-05-15 01:17:18 +02:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-06-03 15:46:03 +02:00
|
|
|
func subscribeToSNSTopic(d *schema.ResourceData, snsconn *sns.SNS) (output *sns.SubscribeOutput, err error) {
|
2015-05-15 01:17:18 +02:00
|
|
|
protocol := d.Get("protocol").(string)
|
|
|
|
endpoint := d.Get("endpoint").(string)
|
|
|
|
topic_arn := d.Get("topic_arn").(string)
|
|
|
|
|
|
|
|
log.Printf("[DEBUG] SNS create topic subscription: %s (%s) @ '%s'", endpoint, protocol, topic_arn)
|
|
|
|
|
|
|
|
req := &sns.SubscribeInput{
|
|
|
|
Protocol: aws.String(protocol),
|
|
|
|
Endpoint: aws.String(endpoint),
|
2015-08-17 20:27:16 +02:00
|
|
|
TopicArn: aws.String(topic_arn),
|
2015-05-15 01:17:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
output, err = snsconn.Subscribe(req)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("Error creating SNS topic: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("[DEBUG] Created new subscription!")
|
|
|
|
return output, nil
|
2015-06-03 15:46:03 +02:00
|
|
|
}
|