Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add cloudavenue_s3_bucket_cors_configuration resource/datasource #589

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changelog/578.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:new-resource
`resource/cloudavenue_s3_bucket_cors_configuration` - Manage S3 bucket CORS configuration.
```

```release-note:new-data-source
`datasource/cloudavenue_s3_bucket_cors_configuration` - Get information about S3 bucket CORS configuration.
```
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

### :rocket: **New Features**

* **New Data Source:** `datasource/cloudavenue_s3_bucket_versioning_configuration` - Get S3 bucket versioning configuration. ([GH-584](https://github.com/orange-cloudavenue/terraform-provider-cloudavenue/issues/584))
* **New Data Source:** `datasource/cloudavenue_s3_bucket` - Retrieve information about S3 buckets. ([GH-576](https://github.com/orange-cloudavenue/terraform-provider-cloudavenue/issues/576))
* **New Resource:** `resource/cloudavenue_s3_bucket_versioning_configuration` - Manage S3 bucket versioning configuration. ([GH-584](https://github.com/orange-cloudavenue/terraform-provider-cloudavenue/issues/584))
* **New Resource:** `resource/cloudavenue_s3_bucket` - Create and manage S3 buckets. ([GH-576](https://github.com/orange-cloudavenue/terraform-provider-cloudavenue/issues/576))

### :dependabot: **Dependencies**
Expand Down
55 changes: 55 additions & 0 deletions docs/data-sources/s3_bucket_cors_configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
page_title: "cloudavenue_s3_bucket_cors_configuration Data Source - cloudavenue"
subcategory: "S3 (Object Storage)"
description: |-
The cloudavenue_s3_bucket_cors_configuration data source allows you to retrieve information about an S3 bucket's Cross-Origin Resource Sharing https://docs.aws.amazon.com/AmazonS3/latest/userguide/cors.html configuration.
---

# cloudavenue_s3_bucket_cors_configuration (Data Source)

The `cloudavenue_s3_bucket_cors_configuration` data source allows you to retrieve information about an S3 bucket's [Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/userguide/cors.html) configuration.

## Example Usage

```terraform
data "cloudavenue_s3_bucket_cors_configuration" "example" {
bucket = "example"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `bucket` (String) The name of the bucket.

### Optional

- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))

### Read-Only

