Skip to content

Commit

Permalink
fix optional blocks in s3 bucket lifecycle and website configuration (#…
Browse files Browse the repository at this point in the history
…670)

* fix optional blocks in s3 bucket lifecycle and website configuration
update documentation for lifecycle configuration
rename cube server and vcpu server resources file names.
fix cube server documentation

* add more rules to s3 bucket lifecycle configuration example

* update change log

* lint fix

* add vendor files

* add hcl tag to apigateway resources doc

* remove tf plugin docs

* update vendor
  • Loading branch information
digna-ionos authored Sep 17, 2024
1 parent 9368093 commit e6a67ba
Show file tree
Hide file tree
Showing 24 changed files with 646 additions and 18 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 6.5.5

### Fixes
- Fix for optional blocks in `ionoscloud_s3_bucket_lifecycle_configuration`
and `ionoscloud_s3_bucket_website_configuration` resources, before were wrongly marked as required

## 6.5.4

### Fixes
Expand Down
2 changes: 1 addition & 1 deletion docs/resources/apigateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ An API gateway consists of the generic rules and configurations.

## Usage example

```
```hcl
resource "ionoscloud_apigateway" "example" {
name = "example-gateway"
metrics = true
Expand Down
4 changes: 2 additions & 2 deletions docs/resources/cube_server.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
subcategory: "Compute Engine"
layout: "ionoscloud"
page_title: "IonosCloud: cube server"
sidebar_current: "docs-resource-server"
page_title: "IonosCloud: ionoscloud_cube_server"
sidebar_current: "docs-resource-cube_server"
description: |-
Creates and manages IonosCloud Cube Server objects.
---
Expand Down
17 changes: 12 additions & 5 deletions docs/resources/s3_bucket_lifecycle_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,29 @@ resource "ionoscloud_s3_bucket" "example" {
resource "ionoscloud_s3_bucket_lifecycle_configuration" "example" {
bucket = ionoscloud_s3_bucket.example.name
rule {
id = "Logs delete"
id = "1"
status = "Enabled"
prefix = "/logs"
expiration {
days = 90
}
}
rule {
id = "2"
status = "Enabled"
prefix = "/logs"
noncurrent_version_expiration {
noncurrent_days = 90
}
}
rule {
id = "3"
status = "Enabled"
prefix = "/logs"
abort_incomplete_multipart_upload {
days_after_initiation = 1
days_after_initiation = 90
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,13 @@ require (
require (
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/stretchr/testify v1.8.2 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/tools v0.24.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)

require (
Expand Down Expand Up @@ -75,7 +79,6 @@ require (
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
Expand Down
14 changes: 11 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,21 @@ github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
Expand Down Expand Up @@ -286,7 +292,9 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/ionos-cloud/terraform-provider-ionoscloud/v6/services/s3"

"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
"github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
Expand Down Expand Up @@ -98,18 +99,24 @@ func (r *bucketLifecycleConfiguration) Schema(ctx context.Context, req resource.
Description: "A lifecycle rule for when non-current object versions expire.",
Attributes: map[string]schema.Attribute{
"noncurrent_days": schema.Int64Attribute{
Required: true,
Optional: true,
Description: "Specifies the number of days an object is noncurrent before Amazon S3 can perform the associated action.",
},
},
Validators: []validator.Object{
objectvalidator.AlsoRequires(path.Expressions{path.MatchRelative().AtName("noncurrent_days")}...),
},
},
"abort_incomplete_multipart_upload": schema.SingleNestedBlock{
Attributes: map[string]schema.Attribute{
"days_after_initiation": schema.Int64Attribute{
Required: true,
Optional: true,
Description: "Specifies the number of days after which IONOS S3 Object Storage aborts an incomplete multipart upload.",
},
},
Validators: []validator.Object{
objectvalidator.AlsoRequires(path.Expressions{path.MatchRelative().AtName("days_after_initiation")}...),
},
Description: "Specifies the days since the initiation of an incomplete multipart upload that IONOS S3 Object Storage will wait before permanently removing all parts of the upload.",
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ func TestAccBucketLifecycleConfigurationResourceBasic(t *testing.T) {
resource.TestCheckResourceAttr(name, "rule.0.status", "Enabled"),
resource.TestCheckResourceAttr(name, "rule.0.prefix", "/logs"),
resource.TestCheckResourceAttr(name, "rule.0.expiration.days", "90"),
resource.TestCheckResourceAttr(name, "rule.0.noncurrent_version_expiration.noncurrent_days", "90"),
resource.TestCheckResourceAttr(name, "rule.0.abort_incomplete_multipart_upload.days_after_initiation", "1"),
),
},
{
Expand All @@ -51,6 +49,92 @@ func TestAccBucketLifecycleConfigurationResourceBasic(t *testing.T) {
})
}

func TestAccBucketLifecycleConfigurationResourceNoncurrent(t *testing.T) {
ctx := context.Background()
bucketName := acctest.GenerateRandomResourceName(bucketPrefix)
name := "ionoscloud_s3_bucket_lifecycle_configuration.test"

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
PreCheck: func() {
acctest.PreCheck(t)
},
CheckDestroy: testAccCheckBucketLifecycleConfigurationDestroy,
Steps: []resource.TestStep{
{
Config: testAccBucketLifecycleConfigurationConfig_noncurrent(bucketName),
Check: resource.ComposeTestCheckFunc(
testAccCheckLifecycleConfigurationExists(ctx, name),
resource.TestCheckResourceAttr(name, "bucket", bucketName),
resource.TestCheckResourceAttr(name, "rule.0.id", "Logs delete"),
resource.TestCheckResourceAttr(name, "rule.0.status", "Enabled"),
resource.TestCheckResourceAttr(name, "rule.0.prefix", "/logs"),
resource.TestCheckResourceAttr(name, "rule.0.noncurrent_version_expiration.noncurrent_days", "90"),
),
},
},
})
}

func TestAccBucketLifecycleConfigurationResourceAbort(t *testing.T) {
ctx := context.Background()
bucketName := acctest.GenerateRandomResourceName(bucketPrefix)
name := "ionoscloud_s3_bucket_lifecycle_configuration.test"

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
PreCheck: func() {
acctest.PreCheck(t)
},
CheckDestroy: testAccCheckBucketLifecycleConfigurationDestroy,
Steps: []resource.TestStep{
{
Config: testAccBucketLifecycleConfigurationConfig_abort(bucketName),
Check: resource.ComposeTestCheckFunc(
testAccCheckLifecycleConfigurationExists(ctx, name),
resource.TestCheckResourceAttr(name, "bucket", bucketName),
resource.TestCheckResourceAttr(name, "rule.0.id", "Logs delete"),
resource.TestCheckResourceAttr(name, "rule.0.status", "Enabled"),
resource.TestCheckResourceAttr(name, "rule.0.prefix", "/logs"),
resource.TestCheckResourceAttr(name, "rule.0.abort_incomplete_multipart_upload.days_after_initiation", "1"),
),
},
},
})
}

func TestAccBucketLifecycleConfigurationResourceMultipleRules(t *testing.T) {
ctx := context.Background()
bucketName := acctest.GenerateRandomResourceName(bucketPrefix)
name := "ionoscloud_s3_bucket_lifecycle_configuration.test"

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
PreCheck: func() {
acctest.PreCheck(t)
},
CheckDestroy: testAccCheckBucketLifecycleConfigurationDestroy,
Steps: []resource.TestStep{
{
Config: testAccBucketLifecycleConfigurationConfig_multipleRules(bucketName),
Check: resource.ComposeTestCheckFunc(
testAccCheckLifecycleConfigurationExists(ctx, name),
resource.TestCheckResourceAttr(name, "bucket", bucketName),
resource.TestCheckResourceAttr(name, "rule.0.id", "Logs delete"),
resource.TestCheckResourceAttr(name, "rule.0.status", "Enabled"),
resource.TestCheckResourceAttr(name, "rule.0.prefix", "/logs"),
resource.TestCheckResourceAttr(name, "rule.0.abort_incomplete_multipart_upload.days_after_initiation", "1"),
resource.TestCheckResourceAttr(name, "rule.1.id", "Rule 2"),
resource.TestCheckResourceAttr(name, "rule.1.status", "Enabled"),
resource.TestCheckResourceAttr(name, "rule.1.prefix", "/logs"),
resource.TestCheckResourceAttr(name, "rule.1.expiration.days", "90"),
),
},
},
})

}

func testAccBucketLifecycleConfigurationConfig_base(bucketName string) string {
return fmt.Sprintf(`
resource "ionoscloud_s3_bucket" "test" {
Expand All @@ -74,15 +158,77 @@ resource "ionoscloud_s3_bucket_lifecycle_configuration" "test" {
expiration {
days = 90
}
}
}
`))
}

