From 65ac8649efa733231d89c4e6d746dbe21e75cf0d Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Wed, 3 Feb 2016 16:41:59 +0000 Subject: [PATCH 1/7] deps: Vendor aws/aws-sdk-go/service/cloudwatchevents --- Godeps/Godeps.json | 5 + .../service/cloudwatchevents/api.go | 1094 +++++++++++++++++ .../cloudwatcheventsiface/interface.go | 62 + .../service/cloudwatchevents/service.go | 101 ++ 4 files changed, 1262 insertions(+) create mode 100644 vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/cloudwatcheventsiface/interface.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/service.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 4b0ed43883..b627c36f39 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -262,6 +262,11 @@ "Comment": "v1.1.0", "Rev": "be2ec39e520e3c4088c0c6288055bdc8184a89ee" }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/cloudwatchevents", + "Comment": "v1.1.0", + "Rev": "be2ec39e520e3c4088c0c6288055bdc8184a89ee" + }, { "ImportPath": "github.com/aws/aws-sdk-go/service/cloudwatchlogs", "Comment": "v1.1.0", diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/api.go b/vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/api.go new file mode 100644 index 0000000000..0ced93d8d7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/api.go @@ -0,0 +1,1094 @@ +// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + +// Package cloudwatchevents provides a client for Amazon CloudWatch Events. +package cloudwatchevents + +import ( + "time" + + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" +) + +const opDeleteRule = "DeleteRule" + +// DeleteRuleRequest generates a request for the DeleteRule operation. +func (c *CloudWatchEvents) DeleteRuleRequest(input *DeleteRuleInput) (req *request.Request, output *DeleteRuleOutput) { + op := &request.Operation{ + Name: opDeleteRule, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteRuleInput{} + } + + req = c.newRequest(op, input, output) + output = &DeleteRuleOutput{} + req.Data = output + return +} + +// Deletes a rule. You must remove all targets from a rule using RemoveTargets +// before you can delete the rule. +// +// Note: When you make a change with this action, incoming events might still +// continue to match to the deleted rule. Please allow a short period of time +// for changes to take effect. +func (c *CloudWatchEvents) DeleteRule(input *DeleteRuleInput) (*DeleteRuleOutput, error) { + req, out := c.DeleteRuleRequest(input) + err := req.Send() + return out, err +} + +const opDescribeRule = "DescribeRule" + +// DescribeRuleRequest generates a request for the DescribeRule operation. +func (c *CloudWatchEvents) DescribeRuleRequest(input *DescribeRuleInput) (req *request.Request, output *DescribeRuleOutput) { + op := &request.Operation{ + Name: opDescribeRule, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeRuleInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeRuleOutput{} + req.Data = output + return +} + +// Describes the details of the specified rule. +func (c *CloudWatchEvents) DescribeRule(input *DescribeRuleInput) (*DescribeRuleOutput, error) { + req, out := c.DescribeRuleRequest(input) + err := req.Send() + return out, err +} + +const opDisableRule = "DisableRule" + +// DisableRuleRequest generates a request for the DisableRule operation. +func (c *CloudWatchEvents) DisableRuleRequest(input *DisableRuleInput) (req *request.Request, output *DisableRuleOutput) { + op := &request.Operation{ + Name: opDisableRule, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DisableRuleInput{} + } + + req = c.newRequest(op, input, output) + output = &DisableRuleOutput{} + req.Data = output + return +} + +// Disables a rule. A disabled rule won't match any events, and won't self-trigger +// if it has a schedule expression. +// +// Note: When you make a change with this action, incoming events might still +// continue to match to the disabled rule. Please allow a short period of time +// for changes to take effect. +func (c *CloudWatchEvents) DisableRule(input *DisableRuleInput) (*DisableRuleOutput, error) { + req, out := c.DisableRuleRequest(input) + err := req.Send() + return out, err +} + +const opEnableRule = "EnableRule" + +// EnableRuleRequest generates a request for the EnableRule operation. +func (c *CloudWatchEvents) EnableRuleRequest(input *EnableRuleInput) (req *request.Request, output *EnableRuleOutput) { + op := &request.Operation{ + Name: opEnableRule, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &EnableRuleInput{} + } + + req = c.newRequest(op, input, output) + output = &EnableRuleOutput{} + req.Data = output + return +} + +// Enables a rule. If the rule does not exist, the operation fails. +// +// Note: When you make a change with this action, incoming events might not +// immediately start matching to a newly enabled rule. Please allow a short +// period of time for changes to take effect. +func (c *CloudWatchEvents) EnableRule(input *EnableRuleInput) (*EnableRuleOutput, error) { + req, out := c.EnableRuleRequest(input) + err := req.Send() + return out, err +} + +const opListRuleNamesByTarget = "ListRuleNamesByTarget" + +// ListRuleNamesByTargetRequest generates a request for the ListRuleNamesByTarget operation. +func (c *CloudWatchEvents) ListRuleNamesByTargetRequest(input *ListRuleNamesByTargetInput) (req *request.Request, output *ListRuleNamesByTargetOutput) { + op := &request.Operation{ + Name: opListRuleNamesByTarget, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ListRuleNamesByTargetInput{} + } + + req = c.newRequest(op, input, output) + output = &ListRuleNamesByTargetOutput{} + req.Data = output + return +} + +// Lists the names of the rules that the given target is put to. Using this +// action, you can find out which of the rules in Amazon CloudWatch Events can +// invoke a specific target in your account. If you have more rules in your +// account than the given limit, the results will be paginated. In that case, +// use the next token returned in the response and repeat the ListRulesByTarget +// action until the NextToken in the response is returned as null. +func (c *CloudWatchEvents) ListRuleNamesByTarget(input *ListRuleNamesByTargetInput) (*ListRuleNamesByTargetOutput, error) { + req, out := c.ListRuleNamesByTargetRequest(input) + err := req.Send() + return out, err +} + +const opListRules = "ListRules" + +// ListRulesRequest generates a request for the ListRules operation. +func (c *CloudWatchEvents) ListRulesRequest(input *ListRulesInput) (req *request.Request, output *ListRulesOutput) { + op := &request.Operation{ + Name: opListRules, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ListRulesInput{} + } + + req = c.newRequest(op, input, output) + output = &ListRulesOutput{} + req.Data = output + return +} + +// Lists the Amazon CloudWatch Events rules in your account. You can either +// list all the rules or you can provide a prefix to match to the rule names. +// If you have more rules in your account than the given limit, the results +// will be paginated. In that case, use the next token returned in the response +// and repeat the ListRules action until the NextToken in the response is returned +// as null. +func (c *CloudWatchEvents) ListRules(input *ListRulesInput) (*ListRulesOutput, error) { + req, out := c.ListRulesRequest(input) + err := req.Send() + return out, err +} + +const opListTargetsByRule = "ListTargetsByRule" + +// ListTargetsByRuleRequest generates a request for the ListTargetsByRule operation. +func (c *CloudWatchEvents) ListTargetsByRuleRequest(input *ListTargetsByRuleInput) (req *request.Request, output *ListTargetsByRuleOutput) { + op := &request.Operation{ + Name: opListTargetsByRule, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ListTargetsByRuleInput{} + } + + req = c.newRequest(op, input, output) + output = &ListTargetsByRuleOutput{} + req.Data = output + return +} + +// Lists of targets assigned to the rule. +func (c *CloudWatchEvents) ListTargetsByRule(input *ListTargetsByRuleInput) (*ListTargetsByRuleOutput, error) { + req, out := c.ListTargetsByRuleRequest(input) + err := req.Send() + return out, err +} + +const opPutEvents = "PutEvents" + +// PutEventsRequest generates a request for the PutEvents operation. +func (c *CloudWatchEvents) PutEventsRequest(input *PutEventsInput) (req *request.Request, output *PutEventsOutput) { + op := &request.Operation{ + Name: opPutEvents, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PutEventsInput{} + } + + req = c.newRequest(op, input, output) + output = &PutEventsOutput{} + req.Data = output + return +} + +// Sends custom events to Amazon CloudWatch Events so that they can be matched +// to rules. +func (c *CloudWatchEvents) PutEvents(input *PutEventsInput) (*PutEventsOutput, error) { + req, out := c.PutEventsRequest(input) + err := req.Send() + return out, err +} + +const opPutRule = "PutRule" + +// PutRuleRequest generates a request for the PutRule operation. +func (c *CloudWatchEvents) PutRuleRequest(input *PutRuleInput) (req *request.Request, output *PutRuleOutput) { + op := &request.Operation{ + Name: opPutRule, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PutRuleInput{} + } + + req = c.newRequest(op, input, output) + output = &PutRuleOutput{} + req.Data = output + return +} + +// Creates or updates a rule. Rules are enabled by default, or based on value +// of the State parameter. You can disable a rule using DisableRule. +// +// Note: When you make a change with this action, incoming events might not +// immediately start matching to new or updated rules. Please allow a short +// period of time for changes to take effect. +// +// A rule must contain at least an EventPattern or ScheduleExpression. Rules +// with EventPatterns are triggered when a matching event is observed. Rules +// with ScheduleExpressions self-trigger based on the given schedule. A rule +// can have both an EventPattern and a ScheduleExpression, in which case the +// rule will trigger on matching events as well as on a schedule. +// +// Note: Most services in AWS treat : or / as the same character in Amazon +// Resource Names (ARNs). However, CloudWatch Events uses an exact match in +// event patterns and rules. Be sure to use the correct ARN characters when +// creating event patterns so that they match the ARN syntax in the event you +// want to match. +func (c *CloudWatchEvents) PutRule(input *PutRuleInput) (*PutRuleOutput, error) { + req, out := c.PutRuleRequest(input) + err := req.Send() + return out, err +} + +const opPutTargets = "PutTargets" + +// PutTargetsRequest generates a request for the PutTargets operation. +func (c *CloudWatchEvents) PutTargetsRequest(input *PutTargetsInput) (req *request.Request, output *PutTargetsOutput) { + op := &request.Operation{ + Name: opPutTargets, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PutTargetsInput{} + } + + req = c.newRequest(op, input, output) + output = &PutTargetsOutput{} + req.Data = output + return +} + +// Adds target(s) to a rule. Updates the target(s) if they are already associated +// with the role. In other words, if there is already a target with the given +// target ID, then the target associated with that ID is updated. +// +// Note: When you make a change with this action, when the associated rule +// triggers, new or updated targets might not be immediately invoked. Please +// allow a short period of time for changes to take effect. +func (c *CloudWatchEvents) PutTargets(input *PutTargetsInput) (*PutTargetsOutput, error) { + req, out := c.PutTargetsRequest(input) + err := req.Send() + return out, err +} + +const opRemoveTargets = "RemoveTargets" + +// RemoveTargetsRequest generates a request for the RemoveTargets operation. +func (c *CloudWatchEvents) RemoveTargetsRequest(input *RemoveTargetsInput) (req *request.Request, output *RemoveTargetsOutput) { + op := &request.Operation{ + Name: opRemoveTargets, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RemoveTargetsInput{} + } + + req = c.newRequest(op, input, output) + output = &RemoveTargetsOutput{} + req.Data = output + return +} + +// Removes target(s) from a rule so that when the rule is triggered, those targets +// will no longer be invoked. +// +// Note: When you make a change with this action, when the associated rule +// triggers, removed targets might still continue to be invoked. Please allow +// a short period of time for changes to take effect. +func (c *CloudWatchEvents) RemoveTargets(input *RemoveTargetsInput) (*RemoveTargetsOutput, error) { + req, out := c.RemoveTargetsRequest(input) + err := req.Send() + return out, err +} + +const opTestEventPattern = "TestEventPattern" + +// TestEventPatternRequest generates a request for the TestEventPattern operation. +func (c *CloudWatchEvents) TestEventPatternRequest(input *TestEventPatternInput) (req *request.Request, output *TestEventPatternOutput) { + op := &request.Operation{ + Name: opTestEventPattern, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &TestEventPatternInput{} + } + + req = c.newRequest(op, input, output) + output = &TestEventPatternOutput{} + req.Data = output + return +} + +// Tests whether an event pattern matches the provided event. +// +// Note: Most services in AWS treat : or / as the same character in Amazon +// Resource Names (ARNs). However, CloudWatch Events uses an exact match in +// event patterns and rules. Be sure to use the correct ARN characters when +// creating event patterns so that they match the ARN syntax in the event you +// want to match. +func (c *CloudWatchEvents) TestEventPattern(input *TestEventPatternInput) (*TestEventPatternOutput, error) { + req, out := c.TestEventPatternRequest(input) + err := req.Send() + return out, err +} + +// Container for the parameters to the DeleteRule operation. +type DeleteRuleInput struct { + _ struct{} `type:"structure"` + + // The name of the rule to be deleted. + Name *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteRuleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRuleInput) GoString() string { + return s.String() +} + +type DeleteRuleOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteRuleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRuleOutput) GoString() string { + return s.String() +} + +// Container for the parameters to the DescribeRule operation. +type DescribeRuleInput struct { + _ struct{} `type:"structure"` + + // The name of the rule you want to describe details for. + Name *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeRuleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRuleInput) GoString() string { + return s.String() +} + +// The result of the DescribeRule operation. +type DescribeRuleOutput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) associated with the rule. + Arn *string `min:"1" type:"string"` + + // The rule's description. + Description *string `type:"string"` + + // The event pattern. + EventPattern *string `type:"string"` + + // The rule's name. + Name *string `min:"1" type:"string"` + + // The Amazon Resource Name (ARN) of the IAM role associated with the rule. + RoleArn *string `min:"1" type:"string"` + + // The scheduling expression. For example, "cron(0 20 * * ? *)", "rate(5 minutes)". + ScheduleExpression *string `type:"string"` + + // Specifies whether the rule is enabled or disabled. + State *string `type:"string" enum:"RuleState"` +} + +// String returns the string representation +func (s DescribeRuleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRuleOutput) GoString() string { + return s.String() +} + +// Container for the parameters to the DisableRule operation. +type DisableRuleInput struct { + _ struct{} `type:"structure"` + + // The name of the rule you want to disable. + Name *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s DisableRuleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableRuleInput) GoString() string { + return s.String() +} + +type DisableRuleOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DisableRuleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableRuleOutput) GoString() string { + return s.String() +} + +// Container for the parameters to the EnableRule operation. +type EnableRuleInput struct { + _ struct{} `type:"structure"` + + // The name of the rule that you want to enable. + Name *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s EnableRuleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableRuleInput) GoString() string { + return s.String() +} + +type EnableRuleOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s EnableRuleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableRuleOutput) GoString() string { + return s.String() +} + +// Container for the parameters to the ListRuleNamesByTarget operation. +type ListRuleNamesByTargetInput struct { + _ struct{} `type:"structure"` + + // The maximum number of results to return. + Limit *int64 `min:"1" type:"integer"` + + // The token returned by a previous call to indicate that there is more data + // available. + NextToken *string `min:"1" type:"string"` + + // The Amazon Resource Name (ARN) of the target resource that you want to list + // the rules for. + TargetArn *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s ListRuleNamesByTargetInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListRuleNamesByTargetInput) GoString() string { + return s.String() +} + +// The result of the ListRuleNamesByTarget operation. +type ListRuleNamesByTargetOutput struct { + _ struct{} `type:"structure"` + + // Indicates that there are additional results to retrieve. + NextToken *string `min:"1" type:"string"` + + // List of rules names that can invoke the given target. + RuleNames []*string `type:"list"` +} + +// String returns the string representation +func (s ListRuleNamesByTargetOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListRuleNamesByTargetOutput) GoString() string { + return s.String() +} + +// Container for the parameters to the ListRules operation. +type ListRulesInput struct { + _ struct{} `type:"structure"` + + // The maximum number of results to return. + Limit *int64 `min:"1" type:"integer"` + + // The prefix matching the rule name. + NamePrefix *string `min:"1" type:"string"` + + // The token returned by a previous call to indicate that there is more data + // available. + NextToken *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s ListRulesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListRulesInput) GoString() string { + return s.String() +} + +// The result of the ListRules operation. +type ListRulesOutput struct { + _ struct{} `type:"structure"` + + // Indicates that there are additional results to retrieve. + NextToken *string `min:"1" type:"string"` + + // List of rules matching the specified criteria. + Rules []*Rule `type:"list"` +} + +// String returns the string representation +func (s ListRulesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListRulesOutput) GoString() string { + return s.String() +} + +// Container for the parameters to the ListTargetsByRule operation. +type ListTargetsByRuleInput struct { + _ struct{} `type:"structure"` + + // The maximum number of results to return. + Limit *int64 `min:"1" type:"integer"` + + // The token returned by a previous call to indicate that there is more data + // available. + NextToken *string `min:"1" type:"string"` + + // The name of the rule whose targets you want to list. + Rule *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s ListTargetsByRuleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTargetsByRuleInput) GoString() string { + return s.String() +} + +// The result of the ListTargetsByRule operation. +type ListTargetsByRuleOutput struct { + _ struct{} `type:"structure"` + + // Indicates that there are additional results to retrieve. + NextToken *string `min:"1" type:"string"` + + // Lists the targets assigned to the rule. + Targets []*Target `type:"list"` +} + +// String returns the string representation +func (s ListTargetsByRuleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTargetsByRuleOutput) GoString() string { + return s.String() +} + +// Container for the parameters to the PutEvents operation. +type PutEventsInput struct { + _ struct{} `type:"structure"` + + // The entry that defines an event in your system. You can specify several parameters + // for the entry such as the source and type of the event, resources associated + // with the event, and so on. + Entries []*PutEventsRequestEntry `min:"1" type:"list" required:"true"` +} + +// String returns the string representation +func (s PutEventsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutEventsInput) GoString() string { + return s.String() +} + +// The result of the PutEvents operation. +type PutEventsOutput struct { + _ struct{} `type:"structure"` + + // A list of successfully and unsuccessfully ingested events results. If the + // ingestion was successful, the entry will have the event ID in it. If not, + // then the ErrorCode and ErrorMessage can be used to identify the problem with + // the entry. + Entries []*PutEventsResultEntry `type:"list"` + + // The number of failed entries. + FailedEntryCount *int64 `type:"integer"` +} + +// String returns the string representation +func (s PutEventsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutEventsOutput) GoString() string { + return s.String() +} + +// Contains information about the event to be used in the PutEvents action. +type PutEventsRequestEntry struct { + _ struct{} `type:"structure"` + + // In the JSON sense, an object containing fields, which may also contain nested + // sub-objects. No constraints are imposed on its contents. + Detail *string `type:"string"` + + // Free-form string used to decide what fields to expect in the event detail. + DetailType *string `type:"string"` + + // AWS resources, identified by Amazon Resource Name (ARN), which the event + // primarily concerns. Any number, including zero, may be present. + Resources []*string `type:"list"` + + // The source of the event. + Source *string `type:"string"` + + // Timestamp of event, per RFC3339 (https://www.rfc-editor.org/rfc/rfc3339.txt). + // If no timestamp is provided, the timestamp of the PutEvents call will be + // used. + Time *time.Time `type:"timestamp" timestampFormat:"unix"` +} + +// String returns the string representation +func (s PutEventsRequestEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutEventsRequestEntry) GoString() string { + return s.String() +} + +// A PutEventsResult contains a list of PutEventsResultEntry. +type PutEventsResultEntry struct { + _ struct{} `type:"structure"` + + // The error code representing why the event submission failed on this entry. + ErrorCode *string `type:"string"` + + // The error message explaining why the event submission failed on this entry. + ErrorMessage *string `type:"string"` + + // The ID of the event submitted to Amazon CloudWatch Events. + EventId *string `type:"string"` +} + +// String returns the string representation +func (s PutEventsResultEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutEventsResultEntry) GoString() string { + return s.String() +} + +// Container for the parameters to the PutRule operation. +type PutRuleInput struct { + _ struct{} `type:"structure"` + + // A description of the rule. + Description *string `type:"string"` + + // The event pattern. + EventPattern *string `type:"string"` + + // The name of the rule that you are creating or updating. + Name *string `min:"1" type:"string" required:"true"` + + // The Amazon Resource Name (ARN) of the IAM role associated with the rule. + RoleArn *string `min:"1" type:"string"` + + // The scheduling expression. For example, "cron(0 20 * * ? *)", "rate(5 minutes)". + ScheduleExpression *string `type:"string"` + + // Indicates whether the rule is enabled or disabled. + State *string `type:"string" enum:"RuleState"` +} + +// String returns the string representation +func (s PutRuleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutRuleInput) GoString() string { + return s.String() +} + +// The result of the PutRule operation. +type PutRuleOutput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) that identifies the rule. + RuleArn *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s PutRuleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutRuleOutput) GoString() string { + return s.String() +} + +// Container for the parameters to the PutTargets operation. +type PutTargetsInput struct { + _ struct{} `type:"structure"` + + // The name of the rule you want to add targets to. + Rule *string `min:"1" type:"string" required:"true"` + + // List of targets you want to update or add to the rule. + Targets []*Target `type:"list" required:"true"` +} + +// String returns the string representation +func (s PutTargetsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutTargetsInput) GoString() string { + return s.String() +} + +// The result of the PutTargets operation. +type PutTargetsOutput struct { + _ struct{} `type:"structure"` + + // An array of failed target entries. + FailedEntries []*PutTargetsResultEntry `type:"list"` + + // The number of failed entries. + FailedEntryCount *int64 `type:"integer"` +} + +// String returns the string representation +func (s PutTargetsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutTargetsOutput) GoString() string { + return s.String() +} + +// A PutTargetsResult contains a list of PutTargetsResultEntry. +type PutTargetsResultEntry struct { + _ struct{} `type:"structure"` + + // The error code representing why the target submission failed on this entry. + ErrorCode *string `type:"string"` + + // The error message explaining why the target submission failed on this entry. + ErrorMessage *string `type:"string"` + + // The ID of the target submitted to Amazon CloudWatch Events. + TargetId *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s PutTargetsResultEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutTargetsResultEntry) GoString() string { + return s.String() +} + +// Container for the parameters to the RemoveTargets operation. +type RemoveTargetsInput struct { + _ struct{} `type:"structure"` + + // The list of target IDs to remove from the rule. + Ids []*string `min:"1" type:"list" required:"true"` + + // The name of the rule you want to remove targets from. + Rule *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s RemoveTargetsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RemoveTargetsInput) GoString() string { + return s.String() +} + +// The result of the RemoveTargets operation. +type RemoveTargetsOutput struct { + _ struct{} `type:"structure"` + + // An array of failed target entries. + FailedEntries []*RemoveTargetsResultEntry `type:"list"` + + // The number of failed entries. + FailedEntryCount *int64 `type:"integer"` +} + +// String returns the string representation +func (s RemoveTargetsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RemoveTargetsOutput) GoString() string { + return s.String() +} + +// The ID of the target requested to be removed from the rule by Amazon CloudWatch +// Events. +type RemoveTargetsResultEntry struct { + _ struct{} `type:"structure"` + + // The error code representing why the target removal failed on this entry. + ErrorCode *string `type:"string"` + + // The error message explaining why the target removal failed on this entry. + ErrorMessage *string `type:"string"` + + // The ID of the target requested to be removed by Amazon CloudWatch Events. + TargetId *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s RemoveTargetsResultEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RemoveTargetsResultEntry) GoString() string { + return s.String() +} + +// Contains information about a rule in Amazon CloudWatch Events. A ListRulesResult +// contains a list of Rules. +type Rule struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the rule. + Arn *string `min:"1" type:"string"` + + // The description of the rule. + Description *string `type:"string"` + + // The event pattern of the rule. + EventPattern *string `type:"string"` + + // The rule's name. + Name *string `min:"1" type:"string"` + + // The Amazon Resource Name (ARN) associated with the role that is used for + // target invocation. + RoleArn *string `min:"1" type:"string"` + + // The scheduling expression. For example, "cron(0 20 * * ? *)", "rate(5 minutes)". + ScheduleExpression *string `type:"string"` + + // The rule's state. + State *string `type:"string" enum:"RuleState"` +} + +// String returns the string representation +func (s Rule) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Rule) GoString() string { + return s.String() +} + +// Targets are the resources that can be invoked when a rule is triggered. For +// example, AWS Lambda functions, Amazon Kinesis streams, and built-in targets. +// +// Input and InputPath are mutually-exclusive and optional parameters of a +// target. When a rule is triggered due to a matched event, if for a target: +// +// Neither Input nor InputPath is specified, then the entire event is passed +// to the target in JSON form. InputPath is specified in the form of JSONPath +// (e.g. $.detail), then only the part of the event specified in the path is +// passed to the target (e.g. only the detail part of the event is passed). +// Input is specified in the form of a valid JSON, then the matched event +// is overridden with this constant. +type Target struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) associated of the target. + Arn *string `min:"1" type:"string" required:"true"` + + // The unique target assignment ID. + Id *string `min:"1" type:"string" required:"true"` + + // Valid JSON text passed to the target. For more information about JSON text, + // see The JavaScript Object Notation (JSON) Data Interchange Format (http://www.rfc-editor.org/rfc/rfc7159.txt). + Input *string `type:"string"` + + // The value of the JSONPath that is used for extracting part of the matched + // event when passing it to the target. For more information about JSON paths, + // see JSONPath (http://goessner.net/articles/JsonPath/). + InputPath *string `type:"string"` +} + +// String returns the string representation +func (s Target) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Target) GoString() string { + return s.String() +} + +// Container for the parameters to the TestEventPattern operation. +type TestEventPatternInput struct { + _ struct{} `type:"structure"` + + // The event in the JSON format to test against the event pattern. + Event *string `type:"string" required:"true"` + + // The event pattern you want to test. + EventPattern *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s TestEventPatternInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TestEventPatternInput) GoString() string { + return s.String() +} + +// The result of the TestEventPattern operation. +type TestEventPatternOutput struct { + _ struct{} `type:"structure"` + + // Indicates whether the event matches the event pattern. + Result *bool `type:"boolean"` +} + +// String returns the string representation +func (s TestEventPatternOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TestEventPatternOutput) GoString() string { + return s.String() +} + +const ( + // @enum RuleState + RuleStateEnabled = "ENABLED" + // @enum RuleState + RuleStateDisabled = "DISABLED" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/cloudwatcheventsiface/interface.go b/vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/cloudwatcheventsiface/interface.go new file mode 100644 index 0000000000..92d299f1e7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/cloudwatcheventsiface/interface.go @@ -0,0 +1,62 @@ +// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + +// Package cloudwatcheventsiface provides an interface for the Amazon CloudWatch Events. +package cloudwatcheventsiface + +import ( + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/service/cloudwatchevents" +) + +// CloudWatchEventsAPI is the interface type for cloudwatchevents.CloudWatchEvents. +type CloudWatchEventsAPI interface { + DeleteRuleRequest(*cloudwatchevents.DeleteRuleInput) (*request.Request, *cloudwatchevents.DeleteRuleOutput) + + DeleteRule(*cloudwatchevents.DeleteRuleInput) (*cloudwatchevents.DeleteRuleOutput, error) + + DescribeRuleRequest(*cloudwatchevents.DescribeRuleInput) (*request.Request, *cloudwatchevents.DescribeRuleOutput) + + DescribeRule(*cloudwatchevents.DescribeRuleInput) (*cloudwatchevents.DescribeRuleOutput, error) + + DisableRuleRequest(*cloudwatchevents.DisableRuleInput) (*request.Request, *cloudwatchevents.DisableRuleOutput) + + DisableRule(*cloudwatchevents.DisableRuleInput) (*cloudwatchevents.DisableRuleOutput, error) + + EnableRuleRequest(*cloudwatchevents.EnableRuleInput) (*request.Request, *cloudwatchevents.EnableRuleOutput) + + EnableRule(*cloudwatchevents.EnableRuleInput) (*cloudwatchevents.EnableRuleOutput, error) + + ListRuleNamesByTargetRequest(*cloudwatchevents.ListRuleNamesByTargetInput) (*request.Request, *cloudwatchevents.ListRuleNamesByTargetOutput) + + ListRuleNamesByTarget(*cloudwatchevents.ListRuleNamesByTargetInput) (*cloudwatchevents.ListRuleNamesByTargetOutput, error) + + ListRulesRequest(*cloudwatchevents.ListRulesInput) (*request.Request, *cloudwatchevents.ListRulesOutput) + + ListRules(*cloudwatchevents.ListRulesInput) (*cloudwatchevents.ListRulesOutput, error) + + ListTargetsByRuleRequest(*cloudwatchevents.ListTargetsByRuleInput) (*request.Request, *cloudwatchevents.ListTargetsByRuleOutput) + + ListTargetsByRule(*cloudwatchevents.ListTargetsByRuleInput) (*cloudwatchevents.ListTargetsByRuleOutput, error) + + PutEventsRequest(*cloudwatchevents.PutEventsInput) (*request.Request, *cloudwatchevents.PutEventsOutput) + + PutEvents(*cloudwatchevents.PutEventsInput) (*cloudwatchevents.PutEventsOutput, error) + + PutRuleRequest(*cloudwatchevents.PutRuleInput) (*request.Request, *cloudwatchevents.PutRuleOutput) + + PutRule(*cloudwatchevents.PutRuleInput) (*cloudwatchevents.PutRuleOutput, error) + + PutTargetsRequest(*cloudwatchevents.PutTargetsInput) (*request.Request, *cloudwatchevents.PutTargetsOutput) + + PutTargets(*cloudwatchevents.PutTargetsInput) (*cloudwatchevents.PutTargetsOutput, error) + + RemoveTargetsRequest(*cloudwatchevents.RemoveTargetsInput) (*request.Request, *cloudwatchevents.RemoveTargetsOutput) + + RemoveTargets(*cloudwatchevents.RemoveTargetsInput) (*cloudwatchevents.RemoveTargetsOutput, error) + + TestEventPatternRequest(*cloudwatchevents.TestEventPatternInput) (*request.Request, *cloudwatchevents.TestEventPatternOutput) + + TestEventPattern(*cloudwatchevents.TestEventPatternInput) (*cloudwatchevents.TestEventPatternOutput, error) +} + +var _ CloudWatchEventsAPI = (*cloudwatchevents.CloudWatchEvents)(nil) diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/service.go b/vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/service.go new file mode 100644 index 0000000000..1534387289 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudwatchevents/service.go @@ -0,0 +1,101 @@ +// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + +package cloudwatchevents + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/jsonrpc" + "github.com/aws/aws-sdk-go/private/signer/v4" +) + +// Amazon CloudWatch Events helps you to respond to state changes in your AWS +// resources. When your resources change state they automatically send events +// into an event stream. You can create rules that match selected events in +// the stream and route them to targets to take action. You can also use rules +// to take action on a pre-determined schedule. For example, you can configure +// rules to: +// +// Automatically invoke an AWS Lambda function to update DNS entries when +// an event notifies you that Amazon EC2 instance enters the running state. +// Direct specific API records from CloudTrail to an Amazon Kinesis stream for +// detailed analysis of potential security or availability risks. Periodically +// invoke a built-in target to create a snapshot of an Amazon EBS volume. +// For more information about Amazon CloudWatch Events features, see the Amazon +// CloudWatch Developer Guide (http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide). +//The service client's operations are safe to be used concurrently. +// It is not safe to mutate any of the client's properties though. +type CloudWatchEvents struct { + *client.Client +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// A ServiceName is the name of the service the client will make API calls to. +const ServiceName = "events" + +// New creates a new instance of the CloudWatchEvents client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// // Create a CloudWatchEvents client from just a session. +// svc := cloudwatchevents.New(mySession) +// +// // Create a CloudWatchEvents client with additional configuration +// svc := cloudwatchevents.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *CloudWatchEvents { + c := p.ClientConfig(ServiceName, cfgs...) + return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *CloudWatchEvents { + svc := &CloudWatchEvents{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + SigningRegion: signingRegion, + Endpoint: endpoint, + APIVersion: "2014-02-03", + JSONVersion: "1.1", + TargetPrefix: "AWSEvents", + }, + handlers, + ), + } + + // Handlers + svc.Handlers.Sign.PushBack(v4.Sign) + svc.Handlers.Build.PushBack(jsonrpc.Build) + svc.Handlers.Unmarshal.PushBack(jsonrpc.Unmarshal) + svc.Handlers.UnmarshalMeta.PushBack(jsonrpc.UnmarshalMeta) + svc.Handlers.UnmarshalError.PushBack(jsonrpc.UnmarshalError) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a CloudWatchEvents operation and runs any +// custom request initialization. +func (c *CloudWatchEvents) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +} From ab89e5e528e06797221680e37fb8e7321212e064 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Fri, 29 Jan 2016 19:13:52 +0000 Subject: [PATCH 2/7] provider/aws: Add CloudWatch Event Rule --- builtin/providers/aws/config.go | 63 +++-- builtin/providers/aws/provider.go | 1 + .../aws/resource_aws_cloudwatch_event_rule.go | 252 ++++++++++++++++++ builtin/providers/aws/validators.go | 31 +++ builtin/providers/aws/validators_test.go | 27 ++ 5 files changed, 345 insertions(+), 29 deletions(-) create mode 100644 builtin/providers/aws/resource_aws_cloudwatch_event_rule.go diff --git a/builtin/providers/aws/config.go b/builtin/providers/aws/config.go index 5178b41191..33645b6a1d 100644 --- a/builtin/providers/aws/config.go +++ b/builtin/providers/aws/config.go @@ -23,6 +23,7 @@ import ( "github.com/aws/aws-sdk-go/service/cloudformation" "github.com/aws/aws-sdk-go/service/cloudtrail" "github.com/aws/aws-sdk-go/service/cloudwatch" + "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/aws/aws-sdk-go/service/cloudwatchlogs" "github.com/aws/aws-sdk-go/service/codecommit" "github.com/aws/aws-sdk-go/service/codedeploy" @@ -70,35 +71,36 @@ type Config struct { } type AWSClient struct { - cfconn *cloudformation.CloudFormation - cloudtrailconn *cloudtrail.CloudTrail - cloudwatchconn *cloudwatch.CloudWatch - cloudwatchlogsconn *cloudwatchlogs.CloudWatchLogs - dsconn *directoryservice.DirectoryService - dynamodbconn *dynamodb.DynamoDB - ec2conn *ec2.EC2 - ecrconn *ecr.ECR - ecsconn *ecs.ECS - efsconn *efs.EFS - elbconn *elb.ELB - esconn *elasticsearch.ElasticsearchService - autoscalingconn *autoscaling.AutoScaling - s3conn *s3.S3 - sqsconn *sqs.SQS - snsconn *sns.SNS - redshiftconn *redshift.Redshift - r53conn *route53.Route53 - region string - rdsconn *rds.RDS - iamconn *iam.IAM - kinesisconn *kinesis.Kinesis - firehoseconn *firehose.Firehose - elasticacheconn *elasticache.ElastiCache - lambdaconn *lambda.Lambda - opsworksconn *opsworks.OpsWorks - glacierconn *glacier.Glacier - codedeployconn *codedeploy.CodeDeploy - codecommitconn *codecommit.CodeCommit + cfconn *cloudformation.CloudFormation + cloudtrailconn *cloudtrail.CloudTrail + cloudwatchconn *cloudwatch.CloudWatch + cloudwatchlogsconn *cloudwatchlogs.CloudWatchLogs + cloudwatcheventsconn *cloudwatchevents.CloudWatchEvents + dsconn *directoryservice.DirectoryService + dynamodbconn *dynamodb.DynamoDB + ec2conn *ec2.EC2 + ecrconn *ecr.ECR + ecsconn *ecs.ECS + efsconn *efs.EFS + elbconn *elb.ELB + esconn *elasticsearch.ElasticsearchService + autoscalingconn *autoscaling.AutoScaling + s3conn *s3.S3 + sqsconn *sqs.SQS + snsconn *sns.SNS + redshiftconn *redshift.Redshift + r53conn *route53.Route53 + region string + rdsconn *rds.RDS + iamconn *iam.IAM + kinesisconn *kinesis.Kinesis + firehoseconn *firehose.Firehose + elasticacheconn *elasticache.ElastiCache + lambdaconn *lambda.Lambda + opsworksconn *opsworks.OpsWorks + glacierconn *glacier.Glacier + codedeployconn *codedeploy.CodeDeploy + codecommitconn *codecommit.CodeCommit } // Client configures and returns a fully initialized AWSClient @@ -256,6 +258,9 @@ func (c *Config) Client() (interface{}, error) { log.Println("[INFO] Initializing CloudWatch SDK connection") client.cloudwatchconn = cloudwatch.New(sess) + log.Println("[INFO] Initializing CloudWatch Events connection") + client.cloudwatcheventsconn = cloudwatchevents.New(sess) + log.Println("[INFO] Initializing CloudTrail connection") client.cloudtrailconn = cloudtrail.New(sess) diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index ffa5a4d7c9..ff737bfb66 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -121,6 +121,7 @@ func Provider() terraform.ResourceProvider { "aws_autoscaling_schedule": resourceAwsAutoscalingSchedule(), "aws_cloudformation_stack": resourceAwsCloudFormationStack(), "aws_cloudtrail": resourceAwsCloudTrail(), + "aws_cloudwatch_event_rule": resourceAwsCloudWatchEventRule(), "aws_cloudwatch_log_group": resourceAwsCloudWatchLogGroup(), "aws_autoscaling_lifecycle_hook": resourceAwsAutoscalingLifecycleHook(), "aws_cloudwatch_metric_alarm": resourceAwsCloudWatchMetricAlarm(), diff --git a/builtin/providers/aws/resource_aws_cloudwatch_event_rule.go b/builtin/providers/aws/resource_aws_cloudwatch_event_rule.go new file mode 100644 index 0000000000..652636b683 --- /dev/null +++ b/builtin/providers/aws/resource_aws_cloudwatch_event_rule.go @@ -0,0 +1,252 @@ +package aws + +import ( + "fmt" + "log" + "regexp" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + + "github.com/aws/aws-sdk-go/aws" + events "github.com/aws/aws-sdk-go/service/cloudwatchevents" +) + +func resourceAwsCloudWatchEventRule() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsCloudWatchEventRuleCreate, + Read: resourceAwsCloudWatchEventRuleRead, + Update: resourceAwsCloudWatchEventRuleUpdate, + Delete: resourceAwsCloudWatchEventRuleDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateCloudWatchEventRuleName, + }, + "schedule_expression": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateMaxLength(256), + }, + "event_pattern": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateMaxLength(2048), + StateFunc: normalizeJson, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateMaxLength(512), + }, + "role_arn": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateMaxLength(1600), + }, + "is_enabled": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "arn": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceAwsCloudWatchEventRuleCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudwatcheventsconn + + input := buildPutRuleInputStruct(d) + log.Printf("[DEBUG] Creating CloudWatch Event Rule: %s", input) + + // IAM Roles take some time to propagate + var out *events.PutRuleOutput + err := resource.Retry(30*time.Second, func() error { + var err error + out, err = conn.PutRule(input) + pattern := regexp.MustCompile("cannot be assumed by principal '[a-z]+\\.amazonaws\\.com'\\.$") + if err != nil { + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "ValidationException" && pattern.MatchString(awsErr.Message()) { + log.Printf("[DEBUG] Retrying creation of CloudWatch Event Rule %q", *input.Name) + return err + } + } + return &resource.RetryError{ + Err: err, + } + } + return nil + }) + if err != nil { + return fmt.Errorf("Creating CloudWatch Event Rule failed: %s", err) + } + + d.Set("arn", out.RuleArn) + d.SetId(d.Get("name").(string)) + + log.Printf("[INFO] CloudWatch Event Rule %q created", *out.RuleArn) + + return resourceAwsCloudWatchEventRuleUpdate(d, meta) +} + +func resourceAwsCloudWatchEventRuleRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudwatcheventsconn + + input := events.DescribeRuleInput{ + Name: aws.String(d.Id()), + } + log.Printf("[DEBUG] Reading CloudWatch Event Rule: %s", input) + out, err := conn.DescribeRule(&input) + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "ResourceNotFoundException" { + log.Printf("[WARN] Removing CloudWatch Event Rule %q because it's gone.", d.Id()) + d.SetId("") + return nil + } + } + if err != nil { + return err + } + log.Printf("[DEBUG] Found Event Rule: %s", out) + + d.Set("arn", out.Arn) + d.Set("description", out.Description) + if out.EventPattern != nil { + d.Set("event_pattern", normalizeJson(*out.EventPattern)) + } + d.Set("name", out.Name) + d.Set("role_arn", out.RoleArn) + d.Set("schedule_expression", out.ScheduleExpression) + + boolState, err := getBooleanStateFromString(*out.State) + if err != nil { + return err + } + log.Printf("[DEBUG] Setting boolean state: %t", boolState) + d.Set("is_enabled", boolState) + + return nil +} + +func resourceAwsCloudWatchEventRuleUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudwatcheventsconn + + if d.HasChange("is_enabled") && d.Get("is_enabled").(bool) { + log.Printf("[DEBUG] Enabling CloudWatch Event Rule %q", d.Id()) + _, err := conn.EnableRule(&events.EnableRuleInput{ + Name: aws.String(d.Id()), + }) + if err != nil { + return err + } + log.Printf("[DEBUG] CloudWatch Event Rule (%q) enabled", d.Id()) + } + + input := buildPutRuleInputStruct(d) + log.Printf("[DEBUG] Updating CloudWatch Event Rule: %s", input) + + // IAM Roles take some time to propagate + var out *events.PutRuleOutput + err := resource.Retry(30*time.Second, func() error { + var err error + out, err = conn.PutRule(input) + pattern := regexp.MustCompile("cannot be assumed by principal '[a-z]+\\.amazonaws\\.com'\\.$") + if err != nil { + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "ValidationException" && pattern.MatchString(awsErr.Message()) { + log.Printf("[DEBUG] Retrying update of CloudWatch Event Rule %q", *input.Name) + return err + } + } + return &resource.RetryError{ + Err: err, + } + } + return nil + }) + if err != nil { + return fmt.Errorf("Updating CloudWatch Event Rule failed: %s", err) + } + + if d.HasChange("is_enabled") && !d.Get("is_enabled").(bool) { + log.Printf("[DEBUG] Disabling CloudWatch Event Rule %q", d.Id()) + _, err := conn.DisableRule(&events.DisableRuleInput{ + Name: aws.String(d.Id()), + }) + if err != nil { + return err + } + log.Printf("[DEBUG] CloudWatch Event Rule (%q) disabled", d.Id()) + } + + return resourceAwsCloudWatchEventRuleRead(d, meta) +} + +func resourceAwsCloudWatchEventRuleDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudwatcheventsconn + + log.Printf("[INFO] Deleting CloudWatch Event Rule: %s", d.Id()) + _, err := conn.DeleteRule(&events.DeleteRuleInput{ + Name: aws.String(d.Id()), + }) + if err != nil { + return fmt.Errorf("Error deleting CloudWatch Event Rule: %s", err) + } + log.Println("[INFO] CloudWatch Event Rule deleted") + + d.SetId("") + + return nil +} + +func buildPutRuleInputStruct(d *schema.ResourceData) *events.PutRuleInput { + input := events.PutRuleInput{ + Name: aws.String(d.Get("name").(string)), + } + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) + } + if v, ok := d.GetOk("event_pattern"); ok { + input.EventPattern = aws.String(v.(string)) + } + if v, ok := d.GetOk("role_arn"); ok { + input.RoleArn = aws.String(v.(string)) + } + if v, ok := d.GetOk("schedule_expression"); ok { + input.ScheduleExpression = aws.String(v.(string)) + } + + input.State = aws.String(getStringStateFromBoolean(d.Get("is_enabled").(bool))) + + return &input +} + +// State is represented as (ENABLED|DISABLED) in the API +func getBooleanStateFromString(state string) (bool, error) { + if state == "ENABLED" { + return true, nil + } else if state == "DISABLED" { + return false, nil + } + // We don't just blindly trust AWS as they tend to return + // unexpected values in similar cases (different casing etc.) + return false, fmt.Errorf("Failed converting state %q into boolean", state) +} + +// State is represented as (ENABLED|DISABLED) in the API +func getStringStateFromBoolean(isEnabled bool) string { + if isEnabled { + return "ENABLED" + } + return "DISABLED" +} diff --git a/builtin/providers/aws/validators.go b/builtin/providers/aws/validators.go index ede6b36dd7..84c5c5403c 100644 --- a/builtin/providers/aws/validators.go +++ b/builtin/providers/aws/validators.go @@ -4,6 +4,8 @@ import ( "fmt" "regexp" "time" + + "github.com/hashicorp/terraform/helper/schema" ) func validateRdsId(v interface{}, k string) (ws []string, errors []error) { @@ -134,3 +136,32 @@ func validateEcrRepositoryName(v interface{}, k string) (ws []string, errors []e return } + +func validateCloudWatchEventRuleName(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_PutRule.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 +} + +func validateMaxLength(length int) schema.SchemaValidateFunc { + return func(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + if len(value) > length { + errors = append(errors, fmt.Errorf( + "%q cannot be longer than %d characters: %q", k, length, value)) + } + return + } +} diff --git a/builtin/providers/aws/validators_test.go b/builtin/providers/aws/validators_test.go index 0b2ee011ea..f801bfcb20 100644 --- a/builtin/providers/aws/validators_test.go +++ b/builtin/providers/aws/validators_test.go @@ -43,3 +43,30 @@ func TestValidateEcrRepositoryName(t *testing.T) { } } } + +func TestValidateCloudWatchEventRuleName(t *testing.T) { + validNames := []string{ + "HelloWorl_d", + "hello-world", + "hello.World0125", + } + for _, v := range validNames { + _, errors := validateCloudWatchEventRuleName(v, "name") + if len(errors) != 0 { + t.Fatalf("%q should be a valid CW event rule name: %q", v, errors) + } + } + + invalidNames := []string{ + "special@character", + "slash/in-the-middle", + // Length > 64 + "TooLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName", + } + for _, v := range invalidNames { + _, errors := validateCloudWatchEventRuleName(v, "name") + if len(errors) == 0 { + t.Fatalf("%q should be an invalid CW event rule name", v) + } + } +} From b5039dd897b360aa433e28e9ed2b28eb9d476bf5 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Fri, 29 Jan 2016 20:50:31 +0100 Subject: [PATCH 3/7] provider/aws: Add acc tests for CloudWatch Event Rule --- ...resource_aws_cloudwatch_event_rule_test.go | 208 ++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 builtin/providers/aws/resource_aws_cloudwatch_event_rule_test.go diff --git a/builtin/providers/aws/resource_aws_cloudwatch_event_rule_test.go b/builtin/providers/aws/resource_aws_cloudwatch_event_rule_test.go new file mode 100644 index 0000000000..5bedff782b --- /dev/null +++ b/builtin/providers/aws/resource_aws_cloudwatch_event_rule_test.go @@ -0,0 +1,208 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + events "github.com/aws/aws-sdk-go/service/cloudwatchevents" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSCloudWatchEventRule_basic(t *testing.T) { + var rule events.DescribeRuleOutput + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSCloudWatchEventRuleConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventRuleExists("aws_cloudwatch_event_rule.foo", &rule), + resource.TestCheckResourceAttr("aws_cloudwatch_event_rule.foo", "name", "tf-acc-cw-event-rule"), + ), + }, + resource.TestStep{ + Config: testAccAWSCloudWatchEventRuleConfigModified, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventRuleExists("aws_cloudwatch_event_rule.foo", &rule), + resource.TestCheckResourceAttr("aws_cloudwatch_event_rule.foo", "name", "tf-acc-cw-event-rule-mod"), + ), + }, + }, + }) +} + +func TestAccAWSCloudWatchEventRule_full(t *testing.T) { + var rule events.DescribeRuleOutput + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSCloudWatchEventRuleConfig_full, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventRuleExists("aws_cloudwatch_event_rule.moobar", &rule), + resource.TestCheckResourceAttr("aws_cloudwatch_event_rule.moobar", "name", "tf-acc-cw-event-rule-full"), + resource.TestCheckResourceAttr("aws_cloudwatch_event_rule.moobar", "schedule_expression", "rate(5 minutes)"), + resource.TestCheckResourceAttr("aws_cloudwatch_event_rule.moobar", "event_pattern", "{\"source\":[\"aws.ec2\"]}"), + resource.TestCheckResourceAttr("aws_cloudwatch_event_rule.moobar", "description", "He's not dead, he's just resting!"), + resource.TestCheckResourceAttr("aws_cloudwatch_event_rule.moobar", "role_arn", ""), + testAccCheckCloudWatchEventRuleEnabled("aws_cloudwatch_event_rule.moobar", "DISABLED", &rule), + ), + }, + }, + }) +} + +func TestAccAWSCloudWatchEventRule_enable(t *testing.T) { + var rule events.DescribeRuleOutput + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSCloudWatchEventRuleConfigEnabled, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventRuleExists("aws_cloudwatch_event_rule.moo", &rule), + testAccCheckCloudWatchEventRuleEnabled("aws_cloudwatch_event_rule.moo", "ENABLED", &rule), + ), + }, + resource.TestStep{ + Config: testAccAWSCloudWatchEventRuleConfigDisabled, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventRuleExists("aws_cloudwatch_event_rule.moo", &rule), + testAccCheckCloudWatchEventRuleEnabled("aws_cloudwatch_event_rule.moo", "DISABLED", &rule), + ), + }, + resource.TestStep{ + Config: testAccAWSCloudWatchEventRuleConfigEnabled, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventRuleExists("aws_cloudwatch_event_rule.moo", &rule), + testAccCheckCloudWatchEventRuleEnabled("aws_cloudwatch_event_rule.moo", "ENABLED", &rule), + ), + }, + }, + }) +} + +func testAccCheckCloudWatchEventRuleExists(n string, rule *events.DescribeRuleOutput) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + conn := testAccProvider.Meta().(*AWSClient).cloudwatcheventsconn + params := events.DescribeRuleInput{ + Name: aws.String(rs.Primary.ID), + } + resp, err := conn.DescribeRule(¶ms) + if err != nil { + return err + } + if resp == nil { + return fmt.Errorf("Rule not found") + } + + *rule = *resp + + return nil + } +} + +func testAccCheckCloudWatchEventRuleEnabled(n string, desired string, rule *events.DescribeRuleOutput) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + conn := testAccProvider.Meta().(*AWSClient).cloudwatcheventsconn + params := events.DescribeRuleInput{ + Name: aws.String(rs.Primary.ID), + } + resp, err := conn.DescribeRule(¶ms) + + if err != nil { + return err + } + if *resp.State != desired { + return fmt.Errorf("Expected state %q, given %q", desired, *resp.State) + } + + return nil + } +} + +func testAccCheckAWSCloudWatchEventRuleDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).cloudwatcheventsconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_cloudwatch_event_rule" { + continue + } + + params := events.DescribeRuleInput{ + Name: aws.String(rs.Primary.ID), + } + + resp, err := conn.DescribeRule(¶ms) + + if err == nil { + return fmt.Errorf("CloudWatch Event Rule %q still exists: %s", + rs.Primary.ID, resp) + } + } + + return nil +} + +var testAccAWSCloudWatchEventRuleConfig = ` +resource "aws_cloudwatch_event_rule" "foo" { + name = "tf-acc-cw-event-rule" + schedule_expression = "rate(1 hour)" +} +` + +var testAccAWSCloudWatchEventRuleConfigEnabled = ` +resource "aws_cloudwatch_event_rule" "moo" { + name = "tf-acc-cw-event-rule-state" + schedule_expression = "rate(1 hour)" +} +` +var testAccAWSCloudWatchEventRuleConfigDisabled = ` +resource "aws_cloudwatch_event_rule" "moo" { + name = "tf-acc-cw-event-rule-state" + schedule_expression = "rate(1 hour)" + is_enabled = false +} +` + +var testAccAWSCloudWatchEventRuleConfigModified = ` +resource "aws_cloudwatch_event_rule" "foo" { + name = "tf-acc-cw-event-rule-mod" + schedule_expression = "rate(1 hour)" +} +` + +var testAccAWSCloudWatchEventRuleConfig_full = ` +resource "aws_cloudwatch_event_rule" "moobar" { + name = "tf-acc-cw-event-rule-full" + schedule_expression = "rate(5 minutes)" + event_pattern = < Date: Wed, 3 Feb 2016 17:55:59 +0000 Subject: [PATCH 4/7] provider/aws: Add CloudWatch Event Target --- builtin/providers/aws/provider.go | 1 + .../resource_aws_cloudwatch_event_target.go | 186 ++++++++++++++++++ builtin/providers/aws/validators.go | 18 ++ 3 files changed, 205 insertions(+) create mode 100644 builtin/providers/aws/resource_aws_cloudwatch_event_target.go diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index ff737bfb66..3b7bb79f6e 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -122,6 +122,7 @@ func Provider() terraform.ResourceProvider { "aws_cloudformation_stack": resourceAwsCloudFormationStack(), "aws_cloudtrail": resourceAwsCloudTrail(), "aws_cloudwatch_event_rule": resourceAwsCloudWatchEventRule(), + "aws_cloudwatch_event_target": resourceAwsCloudWatchEventTarget(), "aws_cloudwatch_log_group": resourceAwsCloudWatchLogGroup(), "aws_autoscaling_lifecycle_hook": resourceAwsAutoscalingLifecycleHook(), "aws_cloudwatch_metric_alarm": resourceAwsCloudWatchMetricAlarm(), diff --git a/builtin/providers/aws/resource_aws_cloudwatch_event_target.go b/builtin/providers/aws/resource_aws_cloudwatch_event_target.go new file mode 100644 index 0000000000..727a17192e --- /dev/null +++ b/builtin/providers/aws/resource_aws_cloudwatch_event_target.go @@ -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 +} diff --git a/builtin/providers/aws/validators.go b/builtin/providers/aws/validators.go index 84c5c5403c..faa07d82d1 100644 --- a/builtin/providers/aws/validators.go +++ b/builtin/providers/aws/validators.go @@ -165,3 +165,21 @@ func validateMaxLength(length int) schema.SchemaValidateFunc { 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 +} From 30082a4c854b4f1c292aba6c0e59f20d851e1f13 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Wed, 3 Feb 2016 17:56:20 +0000 Subject: [PATCH 5/7] provider/aws: Add acc tests for CloudWatch Event Target --- ...source_aws_cloudwatch_event_target_test.go | 203 ++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 builtin/providers/aws/resource_aws_cloudwatch_event_target_test.go diff --git a/builtin/providers/aws/resource_aws_cloudwatch_event_target_test.go b/builtin/providers/aws/resource_aws_cloudwatch_event_target_test.go new file mode 100644 index 0000000000..56fffdeab1 --- /dev/null +++ b/builtin/providers/aws/resource_aws_cloudwatch_event_target_test.go @@ -0,0 +1,203 @@ +package aws + +import ( + "fmt" + "regexp" + "testing" + + events "github.com/aws/aws-sdk-go/service/cloudwatchevents" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSCloudWatchEventTarget_basic(t *testing.T) { + var target events.Target + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCloudWatchEventTargetDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSCloudWatchEventTargetConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventTargetExists("aws_cloudwatch_event_target.moobar", &target), + resource.TestCheckResourceAttr("aws_cloudwatch_event_target.moobar", "rule", "tf-acc-cw-event-rule-basic"), + resource.TestCheckResourceAttr("aws_cloudwatch_event_target.moobar", "target_id", "tf-acc-cw-target-basic"), + resource.TestMatchResourceAttr("aws_cloudwatch_event_target.moobar", "arn", + regexp.MustCompile(":tf-acc-moon$")), + ), + }, + resource.TestStep{ + Config: testAccAWSCloudWatchEventTargetConfigModified, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventTargetExists("aws_cloudwatch_event_target.moobar", &target), + resource.TestCheckResourceAttr("aws_cloudwatch_event_target.moobar", "rule", "tf-acc-cw-event-rule-basic"), + resource.TestCheckResourceAttr("aws_cloudwatch_event_target.moobar", "target_id", "tf-acc-cw-target-modified"), + resource.TestMatchResourceAttr("aws_cloudwatch_event_target.moobar", "arn", + regexp.MustCompile(":tf-acc-sun$")), + ), + }, + }, + }) +} + +func TestAccAWSCloudWatchEventTarget_full(t *testing.T) { + var target events.Target + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCloudWatchEventTargetDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSCloudWatchEventTargetConfig_full, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventTargetExists("aws_cloudwatch_event_target.foobar", &target), + resource.TestCheckResourceAttr("aws_cloudwatch_event_target.foobar", "rule", "tf-acc-cw-event-rule-full"), + resource.TestCheckResourceAttr("aws_cloudwatch_event_target.foobar", "target_id", "tf-acc-cw-target-full"), + resource.TestMatchResourceAttr("aws_cloudwatch_event_target.foobar", "arn", + regexp.MustCompile("^arn:aws:kinesis:.*:stream/terraform-kinesis-test$")), + resource.TestCheckResourceAttr("aws_cloudwatch_event_target.foobar", "input", "{ \"source\": [\"aws.cloudtrail\"] }\n"), + resource.TestCheckResourceAttr("aws_cloudwatch_event_target.foobar", "input_path", ""), + ), + }, + }, + }) +} + +func testAccCheckCloudWatchEventTargetExists(n string, rule *events.Target) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + conn := testAccProvider.Meta().(*AWSClient).cloudwatcheventsconn + t, err := findEventTargetById(rs.Primary.Attributes["target_id"], + rs.Primary.Attributes["rule"], nil, conn) + if err != nil { + return fmt.Errorf("Event Target not found: %s", err) + } + + *rule = *t + + return nil + } +} + +func testAccCheckAWSCloudWatchEventTargetDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).cloudwatcheventsconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_cloudwatch_event_target" { + continue + } + + t, err := findEventTargetById(rs.Primary.Attributes["target_id"], + rs.Primary.Attributes["rule"], nil, conn) + if err == nil { + return fmt.Errorf("CloudWatch Event Target %q still exists: %s", + rs.Primary.ID, t) + } + } + + return nil +} + +var testAccAWSCloudWatchEventTargetConfig = ` +resource "aws_cloudwatch_event_rule" "foo" { + name = "tf-acc-cw-event-rule-basic" + schedule_expression = "rate(1 hour)" +} + +resource "aws_cloudwatch_event_target" "moobar" { + rule = "${aws_cloudwatch_event_rule.foo.name}" + target_id = "tf-acc-cw-target-basic" + arn = "${aws_sns_topic.moon.arn}" +} + +resource "aws_sns_topic" "moon" { + name = "tf-acc-moon" +} +` + +var testAccAWSCloudWatchEventTargetConfigModified = ` +resource "aws_cloudwatch_event_rule" "foo" { + name = "tf-acc-cw-event-rule-basic" + schedule_expression = "rate(1 hour)" +} + +resource "aws_cloudwatch_event_target" "moobar" { + rule = "${aws_cloudwatch_event_rule.foo.name}" + target_id = "tf-acc-cw-target-modified" + arn = "${aws_sns_topic.sun.arn}" +} + +resource "aws_sns_topic" "sun" { + name = "tf-acc-sun" +} +` + +var testAccAWSCloudWatchEventTargetConfig_full = ` +resource "aws_cloudwatch_event_rule" "foo" { + name = "tf-acc-cw-event-rule-full" + schedule_expression = "rate(1 hour)" + role_arn = "${aws_iam_role.role.arn}" +} + +resource "aws_iam_role" "role" { + name = "test_role" + assume_role_policy = < Date: Thu, 4 Feb 2016 23:19:30 +0000 Subject: [PATCH 6/7] provider/aws: Document CloudWatch Events --- .../aws/r/cloudwatch_event_rule.html.markdown | 57 +++++++++++++++++++ .../r/cloudwatch_event_target.html.markdown | 57 +++++++++++++++++++ website/source/layouts/aws.erb | 7 +++ 3 files changed, 121 insertions(+) create mode 100644 website/source/docs/providers/aws/r/cloudwatch_event_rule.html.markdown create mode 100644 website/source/docs/providers/aws/r/cloudwatch_event_target.html.markdown diff --git a/website/source/docs/providers/aws/r/cloudwatch_event_rule.html.markdown b/website/source/docs/providers/aws/r/cloudwatch_event_rule.html.markdown new file mode 100644 index 0000000000..f3ed87cb77 --- /dev/null +++ b/website/source/docs/providers/aws/r/cloudwatch_event_rule.html.markdown @@ -0,0 +1,57 @@ +--- +layout: "aws" +page_title: "AWS: aws_cloudwatch_event_rule" +sidebar_current: "docs-aws-resource-cloudwatch-event-rule" +description: |- + Provides a CloudWatch Event Rule resource. +--- + +# aws\_cloudwatch\_event\_rule + +Provides a CloudWatch Event Rule resource. + +## Example Usage + +``` +resource "aws_cloudwatch_event_rule" "console" { + name = "capture-aws-sign-in" + description = "Capture each AWS Console Sign In" + event_pattern = < **Note:** `input` and `input_path` are mutually exclusive options. + +The following arguments are supported: + +* `rule` - (Required) The name of the rule you want to add targets to. +* `target_id` - (Required) The unique target assignment ID. +* `arn` - (Required) The Amazon Resource Name (ARN) associated of the target. +* `input` - (Optional) Valid JSON text passed to the target. +* `input_path` - (Optional) The value of the [JSONPath](http://goessner.net/articles/JsonPath/) + that is used for extracting part of the matched event when passing it to the target. diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index 4f1319ddab..c9298f34a4 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -31,6 +31,13 @@ > CloudWatch Resources