Skip to content
Open
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
1 change: 1 addition & 0 deletions docs/resources/cloud_project_storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Required:
Optional:

- `storage_class` (String) Destination storage class
- `remove_on_main_bucket_deletion` (Boolean) Whether to remove replicated bucket when the main bucket is deleted (make sure to apply your configuration when changing this value before deleting the main bucket)

<a id="nestedatt--replication--rules--filter"></a>

Expand Down
31 changes: 31 additions & 0 deletions ovh/resource_cloud_project_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package ovh
import (
"context"
"fmt"
"net/http"
"net/url"
"strconv"
"strings"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/ovh/go-ovh/ovh"
ovhtypes "github.com/ovh/terraform-provider-ovh/v2/ovh/types"
)

Expand Down Expand Up @@ -252,4 +254,33 @@ func (r *cloudProjectStorageResource) Delete(ctx context.Context, req resource.D
err.Error(),
)
}

// If replicas exist, delete them manually after the main bucket deletion if option is set
for _, rule := range data.Replication.Rules.Elements() {
destination := rule.(ReplicationRulesValue).Destination

// Empty region means that replica is already deleted
if destination.Region.ValueString() == "" {
continue
}

if destination.RemoveOnMainBucketDeletion.ValueBool() {
replicaEndpoint := "/cloud/project/" + url.PathEscape(data.ServiceName.ValueString()) +
"/region/" + url.PathEscape(destination.Region.ValueString()) +
"/storage/" + url.PathEscape(destination.Name.ValueString())

tflog.Info(ctx, fmt.Sprintf("removing replica bucket %s", replicaEndpoint))
if err := r.config.OVHClient.Delete(replicaEndpoint, nil); err != nil {
if ovhErr, ok := err.(*ovh.APIError); ok && ovhErr.Code == http.StatusNotFound {
// If replica was already deleted, ignore the error
continue
}

resp.Diagnostics.AddError(
fmt.Sprintf("Error removing replica %s", replicaEndpoint),
err.Error(),
)
}
}
}
}
149 changes: 107 additions & 42 deletions ovh/resource_cloud_project_storage_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion ovh/resource_cloud_project_storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func TestAccCloudProjectRegionStorage_withReplication(t *testing.T) {
destination = {
name = "%s"
region = "GRA"
remove_on_main_bucket_deletion = true
}
filter = {
"prefix" = "test"
Expand Down Expand Up @@ -123,6 +124,7 @@ func TestAccCloudProjectRegionStorage_withReplication(t *testing.T) {
destination = {
name = "%s"
region = "GRA"
remove_on_main_bucket_deletion = true
}
filter = {
"prefix" = "test-updated"
Expand Down Expand Up @@ -156,7 +158,9 @@ func TestAccCloudProjectRegionStorage_withReplication(t *testing.T) {
ImportStateVerifyIdentifierAttribute: "name",
ResourceName: "ovh_cloud_project_storage.storage",
ImportStateId: fmt.Sprintf("%s/GRA/%s", os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST"), bucketName),
ImportStateVerifyIgnore: []string{"created_at"}, // Ignore created_at since its value is invalid in response of the POST.
// Ignore created_at since its value is invalid in response of the POST.
// Also ignore remove_on_main_bucket_deletion since its computed value is not returned by the API.
ImportStateVerifyIgnore: []string{"created_at", "replication.rules.0.destination.remove_on_main_bucket_deletion"},
},
},
})
Expand Down
1 change: 1 addition & 0 deletions templates/resources/cloud_project_storage.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ Required:
Optional:

- `storage_class` (String) Destination storage class
- `remove_on_main_bucket_deletion` (Boolean) Whether to remove replicated bucket when the main bucket is deleted (make sure to apply your configuration when changing this value before deleting the main bucket)

<a id="nestedatt--replication--rules--filter"></a>

Expand Down