func testAccBucketLifecycleConfigurationConfig_noncurrent(bucketName string) string {
return utils.ConfigCompose(testAccBucketLifecycleConfigurationConfig_base(bucketName), fmt.Sprintf(`
resource "ionoscloud_s3_bucket_lifecycle_configuration" "test" {
bucket = ionoscloud_s3_bucket.test.name
rule {
id = "Logs delete"
status = "Enabled"
prefix = "/logs"
expiration {
days = 90
}
noncurrent_version_expiration {
noncurrent_days = 90
}
}
}
`))
}

func testAccBucketLifecycleConfigurationConfig_abort(bucketName string) string {
return utils.ConfigCompose(testAccBucketLifecycleConfigurationConfig_base(bucketName), fmt.Sprintf(`
resource "ionoscloud_s3_bucket_lifecycle_configuration" "test" {
bucket = ionoscloud_s3_bucket.test.name
rule {
id = "Logs delete"
status = "Enabled"
prefix = "/logs"
abort_incomplete_multipart_upload {
days_after_initiation = 1
}
}
}
`))
}

func testAccBucketLifecycleConfigurationConfig_multipleRules(bucketName string) string {
return utils.ConfigCompose(testAccBucketLifecycleConfigurationConfig_base(bucketName), fmt.Sprintf(`
resource "ionoscloud_s3_bucket_lifecycle_configuration" "test" {
bucket = ionoscloud_s3_bucket.test.name
rule {
id = "Logs delete"
status = "Enabled"
prefix = "/logs"
abort_incomplete_multipart_upload {
days_after_initiation = 1
}
}
rule {
id = "Rule 2"
status = "Enabled"
prefix = "/logs"
expiration {
days = 90
}
}
}
`))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator"

"github.com/ionos-cloud/terraform-provider-ionoscloud/v6/services/s3"

"github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator"
Expand Down Expand Up @@ -38,6 +40,7 @@ func (r *bucketWebsiteConfiguration) ConfigValidators(ctx context.Context) []res
path.MatchRoot("redirect_all_requests_to"),
path.MatchRoot("routing_rule"),
),
resourcevalidator.ExactlyOneOf(path.MatchRoot("index_document"), path.MatchRoot("redirect_all_requests_to")),
}
}

