Skip to content

Commit

Permalink
r/aws_s3control_bucket_policy: Switch to 'WithoutTimeout' CRUD handle…
Browse files Browse the repository at this point in the history
…rs (#15090).

Acceptance test output:

% make testacc TESTARGS='-run=TestAccS3ControlBucketPolicy_' PKG=s3control ACCTEST_PARALLELISM=3
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test ./internal/service/s3control/... -v -count 1 -parallel 3  -run=TestAccS3ControlBucketPolicy_ -timeout 180m
=== RUN   TestAccS3ControlBucketPolicy_basic
=== PAUSE TestAccS3ControlBucketPolicy_basic
=== RUN   TestAccS3ControlBucketPolicy_disappears
=== PAUSE TestAccS3ControlBucketPolicy_disappears
=== RUN   TestAccS3ControlBucketPolicy_policy
=== PAUSE TestAccS3ControlBucketPolicy_policy
=== CONT  TestAccS3ControlBucketPolicy_basic
=== CONT  TestAccS3ControlBucketPolicy_policy
=== CONT  TestAccS3ControlBucketPolicy_disappears
=== CONT  TestAccS3ControlBucketPolicy_basic
    acctest.go:1368: skipping since no Outposts found
--- SKIP: TestAccS3ControlBucketPolicy_basic (0.92s)
=== CONT  TestAccS3ControlBucketPolicy_policy
    acctest.go:1368: skipping since no Outposts found
--- SKIP: TestAccS3ControlBucketPolicy_policy (0.94s)
=== CONT  TestAccS3ControlBucketPolicy_disappears
    acctest.go:1368: skipping since no Outposts found
--- SKIP: TestAccS3ControlBucketPolicy_disappears (0.98s)
PASS
ok  	github.com/hashicorp/terraform-provider-aws/internal/service/s3control	6.277s
  • Loading branch information
ewbankkit committed Dec 23, 2022
1 parent af25c23 commit 9c13138
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 88 deletions.
1 change: 0 additions & 1 deletion internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2005,7 +2005,6 @@ func New(ctx context.Context) (*schema.Provider, error) {
"aws_s3_object_copy": s3.ResourceObjectCopy(),
"aws_s3_bucket_object": s3.ResourceBucketObject(), // DEPRECATED: use aws_s3_object instead

"aws_s3control_bucket_policy": s3control.ResourceBucketPolicy(),
"aws_s3control_multi_region_access_point": s3control.ResourceMultiRegionAccessPoint(),
"aws_s3control_multi_region_access_point_policy": s3control.ResourceMultiRegionAccessPointPolicy(),
"aws_s3control_object_lambda_access_point": s3control.ResourceObjectLambdaAccessPoint(),
Expand Down
117 changes: 60 additions & 57 deletions internal/service/s3control/bucket_policy.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
package s3control

import (
"fmt"
"context"
"log"

"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/v2/awsv1shim/v2/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
)

func ResourceBucketPolicy() *schema.Resource {
func init() {
_sp.registerSDKResourceFactory("aws_s3control_bucket_policy", resourceBucketPolicy)
}

func resourceBucketPolicy() *schema.Resource {
return &schema.Resource{
Create: resourceBucketPolicyCreate,
Read: resourceBucketPolicyRead,
Update: resourceBucketPolicyUpdate,
Delete: resourceBucketPolicyDelete,
CreateWithoutTimeout: resourceBucketPolicyCreate,
ReadWithoutTimeout: resourceBucketPolicyRead,
UpdateWithoutTimeout: resourceBucketPolicyUpdate,
DeleteWithoutTimeout: resourceBucketPolicyDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
Expand All @@ -47,77 +54,56 @@ func ResourceBucketPolicy() *schema.Resource {
}
}

func resourceBucketPolicyCreate(d *schema.ResourceData, meta interface{}) error {
func resourceBucketPolicyCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).S3ControlConn()

bucket := d.Get("bucket").(string)

policy, err := structure.NormalizeJsonString(d.Get("policy").(string))

if err != nil {
return fmt.Errorf("policy (%s) is invalid JSON: %w", d.Get("policy").(string), err)
return diag.Errorf("policy (%s) is invalid JSON: %s", d.Get("policy").(string), err)
}

input := &s3control.PutBucketPolicyInput{
Bucket: aws.String(bucket),
Policy: aws.String(policy),
}

_, err = conn.PutBucketPolicy(input)
_, err = conn.PutBucketPolicyWithContext(ctx, input)

if err != nil {
return fmt.Errorf("error creating S3 Control Bucket Policy (%s): %w", bucket, err)
return diag.Errorf("creating S3 Control Bucket Policy (%s): %s", bucket, err)
}

d.SetId(bucket)

return resourceBucketPolicyRead(d, meta)
return resourceBucketPolicyRead(ctx, d, meta)
}

func resourceBucketPolicyRead(d *schema.ResourceData, meta interface{}) error {
func resourceBucketPolicyRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.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)
return diag.FromErr(err)
}

if parsedArn.AccountID == "" {
return fmt.Errorf("error parsing S3 Control Bucket ARN (%s): unknown format", d.Id())
}

input := &s3control.GetBucketPolicyInput{
AccountId: aws.String(parsedArn.AccountID),
Bucket: aws.String(d.Id()),
return diag.Errorf("parsing S3 Control Bucket ARN (%s): unknown format", d.Id())
}

output, err := conn.GetBucketPolicy(input)
output, err := FindBucketPolicyByTwoPartKey(ctx, conn, parsedArn.AccountID, d.Id())

if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, "NoSuchBucket") {
log.Printf("[WARN] S3 Control Bucket Policy (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, "NoSuchBucketPolicy") {
log.Printf("[WARN] S3 Control Bucket Policy (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, "NoSuchOutpost") {
if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] S3 Control Bucket Policy (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return fmt.Errorf("error reading S3 Control Bucket Policy (%s): %w", d.Id(), err)
}

if output == nil {
return fmt.Errorf("error reading S3 Control Bucket Policy (%s): empty response", d.Id())
return diag.Errorf("reading S3 Control Bucket Policy (%s): %s", d.Id(), err)
}

d.Set("bucket", d.Id())
Expand All @@ -126,7 +112,7 @@ func resourceBucketPolicyRead(d *schema.ResourceData, meta interface{}) error {
policyToSet, err := verify.PolicyToSet(d.Get("policy").(string), aws.StringValue(output.Policy))

if err != nil {
return err
return diag.FromErr(err)
}

d.Set("policy", policyToSet)
Expand All @@ -137,60 +123,77 @@ func resourceBucketPolicyRead(d *schema.ResourceData, meta interface{}) error {
return nil
}

func resourceBucketPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
func resourceBucketPolicyUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).S3ControlConn()

policy, err := structure.NormalizeJsonString(d.Get("policy").(string))

if err != nil {
return fmt.Errorf("policy (%s) is invalid JSON: %w", d.Get("policy").(string), err)
return diag.Errorf("policy (%s) is invalid JSON: %s", d.Get("policy").(string), err)
}

input := &s3control.PutBucketPolicyInput{
Bucket: aws.String(d.Id()),
Policy: aws.String(policy),
}

_, err = conn.PutBucketPolicy(input)
_, err = conn.PutBucketPolicyWithContext(ctx, input)

if err != nil {
return fmt.Errorf("error updating S3 Control Bucket Policy (%s): %w", d.Id(), err)
return diag.Errorf("updating S3 Control Bucket Policy (%s): %s", d.Id(), err)
}

return resourceBucketPolicyRead(d, meta)
return resourceBucketPolicyRead(ctx, d, meta)
}

func resourceBucketPolicyDelete(d *schema.ResourceData, meta interface{}) error {
func resourceBucketPolicyDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.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)
return diag.FromErr(err)
}

input := &s3control.DeleteBucketPolicyInput{
log.Printf("[DEBUG] Deleting S3 Control Bucket Policy: %s", d.Id())
_, err = conn.DeleteBucketPolicyWithContext(ctx, &s3control.DeleteBucketPolicyInput{
AccountId: aws.String(parsedArn.AccountID),
Bucket: aws.String(d.Id()),
}

_, err = conn.DeleteBucketPolicy(input)
})

if tfawserr.ErrCodeEquals(err, "NoSuchBucket") {
if tfawserr.ErrCodeEquals(err, errCodeNoSuchBucket, errCodeNoSuchBucketPolicy, errCodeNoSuchOutpost) {
return nil
}

if tfawserr.ErrCodeEquals(err, "NoSuchBucketPolicy") {
return nil
if err != nil {
return diag.Errorf("deleting S3 Control Bucket Policy (%s): %s", d.Id(), err)
}

if tfawserr.ErrCodeEquals(err, "NoSuchOutpost") {
return nil
return nil
}

func FindBucketPolicyByTwoPartKey(ctx context.Context, conn *s3control.S3Control, accountID, bucket string) (*s3control.GetBucketPolicyOutput, error) {
input := &s3control.GetBucketPolicyInput{
AccountId: aws.String(accountID),
Bucket: aws.String(bucket),
}

output, err := conn.GetBucketPolicyWithContext(ctx, input)

if tfawserr.ErrCodeEquals(err, errCodeNoSuchBucket, errCodeNoSuchBucketPolicy, errCodeNoSuchOutpost) {
return nil, &resource.NotFoundError{
LastError: err,
LastRequest: input,
}
}

if err != nil {
return fmt.Errorf("error deleting S3 Control Bucket Policy (%s): %w", d.Id(), err)
return nil, err
}

return nil
if output == nil {
return nil, tfresource.NewEmptyResultError(input)
}

return output, nil
}
42 changes: 12 additions & 30 deletions internal/service/s3control/bucket_policy_test.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package s3control_test

import (
"context"
"fmt"
"regexp"
"testing"

"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/v2/awsv1shim/v2/tfawserr"
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tfs3control "github.com/hashicorp/terraform-provider-aws/internal/service/s3control"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
)

func TestAccS3ControlBucketPolicy_basic(t *testing.T) {
Expand Down Expand Up @@ -110,63 +110,45 @@ func testAccCheckBucketPolicyDestroy(s *terraform.State) error {
parsedArn, err := arn.Parse(rs.Primary.ID)

if err != nil {
return fmt.Errorf("error parsing S3 Control Bucket ARN (%s): %w", rs.Primary.ID, err)
}

input := &s3control.GetBucketPolicyInput{
AccountId: aws.String(parsedArn.AccountID),
Bucket: aws.String(rs.Primary.ID),
}

_, err = conn.GetBucketPolicy(input)

if tfawserr.ErrCodeEquals(err, "NoSuchBucket") {
continue
return err
}

if tfawserr.ErrCodeEquals(err, "NoSuchBucketPolicy") {
continue
}
_, err = tfs3control.FindBucketPolicyByTwoPartKey(context.Background(), conn, parsedArn.AccountID, rs.Primary.ID)

if tfawserr.ErrCodeEquals(err, "NoSuchOutpost") {
if tfresource.NotFound(err) {
continue
}

if err != nil {
return err
}

return fmt.Errorf("S3 Control Bucket Policy (%s) still exists", rs.Primary.ID)
return fmt.Errorf("S3 Control Bucket Policy %s still exists", rs.Primary.ID)
}

return nil
}

func testAccCheckBucketPolicyExists(resourceName string) resource.TestCheckFunc {
func testAccCheckBucketPolicyExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("not found: %s", resourceName)
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("no resource ID is set")
return fmt.Errorf("No S3 Control Bucket Policy ID is set")
}

conn := acctest.Provider.Meta().(*conns.AWSClient).S3ControlConn()

parsedArn, err := arn.Parse(rs.Primary.ID)

if err != nil {
return fmt.Errorf("error parsing S3 Control Bucket ARN (%s): %w", rs.Primary.ID, err)
}

input := &s3control.GetBucketPolicyInput{
AccountId: aws.String(parsedArn.AccountID),
Bucket: aws.String(rs.Primary.ID),
return err
}

_, err = conn.GetBucketPolicy(input)
_, err = tfs3control.FindBucketPolicyByTwoPartKey(context.Background(), conn, parsedArn.AccountID, rs.Primary.ID)

return err
}
Expand Down
1 change: 1 addition & 0 deletions internal/service/s3control/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const (
errCodeNoSuchAccessPointPolicy = "NoSuchAccessPointPolicy"
errCodeNoSuchAsyncRequest = "NoSuchAsyncRequest"
errCodeNoSuchBucket = "NoSuchBucket"
errCodeNoSuchBucketPolicy = "NoSuchBucketPolicy"
errCodeNoSuchLifecycleConfiguration = "NoSuchLifecycleConfiguration"
errCodeNoSuchMultiRegionAccessPoint = "NoSuchMultiRegionAccessPoint"
errCodeNoSuchOutpost = "NoSuchOutpost"
Expand Down
1 change: 1 addition & 0 deletions internal/service/s3control/exports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ var (
ResourceAccountPublicAccessBlock = resourceAccountPublicAccessBlock
ResourceBucket = resourceBucket
ResourceBucketLifecycleConfiguration = resourceBucketLifecycleConfiguration
ResourceBucketPolicy = resourceBucketPolicy
ResourceStorageLensConfiguration = resourceStorageLensConfiguration
)

0 comments on commit 9c13138

Please sign in to comment.