provider/aws: Add CloudWatch Event Target
This commit is contained in:
parent
b5039dd897
commit
61afc6d34d
|
@ -122,6 +122,7 @@ func Provider() terraform.ResourceProvider {
|
||||||
"aws_cloudformation_stack": resourceAwsCloudFormationStack(),
|
"aws_cloudformation_stack": resourceAwsCloudFormationStack(),
|
||||||
"aws_cloudtrail": resourceAwsCloudTrail(),
|
"aws_cloudtrail": resourceAwsCloudTrail(),
|
||||||
"aws_cloudwatch_event_rule": resourceAwsCloudWatchEventRule(),
|
"aws_cloudwatch_event_rule": resourceAwsCloudWatchEventRule(),
|
||||||
|
"aws_cloudwatch_event_target": resourceAwsCloudWatchEventTarget(),
|
||||||
"aws_cloudwatch_log_group": resourceAwsCloudWatchLogGroup(),
|
"aws_cloudwatch_log_group": resourceAwsCloudWatchLogGroup(),
|
||||||
"aws_autoscaling_lifecycle_hook": resourceAwsAutoscalingLifecycleHook(),
|
"aws_autoscaling_lifecycle_hook": resourceAwsAutoscalingLifecycleHook(),
|
||||||
"aws_cloudwatch_metric_alarm": resourceAwsCloudWatchMetricAlarm(),
|
"aws_cloudwatch_metric_alarm": resourceAwsCloudWatchMetricAlarm(),
|
||||||
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
events "github.com/aws/aws-sdk-go/service/cloudwatchevents"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceAwsCloudWatchEventTarget() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceAwsCloudWatchEventTargetCreate,
|
||||||
|
Read: resourceAwsCloudWatchEventTargetRead,
|
||||||
|
Update: resourceAwsCloudWatchEventTargetUpdate,
|
||||||
|
Delete: resourceAwsCloudWatchEventTargetDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"rule": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ValidateFunc: validateCloudWatchEventRuleName,
|
||||||
|
},
|
||||||
|
|
||||||
|
"target_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ValidateFunc: validateCloudWatchEventTargetId,
|
||||||
|
},
|
||||||
|
|
||||||
|
"arn": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"input": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ConflictsWith: []string{"input_path"},
|
||||||
|
// We could be normalizing the JSON here,
|
||||||
|
// but for built-in targets input may not be JSON
|
||||||
|
},
|
||||||
|
|
||||||
|
"input_path": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ConflictsWith: []string{"input"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsCloudWatchEventTargetCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).cloudwatcheventsconn
|
||||||
|
|
||||||
|
rule := d.Get("rule").(string)
|
||||||
|
targetId := d.Get("target_id").(string)
|
||||||
|
|
||||||
|
id := rule + "-" + targetId
|
||||||
|
d.SetId(id)
|
||||||
|
|
||||||
|
input := buildPutTargetInputStruct(d)
|
||||||
|
log.Printf("[DEBUG] Creating CloudWatch Event Target: %s", input)
|
||||||
|
out, err := conn.PutTargets(input)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Creating CloudWatch Event Target failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(out.FailedEntries) > 0 {
|
||||||
|
return fmt.Errorf("Creating CloudWatch Event Target failed: %s",
|
||||||
|
out.FailedEntries)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[INFO] CloudWatch Event Target %q created", d.Id())
|
||||||
|
|
||||||
|
return resourceAwsCloudWatchEventTargetRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsCloudWatchEventTargetRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).cloudwatcheventsconn
|
||||||
|
|
||||||
|
t, err := findEventTargetById(
|
||||||
|
d.Get("target_id").(string),
|
||||||
|
d.Get("rule").(string),
|
||||||
|
nil, conn)
|
||||||
|
if err != nil {
|
||||||
|
if regexp.MustCompile(" not found$").MatchString(err.Error()) {
|
||||||
|
log.Printf("[WARN] Removing CloudWatch Event Target %q because it's gone.", d.Id())
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Printf("[DEBUG] Found Event Target: %s", t)
|
||||||
|
|
||||||
|
d.Set("arn", t.Arn)
|
||||||
|
d.Set("target_id", t.Id)
|
||||||
|
d.Set("input", t.Input)
|
||||||
|
d.Set("input_path", t.InputPath)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func findEventTargetById(id, rule string, nextToken *string, conn *events.CloudWatchEvents) (
|
||||||
|
*events.Target, error) {
|
||||||
|
input := events.ListTargetsByRuleInput{
|
||||||
|
Rule: aws.String(rule),
|
||||||
|
NextToken: nextToken,
|
||||||
|
Limit: aws.Int64(100), // Set limit to allowed maximum to prevent API throttling
|
||||||
|
}
|
||||||
|
log.Printf("[DEBUG] Reading CloudWatch Event Target: %s", input)
|
||||||
|
out, err := conn.ListTargetsByRule(&input)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, t := range out.Targets {
|
||||||
|
if *t.Id == id {
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if out.NextToken != nil {
|
||||||
|
return findEventTargetById(id, rule, nextToken, conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("CloudWatch Event Target %q (%q) not found", id, rule)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsCloudWatchEventTargetUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).cloudwatcheventsconn
|
||||||
|
|
||||||
|
input := buildPutTargetInputStruct(d)
|
||||||
|
log.Printf("[DEBUG] Updating CloudWatch Event Target: %s", input)
|
||||||
|
_, err := conn.PutTargets(input)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Updating CloudWatch Event Target failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceAwsCloudWatchEventTargetRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsCloudWatchEventTargetDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).cloudwatcheventsconn
|
||||||
|
|
||||||
|
input := events.RemoveTargetsInput{
|
||||||
|
Ids: []*string{aws.String(d.Get("target_id").(string))},
|
||||||
|
Rule: aws.String(d.Get("rule").(string)),
|
||||||
|
}
|
||||||
|
log.Printf("[INFO] Deleting CloudWatch Event Target: %s", input)
|
||||||
|
_, err := conn.RemoveTargets(&input)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error deleting CloudWatch Event Target: %s", err)
|
||||||
|
}
|
||||||
|
log.Println("[INFO] CloudWatch Event Target deleted")
|
||||||
|
|
||||||
|
d.SetId("")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildPutTargetInputStruct(d *schema.ResourceData) *events.PutTargetsInput {
|
||||||
|
e := &events.Target{
|
||||||
|
Arn: aws.String(d.Get("arn").(string)),
|
||||||
|
Id: aws.String(d.Get("target_id").(string)),
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("input"); ok {
|
||||||
|
e.Input = aws.String(v.(string))
|
||||||
|
}
|
||||||
|
if v, ok := d.GetOk("input_path"); ok {
|
||||||
|
e.InputPath = aws.String(v.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
input := events.PutTargetsInput{
|
||||||
|
Rule: aws.String(d.Get("rule").(string)),
|
||||||
|
Targets: []*events.Target{e},
|
||||||
|
}
|
||||||
|
|
||||||
|
return &input
|
||||||
|
}
|
|
@ -165,3 +165,21 @@ func validateMaxLength(length int) schema.SchemaValidateFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateCloudWatchEventTargetId(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
value := v.(string)
|
||||||
|
if len(value) > 64 {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q cannot be longer than 64 characters: %q", k, value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_Target.html
|
||||||
|
pattern := `^[\.\-_A-Za-z0-9]+$`
|
||||||
|
if !regexp.MustCompile(pattern).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q doesn't comply with restrictions (%q): %q",
|
||||||
|
k, pattern, value))
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue