-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8626 from hashicorp/aws-cloudwatch-log-stream
provider/aws: `aws_cloudwatch_log_stream` resource
- Loading branch information
Showing
5 changed files
with
327 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
133 changes: 133 additions & 0 deletions
133
builtin/providers/aws/resource_aws_cloudwatch_log_stream.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"regexp" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/cloudwatchlogs" | ||
"github.com/hashicorp/errwrap" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsCloudWatchLogStream() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsCloudWatchLogStreamCreate, | ||
Read: resourceAwsCloudWatchLogStreamRead, | ||
Delete: resourceAwsCloudWatchLogStreamDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"arn": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validateCloudWatchLogStreamName, | ||
}, | ||
|
||
"log_group_name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsCloudWatchLogStreamCreate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).cloudwatchlogsconn | ||
|
||
log.Printf("[DEBUG] Creating CloudWatch Log Stream: %s", d.Get("name").(string)) | ||
_, err := conn.CreateLogStream(&cloudwatchlogs.CreateLogStreamInput{ | ||
LogGroupName: aws.String(d.Get("log_group_name").(string)), | ||
LogStreamName: aws.String(d.Get("name").(string)), | ||
}) | ||
if err != nil { | ||
return errwrap.Wrapf("Creating CloudWatch Log Stream failed: %s", err) | ||
} | ||
|
||
d.SetId(d.Get("name").(string)) | ||
|
||
return resourceAwsCloudWatchLogStreamRead(d, meta) | ||
} | ||
|
||
func resourceAwsCloudWatchLogStreamRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).cloudwatchlogsconn | ||
|
||
ls, exists, err := lookupCloudWatchLogStream(conn, d.Id(), d.Get("log_group_name").(string), nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !exists { | ||
log.Printf("[DEBUG] CloudWatch Stream %q Not Found. Removing from state", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
d.Set("arn", ls.Arn) | ||
d.Set("name", ls.LogStreamName) | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsCloudWatchLogStreamDelete(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).cloudwatchlogsconn | ||
|
||
log.Printf("[INFO] Deleting CloudWatch Log Stream: %s", d.Id()) | ||
params := &cloudwatchlogs.DeleteLogStreamInput{ | ||
LogGroupName: aws.String(d.Get("log_group_name").(string)), | ||
LogStreamName: aws.String(d.Id()), | ||
} | ||
_, err := conn.DeleteLogStream(params) | ||
if err != nil { | ||
return errwrap.Wrapf("Error deleting CloudWatch Log Stream: %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func lookupCloudWatchLogStream(conn *cloudwatchlogs.CloudWatchLogs, | ||
name string, logStreamName string, nextToken *string) (*cloudwatchlogs.LogStream, bool, error) { | ||
input := &cloudwatchlogs.DescribeLogStreamsInput{ | ||
LogStreamNamePrefix: aws.String(name), | ||
LogGroupName: aws.String(logStreamName), | ||
NextToken: nextToken, | ||
} | ||
resp, err := conn.DescribeLogStreams(input) | ||
if err != nil { | ||
return nil, true, err | ||
} | ||
|
||
for _, ls := range resp.LogStreams { | ||
if *ls.LogStreamName == name { | ||
return ls, true, nil | ||
} | ||
} | ||
|
||
if resp.NextToken != nil { | ||
return lookupCloudWatchLogStream(conn, name, logStreamName, resp.NextToken) | ||
} | ||
|
||
return nil, false, nil | ||
} | ||
|
||
func validateCloudWatchLogStreamName(v interface{}, k string) (ws []string, errors []error) { | ||
value := v.(string) | ||
if regexp.MustCompile(`:`).MatchString(value) { | ||
errors = append(errors, fmt.Errorf( | ||
"colons not allowed in %q:", k)) | ||
} | ||
if len(value) < 1 || len(value) > 512 { | ||
errors = append(errors, fmt.Errorf( | ||
"%q must be between 1 and 512 characters: %q", k, value)) | ||
} | ||
|
||
return | ||
|
||
} |
152 changes: 152 additions & 0 deletions
152
builtin/providers/aws/resource_aws_cloudwatch_log_stream_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/cloudwatchlogs" | ||
"github.com/hashicorp/terraform/helper/acctest" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccAWSCloudWatchLogStream_basic(t *testing.T) { | ||
var ls cloudwatchlogs.LogStream | ||
rName := acctest.RandString(15) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSCloudWatchLogStreamDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSCloudWatchLogStreamConfig(rName), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCloudWatchLogStreamExists("aws_cloudwatch_log_stream.foobar", &ls), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSCloudWatchLogStream_disappears(t *testing.T) { | ||
var ls cloudwatchlogs.LogStream | ||
rName := acctest.RandString(15) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSCloudWatchLogStreamDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSCloudWatchLogStreamConfig(rName), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCloudWatchLogStreamExists("aws_cloudwatch_log_stream.foobar", &ls), | ||
testAccCheckCloudWatchLogStreamDisappears(&ls, rName), | ||
), | ||
ExpectNonEmptyPlan: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckCloudWatchLogStreamDisappears(ls *cloudwatchlogs.LogStream, lgn string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
conn := testAccProvider.Meta().(*AWSClient).cloudwatchlogsconn | ||
opts := &cloudwatchlogs.DeleteLogStreamInput{ | ||
LogGroupName: aws.String(lgn), | ||
LogStreamName: ls.LogStreamName, | ||
} | ||
if _, err := conn.DeleteLogStream(opts); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
} | ||
|
||
func testAccCheckCloudWatchLogStreamExists(n string, ls *cloudwatchlogs.LogStream) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[n] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", n) | ||
} | ||
|
||
logGroupName := rs.Primary.Attributes["log_group_name"] | ||
conn := testAccProvider.Meta().(*AWSClient).cloudwatchlogsconn | ||
logGroup, exists, err := lookupCloudWatchLogStream(conn, rs.Primary.ID, logGroupName, nil) | ||
if err != nil { | ||
return err | ||
} | ||
if !exists { | ||
return fmt.Errorf("Bad: LogStream %q does not exist", rs.Primary.ID) | ||
} | ||
|
||
*ls = *logGroup | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccCheckAWSCloudWatchLogStreamDestroy(s *terraform.State) error { | ||
conn := testAccProvider.Meta().(*AWSClient).cloudwatchlogsconn | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "aws_cloudwatch_log_stream" { | ||
continue | ||
} | ||
|
||
logGroupName := rs.Primary.Attributes["log_group_name"] | ||
_, exists, err := lookupCloudWatchLogStream(conn, rs.Primary.ID, logGroupName, nil) | ||
if err != nil { | ||
return nil | ||
} | ||
|
||
if exists { | ||
return fmt.Errorf("Bad: LogStream still exists: %q", rs.Primary.ID) | ||
} | ||
|
||
} | ||
|
||
return nil | ||
} | ||
|
||
func TestValidateCloudWatchLogStreamName(t *testing.T) { | ||
validNames := []string{ | ||
"test-log-stream", | ||
"my_sample_log_stream", | ||
"012345678", | ||
"logstream/1234", | ||
} | ||
for _, v := range validNames { | ||
_, errors := validateCloudWatchLogStreamName(v, "name") | ||
if len(errors) != 0 { | ||
t.Fatalf("%q should be a valid CloudWatch LogStream name: %q", v, errors) | ||
} | ||
} | ||
|
||
invalidNames := []string{ | ||
acctest.RandString(513), | ||
"", | ||
"stringwith:colon", | ||
} | ||
for _, v := range invalidNames { | ||
_, errors := validateCloudWatchLogStreamName(v, "name") | ||
if len(errors) == 0 { | ||
t.Fatalf("%q should be an invalid CloudWatch LogStream name", v) | ||
} | ||
} | ||
} | ||
|
||
func testAccAWSCloudWatchLogStreamConfig(rName string) string { | ||
return fmt.Sprintf(` | ||
resource "aws_cloudwatch_log_group" "foobar" { | ||
name = "%s" | ||
} | ||
resource "aws_cloudwatch_log_stream" "foobar" { | ||
name = "%s" | ||
log_group_name = "${aws_cloudwatch_log_group.foobar.id}" | ||
} | ||
`, rName, rName) | ||
} |
37 changes: 37 additions & 0 deletions
37
website/source/docs/providers/aws/r/cloudwatch_log_stream.html.markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
--- | ||
layout: "aws" | ||
page_title: "AWS: aws_cloudwatch_log_stream" | ||
sidebar_current: "docs-aws-resource-cloudwatch-log-stream" | ||
description: |- | ||
Provides a CloudWatch Log Stream resource. | ||
--- | ||
|
||
# aws\_cloudwatch\_log\_stream | ||
|
||
Provides a CloudWatch Log Stream resource. | ||
|
||
## Example Usage | ||
|
||
``` | ||
resource "aws_cloudwatch_log_group" "yada" { | ||
name = "Yada" | ||
} | ||
resource "aws_cloudwatch_log_stream" "foo" { | ||
name = "SampleLogStream1234" | ||
log_group_name = "${aws_cloudwatch_log_group.yada.name}" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `name` - (Required) The name of the log stream. Must not be longer than 512 characters and must not contain `:` | ||
* `log_group_name` - (Required) The name of the log group under which the log stream is to be created. | ||
|
||
## Attributes Reference | ||
|
||
The following attributes are exported: | ||
|
||
* `arn` - The Amazon Resource Name (ARN) specifying the log stream. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters