github.com/richardbowden/terraform@v0.6.12-0.20160901200758-30ea22c25211/builtin/providers/aws/resource_aws_sqs_queue.go (about)

     1  package aws
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"log"
     8  	"net/url"
     9  	"strconv"
    10  
    11  	"github.com/hashicorp/terraform/helper/schema"
    12  
    13  	"strings"
    14  
    15  	"github.com/aws/aws-sdk-go/aws"
    16  	"github.com/aws/aws-sdk-go/aws/awserr"
    17  	"github.com/aws/aws-sdk-go/service/sqs"
    18  )
    19  
    20  var AttributeMap = map[string]string{
    21  	"delay_seconds":              "DelaySeconds",
    22  	"max_message_size":           "MaximumMessageSize",
    23  	"message_retention_seconds":  "MessageRetentionPeriod",
    24  	"receive_wait_time_seconds":  "ReceiveMessageWaitTimeSeconds",
    25  	"visibility_timeout_seconds": "VisibilityTimeout",
    26  	"policy":                     "Policy",
    27  	"redrive_policy":             "RedrivePolicy",
    28  	"arn":                        "QueueArn",
    29  }
    30  
    31  // A number of these are marked as computed because if you don't
    32  // provide a value, SQS will provide you with defaults (which are the
    33  // default values specified below)
    34  func resourceAwsSqsQueue() *schema.Resource {
    35  	return &schema.Resource{
    36  		Create: resourceAwsSqsQueueCreate,
    37  		Read:   resourceAwsSqsQueueRead,
    38  		Update: resourceAwsSqsQueueUpdate,
    39  		Delete: resourceAwsSqsQueueDelete,
    40  		Importer: &schema.ResourceImporter{
    41  			State: schema.ImportStatePassthrough,
    42  		},
    43  
    44  		Schema: map[string]*schema.Schema{
    45  			"name": &schema.Schema{
    46  				Type:     schema.TypeString,
    47  				Required: true,
    48  				ForceNew: true,
    49  			},
    50  			"delay_seconds": &schema.Schema{
    51  				Type:     schema.TypeInt,
    52  				Optional: true,
    53  				Default:  0,
    54  			},
    55  			"max_message_size": &schema.Schema{
    56  				Type:     schema.TypeInt,
    57  				Optional: true,
    58  				Default:  262144,
    59  			},
    60  			"message_retention_seconds": &schema.Schema{
    61  				Type:     schema.TypeInt,
    62  				Optional: true,
    63  				Default:  345600,
    64  			},
    65  			"receive_wait_time_seconds": &schema.Schema{
    66  				Type:     schema.TypeInt,
    67  				Optional: true,
    68  				Default:  0,
    69  			},
    70  			"visibility_timeout_seconds": &schema.Schema{
    71  				Type:     schema.TypeInt,
    72  				Optional: true,
    73  				Default:  30,
    74  			},
    75  			"policy": &schema.Schema{
    76  				Type:     schema.TypeString,
    77  				Optional: true,
    78  				StateFunc: func(v interface{}) string {
    79  					s, ok := v.(string)
    80  					if !ok || s == "" {
    81  						return ""
    82  					}
    83  					jsonb := []byte(s)
    84  					buffer := new(bytes.Buffer)
    85  					if err := json.Compact(buffer, jsonb); err != nil {
    86  						log.Printf("[WARN] Error compacting JSON for Policy in SNS Queue, using raw string: %s", err)
    87  						return s
    88  					}
    89  					return buffer.String()
    90  				},
    91  			},
    92  			"redrive_policy": &schema.Schema{
    93  				Type:      schema.TypeString,
    94  				Optional:  true,
    95  				StateFunc: normalizeJson,
    96  			},
    97  			"arn": &schema.Schema{
    98  				Type:     schema.TypeString,
    99  				Computed: true,
   100  			},
   101  		},
   102  	}
   103  }
   104  
   105  func resourceAwsSqsQueueCreate(d *schema.ResourceData, meta interface{}) error {
   106  	sqsconn := meta.(*AWSClient).sqsconn
   107  
   108  	name := d.Get("name").(string)
   109  
   110  	log.Printf("[DEBUG] SQS queue create: %s", name)
   111  
   112  	req := &sqs.CreateQueueInput{
   113  		QueueName: aws.String(name),
   114  	}
   115  
   116  	attributes := make(map[string]*string)
   117  
   118  	resource := *resourceAwsSqsQueue()
   119  
   120  	for k, s := range resource.Schema {
   121  		if attrKey, ok := AttributeMap[k]; ok {
   122  			if value, ok := d.GetOk(k); ok {
   123  				if s.Type == schema.TypeInt {
   124  					attributes[attrKey] = aws.String(strconv.Itoa(value.(int)))
   125  				} else {
   126  					attributes[attrKey] = aws.String(value.(string))
   127  				}
   128  			}
   129  
   130  		}
   131  	}
   132  
   133  	if len(attributes) > 0 {
   134  		req.Attributes = attributes
   135  	}
   136  
   137  	output, err := sqsconn.CreateQueue(req)
   138  	if err != nil {
   139  		return fmt.Errorf("Error creating SQS queue: %s", err)
   140  	}
   141  
   142  	d.SetId(*output.QueueUrl)
   143  
   144  	return resourceAwsSqsQueueUpdate(d, meta)
   145  }
   146  
   147  func resourceAwsSqsQueueUpdate(d *schema.ResourceData, meta interface{}) error {
   148  	sqsconn := meta.(*AWSClient).sqsconn
   149  	attributes := make(map[string]*string)
   150  
   151  	resource := *resourceAwsSqsQueue()
   152  
   153  	for k, s := range resource.Schema {
   154  		if attrKey, ok := AttributeMap[k]; ok {
   155  			if d.HasChange(k) {
   156  				log.Printf("[DEBUG] Updating %s", attrKey)
   157  				_, n := d.GetChange(k)
   158  				if s.Type == schema.TypeInt {
   159  					attributes[attrKey] = aws.String(strconv.Itoa(n.(int)))
   160  				} else {
   161  					attributes[attrKey] = aws.String(n.(string))
   162  				}
   163  			}
   164  		}
   165  	}
   166  
   167  	if len(attributes) > 0 {
   168  		req := &sqs.SetQueueAttributesInput{
   169  			QueueUrl:   aws.String(d.Id()),
   170  			Attributes: attributes,
   171  		}
   172  		sqsconn.SetQueueAttributes(req)
   173  	}
   174  
   175  	return resourceAwsSqsQueueRead(d, meta)
   176  }
   177  
   178  func resourceAwsSqsQueueRead(d *schema.ResourceData, meta interface{}) error {
   179  	sqsconn := meta.(*AWSClient).sqsconn
   180  
   181  	attributeOutput, err := sqsconn.GetQueueAttributes(&sqs.GetQueueAttributesInput{
   182  		QueueUrl:       aws.String(d.Id()),
   183  		AttributeNames: []*string{aws.String("All")},
   184  	})
   185  
   186  	if err != nil {
   187  		if awsErr, ok := err.(awserr.Error); ok {
   188  			log.Printf("ERROR Found %s", awsErr.Code())
   189  			if "AWS.SimpleQueueService.NonExistentQueue" == awsErr.Code() {
   190  				d.SetId("")
   191  				log.Printf("[DEBUG] SQS Queue (%s) not found", d.Get("name").(string))
   192  				return nil
   193  			}
   194  		}
   195  		return err
   196  	}
   197  
   198  	name, err := extractNameFromSqsQueueUrl(d.Id())
   199  	if err != nil {
   200  		return err
   201  	}
   202  	d.Set("name", name)
   203  
   204  	if attributeOutput.Attributes != nil && len(attributeOutput.Attributes) > 0 {
   205  		attrmap := attributeOutput.Attributes
   206  		resource := *resourceAwsSqsQueue()
   207  		// iKey = internal struct key, oKey = AWS Attribute Map key
   208  		for iKey, oKey := range AttributeMap {
   209  			if attrmap[oKey] != nil {
   210  				if resource.Schema[iKey].Type == schema.TypeInt {
   211  					value, err := strconv.Atoi(*attrmap[oKey])
   212  					if err != nil {
   213  						return err
   214  					}
   215  					d.Set(iKey, value)
   216  					log.Printf("[DEBUG] Reading %s => %s -> %d", iKey, oKey, value)
   217  				} else {
   218  					log.Printf("[DEBUG] Reading %s => %s -> %s", iKey, oKey, *attrmap[oKey])
   219  					d.Set(iKey, *attrmap[oKey])
   220  				}
   221  			}
   222  		}
   223  	}
   224  
   225  	return nil
   226  }
   227  
   228  func resourceAwsSqsQueueDelete(d *schema.ResourceData, meta interface{}) error {
   229  	sqsconn := meta.(*AWSClient).sqsconn
   230  
   231  	log.Printf("[DEBUG] SQS Delete Queue: %s", d.Id())
   232  	_, err := sqsconn.DeleteQueue(&sqs.DeleteQueueInput{
   233  		QueueUrl: aws.String(d.Id()),
   234  	})
   235  	if err != nil {
   236  		return err
   237  	}
   238  	return nil
   239  }
   240  
   241  func extractNameFromSqsQueueUrl(queue string) (string, error) {
   242  	//http://sqs.us-west-2.amazonaws.com/123456789012/queueName
   243  	u, err := url.Parse(queue)
   244  	if err != nil {
   245  		return "", err
   246  	}
   247  	segments := strings.Split(u.Path, "/")
   248  	if len(segments) != 3 {
   249  		return "", fmt.Errorf("SQS Url not parsed correctly")
   250  	}
   251  
   252  	return segments[2], nil
   253  
   254  }