github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_cloudwatch_event_target.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "regexp" 7 8 "github.com/hashicorp/terraform/helper/resource" 9 "github.com/hashicorp/terraform/helper/schema" 10 11 "github.com/aws/aws-sdk-go/aws" 12 "github.com/aws/aws-sdk-go/aws/awserr" 13 events "github.com/aws/aws-sdk-go/service/cloudwatchevents" 14 ) 15 16 func resourceAwsCloudWatchEventTarget() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceAwsCloudWatchEventTargetCreate, 19 Read: resourceAwsCloudWatchEventTargetRead, 20 Update: resourceAwsCloudWatchEventTargetUpdate, 21 Delete: resourceAwsCloudWatchEventTargetDelete, 22 23 Schema: map[string]*schema.Schema{ 24 "rule": &schema.Schema{ 25 Type: schema.TypeString, 26 Required: true, 27 ForceNew: true, 28 ValidateFunc: validateCloudWatchEventRuleName, 29 }, 30 31 "target_id": &schema.Schema{ 32 Type: schema.TypeString, 33 Optional: true, 34 Computed: true, 35 ForceNew: true, 36 ValidateFunc: validateCloudWatchEventTargetId, 37 }, 38 39 "arn": &schema.Schema{ 40 Type: schema.TypeString, 41 Required: true, 42 }, 43 44 "input": &schema.Schema{ 45 Type: schema.TypeString, 46 Optional: true, 47 ConflictsWith: []string{"input_path"}, 48 // We could be normalizing the JSON here, 49 // but for built-in targets input may not be JSON 50 }, 51 52 "input_path": &schema.Schema{ 53 Type: schema.TypeString, 54 Optional: true, 55 ConflictsWith: []string{"input"}, 56 }, 57 }, 58 } 59 } 60 61 func resourceAwsCloudWatchEventTargetCreate(d *schema.ResourceData, meta interface{}) error { 62 conn := meta.(*AWSClient).cloudwatcheventsconn 63 64 rule := d.Get("rule").(string) 65 66 var targetId string 67 if v, ok := d.GetOk("target_id"); ok { 68 targetId = v.(string) 69 } else { 70 targetId = resource.UniqueId() 71 d.Set("target_id", targetId) 72 } 73 74 input := buildPutTargetInputStruct(d) 75 log.Printf("[DEBUG] Creating CloudWatch Event Target: %s", input) 76 out, err := conn.PutTargets(input) 77 if err != nil { 78 return fmt.Errorf("Creating CloudWatch Event Target failed: %s", err) 79 } 80 81 if len(out.FailedEntries) > 0 { 82 return fmt.Errorf("Creating CloudWatch Event Target failed: %s", 83 out.FailedEntries) 84 } 85 86 id := rule + "-" + targetId 87 d.SetId(id) 88 89 log.Printf("[INFO] CloudWatch Event Target %q created", d.Id()) 90 91 return resourceAwsCloudWatchEventTargetRead(d, meta) 92 } 93 94 func resourceAwsCloudWatchEventTargetRead(d *schema.ResourceData, meta interface{}) error { 95 conn := meta.(*AWSClient).cloudwatcheventsconn 96 97 t, err := findEventTargetById( 98 d.Get("target_id").(string), 99 d.Get("rule").(string), 100 nil, conn) 101 if err != nil { 102 if regexp.MustCompile(" not found$").MatchString(err.Error()) { 103 log.Printf("[WARN] Removing CloudWatch Event Target %q because it's gone.", d.Id()) 104 d.SetId("") 105 return nil 106 } 107 if awsErr, ok := err.(awserr.Error); ok { 108 // This should never happen, but it's useful 109 // for recovering from https://github.com/hashicorp/terraform/issues/5389 110 if awsErr.Code() == "ValidationException" { 111 log.Printf("[WARN] Removing CloudWatch Event Target %q because it never existed.", d.Id()) 112 d.SetId("") 113 return nil 114 } 115 116 if awsErr.Code() == "ResourceNotFoundException" { 117 log.Printf("[WARN] CloudWatch Event Target (%q) not found. Removing it from state.", d.Id()) 118 d.SetId("") 119 return nil 120 } 121 122 } 123 return err 124 } 125 log.Printf("[DEBUG] Found Event Target: %s", t) 126 127 d.Set("arn", t.Arn) 128 d.Set("target_id", t.Id) 129 d.Set("input", t.Input) 130 d.Set("input_path", t.InputPath) 131 132 return nil 133 } 134 135 func findEventTargetById(id, rule string, nextToken *string, conn *events.CloudWatchEvents) ( 136 *events.Target, error) { 137 input := events.ListTargetsByRuleInput{ 138 Rule: aws.String(rule), 139 NextToken: nextToken, 140 Limit: aws.Int64(100), // Set limit to allowed maximum to prevent API throttling 141 } 142 log.Printf("[DEBUG] Reading CloudWatch Event Target: %s", input) 143 out, err := conn.ListTargetsByRule(&input) 144 if err != nil { 145 return nil, err 146 } 147 148 for _, t := range out.Targets { 149 if *t.Id == id { 150 return t, nil 151 } 152 } 153 154 if out.NextToken != nil { 155 return findEventTargetById(id, rule, nextToken, conn) 156 } 157 158 return nil, fmt.Errorf("CloudWatch Event Target %q (%q) not found", id, rule) 159 } 160 161 func resourceAwsCloudWatchEventTargetUpdate(d *schema.ResourceData, meta interface{}) error { 162 conn := meta.(*AWSClient).cloudwatcheventsconn 163 164 input := buildPutTargetInputStruct(d) 165 log.Printf("[DEBUG] Updating CloudWatch Event Target: %s", input) 166 _, err := conn.PutTargets(input) 167 if err != nil { 168 return fmt.Errorf("Updating CloudWatch Event Target failed: %s", err) 169 } 170 171 return resourceAwsCloudWatchEventTargetRead(d, meta) 172 } 173 174 func resourceAwsCloudWatchEventTargetDelete(d *schema.ResourceData, meta interface{}) error { 175 conn := meta.(*AWSClient).cloudwatcheventsconn 176 177 input := events.RemoveTargetsInput{ 178 Ids: []*string{aws.String(d.Get("target_id").(string))}, 179 Rule: aws.String(d.Get("rule").(string)), 180 } 181 log.Printf("[INFO] Deleting CloudWatch Event Target: %s", input) 182 _, err := conn.RemoveTargets(&input) 183 if err != nil { 184 return fmt.Errorf("Error deleting CloudWatch Event Target: %s", err) 185 } 186 log.Println("[INFO] CloudWatch Event Target deleted") 187 188 d.SetId("") 189 190 return nil 191 } 192 193 func buildPutTargetInputStruct(d *schema.ResourceData) *events.PutTargetsInput { 194 e := &events.Target{ 195 Arn: aws.String(d.Get("arn").(string)), 196 Id: aws.String(d.Get("target_id").(string)), 197 } 198 199 if v, ok := d.GetOk("input"); ok { 200 e.Input = aws.String(v.(string)) 201 } 202 if v, ok := d.GetOk("input_path"); ok { 203 e.InputPath = aws.String(v.(string)) 204 } 205 206 input := events.PutTargetsInput{ 207 Rule: aws.String(d.Get("rule").(string)), 208 Targets: []*events.Target{e}, 209 } 210 211 return &input 212 }