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 }