-
Notifications
You must be signed in to change notification settings - Fork 9.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reference: #15413 Output from acceptance testing: ``` Pending ```
- Loading branch information
Showing
9 changed files
with
599 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
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,90 @@ | ||
package keyvaluetags | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/arn" | ||
"github.com/aws/aws-sdk-go/service/s3control" | ||
"github.com/hashicorp/aws-sdk-go-base/tfawserr" | ||
) | ||
|
||
// Custom S3control tagging functions using similar formatting as other service generated code. | ||
|
||
// S3controlBucketListTags lists S3control bucket tags. | ||
// The identifier is the bucket ARN. | ||
func S3controlBucketListTags(conn *s3control.S3Control, identifier string) (KeyValueTags, error) { | ||
parsedArn, err := arn.Parse(identifier) | ||
|
||
if err != nil { | ||
return New(nil), fmt.Errorf("error parsing S3 Control Bucket ARN (%s): %w", identifier, err) | ||
} | ||
|
||
input := &s3control.GetBucketTaggingInput{ | ||
AccountId: aws.String(parsedArn.AccountID), | ||
Bucket: aws.String(identifier), | ||
} | ||
|
||
output, err := conn.GetBucketTagging(input) | ||
|
||
if tfawserr.ErrCodeEquals(err, "NoSuchTagSet") { | ||
return New(nil), nil | ||
} | ||
|
||
if err != nil { | ||
return New(nil), err | ||
} | ||
|
||
return S3controlKeyValueTags(output.TagSet), nil | ||
} | ||
|
||
// S3controlBucketUpdateTags updates S3control bucket tags. | ||
// The identifier is the bucket ARN. | ||
func S3controlBucketUpdateTags(conn *s3control.S3Control, identifier string, oldTagsMap interface{}, newTagsMap interface{}) error { | ||
parsedArn, err := arn.Parse(identifier) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error parsing S3 Control Bucket ARN (%s): %w", identifier, err) | ||
} | ||
|
||
oldTags := New(oldTagsMap) | ||
newTags := New(newTagsMap) | ||
|
||
// We need to also consider any existing ignored tags. | ||
allTags, err := S3controlBucketListTags(conn, identifier) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error listing resource tags (%s): %w", identifier, err) | ||
} | ||
|
||
ignoredTags := allTags.Ignore(oldTags).Ignore(newTags) | ||
|
||
if len(newTags)+len(ignoredTags) > 0 { | ||
input := &s3control.PutBucketTaggingInput{ | ||
AccountId: aws.String(parsedArn.AccountID), | ||
Bucket: aws.String(identifier), | ||
Tagging: &s3control.Tagging{ | ||
TagSet: newTags.Merge(ignoredTags).S3controlTags(), | ||
}, | ||
} | ||
|
||
_, err := conn.PutBucketTagging(input) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error setting resource tags (%s): %w", identifier, err) | ||
} | ||
} else if len(oldTags) > 0 && len(ignoredTags) == 0 { | ||
input := &s3control.DeleteBucketTaggingInput{ | ||
AccountId: aws.String(parsedArn.AccountID), | ||
Bucket: aws.String(identifier), | ||
} | ||
|
||
_, err := conn.DeleteBucketTagging(input) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error deleting resource tags (%s): %w", identifier, err) | ||
} | ||
} | ||
|
||
return nil | ||
} |
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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,196 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"regexp" | ||
"strings" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/arn" | ||
"github.com/aws/aws-sdk-go/service/s3control" | ||
"github.com/hashicorp/aws-sdk-go-base/tfawserr" | ||
"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 resourceAwsS3ControlBucket() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsS3ControlBucketCreate, | ||
Read: resourceAwsS3ControlBucketRead, | ||
Update: resourceAwsS3ControlBucketUpdate, | ||
Delete: resourceAwsS3ControlBucketDelete, | ||
|
||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"arn": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"bucket": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.All( | ||
validation.StringLenBetween(3, 63), | ||
validation.StringMatch(regexp.MustCompile(`^[a-z0-9.-]+$`), "must contain only lowercase letters, numbers, periods, and hyphens"), | ||
validation.StringMatch(regexp.MustCompile(`^[a-z0-9]`), "must begin with lowercase letter or number"), | ||
validation.StringMatch(regexp.MustCompile(`[a-z0-9]$`), "must end with lowercase letter or number"), | ||
), | ||
}, | ||
"creation_date": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"outpost_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.StringLenBetween(1, 64), | ||
}, | ||
"public_access_block_enabled": { | ||
Type: schema.TypeBool, | ||
Computed: true, | ||
}, | ||
"tags": tagsSchema(), | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsS3ControlBucketCreate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).s3controlconn | ||
|
||
bucket := d.Get("bucket").(string) | ||
|
||
input := &s3control.CreateBucketInput{ | ||
Bucket: aws.String(bucket), | ||
OutpostId: aws.String(d.Get("outpost_id").(string)), | ||
} | ||
|
||
output, err := conn.CreateBucket(input) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error creating S3 Control Bucket (%s): %w", bucket, err) | ||
} | ||
|
||
if output == nil { | ||
return fmt.Errorf("error creating S3 Control Bucket (%s): empty response", bucket) | ||
} | ||
|
||
d.SetId(aws.StringValue(output.BucketArn)) | ||
|
||
if v := d.Get("tags").(map[string]interface{}); len(v) > 0 { | ||
if err := keyvaluetags.S3controlBucketUpdateTags(conn, d.Id(), nil, v); err != nil { | ||
return fmt.Errorf("error adding S3 Control Bucket (%s) tags: %w", d.Id(), err) | ||
} | ||
} | ||
|
||
return resourceAwsS3ControlBucketRead(d, meta) | ||
} | ||
|
||
func resourceAwsS3ControlBucketRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).s3controlconn | ||
ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig | ||
|
||
parsedArn, err := arn.Parse(d.Id()) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error parsing S3 Control Bucket ARN (%s): %w", d.Id(), err) | ||
} | ||
|
||
// ARN resource format: outpost/<outpost-id>/bucket/<my-bucket-name> | ||
arnResourceParts := strings.Split(parsedArn.Resource, "/") | ||
|
||
if parsedArn.AccountID == "" || len(arnResourceParts) != 4 { | ||
return fmt.Errorf("error parsing S3 Control Bucket ARN (%s): unknown format", d.Id()) | ||
} | ||
|
||
input := &s3control.GetBucketInput{ | ||
AccountId: aws.String(parsedArn.AccountID), | ||
Bucket: aws.String(d.Id()), | ||
} | ||
|
||
output, err := conn.GetBucket(input) | ||
|
||
if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, "NoSuchBucket") { | ||
log.Printf("[WARN] S3 Control Bucket (%s) not found, removing from state", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("error reading S3 Control Bucket (%s): %w", d.Id(), err) | ||
} | ||
|
||
if output == nil { | ||
return fmt.Errorf("error reading S3 Control Bucket (%s): empty response", d.Id()) | ||
} | ||
|
||
d.Set("arn", d.Id()) | ||
d.Set("bucket", output.Bucket) | ||
|
||
if output.CreationDate != nil { | ||
d.Set("creation_date", aws.TimeValue(output.CreationDate).Format(time.RFC3339)) | ||
} | ||
|
||
d.Set("outpost_id", arnResourceParts[1]) | ||
d.Set("public_access_block_enabled", output.PublicAccessBlockEnabled) | ||
|
||
tags, err := keyvaluetags.S3controlBucketListTags(conn, d.Id()) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error listing tags for S3 Control Bucket (%s): %w", d.Id(), err) | ||
} | ||
|
||
if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { | ||
return fmt.Errorf("error setting tags: %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsS3ControlBucketUpdate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).s3controlconn | ||
|
||
if d.HasChange("tags") { | ||
o, n := d.GetChange("tags") | ||
|
||
if err := keyvaluetags.S3controlBucketUpdateTags(conn, d.Id(), o, n); err != nil { | ||
return fmt.Errorf("error updating S3 Control Bucket (%s) tags: %w", d.Id(), err) | ||
} | ||
} | ||
|
||
return resourceAwsS3ControlBucketRead(d, meta) | ||
} | ||
|
||
func resourceAwsS3ControlBucketDelete(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).s3controlconn | ||
|
||
parsedArn, err := arn.Parse(d.Id()) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error parsing S3 Control Bucket ARN (%s): %w", d.Id(), err) | ||
} | ||
|
||
input := &s3control.DeleteBucketInput{ | ||
AccountId: aws.String(parsedArn.AccountID), | ||
Bucket: aws.String(d.Id()), | ||
} | ||
|
||
_, err = conn.DeleteBucket(input) | ||
|
||
if tfawserr.ErrCodeEquals(err, "NoSuchBucket") { | ||
return nil | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("error deleting S3 Control Bucket (%s): %w", d.Id(), err) | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.