From 6ca1b05494c9b904348d214a5724daf49aa746e9 Mon Sep 17 00:00:00 2001 From: magodo Date: Mon, 12 Dec 2022 15:33:54 +0800 Subject: [PATCH] `azurerm_storage_account` - Support `blob_properties.0.restore_policy` --- .../storage/storage_account_resource.go | 68 +++++++++++++++++++ .../storage/storage_account_resource_test.go | 6 ++ website/docs/r/storage_account.html.markdown | 8 +++ 3 files changed, 82 insertions(+) diff --git a/internal/services/storage/storage_account_resource.go b/internal/services/storage/storage_account_resource.go index c8c821b03629..d798b05b9b3c 100644 --- a/internal/services/storage/storage_account_resource.go +++ b/internal/services/storage/storage_account_resource.go @@ -460,6 +460,22 @@ func resourceStorageAccount() *pluginsdk.Resource { }, }, + "restore_policy": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "days": { + Type: pluginsdk.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, 365), + }, + }, + }, + RequiredWith: []string{"blob_properties.0.delete_retention_policy"}, + }, + "versioning_enabled": { Type: pluginsdk.TypeBool, Optional: true, @@ -1310,6 +1326,11 @@ func resourceStorageAccountCreate(d *pluginsdk.ResourceData, meta interface{}) e return fmt.Errorf("`versioning_enabled` can't be true when `is_hns_enabled` is true") } + if (blobProperties.IsVersioningEnabled != nil && !*blobProperties.IsVersioningEnabled) && (blobProperties.RestorePolicy != nil && blobProperties.RestorePolicy.Enabled != nil && *blobProperties.RestorePolicy.Enabled) { + // Otherwise, API returns: "Conflicting feature 'restorePolicy' is enabled. Please disable it and retry." + return fmt.Errorf("`blob_properties.restore_policy` can't be set when `versioning_enabled` is false") + } + if _, err = blobClient.SetServiceProperties(ctx, id.ResourceGroup, id.Name, *blobProperties); err != nil { return fmt.Errorf("updating Azure Storage Account `blob_properties` %q: %+v", id.Name, err) } @@ -2582,6 +2603,10 @@ func expandBlobProperties(input []interface{}) *storage.BlobServiceProperties { deletePolicyRaw := v["delete_retention_policy"].([]interface{}) props.BlobServicePropertiesProperties.DeleteRetentionPolicy = expandBlobPropertiesDeleteRetentionPolicy(deletePolicyRaw) + + restorePolicyRaw := v["restore_policy"].([]interface{}) + props.BlobServicePropertiesProperties.RestorePolicy = expandBlobPropertiesRestorePolicy(restorePolicyRaw) + corsRaw := v["cors_rule"].([]interface{}) props.BlobServicePropertiesProperties.Cors = expandBlobPropertiesCors(corsRaw) @@ -2618,6 +2643,22 @@ func expandBlobPropertiesDeleteRetentionPolicy(input []interface{}) *storage.Del } } +func expandBlobPropertiesRestorePolicy(input []interface{}) *storage.RestorePolicyProperties { + result := storage.RestorePolicyProperties{ + Enabled: utils.Bool(false), + } + if len(input) == 0 || input[0] == nil { + return &result + } + + policy := input[0].(map[string]interface{}) + + return &storage.RestorePolicyProperties{ + Enabled: utils.Bool(true), + Days: utils.Int32(int32(policy["days"].(int))), + } +} + func expandBlobPropertiesCors(input []interface{}) *storage.CorsRules { blobCorsRules := storage.CorsRules{} @@ -3047,6 +3088,11 @@ func flattenBlobProperties(input storage.BlobServiceProperties) []interface{} { flattenedDeletePolicy = flattenBlobPropertiesDeleteRetentionPolicy(deletePolicy) } + flattenedRestorePolicy := make([]interface{}, 0) + if restorePolicy := input.BlobServicePropertiesProperties.RestorePolicy; restorePolicy != nil { + flattenedRestorePolicy = flattenBlobPropertiesRestorePolicy(restorePolicy) + } + flattenedContainerDeletePolicy := make([]interface{}, 0) if containerDeletePolicy := input.BlobServicePropertiesProperties.ContainerDeleteRetentionPolicy; containerDeletePolicy != nil { flattenedContainerDeletePolicy = flattenBlobPropertiesDeleteRetentionPolicy(containerDeletePolicy) @@ -3080,6 +3126,7 @@ func flattenBlobProperties(input storage.BlobServiceProperties) []interface{} { map[string]interface{}{ "cors_rule": flattenedCorsRules, "delete_retention_policy": flattenedDeletePolicy, + "restore_policy": flattenedRestorePolicy, "versioning_enabled": versioning, "change_feed_enabled": changeFeedEnabled, "change_feed_retention_in_days": changeFeedRetentionInDays, @@ -3156,6 +3203,27 @@ func flattenBlobPropertiesDeleteRetentionPolicy(input *storage.DeleteRetentionPo return deleteRetentionPolicy } +func flattenBlobPropertiesRestorePolicy(input *storage.RestorePolicyProperties) []interface{} { + restorePolicy := make([]interface{}, 0) + + if input == nil { + return restorePolicy + } + + if enabled := input.Enabled; enabled != nil && *enabled { + days := 0 + if input.Days != nil { + days = int(*input.Days) + } + + restorePolicy = append(restorePolicy, map[string]interface{}{ + "days": days, + }) + } + + return restorePolicy +} + func flattenQueueProperties(input *queues.StorageServiceProperties) []interface{} { if input == nil { return []interface{}{} diff --git a/internal/services/storage/storage_account_resource_test.go b/internal/services/storage/storage_account_resource_test.go index c657e0b15898..b4215895a593 100644 --- a/internal/services/storage/storage_account_resource_test.go +++ b/internal/services/storage/storage_account_resource_test.go @@ -606,6 +606,7 @@ func TestAccStorageAccount_blobProperties(t *testing.T) { check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("blob_properties.0.cors_rule.#").HasValue("1"), check.That(data.ResourceName).Key("blob_properties.0.delete_retention_policy.0.days").HasValue("300"), + check.That(data.ResourceName).Key("blob_properties.0.restore_policy.0.days").HasValue("299"), ), }, data.ImportStep(), @@ -625,6 +626,7 @@ func TestAccStorageAccount_blobProperties(t *testing.T) { Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("blob_properties.0.delete_retention_policy.#").DoesNotExist(), + check.That(data.ResourceName).Key("blob_properties.0.restore_policy.#").DoesNotExist(), check.That(data.ResourceName).Key("blob_properties.0.container_delete_retention_policy.#").DoesNotExist(), ), }, @@ -2414,6 +2416,10 @@ resource "azurerm_storage_account" "test" { days = 300 } + restore_policy { + days = 299 + } + default_service_version = "2019-07-07" versioning_enabled = true change_feed_enabled = true diff --git a/website/docs/r/storage_account.html.markdown b/website/docs/r/storage_account.html.markdown index c769267eb0db..fbb0d1dceb5e 100644 --- a/website/docs/r/storage_account.html.markdown +++ b/website/docs/r/storage_account.html.markdown @@ -180,6 +180,8 @@ A `blob_properties` block supports the following: * `delete_retention_policy` - (Optional) A `delete_retention_policy` block as defined below. +* `restore_policy` - (Optional) A `restore_policy` block as defined below. This must be used together with `delete_retention_policy` set and `versioning_enabled` set to `true`. + * `versioning_enabled` - (Optional) Is versioning enabled? Default to `false`. * `change_feed_enabled` - (Optional) Is the blob service properties for change feed events enabled? Default to `false`. @@ -233,6 +235,12 @@ A `delete_retention_policy` block supports the following: --- +A `restore_policy` block supports the following: + +* `days` - (Required) Specifies the number of days that the blob can be restored, between `1` and `365` days. This must be less than the `days` specified for `delete_retention_policy`. + +--- + A `container_delete_retention_policy` block supports the following: * `days` - (Optional) Specifies the number of days that the container should be retained, between `1` and `365` days. Defaults to `7`.