github.com/gabrielperezs/terraform@v0.7.0-rc2.0.20160715084931-f7da2612946f/builtin/providers/aws/resource_aws_db_event_subscription.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/aws/awserr" 10 "github.com/aws/aws-sdk-go/service/rds" 11 "github.com/hashicorp/terraform/helper/resource" 12 "github.com/hashicorp/terraform/helper/schema" 13 ) 14 15 func resourceAwsDbEventSubscription() *schema.Resource { 16 return &schema.Resource{ 17 Create: resourceAwsDbEventSubscriptionCreate, 18 Read: resourceAwsDbEventSubscriptionRead, 19 Update: resourceAwsDbEventSubscriptionUpdate, 20 Delete: resourceAwsDbEventSubscriptionDelete, 21 Schema: map[string]*schema.Schema{ 22 "name": &schema.Schema{ 23 Type: schema.TypeString, 24 Required: true, 25 ForceNew: true, 26 ValidateFunc: validateDbEventSubscriptionName, 27 }, 28 "sns_topic": &schema.Schema{ 29 Type: schema.TypeString, 30 Required: true, 31 }, 32 "event_categories": &schema.Schema{ 33 Type: schema.TypeSet, 34 Optional: true, 35 Elem: &schema.Schema{Type: schema.TypeString}, 36 Set: schema.HashString, 37 }, 38 "source_ids": &schema.Schema{ 39 Type: schema.TypeSet, 40 Optional: true, 41 ForceNew: true, 42 Elem: &schema.Schema{Type: schema.TypeString}, 43 Set: schema.HashString, 44 // ValidateFunc: validateDbEventSubscriptionSourceIds, 45 // requires source_type to be set, does not seem to be a way to validate this 46 }, 47 "source_type": &schema.Schema{ 48 Type: schema.TypeString, 49 Optional: true, 50 }, 51 "enabled": &schema.Schema{ 52 Type: schema.TypeBool, 53 Optional: true, 54 Default: true, 55 }, 56 "customer_aws_id": &schema.Schema{ 57 Type: schema.TypeString, 58 Computed: true, 59 }, 60 "tags": tagsSchema(), 61 }, 62 } 63 } 64 65 func resourceAwsDbEventSubscriptionCreate(d *schema.ResourceData, meta interface{}) error { 66 rdsconn := meta.(*AWSClient).rdsconn 67 name := d.Get("name").(string) 68 tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{})) 69 70 sourceIdsSet := d.Get("source_ids").(*schema.Set) 71 sourceIds := make([]*string, sourceIdsSet.Len()) 72 for i, sourceId := range sourceIdsSet.List() { 73 sourceIds[i] = aws.String(sourceId.(string)) 74 } 75 76 eventCategoriesSet := d.Get("event_categories").(*schema.Set) 77 eventCategories := make([]*string, eventCategoriesSet.Len()) 78 for i, eventCategory := range eventCategoriesSet.List() { 79 eventCategories[i] = aws.String(eventCategory.(string)) 80 } 81 82 request := &rds.CreateEventSubscriptionInput{ 83 SubscriptionName: aws.String(name), 84 SnsTopicArn: aws.String(d.Get("sns_topic").(string)), 85 Enabled: aws.Bool(d.Get("enabled").(bool)), 86 SourceIds: sourceIds, 87 SourceType: aws.String(d.Get("source_type").(string)), 88 EventCategories: eventCategories, 89 Tags: tags, 90 } 91 92 log.Println("[DEBUG] Create RDS Event Subscription:", request) 93 94 _, err := rdsconn.CreateEventSubscription(request) 95 if err != nil { 96 return fmt.Errorf("Error creating RDS Event Subscription %s: %s", name, err) 97 } 98 99 log.Println( 100 "[INFO] Waiting for RDS Event Subscription to be ready") 101 102 stateConf := &resource.StateChangeConf{ 103 Pending: []string{"creating"}, 104 Target: []string{"active"}, 105 Refresh: resourceAwsDbEventSubscriptionRefreshFunc(d, meta.(*AWSClient).rdsconn), 106 Timeout: 40 * time.Minute, 107 MinTimeout: 10 * time.Second, 108 Delay: 30 * time.Second, // Wait 30 secs before starting 109 } 110 111 // Wait, catching any errors 112 _, err = stateConf.WaitForState() 113 if err != nil { 114 return fmt.Errorf("Creating RDS Event Subscription %s failed: %s", d.Id(), err) 115 } 116 117 return resourceAwsDbEventSubscriptionRead(d, meta) 118 } 119 120 func resourceAwsDbEventSubscriptionRead(d *schema.ResourceData, meta interface{}) error { 121 sub, err := resourceAwsDbEventSubscriptionRetrieve(d.Get("name").(string), meta.(*AWSClient).rdsconn) 122 if err != nil { 123 return fmt.Errorf("Error retrieving RDS Event Subscription %s: %s", d.Id(), err) 124 } 125 if sub == nil { 126 d.SetId("") 127 return nil 128 } 129 130 d.SetId(*sub.CustSubscriptionId) 131 if err := d.Set("name", sub.CustSubscriptionId); err != nil { 132 return err 133 } 134 if err := d.Set("sns_topic", sub.SnsTopicArn); err != nil { 135 return err 136 } 137 if err := d.Set("source_type", sub.SourceType); err != nil { 138 return err 139 } 140 if err := d.Set("enabled", sub.Enabled); err != nil { 141 return err 142 } 143 if err := d.Set("source_ids", flattenStringList(sub.SourceIdsList)); err != nil { 144 return err 145 } 146 if err := d.Set("event_categories", flattenStringList(sub.EventCategoriesList)); err != nil { 147 return err 148 } 149 if err := d.Set("customer_aws_id", sub.CustomerAwsId); err != nil { 150 return err 151 } 152 153 // list tags for resource 154 // set tags 155 conn := meta.(*AWSClient).rdsconn 156 arn := buildRDSEventSubscriptionARN(d.Get("customer_aws_id").(string), d.Id(), meta.(*AWSClient).region) 157 resp, err := conn.ListTagsForResource(&rds.ListTagsForResourceInput{ 158 ResourceName: aws.String(arn), 159 }) 160 161 if err != nil { 162 log.Printf("[DEBUG] Error retrieving tags for ARN: %s", arn) 163 } 164 165 var dt []*rds.Tag 166 if len(resp.TagList) > 0 { 167 dt = resp.TagList 168 } 169 d.Set("tags", tagsToMapRDS(dt)) 170 171 return nil 172 } 173 174 func resourceAwsDbEventSubscriptionRetrieve( 175 name string, rdsconn *rds.RDS) (*rds.EventSubscription, error) { 176 177 request := &rds.DescribeEventSubscriptionsInput{ 178 SubscriptionName: aws.String(name), 179 } 180 181 describeResp, err := rdsconn.DescribeEventSubscriptions(request) 182 if err != nil { 183 if rdserr, ok := err.(awserr.Error); ok && rdserr.Code() == "SubscriptionNotFound" { 184 log.Printf("[WARN] No RDS Event Subscription by name (%s) found", name) 185 return nil, nil 186 } 187 return nil, fmt.Errorf("Error reading RDS Event Subscription %s: %s", name, err) 188 } 189 190 if len(describeResp.EventSubscriptionsList) != 1 { 191 return nil, fmt.Errorf("Unable to find RDS Event Subscription: %#v", describeResp.EventSubscriptionsList) 192 } 193 194 return describeResp.EventSubscriptionsList[0], nil 195 } 196 197 func resourceAwsDbEventSubscriptionUpdate(d *schema.ResourceData, meta interface{}) error { 198 rdsconn := meta.(*AWSClient).rdsconn 199 200 d.Partial(true) 201 requestUpdate := false 202 203 req := &rds.ModifyEventSubscriptionInput{ 204 SubscriptionName: aws.String(d.Id()), 205 } 206 207 if d.HasChange("event_categories") { 208 eventCategoriesSet := d.Get("event_categories").(*schema.Set) 209 req.EventCategories = make([]*string, eventCategoriesSet.Len()) 210 for i, eventCategory := range eventCategoriesSet.List() { 211 req.EventCategories[i] = aws.String(eventCategory.(string)) 212 } 213 requestUpdate = true 214 } 215 216 if d.HasChange("enabled") { 217 req.Enabled = aws.Bool(d.Get("enabled").(bool)) 218 requestUpdate = true 219 } 220 221 if d.HasChange("sns_topic") { 222 req.SnsTopicArn = aws.String(d.Get("sns_topic").(string)) 223 requestUpdate = true 224 } 225 226 if d.HasChange("source_type") { 227 req.SourceType = aws.String(d.Get("source_type").(string)) 228 requestUpdate = true 229 } 230 231 log.Printf("[DEBUG] Send RDS Event Subscription modification request: %#v", requestUpdate) 232 if requestUpdate { 233 log.Printf("[DEBUG] RDS Event Subscription modification request: %#v", req) 234 _, err := rdsconn.ModifyEventSubscription(req) 235 if err != nil { 236 return fmt.Errorf("Modifying RDS Event Subscription %s failed: %s", d.Id(), err) 237 } 238 239 log.Println( 240 "[INFO] Waiting for RDS Event Subscription modification to finish") 241 242 stateConf := &resource.StateChangeConf{ 243 Pending: []string{"modifying"}, 244 Target: []string{"active"}, 245 Refresh: resourceAwsDbEventSubscriptionRefreshFunc(d, meta.(*AWSClient).rdsconn), 246 Timeout: 40 * time.Minute, 247 MinTimeout: 10 * time.Second, 248 Delay: 30 * time.Second, // Wait 30 secs before starting 249 } 250 251 // Wait, catching any errors 252 _, err = stateConf.WaitForState() 253 if err != nil { 254 return fmt.Errorf("Modifying RDS Event Subscription %s failed: %s", d.Id(), err) 255 } 256 d.SetPartial("event_categories") 257 d.SetPartial("enabled") 258 d.SetPartial("sns_topic") 259 d.SetPartial("source_type") 260 } 261 262 arn := buildRDSEventSubscriptionARN(d.Get("customer_aws_id").(string), d.Id(), meta.(*AWSClient).region) 263 if err := setTagsRDS(rdsconn, d, arn); err != nil { 264 return err 265 } else { 266 d.SetPartial("tags") 267 } 268 d.Partial(false) 269 270 return nil 271 } 272 273 func resourceAwsDbEventSubscriptionDelete(d *schema.ResourceData, meta interface{}) error { 274 rdsconn := meta.(*AWSClient).rdsconn 275 deleteOpts := rds.DeleteEventSubscriptionInput{ 276 SubscriptionName: aws.String(d.Id()), 277 } 278 279 if _, err := rdsconn.DeleteEventSubscription(&deleteOpts); err != nil { 280 rdserr, ok := err.(awserr.Error) 281 if !ok { 282 return fmt.Errorf("Error deleting RDS Event Subscription %s: %s", d.Id(), err) 283 } 284 285 if rdserr.Code() != "DBEventSubscriptionNotFoundFault" { 286 log.Printf("[WARN] RDS Event Subscription %s missing during delete", d.Id()) 287 return fmt.Errorf("Error deleting RDS Event Subscription %s: %s", d.Id(), err) 288 } 289 } 290 291 stateConf := &resource.StateChangeConf{ 292 Pending: []string{"deleting"}, 293 Target: []string{}, 294 Refresh: resourceAwsDbEventSubscriptionRefreshFunc(d, meta.(*AWSClient).rdsconn), 295 Timeout: 40 * time.Minute, 296 MinTimeout: 10 * time.Second, 297 Delay: 30 * time.Second, // Wait 30 secs before starting 298 } 299 _, err := stateConf.WaitForState() 300 if err != nil { 301 return fmt.Errorf("Error deleting RDS Event Subscription %s: %s", d.Id(), err) 302 } 303 return err 304 } 305 306 func resourceAwsDbEventSubscriptionRefreshFunc( 307 d *schema.ResourceData, 308 rdsconn *rds.RDS) resource.StateRefreshFunc { 309 310 return func() (interface{}, string, error) { 311 sub, err := resourceAwsDbEventSubscriptionRetrieve(d.Get("name").(string), rdsconn) 312 313 if err != nil { 314 log.Printf("Error on retrieving DB Event Subscription when waiting: %s", err) 315 return nil, "", err 316 } 317 318 if sub == nil { 319 return nil, "", nil 320 } 321 322 if sub.Status != nil { 323 log.Printf("[DEBUG] DB Event Subscription status for %s: %s", d.Id(), *sub.Status) 324 } 325 326 return sub, *sub.Status, nil 327 } 328 } 329 330 func buildRDSEventSubscriptionARN(customerAwsId, subscriptionId, region string) string { 331 arn := fmt.Sprintf("arn:aws:rds:%s:%s:es:%s", region, customerAwsId, subscriptionId) 332 return arn 333 }