Expand Down Expand Up @@ -66,20 +69,27 @@ func (r *bucketWebsiteConfiguration) Schema(ctx context.Context, req resource.Sc
Attributes: map[string]schema.Attribute{
"suffix": schema.StringAttribute{
Description: "A suffix that is appended to a request that is for a directory on the website endpoint (for example, if the suffix is index.html and you make a request to samplebucket/images/ the data that is returned will be for the object with the key name images/index.html) The suffix must not be empty and must not include a slash character. Replacement must be made for object keys containing special characters (such as carriage returns) when using XML requests.",
Required: true,
Optional: true,
Validators: []validator.String{stringvalidator.LengthAtLeast(1), stringvalidator.NoneOf("/")},
},
},
Validators: []validator.Object{
objectvalidator.AlsoRequires(path.Expressions{path.MatchRelative().AtName("suffix")}...),
},
},
"error_document": schema.SingleNestedBlock{
Description: "The object key name to use when a 4XX class error occurs. Replacement must be made for object keys containing special characters (such as carriage returns) when using XML requests.",
Attributes: map[string]schema.Attribute{
"key": schema.StringAttribute{
Description: "The object key.",
Required: true,
Optional: true,
Validators: []validator.String{stringvalidator.LengthBetween(1, 1024)},
},
},

Validators: []validator.Object{
objectvalidator.AlsoRequires(path.Expressions{path.MatchRelative().AtName("key")}...),
},
},
"redirect_all_requests_to": schema.SingleNestedBlock{
Description: "Container for redirect information. You can redirect requests to another host, to another page, or with another protocol. In the event of an error, you can specify a different error code to return.",
Expand Down
Loading

0 comments on commit e6a67ba

Please sign in to comment.