- `cors_rules` (Attributes Set) Set of origins and methods (cross-origin access that you want to allow). Set must contain at least 1 elements and at most 100 elements. (see [below for nested schema](#nestedatt--cors_rules))
- `id` (String) The ID of the bucket.

<a id="nestedatt--timeouts"></a>
### Nested Schema for `timeouts`

Optional:

- `read` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours).


<a id="nestedatt--cors_rules"></a>
### Nested Schema for `cors_rules`

Read-Only:

- `allowed_headers` (Set of String) Set of Headers that are specified in the Access-Control-Request-Headers header.
- `allowed_methods` (Set of String) Set of HTTP methods that you allow the origin to execute.
- `allowed_origins` (Set of String) Set of origins you want customers to be able to access the bucket from.
- `expose_headers` (Set of String) Set of headers in the response that you want customers to be able to access from their applications (for example, from a JavaScript XMLHttpRequest object).
- `id` (String) Unique identifier for the rule.
- `max_age_seconds` (Number) Time in seconds that your browser is to cache the preflight response for the specified resource.

98 changes: 98 additions & 0 deletions docs/resources/s3_bucket_cors_configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
page_title: "cloudavenue_s3_bucket_cors_configuration Resource - cloudavenue"
subcategory: "S3 (Object Storage)"
description: |-
The cloudavenue_s3_bucket_cors_configuration resource allows you to manage the Cross-Origin Resource Sharing https://docs.aws.amazon.com/AmazonS3/latest/userguide/cors.html configuration of an S3 bucket.
---

# cloudavenue_s3_bucket_cors_configuration (Resource)

The `cloudavenue_s3_bucket_cors_configuration` resource allows you to manage the [Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/userguide/cors.html) configuration of an S3 bucket.

~> S3 Buckets only support a single CORS configuration. Declaring multiple `cloudavenue_s3_bucket_cors_configuration` resources to the same S3 Bucket will cause a perpetual difference in configuration.

## Examples Usage

### Basic example

```hcl
resource "cloudavenue_s3_bucket_cors_configuration" "example" {
bucket = cloudavenue_s3_bucket.example.name
cors_rules = [{
allowed_headers = ["*"]
allowed_methods = ["GET"]
allowed_origins = ["*"]
}]
}
```

### Advanced example

```hcl
resource "cloudavenue_s3_bucket_cors_configuration" "example" {
bucket = cloudavenue_s3_bucket.example.name
cors_rules = [{
allowed_headers = ["Content-Type"]
allowed_methods = ["GET", "DELETE"]
allowed_origins = ["https://www.example.com"]
expose_headers = ["X-Custom-Header"]
max_age_seconds = 3600
},
{
allowed_headers = ["Accept"]
allowed_methods = ["GET"]
allowed_origins = ["https://www.example.com"]
}]
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `bucket` (String) (ForceNew) The name of the bucket.
- `cors_rules` (Attributes Set) Set of origins and methods (cross-origin access that you want to allow). Set must contain at least 1 elements and at most 100 elements. (see [below for nested schema](#nestedatt--cors_rules))

### Optional

- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))

### Read-Only

- `id` (String) The ID of the bucket.

<a id="nestedatt--cors_rules"></a>
### Nested Schema for `cors_rules`

Required:

- `allowed_methods` (Set of String) Set of HTTP methods that you allow the origin to execute. Element value must satisfy all validations: value must be one of: ["GET" "PUT" "HEAD" "POST" "DELETE"].
- `allowed_origins` (Set of String) Set of origins you want customers to be able to access the bucket from.

Optional:

- `allowed_headers` (Set of String) Set of Headers that are specified in the Access-Control-Request-Headers header.
- `expose_headers` (Set of String) Set of headers in the response that you want customers to be able to access from their applications (for example, from a JavaScript XMLHttpRequest object).
- `id` (String) Unique identifier for the rule. String length must be between 1 and 255.
- `max_age_seconds` (Number) Time in seconds that your browser is to cache the preflight response for the specified resource.


<a id="nestedatt--timeouts"></a>
### Nested Schema for `timeouts`

Optional:

- `create` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours).
- `delete` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours). Setting a timeout for a Delete operation is only applicable if changes are saved into state before the destroy operation occurs.
- `read` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours). Read operations occur during any refresh or planning operation when refresh is enabled.
- `update` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours).

-> **Timeout** Default timeout is **5 minutes**.

## Import

Import is supported using the following syntax:
```shell
terraform import cloudavenue_s3_bucket_cors_configuration.example bucketName
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "cloudavenue_s3_bucket_cors_configuration" "example" {
bucket = "example"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import cloudavenue_s3_bucket_cors_configuration.example bucketName
14 changes: 12 additions & 2 deletions internal/helpers/testsacc/testsacc.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,18 +399,28 @@ func ImportStateIDBuilder(resourceName string, attributeNames []string) resource
return func(state *terraform.State) (string, error) {
rs, ok := state.RootModule().Resources[resourceName]
if !ok {
return "", fmt.Errorf("not found: %s", resourceName)
return "", fmt.Errorf("ImportStateIDBuilder : Resource %s not found", resourceName)
}

// Build the ID
id := ""
for _, attributeName := range attributeNames {
id += rs.Primary.Attributes[attributeName]
// Catch attribute not found
i, ok := rs.Primary.Attributes[attributeName]
if !ok {
return "", fmt.Errorf("ImportStateIDBuilder : Attribute %s not found", attributeName)
}

id += i
if attributeName != attributeNames[len(attributeNames)-1] {
id += "."
}
}

if id == "" {
return "", fmt.Errorf("ImportStateIDBuilder : ID is empty after building")
}

return id, nil
}
}
1 change: 1 addition & 0 deletions internal/provider/provider_datasources.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,6 @@ func (p *cloudavenueProvider) DataSources(_ context.Context) []func() datasource
// * S3
s3.NewBucketDataSource,
s3.NewBucketVersioningConfigurationDatasource,
s3.NewBucketCorsConfigurationDatasource,
}
}
1 change: 1 addition & 0 deletions internal/provider/provider_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,6 @@ func (p *cloudavenueProvider) Resources(_ context.Context) []func() resource.Res
// * S3
s3.NewBucketVersioningConfigurationResource,
s3.NewBucketResource,
s3.NewBucketCorsConfigurationResource,
}
}
46 changes: 44 additions & 2 deletions internal/provider/s3/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,50 @@ import (
const (
categoryName = "s3"

// ErrCodeObjectLockConfigurationNotFoundError object lock configuration not found.
ErrCodeObjectLockConfigurationNotFoundError = "ObjectLockConfigurationNotFoundError"
// defaultReadTimeout is the default timeout for read operations.
defaultReadTimeout = 5 * time.Minute
// defaultCreateTimeout is the default timeout for create operations.
defaultCreateTimeout = 5 * time.Minute
// defaultUpdateTimeout is the default timeout for update operations.
defaultUpdateTimeout = 5 * time.Minute
// defaultDeleteTimeout is the default timeout for delete operations.
defaultDeleteTimeout = 5 * time.Minute
)

// Error code constants missing from AWS Go SDK:
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#pkg-constants

const (
ErrCodeAccessDenied = "AccessDenied"
ErrCodeBucketNotEmpty = "BucketNotEmpty"
ErrCodeInvalidBucketState = "InvalidBucketState"
ErrCodeInvalidRequest = "InvalidRequest"
ErrCodeMalformedPolicy = "MalformedPolicy"
ErrCodeMethodNotAllowed = "MethodNotAllowed"
ErrCodeNoSuchBucket = "NoSuchBucket"
ErrCodeNoSuchBucketPolicy = "NoSuchBucketPolicy"
ErrCodeNoSuchConfiguration = "NoSuchConfiguration"
ErrCodeNoSuchCORSConfiguration = "NoSuchCORSConfiguration"
ErrCodeNoSuchLifecycleConfiguration = "NoSuchLifecycleConfiguration"
ErrCodeNoSuchKey = "NoSuchKey"
ErrCodeNoSuchPublicAccessBlockConfiguration = "NoSuchPublicAccessBlockConfiguration"
ErrCodeNoSuchTagSet = "NoSuchTagSet"
ErrCodeNoSuchTagSetError = "NoSuchTagSetError"
ErrCodeNoSuchWebsiteConfiguration = "NoSuchWebsiteConfiguration"
ErrCodeNotImplemented = "NotImplemented"
// ErrCodeObjectLockConfigurationNotFound should be used with tfawsErr.ErrCodeContains, not tfawsErr.ErrCodeEquals.
// Reference: https://github.com/hashicorp/tErraform-provider-aws/pull/26317
ErrCodeObjectLockConfigurationNotFound = "ObjectLockConfigurationNotFound"
ErrCodeObjectLockConfigurationNotFoundError = "ObjectLockConfigurationNotFoundError"
ErrCodeOperationAborted = "OperationAborted"
ErrCodeOwnershipControlsNotFoundError = "OwnershipControlsNotFoundError"
ErrCodeReplicationConfigurationNotFound = "ReplicationConfigurationNotFoundError"
ErrCodeServerSideEncryptionConfigurationNotFound = "ServerSideEncryptionConfigurationNotFoundError"
ErrCodeUnsupportedArgument = "UnsupportedArgument"
// ErrCodeXNotImplemented is returned from Third Party S3 implementations
// and so far has been noticed with calls to GetBucketWebsite.
// Reference: https://github.com/hashicorp/tErraform-provider-aws/issues/14645
ErrCodeXNotImplemented = "XNotImplemented"
)

// DefaultWaitRetryInterval is used to set the retry interval to 0 during acceptance tests.
Expand Down
Loading
Loading