Skip to content

Commit

Permalink
Merge pull request #24916 from DrFaust92/redshift-usage
Browse files Browse the repository at this point in the history
r/redshift_usage_limit - new resource
  • Loading branch information
ewbankkit authored May 23, 2022
2 parents 63ac5cd + a9b68c0 commit eb52a1f
Show file tree
Hide file tree
Showing 6 changed files with 505 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/24916.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_redshift_usage_limit
```
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,7 @@ func Provider() *schema.Provider {
"aws_redshift_snapshot_schedule": redshift.ResourceSnapshotSchedule(),
"aws_redshift_snapshot_schedule_association": redshift.ResourceSnapshotScheduleAssociation(),
"aws_redshift_subnet_group": redshift.ResourceSubnetGroup(),
"aws_redshift_usage_limit": redshift.ResourceUsageLimit(),

"aws_resourcegroups_group": resourcegroups.ResourceGroup(),

Expand Down
29 changes: 29 additions & 0 deletions internal/service/redshift/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,32 @@ func FindHsmClientCertificateByID(conn *redshift.Redshift, id string) (*redshift

return out.HsmClientCertificates[0], nil
}

func FindUsageLimitByID(conn *redshift.Redshift, id string) (*redshift.UsageLimit, error) {
input := &redshift.DescribeUsageLimitsInput{
UsageLimitId: aws.String(id),
}

output, err := conn.DescribeUsageLimits(input)

if tfawserr.ErrCodeEquals(err, redshift.ErrCodeUsageLimitNotFoundFault) {
return nil, &resource.NotFoundError{
LastError: err,
LastRequest: input,
}
}

if err != nil {
return nil, err
}

if output == nil || len(output.UsageLimits) == 0 || output.UsageLimits[0] == nil {
return nil, tfresource.NewEmptyResultError(input)
}

if count := len(output.UsageLimits); count > 1 {
return nil, tfresource.NewTooManyResultsError(count, input)
}

return output.UsageLimits[0], nil
}
209 changes: 209 additions & 0 deletions internal/service/redshift/usage_limit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
package redshift

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/redshift"
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
)

func ResourceUsageLimit() *schema.Resource {
return &schema.Resource{
Create: resourceUsageLimitCreate,
Read: resourceUsageLimitRead,
Update: resourceUsageLimitUpdate,
Delete: resourceUsageLimitDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"amount": {
Type: schema.TypeInt,
Required: true,
},
"arn": {
Type: schema.TypeString,
Computed: true,
},
"breach_action": {
Type: schema.TypeString,
Optional: true,
Default: redshift.UsageLimitBreachActionLog,
ValidateFunc: validation.StringInSlice(redshift.UsageLimitBreachAction_Values(), false),
},
"cluster_identifier": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"feature_type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice(redshift.UsageLimitFeatureType_Values(), false),
},
"limit_type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice(redshift.UsageLimitLimitType_Values(), false),
},
"period": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Default: redshift.UsageLimitPeriodMonthly,
ValidateFunc: validation.StringInSlice(redshift.UsageLimitPeriod_Values(), false),
},
"tags": tftags.TagsSchema(),
"tags_all": tftags.TagsSchemaComputed(),
},

CustomizeDiff: verify.SetTagsDiff,
}
}

func resourceUsageLimitCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).RedshiftConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{})))

clusterId := d.Get("cluster_identifier").(string)

input := redshift.CreateUsageLimitInput{
Amount: aws.Int64(int64(d.Get("amount").(int))),
ClusterIdentifier: aws.String(clusterId),
FeatureType: aws.String(d.Get("feature_type").(string)),
LimitType: aws.String(d.Get("limit_type").(string)),
}

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

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

input.Tags = Tags(tags.IgnoreAWS())

out, err := conn.CreateUsageLimit(&input)

if err != nil {
return fmt.Errorf("error creating Redshift Usage Limit (%s): %s", clusterId, err)
}

d.SetId(aws.StringValue(out.UsageLimitId))

return resourceUsageLimitRead(d, meta)
}

func resourceUsageLimitRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).RedshiftConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig

out, err := FindUsageLimitByID(conn, d.Id())
if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] Redshift Usage Limit (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return fmt.Errorf("error reading Redshift Usage Limit (%s): %w", d.Id(), err)
}

arn := arn.ARN{
Partition: meta.(*conns.AWSClient).Partition,
Service: "redshift",
Region: meta.(*conns.AWSClient).Region,
AccountID: meta.(*conns.AWSClient).AccountID,
Resource: fmt.Sprintf("usagelimit:%s", d.Id()),
}.String()

d.Set("arn", arn)
d.Set("amount", out.Amount)
d.Set("period", out.Period)
d.Set("limit_type", out.LimitType)
d.Set("feature_type", out.FeatureType)
d.Set("breach_action", out.BreachAction)
d.Set("cluster_identifier", out.ClusterIdentifier)

tags := KeyValueTags(out.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig)

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

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

return nil
}

func resourceUsageLimitUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).RedshiftConn

if d.HasChangesExcept("tags", "tags_all") {
input := &redshift.ModifyUsageLimitInput{
UsageLimitId: aws.String(d.Id()),
}

if d.HasChange("amount") {
input.Amount = aws.Int64(int64(d.Get("amount").(int)))
}

if d.HasChange("breach_action") {
input.BreachAction = aws.String(d.Get("breach_action").(string))
}

_, err := conn.ModifyUsageLimit(input)
if err != nil {
return fmt.Errorf("error updating Redshift Usage Limit (%s): %w", d.Id(), err)
}
}

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

if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
return fmt.Errorf("error updating Redshift Usage Limit (%s) tags: %s", d.Get("arn").(string), err)
}
}

return resourceUsageLimitRead(d, meta)
}

func resourceUsageLimitDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).RedshiftConn

deleteInput := redshift.DeleteUsageLimitInput{
UsageLimitId: aws.String(d.Id()),
}

log.Printf("[DEBUG] Deleting snapshot copy grant: %s", d.Id())
_, err := conn.DeleteUsageLimit(&deleteInput)

if err != nil {
if tfawserr.ErrCodeEquals(err, redshift.ErrCodeUsageLimitNotFoundFault) {
return nil
}
return err
}

return err
}
Loading

0 comments on commit eb52a1f

Please sign in to comment.