Skip to content

Commit

Permalink
Merge pull request #15463 from yardensachs/f-timestreamwrite-database…
Browse files Browse the repository at this point in the history
…-resource

New resource: Timestream Write database resource
  • Loading branch information
anGie44 authored May 8, 2021
2 parents 668fd33 + eb443d6 commit 3a36f47
Show file tree
Hide file tree
Showing 12 changed files with 716 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/15463.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_timestreamwrite_database
```
1 change: 1 addition & 0 deletions aws/internal/keyvaluetags/generators/listtags/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ var serviceNames = []string{
"ssoadmin",
"storagegateway",
"swf",
"timestreamwrite",
"transfer",
"waf",
"wafregional",
Expand Down
1 change: 1 addition & 0 deletions aws/internal/keyvaluetags/generators/servicetags/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ var sliceServiceNames = []string{
"ssoadmin",
"storagegateway",
"swf",
"timestreamwrite",
"transfer",
"waf",
"wafregional",
Expand Down
1 change: 1 addition & 0 deletions aws/internal/keyvaluetags/generators/updatetags/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ var serviceNames = []string{
"storagegateway",
"swf",
"synthetics",
"timestreamwrite",
"transfer",
"waf",
"wafregional",
Expand Down
18 changes: 18 additions & 0 deletions aws/internal/keyvaluetags/list_tags_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ import (
"github.com/aws/aws-sdk-go/service/storagegateway"
"github.com/aws/aws-sdk-go/service/swf"
"github.com/aws/aws-sdk-go/service/synthetics"
"github.com/aws/aws-sdk-go/service/timestreamwrite"
"github.com/aws/aws-sdk-go/service/transfer"
"github.com/aws/aws-sdk-go/service/waf"
"github.com/aws/aws-sdk-go/service/wafregional"
Expand Down Expand Up @@ -349,6 +350,8 @@ func ServiceClientType(serviceName string) string {
funcType = reflect.TypeOf(swf.New)
case "synthetics":
funcType = reflect.TypeOf(synthetics.New)
case "timestreamwrite":
funcType = reflect.TypeOf(timestreamwrite.New)
case "transfer":
funcType = reflect.TypeOf(transfer.New)
case "waf":
Expand Down Expand Up @@ -752,6 +755,8 @@ func ServiceTagInputIdentifierField(serviceName string) string {
return "ResourceId"
case "storagegateway":
return "ResourceARN"
case "timestreamwrite":
return "ResourceARN"
case "transfer":
return "Arn"
case "waf":
Expand Down
28 changes: 28 additions & 0 deletions aws/internal/keyvaluetags/service_tags_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions aws/internal/keyvaluetags/update_tags_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,7 @@ func Provider() *schema.Provider {
"aws_subnet": resourceAwsSubnet(),
"aws_swf_domain": resourceAwsSwfDomain(),
"aws_synthetics_canary": resourceAwsSyntheticsCanary(),
"aws_timestreamwrite_database": resourceAwsTimestreamWriteDatabase(),
"aws_transfer_server": resourceAwsTransferServer(),
"aws_transfer_ssh_key": resourceAwsTransferSshKey(),
"aws_transfer_user": resourceAwsTransferUser(),
Expand Down
202 changes: 202 additions & 0 deletions aws/resource_aws_timestreamwrite_database.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package aws

import (
"context"
"fmt"
"log"
"regexp"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/timestreamwrite"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func resourceAwsTimestreamWriteDatabase() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourceAwsTimestreamWriteDatabaseCreate,
ReadWithoutTimeout: resourceAwsTimestreamWriteDatabaseRead,
UpdateWithoutTimeout: resourceAwsTimestreamWriteDatabaseUpdate,
DeleteWithoutTimeout: resourceAwsTimestreamWriteDatabaseDelete,

Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},

"database_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.All(
validation.StringLenBetween(3, 64),
validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9_.-]+$`), "must only include alphanumeric, underscore, period, or hyphen characters"),
),
},

"kms_key_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
// The Timestream API accepts the KmsKeyId as an ID, ARN, alias, or alias ARN but always returns the ARN of the key.
// The ARN is of the format 'arn:aws:kms:REGION:ACCOUNT_ID:key/KMS_KEY_ID'. Appropriate diff suppression
// would require an extra API call to the kms service's DescribeKey method to decipher aliases.
// To avoid importing an extra service in this resource, input here is restricted to only ARNs.
ValidateFunc: validateArn,
},

