From 3b5ba5d6af8c31d74f135044e5966d32e6977d56 Mon Sep 17 00:00:00 2001 From: Kilian Decaderincourt Date: Wed, 8 Jan 2025 14:45:22 +0100 Subject: [PATCH 1/2] feat: storage_account_blob_container_sas_data_source add support for more permissions --- ..._account_blob_container_sas_data_source.go | 96 ++++++++++---- ...unt_blob_container_sas_data_source_test.go | 124 +++++++++++++++++- .../storage_account_sas_data_source.go | 20 +-- ...e_account_blob_container_sas.html.markdown | 24 ++-- .../docs/d/storage_account_sas.html.markdown | 20 +-- 5 files changed, 221 insertions(+), 63 deletions(-) diff --git a/internal/services/storage/storage_account_blob_container_sas_data_source.go b/internal/services/storage/storage_account_blob_container_sas_data_source.go index 676f5b6438ff..2cd7766fb7f4 100644 --- a/internal/services/storage/storage_account_blob_container_sas_data_source.go +++ b/internal/services/storage/storage_account_blob_container_sas_data_source.go @@ -69,32 +69,72 @@ func dataSourceStorageAccountBlobContainerSharedAccessSignature() *pluginsdk.Res Schema: map[string]*pluginsdk.Schema{ "read": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "add": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "create": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "write": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "delete": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, + }, + + "delete_version": { + Type: pluginsdk.TypeBool, + Optional: true, }, "list": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, + }, + + "tags": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "find": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "move": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "execute": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "ownership": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "permissions": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "set_immutability_policy": { + Type: pluginsdk.TypeBool, + Optional: true, }, }, }, @@ -184,30 +224,32 @@ func dataSourceStorageContainerSasRead(d *pluginsdk.ResourceData, _ interface{}) } func BuildContainerPermissionsString(perms map[string]interface{}) string { - retVal := "" - - if val, pres := perms["read"].(bool); pres && val { - retVal += "r" + orderedPermissions := []struct { + name string + letter string + }{ + {"read", "r"}, + {"add", "a"}, + {"create", "c"}, + {"write", "w"}, + {"delete", "d"}, + {"delete_version", "x"}, + {"list", "l"}, + {"tags", "t"}, + {"find", "f"}, + {"move", "m"}, + {"execute", "e"}, + {"ownership", "o"}, + {"permissions", "p"}, + {"set_immutability_policy", "i"}, } - if val, pres := perms["add"].(bool); pres && val { - retVal += "a" - } - - if val, pres := perms["create"].(bool); pres && val { - retVal += "c" - } - - if val, pres := perms["write"].(bool); pres && val { - retVal += "w" - } - - if val, pres := perms["delete"].(bool); pres && val { - retVal += "d" - } + retVal := "" - if val, pres := perms["list"].(bool); pres && val { - retVal += "l" + for _, perm := range orderedPermissions { + if val, pres := perms[perm.name].(bool); pres && val { + retVal += perm.letter + } } return retVal diff --git a/internal/services/storage/storage_account_blob_container_sas_data_source_test.go b/internal/services/storage/storage_account_blob_container_sas_data_source_test.go index 80977fe89c0a..ced54deb1f02 100644 --- a/internal/services/storage/storage_account_blob_container_sas_data_source_test.go +++ b/internal/services/storage/storage_account_blob_container_sas_data_source_test.go @@ -35,7 +35,55 @@ func TestAccDataSourceStorageAccountBlobContainerSas_basic(t *testing.T) { check.That(data.ResourceName).Key("permissions.0.create").HasValue("false"), check.That(data.ResourceName).Key("permissions.0.write").HasValue("false"), check.That(data.ResourceName).Key("permissions.0.delete").HasValue("true"), + check.That(data.ResourceName).Key("permissions.0.delete_version").HasValue("true"), check.That(data.ResourceName).Key("permissions.0.list").HasValue("true"), + check.That(data.ResourceName).Key("permissions.0.tags").HasValue("true"), + check.That(data.ResourceName).Key("permissions.0.find").HasValue("true"), + check.That(data.ResourceName).Key("permissions.0.move").HasValue("false"), + check.That(data.ResourceName).Key("permissions.0.execute").HasValue("false"), + check.That(data.ResourceName).Key("permissions.0.ownership").HasValue("true"), + check.That(data.ResourceName).Key("permissions.0.permissions").HasValue("true"), + check.That(data.ResourceName).Key("permissions.0.set_immutability_policy").HasValue("true"), + check.That(data.ResourceName).Key("cache_control").HasValue("max-age=5"), + check.That(data.ResourceName).Key("content_disposition").HasValue("inline"), + check.That(data.ResourceName).Key("content_encoding").HasValue("deflate"), + check.That(data.ResourceName).Key("content_language").HasValue("en-US"), + check.That(data.ResourceName).Key("content_type").HasValue("application/json"), + check.That(data.ResourceName).Key("sas").Exists(), + ), + }, + }) +} + +func TestAccDataSourceStorageAccountBlobContainerSas_partial(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_storage_account_blob_container_sas", "test") + utcNow := time.Now().UTC() + startDate := utcNow.Format(time.RFC3339) + endDate := utcNow.Add(time.Hour * 24).Format(time.RFC3339) + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: StorageAccountBlobContainerSASDataSource{}.partial(data, startDate, endDate), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("https_only").HasValue("true"), + check.That(data.ResourceName).Key("start").HasValue(startDate), + check.That(data.ResourceName).Key("expiry").HasValue(endDate), + check.That(data.ResourceName).Key("ip_address").HasValue("168.1.5.65"), + check.That(data.ResourceName).Key("permissions.#").HasValue("1"), + check.That(data.ResourceName).Key("permissions.0.read").HasValue("true"), + check.That(data.ResourceName).Key("permissions.0.add").HasValue("true"), + check.That(data.ResourceName).Key("permissions.0.create").HasValue("false"), + check.That(data.ResourceName).Key("permissions.0.write").HasValue("false"), + check.That(data.ResourceName).Key("permissions.0.delete").HasValue("true"), + check.That(data.ResourceName).Key("permissions.0.delete_version").HasValue("false"), + check.That(data.ResourceName).Key("permissions.0.list").HasValue("true"), + check.That(data.ResourceName).Key("permissions.0.tags").HasValue("false"), + check.That(data.ResourceName).Key("permissions.0.find").HasValue("false"), + check.That(data.ResourceName).Key("permissions.0.move").HasValue("false"), + check.That(data.ResourceName).Key("permissions.0.execute").HasValue("false"), + check.That(data.ResourceName).Key("permissions.0.ownership").HasValue("false"), + check.That(data.ResourceName).Key("permissions.0.permissions").HasValue("false"), + check.That(data.ResourceName).Key("permissions.0.set_immutability_policy").HasValue("false"), check.That(data.ResourceName).Key("cache_control").HasValue("max-age=5"), check.That(data.ResourceName).Key("content_disposition").HasValue("inline"), check.That(data.ResourceName).Key("content_encoding").HasValue("deflate"), @@ -84,12 +132,74 @@ data "azurerm_storage_account_blob_container_sas" "test" { expiry = "%s" permissions { - read = true - add = true - create = false - write = false - delete = true - list = true + read = true + add = true + create = false + write = false + delete = true + delete_version = true + list = true + tags = true + find = true + move = false + execute = false + ownership = true + permissions = true + set_immutability_policy = true + } + + cache_control = "max-age=5" + content_disposition = "inline" + content_encoding = "deflate" + content_language = "en-US" + content_type = "application/json" +} +`, data.RandomInteger, data.Locations.Primary, data.RandomString, startDate, endDate) +} + +func (d StorageAccountBlobContainerSASDataSource) partial(data acceptance.TestData, startDate string, endDate string) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "rg" { + name = "acctestRG-storage-%d" + location = "%s" +} + +resource "azurerm_storage_account" "storage" { + name = "acctestsads%s" + resource_group_name = azurerm_resource_group.rg.name + + location = azurerm_resource_group.rg.location + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "container" { + name = "sas-test" + storage_account_name = azurerm_storage_account.storage.name + container_access_type = "private" +} + +data "azurerm_storage_account_blob_container_sas" "test" { + connection_string = azurerm_storage_account.storage.primary_connection_string + container_name = azurerm_storage_container.container.name + https_only = true + + ip_address = "168.1.5.65" + + start = "%s" + expiry = "%s" + + permissions { + read = true + add = true + create = false + write = false + delete = true + list = true } cache_control = "max-age=5" @@ -113,6 +223,8 @@ func TestAccDataSourceStorageAccountBlobContainerSas_permissionsString(t *testin {map[string]interface{}{"delete": true}, "d"}, {map[string]interface{}{"list": true}, "l"}, {map[string]interface{}{"add": true, "write": true, "read": true, "delete": true}, "rawd"}, + {map[string]interface{}{"add": true, "write": false, "read": true, "delete": false}, "ra"}, + {map[string]interface{}{"add": true, "write": true, "read": true, "delete": true, "delete_version": true, "list": true, "tags": true, "find": true, "move": true, "execute": true, "ownership": true, "permissions": true, "set_immutability_policy": true}, "rawdxltfmeopi"}, } for _, test := range testCases { diff --git a/internal/services/storage/storage_account_sas_data_source.go b/internal/services/storage/storage_account_sas_data_source.go index 952f1171affd..c0ceb2b03435 100644 --- a/internal/services/storage/storage_account_sas_data_source.go +++ b/internal/services/storage/storage_account_sas_data_source.go @@ -133,52 +133,52 @@ func dataSourceStorageAccountSharedAccessSignature() *pluginsdk.Resource { Schema: map[string]*pluginsdk.Schema{ "read": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "write": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "delete": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "list": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "add": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "create": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "update": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "process": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "tag": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, "filter": { Type: pluginsdk.TypeBool, - Required: true, + Optional: true, }, }, }, diff --git a/website/docs/d/storage_account_blob_container_sas.html.markdown b/website/docs/d/storage_account_blob_container_sas.html.markdown index dfd7e805a58d..d995f3d810c6 100644 --- a/website/docs/d/storage_account_blob_container_sas.html.markdown +++ b/website/docs/d/storage_account_blob_container_sas.html.markdown @@ -98,17 +98,21 @@ output "sas_url_query_string" { A `permissions` block contains: -* `read` - Should Read permissions be enabled for this SAS? +* `read` - (Optional) Should Read permissions be enabled for this SAS? +* `add` - (Optional) Should Add permissions be enabled for this SAS? +* `create` - (Optional) Should Create permissions be enabled for this SAS? +* `write` - (Optional) Should Write permissions be enabled for this SAS? +* `delete` - (Optional) Should Delete permissions be enabled for this SAS? +* `delete_version` - (Optional) Should Delete version permissions be enabled for this SAS? +* `list` - (Optional) Should List permissions be enabled for this SAS? +* `tags` - (Optional) Should Tags permissions be enabled for this SAS? +* `find` - (Optional) Should Find permissions be enabled for this SAS? +* `move` - (Optional) Should Move permissions be enabled for this SAS? +* `execute` - (Optional) Should Execute permissions be enabled for this SAS? +* `ownership` - (Optional) Should Ownership permissions be enabled for this SAS? +* `permissions` - (Optional) Should Permissions permissions be enabled for this SAS? +* `set_immutability_policy` - (Optional) Should Set Immutability Policy permissions be enabled for this SAS? -* `add` - Should Add permissions be enabled for this SAS? - -* `create` - Should Create permissions be enabled for this SAS? - -* `write` - Should Write permissions be enabled for this SAS? - -* `delete` - Should Delete permissions be enabled for this SAS? - -* `list` - Should List permissions be enabled for this SAS? Refer to the [SAS creation reference from Azure](https://docs.microsoft.com/rest/api/storageservices/create-service-sas) for additional details on the fields above. diff --git a/website/docs/d/storage_account_sas.html.markdown b/website/docs/d/storage_account_sas.html.markdown index 44a68ad68c37..02ae851544ce 100644 --- a/website/docs/d/storage_account_sas.html.markdown +++ b/website/docs/d/storage_account_sas.html.markdown @@ -118,16 +118,16 @@ A `services` block contains: A `permissions` block contains: -* `read` - Should Read permissions be enabled for this SAS? -* `write` - Should Write permissions be enabled for this SAS? -* `delete` - Should Delete permissions be enabled for this SAS? -* `list` - Should List permissions be enabled for this SAS? -* `add` - Should Add permissions be enabled for this SAS? -* `create` - Should Create permissions be enabled for this SAS? -* `update` - Should Update permissions be enabled for this SAS? -* `process` - Should Process permissions be enabled for this SAS? -* `tag` - Should Get / Set Index Tags permissions be enabled for this SAS? -* `filter` - Should Filter by Index Tags permissions be enabled for this SAS? +* `read` - (Optional) Should Read permissions be enabled for this SAS? +* `write` - (Optional) Should Write permissions be enabled for this SAS? +* `delete` - (Optional) Should Delete permissions be enabled for this SAS? +* `list` - (Optional) Should List permissions be enabled for this SAS? +* `add` - (Optional) Should Add permissions be enabled for this SAS? +* `create` - (Optional) Should Create permissions be enabled for this SAS? +* `update` - (Optional) Should Update permissions be enabled for this SAS? +* `process` - (Optional) Should Process permissions be enabled for this SAS? +* `tag` - (Optional) Should Get / Set Index Tags permissions be enabled for this SAS? +* `filter` - (Optional) Should Filter by Index Tags permissions be enabled for this SAS? Refer to the [SAS creation reference from Azure](https://docs.microsoft.com/rest/api/storageservices/constructing-an-account-sas) for additional details on the fields above. From 6b052f048cc75e4292b87922a6c771a431b6aa5b Mon Sep 17 00:00:00 2001 From: Kilian Decaderincourt Date: Fri, 23 May 2025 16:53:33 +0200 Subject: [PATCH 2/2] docs: mark all properties as required or optional and harmonize formating --- ...unt_blob_container_sas_data_source_test.go | 40 ++++++++-------- ...e_account_blob_container_sas.html.markdown | 23 +++++++-- .../docs/d/storage_account_sas.html.markdown | 47 ++++++++++++++----- 3 files changed, 72 insertions(+), 38 deletions(-) diff --git a/internal/services/storage/storage_account_blob_container_sas_data_source_test.go b/internal/services/storage/storage_account_blob_container_sas_data_source_test.go index ced54deb1f02..7355a61a9873 100644 --- a/internal/services/storage/storage_account_blob_container_sas_data_source_test.go +++ b/internal/services/storage/storage_account_blob_container_sas_data_source_test.go @@ -132,20 +132,20 @@ data "azurerm_storage_account_blob_container_sas" "test" { expiry = "%s" permissions { - read = true - add = true - create = false - write = false - delete = true - delete_version = true - list = true - tags = true - find = true - move = false - execute = false - ownership = true - permissions = true - set_immutability_policy = true + read = true + add = true + create = false + write = false + delete = true + delete_version = true + list = true + tags = true + find = true + move = false + execute = false + ownership = true + permissions = true + set_immutability_policy = true } cache_control = "max-age=5" @@ -194,12 +194,12 @@ data "azurerm_storage_account_blob_container_sas" "test" { expiry = "%s" permissions { - read = true - add = true - create = false - write = false - delete = true - list = true + read = true + add = true + create = false + write = false + delete = true + list = true } cache_control = "max-age=5" diff --git a/website/docs/d/storage_account_blob_container_sas.html.markdown b/website/docs/d/storage_account_blob_container_sas.html.markdown index d995f3d810c6..f60e105e89f9 100644 --- a/website/docs/d/storage_account_blob_container_sas.html.markdown +++ b/website/docs/d/storage_account_blob_container_sas.html.markdown @@ -68,21 +68,21 @@ output "sas_url_query_string" { ## Argument Reference -* `connection_string` - The connection string for the storage account to which this SAS applies. Typically directly from the `primary_connection_string` attribute of a terraform created `azurerm_storage_account` resource. +* `connection_string` - (Required) The connection string for the storage account to which this SAS applies. Typically directly from the `primary_connection_string` attribute of a terraform created `azurerm_storage_account` resource. -* `container_name` - Name of the container. +* `container_name` - (Required) Name of the container. * `https_only` - (Optional) Only permit `https` access. If `false`, both `http` and `https` are permitted. Defaults to `true`. * `ip_address` - (Optional) Single IPv4 address or range (connected with a dash) of IPv4 addresses. -* `start` - The starting time and date of validity of this SAS. Must be a valid ISO-8601 format time/date string. +* `start` - (Required) The starting time and date of validity of this SAS. Must be a valid ISO-8601 format time/date string. -* `expiry` - The expiration time and date of this SAS. Must be a valid ISO-8601 format time/date string. +* `expiry` - (Required) The expiration time and date of this SAS. Must be a valid ISO-8601 format time/date string. -> **NOTE:** The [ISO-8601 Time offset from UTC](https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC) is currently not supported by the service, which will result into 409 error. -* `permissions` - A `permissions` block as defined below. +* `permissions` - (Required) A `permissions` block as defined below. * `cache_control` - (Optional) The `Cache-Control` response header that is sent when this SAS token is used. @@ -99,18 +99,31 @@ output "sas_url_query_string" { A `permissions` block contains: * `read` - (Optional) Should Read permissions be enabled for this SAS? + * `add` - (Optional) Should Add permissions be enabled for this SAS? + * `create` - (Optional) Should Create permissions be enabled for this SAS? + * `write` - (Optional) Should Write permissions be enabled for this SAS? + * `delete` - (Optional) Should Delete permissions be enabled for this SAS? + * `delete_version` - (Optional) Should Delete version permissions be enabled for this SAS? + * `list` - (Optional) Should List permissions be enabled for this SAS? + * `tags` - (Optional) Should Tags permissions be enabled for this SAS? + * `find` - (Optional) Should Find permissions be enabled for this SAS? + * `move` - (Optional) Should Move permissions be enabled for this SAS? + * `execute` - (Optional) Should Execute permissions be enabled for this SAS? + * `ownership` - (Optional) Should Ownership permissions be enabled for this SAS? + * `permissions` - (Optional) Should Permissions permissions be enabled for this SAS? + * `set_immutability_policy` - (Optional) Should Set Immutability Policy permissions be enabled for this SAS? diff --git a/website/docs/d/storage_account_sas.html.markdown b/website/docs/d/storage_account_sas.html.markdown index 02ae851544ce..001b7bfef758 100644 --- a/website/docs/d/storage_account_sas.html.markdown +++ b/website/docs/d/storage_account_sas.html.markdown @@ -78,18 +78,25 @@ output "sas_url_query_string" { ## Argument Reference -* `connection_string` - The connection string for the storage account to which this SAS applies. Typically directly from the `primary_connection_string` attribute of a terraform created `azurerm_storage_account` resource. +* `connection_string` - (Required) The connection string for the storage account to which this SAS applies. Typically directly from the `primary_connection_string` attribute of a terraform created `azurerm_storage_account` resource. + * `https_only` - (Optional) Only permit `https` access. If `false`, both `http` and `https` are permitted. Defaults to `true`. + * `ip_addresses` - (Optional) IP address, or a range of IP addresses, from which to accept requests. When specifying a range, note that the range is inclusive. + * `signed_version` - (Optional) Specifies the signed storage service version to use to authorize requests made with this account SAS. Defaults to `2022-11-02`. -* `resource_types` - A `resource_types` block as defined below. -* `services` - A `services` block as defined below. -* `start` - The starting time and date of validity of this SAS. Must be a valid ISO-8601 format time/date string. -* `expiry` - The expiration time and date of this SAS. Must be a valid ISO-8601 format time/date string. + +* `resource_types` - (Required) A `resource_types` block as defined below. + +* `services` - (Required) A `services` block as defined below. + +* `start` - (Required) The starting time and date of validity of this SAS. Must be a valid ISO-8601 format time/date string. + +* `expiry` - (Required) The expiration time and date of this SAS. Must be a valid ISO-8601 format time/date string. -> **NOTE:** The [ISO-8601 Time offset from UTC](https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC) is currently not supported by the service, which will result into 409 error. -* `permissions` - A `permissions` block as defined below. +* `permissions` - (Required) A `permissions` block as defined below. --- @@ -99,9 +106,11 @@ larger scope (affecting all sub-resources) than `object`. A `resource_types` block contains: -* `service` - Should permission be granted to the entire service? -* `container` - Should permission be granted to the container? -* `object` - Should permission be granted only to a specific object? +* `service` - (Required) Should permission be granted to the entire service? + +* `container` - (Required) Should permission be granted to the container? + +* `object` - (Required) Should permission be granted only to a specific object? --- @@ -109,24 +118,36 @@ A `resource_types` block contains: A `services` block contains: -* `blob` - Should permission be granted to `blob` services within this storage account? -* `queue` - Should permission be granted to `queue` services within this storage account? -* `table` - Should permission be granted to `table` services within this storage account? -* `file` - Should permission be granted to `file` services within this storage account? +* `blob` - (Required) Should permission be granted to `blob` services within this storage account? + +* `queue` - (Required) Should permission be granted to `queue` services within this storage account? + +* `table` - (Required) Should permission be granted to `table` services within this storage account? + +* `file` - (Required) Should permission be granted to `file` services within this storage account? --- A `permissions` block contains: * `read` - (Optional) Should Read permissions be enabled for this SAS? + * `write` - (Optional) Should Write permissions be enabled for this SAS? + * `delete` - (Optional) Should Delete permissions be enabled for this SAS? + * `list` - (Optional) Should List permissions be enabled for this SAS? + * `add` - (Optional) Should Add permissions be enabled for this SAS? + * `create` - (Optional) Should Create permissions be enabled for this SAS? + * `update` - (Optional) Should Update permissions be enabled for this SAS? + * `process` - (Optional) Should Process permissions be enabled for this SAS? + * `tag` - (Optional) Should Get / Set Index Tags permissions be enabled for this SAS? + * `filter` - (Optional) Should Filter by Index Tags permissions be enabled for this SAS? Refer to the [SAS creation reference from Azure](https://docs.microsoft.com/rest/api/storageservices/constructing-an-account-sas)