github.com/erriapo/terraform@v0.6.12-0.20160203182612-0340ea72354f/builtin/providers/aws/resource_aws_sns_topic_subscription.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strings"
     7  
     8  	"github.com/hashicorp/terraform/helper/schema"
     9  
    10  	"github.com/aws/aws-sdk-go/aws"
    11  	"github.com/aws/aws-sdk-go/service/sns"
    12  )
    13  
    14  const awsSNSPendingConfirmationMessage = "pending confirmation"
    15  
    16  func resourceAwsSnsTopicSubscription() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceAwsSnsTopicSubscriptionCreate,
    19  		Read:   resourceAwsSnsTopicSubscriptionRead,
    20  		Update: resourceAwsSnsTopicSubscriptionUpdate,
    21  		Delete: resourceAwsSnsTopicSubscriptionDelete,
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"protocol": &schema.Schema{
    25  				Type:     schema.TypeString,
    26  				Required: true,
    27  				ForceNew: false,
    28  				ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
    29  					value := v.(string)
    30  					forbidden := []string{"email", "sms", "http"}
    31  					for _, f := range forbidden {
    32  						if strings.Contains(value, f) {
    33  							errors = append(
    34  								errors,
    35  								fmt.Errorf("Unsupported protocol (%s) for SNS Topic", value),
    36  							)
    37  						}
    38  					}
    39  					return
    40  				},
    41  			},
    42  			"endpoint": &schema.Schema{
    43  				Type:     schema.TypeString,
    44  				Required: true,
    45  				ForceNew: false,
    46  			},
    47  			"topic_arn": &schema.Schema{
    48  				Type:     schema.TypeString,
    49  				Required: true,
    50  				ForceNew: false,
    51  			},
    52  			"delivery_policy": &schema.Schema{
    53  				Type:     schema.TypeString,
    54  				Optional: true,
    55  				ForceNew: false,
    56  			},
    57  			"raw_message_delivery": &schema.Schema{
    58  				Type:     schema.TypeBool,
    59  				Optional: true,
    60  				ForceNew: false,
    61  				Default:  false,
    62  			},
    63  			"arn": &schema.Schema{
    64  				Type:     schema.TypeString,
    65  				Computed: true,
    66  			},
    67  		},
    68  	}
    69  }
    70  
    71  func resourceAwsSnsTopicSubscriptionCreate(d *schema.ResourceData, meta interface{}) error {
    72  	snsconn := meta.(*AWSClient).snsconn
    73  
    74  	output, err := subscribeToSNSTopic(d, snsconn)
    75  
    76  	if err != nil {
    77  		return err
    78  	}
    79  
    80  	if output.SubscriptionArn != nil && *output.SubscriptionArn == awsSNSPendingConfirmationMessage {
    81  		log.Printf("[WARN] Invalid SNS Subscription, received a \"%s\" ARN", awsSNSPendingConfirmationMessage)
    82  		return nil
    83  	}
    84  
    85  	log.Printf("New subscription ARN: %s", *output.SubscriptionArn)
    86  	d.SetId(*output.SubscriptionArn)
    87  
    88  	// Write the ARN to the 'arn' field for export
    89  	d.Set("arn", *output.SubscriptionArn)
    90  
    91  	return resourceAwsSnsTopicSubscriptionUpdate(d, meta)
    92  }
    93  
    94  func resourceAwsSnsTopicSubscriptionUpdate(d *schema.ResourceData, meta interface{}) error {
    95  	snsconn := meta.(*AWSClient).snsconn
    96  
    97  	// If any changes happened, un-subscribe and re-subscribe
    98  	if d.HasChange("protocol") || d.HasChange("endpoint") || d.HasChange("topic_arn") {
    99  		log.Printf("[DEBUG] Updating subscription %s", d.Id())
   100  		// Unsubscribe
   101  		_, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{
   102  			SubscriptionArn: aws.String(d.Id()),
   103  		})
   104  
   105  		if err != nil {
   106  			return fmt.Errorf("Error unsubscribing from SNS topic: %s", err)
   107  		}
   108  
   109  		// Re-subscribe and set id
   110  		output, err := subscribeToSNSTopic(d, snsconn)
   111  		d.SetId(*output.SubscriptionArn)
   112  		d.Set("arn", *output.SubscriptionArn)
   113  	}
   114  
   115  	if d.HasChange("raw_message_delivery") {
   116  		_, n := d.GetChange("raw_message_delivery")
   117  
   118  		attrValue := "false"
   119  
   120  		if n.(bool) {
   121  			attrValue = "true"
   122  		}
   123  
   124  		req := &sns.SetSubscriptionAttributesInput{
   125  			SubscriptionArn: aws.String(d.Id()),
   126  			AttributeName:   aws.String("RawMessageDelivery"),
   127  			AttributeValue:  aws.String(attrValue),
   128  		}
   129  		_, err := snsconn.SetSubscriptionAttributes(req)
   130  
   131  		if err != nil {
   132  			return fmt.Errorf("Unable to set raw message delivery attribute on subscription")
   133  		}
   134  	}
   135  
   136  	return resourceAwsSnsTopicSubscriptionRead(d, meta)
   137  }
   138  
   139  func resourceAwsSnsTopicSubscriptionRead(d *schema.ResourceData, meta interface{}) error {
   140  	snsconn := meta.(*AWSClient).snsconn
   141  
   142  	log.Printf("[DEBUG] Loading subscription %s", d.Id())
   143  
   144  	attributeOutput, err := snsconn.GetSubscriptionAttributes(&sns.GetSubscriptionAttributesInput{
   145  		SubscriptionArn: aws.String(d.Id()),
   146  	})
   147  	if err != nil {
   148  		return err
   149  	}
   150  
   151  	if attributeOutput.Attributes != nil && len(attributeOutput.Attributes) > 0 {
   152  		attrHash := attributeOutput.Attributes
   153  		log.Printf("[DEBUG] raw message delivery: %s", *attrHash["RawMessageDelivery"])
   154  		if *attrHash["RawMessageDelivery"] == "true" {
   155  			d.Set("raw_message_delivery", true)
   156  		} else {
   157  			d.Set("raw_message_delivery", false)
   158  		}
   159  	}
   160  
   161  	return nil
   162  }
   163  
   164  func resourceAwsSnsTopicSubscriptionDelete(d *schema.ResourceData, meta interface{}) error {
   165  	snsconn := meta.(*AWSClient).snsconn
   166  
   167  	log.Printf("[DEBUG] SNS delete topic subscription: %s", d.Id())
   168  	_, err := snsconn.Unsubscribe(&sns.UnsubscribeInput{
   169  		SubscriptionArn: aws.String(d.Id()),
   170  	})
   171  	if err != nil {
   172  		return err
   173  	}
   174  	return nil
   175  }
   176  
   177  func subscribeToSNSTopic(d *schema.ResourceData, snsconn *sns.SNS) (output *sns.SubscribeOutput, err error) {
   178  	protocol := d.Get("protocol").(string)
   179  	endpoint := d.Get("endpoint").(string)
   180  	topic_arn := d.Get("topic_arn").(string)
   181  
   182  	log.Printf("[DEBUG] SNS create topic subscription: %s (%s) @ '%s'", endpoint, protocol, topic_arn)
   183  
   184  	req := &sns.SubscribeInput{
   185  		Protocol: aws.String(protocol),
   186  		Endpoint: aws.String(endpoint),
   187  		TopicArn: aws.String(topic_arn),
   188  	}
   189  
   190  	output, err = snsconn.Subscribe(req)
   191  	if err != nil {
   192  		return nil, fmt.Errorf("Error creating SNS topic: %s", err)
   193  	}
   194  
   195  	log.Printf("[DEBUG] Created new subscription!")
   196  	return output, nil
   197  }