"table_count": {
Type: schema.TypeInt,
Computed: true,
},

"tags": tagsSchema(),

"tags_all": tagsSchemaComputed(),
},

CustomizeDiff: SetTagsDiff,
}
}

func resourceAwsTimestreamWriteDatabaseCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*AWSClient).timestreamwriteconn
defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig
tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{})))

dbName := d.Get("database_name").(string)

input := &timestreamwrite.CreateDatabaseInput{
DatabaseName: aws.String(dbName),
}

if v, ok := d.GetOk("kms_key_id"); ok {
input.KmsKeyId = aws.String(v.(string))
}

if len(tags) > 0 {
input.Tags = tags.IgnoreAws().TimestreamwriteTags()
}

resp, err := conn.CreateDatabaseWithContext(ctx, input)

if err != nil {
return diag.FromErr(fmt.Errorf("error creating Timestream Database (%s): %w", dbName, err))
}

if resp == nil || resp.Database == nil {
return diag.FromErr(fmt.Errorf("error creating Timestream Database (%s): empty output", dbName))
}

d.SetId(aws.StringValue(resp.Database.DatabaseName))

return resourceAwsTimestreamWriteDatabaseRead(ctx, d, meta)
}

func resourceAwsTimestreamWriteDatabaseRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*AWSClient).timestreamwriteconn
defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig
ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

input := &timestreamwrite.DescribeDatabaseInput{
DatabaseName: aws.String(d.Id()),
}

resp, err := conn.DescribeDatabaseWithContext(ctx, input)

if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, timestreamwrite.ErrCodeResourceNotFoundException) {
log.Printf("[WARN] Timestream Database %s not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return diag.FromErr(fmt.Errorf("error reading Timestream Database (%s): %w", d.Id(), err))
}

if resp == nil || resp.Database == nil {
return diag.FromErr(fmt.Errorf("error reading Timestream Database (%s): empty output", d.Id()))
}

db := resp.Database
arn := aws.StringValue(db.Arn)

d.Set("arn", arn)
d.Set("database_name", db.DatabaseName)
d.Set("kms_key_id", db.KmsKeyId)
d.Set("table_count", db.TableCount)

tags, err := keyvaluetags.TimestreamwriteListTags(conn, arn)

if err != nil {
return diag.FromErr(fmt.Errorf("error listing tags for Timestream Database (%s): %w", arn, err))
}

tags = tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig)

//lintignore:AWSR002
if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil {
return diag.FromErr(fmt.Errorf("error setting tags: %w", err))
}

if err := d.Set("tags_all", tags.Map()); err != nil {
return diag.FromErr(fmt.Errorf("error setting tags_all: %w", err))
}

return nil
}

func resourceAwsTimestreamWriteDatabaseUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*AWSClient).timestreamwriteconn

if d.HasChange("kms_key_id") {
input := &timestreamwrite.UpdateDatabaseInput{
DatabaseName: aws.String(d.Id()),
KmsKeyId: aws.String(d.Get("kms_key_id").(string)),
}

_, err := conn.UpdateDatabaseWithContext(ctx, input)

if err != nil {
return diag.FromErr(fmt.Errorf("error updating Timestream Database (%s): %w", d.Id(), err))
}
}

if d.HasChange("tags_all") {
o, n := d.GetChange("tags_all")

if err := keyvaluetags.TimestreamwriteUpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
return diag.FromErr(fmt.Errorf("error updating Timestream Database (%s) tags: %w", d.Get("arn").(string), err))
}
}

return resourceAwsTimestreamWriteDatabaseRead(ctx, d, meta)
}

func resourceAwsTimestreamWriteDatabaseDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*AWSClient).timestreamwriteconn

input := &timestreamwrite.DeleteDatabaseInput{
DatabaseName: aws.String(d.Id()),
}

_, err := conn.DeleteDatabaseWithContext(ctx, input)

if tfawserr.ErrCodeEquals(err, timestreamwrite.ErrCodeResourceNotFoundException) {
return nil
}

if err != nil {
return diag.FromErr(fmt.Errorf("error deleting Timestream Database (%s): %w", d.Id(), err))
}

return nil
}
Loading

0 comments on commit 3a36f47

Please sign in to comment.