From 2228dcaf7576fab9f04e02416a83eef8a4f26f03 Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Mon, 28 Jan 2019 22:23:58 -0800 Subject: [PATCH 1/8] Add host attribute for endpoints of blob, table, queue, and file. --- azurerm/resource_arm_storage_account.go | 98 +++++++++++++++++++- website/docs/d/storage_account.html.markdown | 14 +++ 2 files changed, 108 insertions(+), 4 deletions(-) diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index 0272d60030b4..24c29f0e900f 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -2,6 +2,7 @@ package azurerm import ( "fmt" + "github.com/hashicorp/go-getter/helper/url" "log" "regexp" "strings" @@ -195,37 +196,72 @@ func resourceArmStorageAccount() *schema.Resource { Computed: true, }, + "primary_blob_host": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_blob_endpoint": { Type: schema.TypeString, Computed: true, }, + "secondary_blob_host": { + Type: schema.TypeString, + Computed: true, + }, + "primary_queue_endpoint": { Type: schema.TypeString, Computed: true, }, + "primary_queue_host": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_queue_endpoint": { Type: schema.TypeString, Computed: true, }, + "secondary_queue_host": { + Type: schema.TypeString, + Computed: true, + }, + "primary_table_endpoint": { Type: schema.TypeString, Computed: true, }, + "primary_table_host": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_table_endpoint": { Type: schema.TypeString, Computed: true, }, + "secondary_table_host": { + Type: schema.TypeString, + Computed: true, + }, + // NOTE: The API does not appear to expose a secondary file endpoint "primary_file_endpoint": { Type: schema.TypeString, Computed: true, }, + "primary_file_host": { + Type: schema.TypeString, + Computed: true, + }, + "primary_access_key": { Type: schema.TypeString, Sensitive: true, @@ -663,10 +699,45 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err } if endpoints := props.PrimaryEndpoints; endpoints != nil { - d.Set("primary_blob_endpoint", endpoints.Blob) - d.Set("primary_queue_endpoint", endpoints.Queue) - d.Set("primary_table_endpoint", endpoints.Table) - d.Set("primary_file_endpoint", endpoints.File) + if v := endpoints.Blob; v != nil { + d.Set("primary_blob_endpoint", endpoints.Blob) + if u, err := url.Parse(*v); err != nil { + d.Set("primary_blob_host", u.Host) + } + } else { + d.Set("primary_blob_endpoint", "") + d.Set("primary_blob_host", "") + } + + if v := endpoints.Queue; v != nil { + d.Set("primary_queue_endpoint", endpoints.Queue) + if u, err := url.Parse(*v); err != nil { + d.Set("primary_queue_host", u.Host) + } + } else { + d.Set("primary_queue_endpoint", "") + d.Set("primary_queue_host", "") + } + + if v := endpoints.Table; v != nil { + d.Set("primary_table_endpoint", endpoints.Table) + if u, err := url.Parse(*v); err != nil { + d.Set("primary_table_host", u.Host) + } + } else { + d.Set("primary_table_endpoint", "") + d.Set("primary_table_host", "") + } + + if v := endpoints.File; v != nil { + d.Set("primary_file_endpoint", endpoints.File) + if u, err := url.Parse(*v); err != nil { + d.Set("primary_file_host", u.Host) + } + } else { + d.Set("primary_file_endpoint", "") + d.Set("primary_file_host", "") + } pscs := fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s", *endpoints.Blob, *resp.Name, *accessKeys[0].Value) @@ -676,24 +747,43 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err if endpoints := props.SecondaryEndpoints; endpoints != nil { if blob := endpoints.Blob; blob != nil { d.Set("secondary_blob_endpoint", blob) + if v := endpoints.Blob; v != nil { + if u, err := url.Parse(*v); err != nil { + d.Set("secondary_blob_host", u.Host) + } + } + sscs := fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s", *blob, *resp.Name, *accessKeys[1].Value) d.Set("secondary_blob_connection_string", sscs) } else { d.Set("secondary_blob_endpoint", "") + d.Set("secondary_blob_host", "") d.Set("secondary_blob_connection_string", "") } if endpoints.Queue != nil { d.Set("secondary_queue_endpoint", endpoints.Queue) + if v := endpoints.Queue; v != nil { + if u, err := url.Parse(*v); err != nil { + d.Set("secondary_queue_host", u.Host) + } + } } else { d.Set("secondary_queue_endpoint", "") + d.Set("secondary_queue_host", "") } if endpoints.Table != nil { d.Set("secondary_table_endpoint", endpoints.Table) + if v := endpoints.Table; v != nil { + if u, err := url.Parse(*v); err != nil { + d.Set("secondary_table_host", u.Host) + } + } } else { d.Set("secondary_table_endpoint", "") + d.Set("secondary_table_host", "") } } diff --git a/website/docs/d/storage_account.html.markdown b/website/docs/d/storage_account.html.markdown index 731c1a03a8ed..a5094c2c52f6 100644 --- a/website/docs/d/storage_account.html.markdown +++ b/website/docs/d/storage_account.html.markdown @@ -64,18 +64,32 @@ output "storage_account_tier" { * `primary_blob_endpoint` - The endpoint URL for blob storage in the primary location. +* `primary_blob_host` - The host for blob storage in the primary location. + * `secondary_blob_endpoint` - The endpoint URL for blob storage in the secondary location. +* `secondary_blob_host` - The host for blob storage in the secondary location. + * `primary_queue_endpoint` - The endpoint URL for queue storage in the primary location. +* `primary_queue_host` - The host for queue storage in the primary location. + * `secondary_queue_endpoint` - The endpoint URL for queue storage in the secondary location. +* `secondary_queue_host` - The host for queue storage in the secondary location. + * `primary_table_endpoint` - The endpoint URL for table storage in the primary location. +* `primary_table_host` - The host for table storage in the primary location. + * `secondary_table_endpoint` - The endpoint URL for table storage in the secondary location. +* `secondary_table_host` - The host for table storage in the secondary location. + * `primary_file_endpoint` - The endpoint URL for file storage in the primary location. +* `primary_file_host` - The host for file storage in the primary location. + * `primary_access_key` - The primary access key for the Storage Account. * `secondary_access_key` - The secondary access key for the Storage Account. From 839c856254cd611550c044c54f01da5b0920623f Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Mon, 28 Jan 2019 23:14:17 -0800 Subject: [PATCH 2/8] Fix: goimport issue. --- azurerm/resource_arm_storage_account.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index 24c29f0e900f..dc88fcb008e7 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -2,12 +2,12 @@ package azurerm import ( "fmt" - "github.com/hashicorp/go-getter/helper/url" "log" "regexp" "strings" "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage" + "github.com/hashicorp/go-getter/helper/url" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" From 253f3e0bab443e885b5e643923e63abf0de9ffdf Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Wed, 30 Jan 2019 17:53:42 -0800 Subject: [PATCH 3/8] Update the code and documentation to address comments in PR. --- azurerm/data_source_storage_account.go | 35 +--- azurerm/resource_arm_storage_account.go | 210 +++++++++++-------- website/docs/d/storage_account.html.markdown | 14 +- website/docs/r/storage_account.html.markdown | 43 +++- 4 files changed, 173 insertions(+), 129 deletions(-) diff --git a/azurerm/data_source_storage_account.go b/azurerm/data_source_storage_account.go index c205d36fbba0..8d5102b7de2b 100644 --- a/azurerm/data_source_storage_account.go +++ b/azurerm/data_source_storage_account.go @@ -234,39 +234,12 @@ func dataSourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) e d.Set("secondary_connection_string", scs) } - if endpoints := props.PrimaryEndpoints; endpoints != nil { - d.Set("primary_blob_endpoint", endpoints.Blob) - d.Set("primary_queue_endpoint", endpoints.Queue) - d.Set("primary_table_endpoint", endpoints.Table) - d.Set("primary_file_endpoint", endpoints.File) - - pscs := fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s", - *endpoints.Blob, *resp.Name, *accessKeys[0].Value) - d.Set("primary_blob_connection_string", pscs) + if err := flattenAzureRmStorageAccountPrimaryEndpoints(d, props.PrimaryEndpoints, resp.Name, accessKeys[0].Value); err != nil { + return fmt.Errorf("error setting primary endpoints and hosts for blob, queue, table and file: %+v", err) } - if endpoints := props.SecondaryEndpoints; endpoints != nil { - if blob := endpoints.Blob; blob != nil { - d.Set("secondary_blob_endpoint", blob) - sscs := fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s", - *blob, *resp.Name, *accessKeys[1].Value) - d.Set("secondary_blob_connection_string", sscs) - } else { - d.Set("secondary_blob_endpoint", "") - d.Set("secondary_blob_connection_string", "") - } - - if endpoints.Queue != nil { - d.Set("secondary_queue_endpoint", endpoints.Queue) - } else { - d.Set("secondary_queue_endpoint", "") - } - - if endpoints.Table != nil { - d.Set("secondary_table_endpoint", endpoints.Table) - } else { - d.Set("secondary_table_endpoint", "") - } + if err := flattenAzureRmStorageAccountSecondaryEndpoints(d, props.SecondaryEndpoints, resp.Name, accessKeys[1].Value); err != nil { + return fmt.Errorf("error setting secondary endpoints and hosts for blob, queue, table: %+v", err) } } diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index dc88fcb008e7..c99bae757ba8 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -698,93 +698,12 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err d.Set("secondary_connection_string", scs) } - if endpoints := props.PrimaryEndpoints; endpoints != nil { - if v := endpoints.Blob; v != nil { - d.Set("primary_blob_endpoint", endpoints.Blob) - if u, err := url.Parse(*v); err != nil { - d.Set("primary_blob_host", u.Host) - } - } else { - d.Set("primary_blob_endpoint", "") - d.Set("primary_blob_host", "") - } - - if v := endpoints.Queue; v != nil { - d.Set("primary_queue_endpoint", endpoints.Queue) - if u, err := url.Parse(*v); err != nil { - d.Set("primary_queue_host", u.Host) - } - } else { - d.Set("primary_queue_endpoint", "") - d.Set("primary_queue_host", "") - } - - if v := endpoints.Table; v != nil { - d.Set("primary_table_endpoint", endpoints.Table) - if u, err := url.Parse(*v); err != nil { - d.Set("primary_table_host", u.Host) - } - } else { - d.Set("primary_table_endpoint", "") - d.Set("primary_table_host", "") - } - - if v := endpoints.File; v != nil { - d.Set("primary_file_endpoint", endpoints.File) - if u, err := url.Parse(*v); err != nil { - d.Set("primary_file_host", u.Host) - } - } else { - d.Set("primary_file_endpoint", "") - d.Set("primary_file_host", "") - } - - pscs := fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s", - *endpoints.Blob, *resp.Name, *accessKeys[0].Value) - d.Set("primary_blob_connection_string", pscs) + if err := flattenAzureRmStorageAccountPrimaryEndpoints(d, props.PrimaryEndpoints, resp.Name, accessKeys[0].Value); err != nil { + return fmt.Errorf("error setting primary endpoints and hosts for blob, queue, table and file: %+v", err) } - if endpoints := props.SecondaryEndpoints; endpoints != nil { - if blob := endpoints.Blob; blob != nil { - d.Set("secondary_blob_endpoint", blob) - if v := endpoints.Blob; v != nil { - if u, err := url.Parse(*v); err != nil { - d.Set("secondary_blob_host", u.Host) - } - } - - sscs := fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s", - *blob, *resp.Name, *accessKeys[1].Value) - d.Set("secondary_blob_connection_string", sscs) - } else { - d.Set("secondary_blob_endpoint", "") - d.Set("secondary_blob_host", "") - d.Set("secondary_blob_connection_string", "") - } - - if endpoints.Queue != nil { - d.Set("secondary_queue_endpoint", endpoints.Queue) - if v := endpoints.Queue; v != nil { - if u, err := url.Parse(*v); err != nil { - d.Set("secondary_queue_host", u.Host) - } - } - } else { - d.Set("secondary_queue_endpoint", "") - d.Set("secondary_queue_host", "") - } - - if endpoints.Table != nil { - d.Set("secondary_table_endpoint", endpoints.Table) - if v := endpoints.Table; v != nil { - if u, err := url.Parse(*v); err != nil { - d.Set("secondary_table_host", u.Host) - } - } - } else { - d.Set("secondary_table_endpoint", "") - d.Set("secondary_table_host", "") - } + if err := flattenAzureRmStorageAccountSecondaryEndpoints(d, props.SecondaryEndpoints, resp.Name, accessKeys[1].Value); err != nil { + return fmt.Errorf("error setting secondary endpoints and hosts for blob, queue, table: %+v", err) } networkRules := props.NetworkRuleSet @@ -1053,3 +972,124 @@ func flattenAzureRmStorageAccountIdentity(identity *storage.Identity) []interfac return []interface{}{result} } + +func flattenAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primary *storage.Endpoints, acctName *string, acctKey *string) error { + if primary == nil { + return fmt.Errorf("primary endpoints should not be empty") + } + + if acctName == nil { + return fmt.Errorf("account name should not be nil") + } + + if acctKey == nil { + return fmt.Errorf("account key should not be nil") + } + + var blobEndpoint, blobHost, blobConnectionStr string + if v := primary.Blob; v != nil { + blobEndpoint = *v + + if u, err := url.Parse(*v); err != nil { + blobHost = u.Host + } else { + return fmt.Errorf("invalid blob endpoint for parsing: %q", *v) + } + + blobConnectionStr = fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s", blobEndpoint, *acctName, *acctKey) + } + d.Set("primary_blob_endpoint", blobEndpoint) + d.Set("primary_blob_host", blobHost) + d.Set("primary_blob_connection_string", blobConnectionStr) + + var queueEndpoint, queueHost string + if v := primary.Queue; v != nil { + queueEndpoint = *v + + if u, err := url.Parse(*v); err != nil { + queueHost = u.Host + } else { + return fmt.Errorf("invalid queue endpoint for parsing: %q", *v) + } + } + d.Set("primary_queue_endpoint", queueEndpoint) + d.Set("primary_queue_host", queueHost) + + var tableEndpoint, tableHost string + if v := primary.Table; v != nil { + tableEndpoint = *v + + if u, err := url.Parse(*v); err != nil { + tableHost = u.Host + } else { + return fmt.Errorf("invalid table endpoint for parsing: %q", *v) + } + } + d.Set("primary_table_endpoint", tableEndpoint) + d.Set("primary_table_host", tableHost) + + var fileEndpoint, fileHost string + if v := primary.File; v != nil { + fileEndpoint = *v + + if u, err := url.Parse(*v); err != nil { + fileHost = u.Host + } else { + return fmt.Errorf("invalid file endpoint for parsing: %q", *v) + } + } + d.Set("primary_file_endpoint", fileEndpoint) + d.Set("primary_file_host", fileHost) + + return nil +} + +func flattenAzureRmStorageAccountSecondaryEndpoints(d *schema.ResourceData, secondary *storage.Endpoints, acctName *string, acctKey *string) error { + if secondary == nil { + return fmt.Errorf("secondary Endpoints should not be empty") + } + + var blobEndpoint, blobHost, blobConnectionStr string + if v := secondary.Blob; v != nil { + blobEndpoint = *v + + if u, err := url.Parse(*v); err != nil { + blobHost = u.Host + } else { + return fmt.Errorf("invalid blob endpoint for parsing: %q", *v) + } + + blobConnectionStr = fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s", blobEndpoint, *acctName, *acctKey) + } + d.Set("secondary_blob_endpoint", blobEndpoint) + d.Set("secondary_blob_host", blobHost) + d.Set("secondary_blob_connection_string", blobConnectionStr) + + var queueEndpoint, queueHost string + if v := secondary.Queue; v != nil { + queueEndpoint = *v + + if u, err := url.Parse(*v); err != nil { + queueHost = u.Host + } else { + return fmt.Errorf("invalid queue endpoint for parsing: %q", *v) + } + } + d.Set("secondary_queue_endpoint", queueEndpoint) + d.Set("secondary_queue_host", queueHost) + + var tableEndpoint, tableHost string + if v := secondary.Table; v != nil { + tableEndpoint = *v + + if u, err := url.Parse(*v); err != nil { + tableHost = u.Host + } else { + return fmt.Errorf("invalid table endpoint for parsing: %q", *v) + } + } + d.Set("secondary_table_endpoint", tableEndpoint) + d.Set("secondary_table_host", tableHost) + + return nil +} diff --git a/website/docs/d/storage_account.html.markdown b/website/docs/d/storage_account.html.markdown index a5094c2c52f6..254756842579 100644 --- a/website/docs/d/storage_account.html.markdown +++ b/website/docs/d/storage_account.html.markdown @@ -64,31 +64,31 @@ output "storage_account_tier" { * `primary_blob_endpoint` - The endpoint URL for blob storage in the primary location. -* `primary_blob_host` - The host for blob storage in the primary location. +* `primary_blob_host` - The `host` or `host:port` for blob storage in the primary location. * `secondary_blob_endpoint` - The endpoint URL for blob storage in the secondary location. -* `secondary_blob_host` - The host for blob storage in the secondary location. +* `secondary_blob_host` - The `host` or `host:port` for blob storage in the secondary location. * `primary_queue_endpoint` - The endpoint URL for queue storage in the primary location. -* `primary_queue_host` - The host for queue storage in the primary location. +* `primary_queue_host` - The `host` or `host:port` for queue storage in the primary location. * `secondary_queue_endpoint` - The endpoint URL for queue storage in the secondary location. -* `secondary_queue_host` - The host for queue storage in the secondary location. +* `secondary_queue_host` - The `host` or `host:port` for queue storage in the secondary location. * `primary_table_endpoint` - The endpoint URL for table storage in the primary location. -* `primary_table_host` - The host for table storage in the primary location. +* `primary_table_host` - The `host` or `host:port` for table storage in the primary location. * `secondary_table_endpoint` - The endpoint URL for table storage in the secondary location. -* `secondary_table_host` - The host for table storage in the secondary location. +* `secondary_table_host` - The `host` or `host:port` for table storage in the secondary location. * `primary_file_endpoint` - The endpoint URL for file storage in the primary location. -* `primary_file_host` - The host for file storage in the primary location. +* `primary_file_host` - The `host` or `host:port` for file storage in the primary location. * `primary_access_key` - The primary access key for the Storage Account. diff --git a/website/docs/r/storage_account.html.markdown b/website/docs/r/storage_account.html.markdown index e3fb7779818d..4d44fd812f75 100644 --- a/website/docs/r/storage_account.html.markdown +++ b/website/docs/r/storage_account.html.markdown @@ -1,3 +1,4 @@ + --- layout: "azurerm" page_title: "Azure Resource Manager: azurerm_storage_account" @@ -145,21 +146,51 @@ any combination of `Logging`, `Metrics`, `AzureServices`, or `None`. The following attributes are exported in addition to the arguments listed above: * `id` - The storage account Resource ID. + * `primary_location` - The primary location of the storage account. + * `secondary_location` - The secondary location of the storage account. + * `primary_blob_endpoint` - The endpoint URL for blob storage in the primary location. + +* `primary_blob_host` - The `host` or `host:port` for blob storage in the primary location. + * `secondary_blob_endpoint` - The endpoint URL for blob storage in the secondary location. + +* `secondary_blob_host` - The `host` or `host:port`for blob storage in the secondary location. + * `primary_queue_endpoint` - The endpoint URL for queue storage in the primary location. + +* `primary_queue_host` - The `host` or `host:port`for queue storage in the primary location. + * `secondary_queue_endpoint` - The endpoint URL for queue storage in the secondary location. + +* `secondary_queue_host` - The `host` or `host:port`for queue storage in the secondary location. + * `primary_table_endpoint` - The endpoint URL for table storage in the primary location. + +* `primary_table_host` - The `host` or `host:port`for table storage in the primary location. + * `secondary_table_endpoint` - The endpoint URL for table storage in the secondary location. + +* `secondary_table_host` - The `host` or `host:port`for table storage in the secondary location. + * `primary_file_endpoint` - The endpoint URL for file storage in the primary location. -* `primary_access_key` - The primary access key for the storage account -* `secondary_access_key` - The secondary access key for the storage account -* `primary_connection_string` - The connection string associated with the primary location -* `secondary_connection_string` - The connection string associated with the secondary location -* `primary_blob_connection_string` - The connection string associated with the primary blob location -* `secondary_blob_connection_string` - The connection string associated with the secondary blob location + +* `primary_file_host` - The `host` or `host:port`for file storage in the primary location. + +* `primary_access_key` - The primary access key for the storage account. + +* `secondary_access_key` - The secondary access key for the storage account. + +* `primary_connection_string` - The connection string associated with the primary location. + +* `secondary_connection_string` - The connection string associated with the secondary location. + +* `primary_blob_connection_string` - The connection string associated with the primary blob location. + +* `secondary_blob_connection_string` - The connection string associated with the secondary blob location. + * `identity` - An `identity` block as defined below, which contains the Identity information for this Storage Account. --- From 2092c797bf08dae1a89a93d5fe4cea9c74590be0 Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Wed, 30 Jan 2019 17:57:13 -0800 Subject: [PATCH 4/8] add the schema for host in data source of sa. --- azurerm/data_source_storage_account.go | 35 ++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/azurerm/data_source_storage_account.go b/azurerm/data_source_storage_account.go index 8d5102b7de2b..dab36d733ded 100644 --- a/azurerm/data_source_storage_account.go +++ b/azurerm/data_source_storage_account.go @@ -91,37 +91,72 @@ func dataSourceArmStorageAccount() *schema.Resource { Computed: true, }, + "primary_blob_host": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_blob_endpoint": { Type: schema.TypeString, Computed: true, }, + "secondary_blob_host": { + Type: schema.TypeString, + Computed: true, + }, + "primary_queue_endpoint": { Type: schema.TypeString, Computed: true, }, + "primary_queue_host": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_queue_endpoint": { Type: schema.TypeString, Computed: true, }, + "secondary_queue_host": { + Type: schema.TypeString, + Computed: true, + }, + "primary_table_endpoint": { Type: schema.TypeString, Computed: true, }, + "primary_table_host": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_table_endpoint": { Type: schema.TypeString, Computed: true, }, + "secondary_table_host": { + Type: schema.TypeString, + Computed: true, + }, + // NOTE: The API does not appear to expose a secondary file endpoint "primary_file_endpoint": { Type: schema.TypeString, Computed: true, }, + "primary_file_host": { + Type: schema.TypeString, + Computed: true, + }, + "primary_access_key": { Type: schema.TypeString, Computed: true, From 7b817ddb75477e3cd0b93b23d3a4bb64d1ec310e Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Thu, 31 Jan 2019 00:42:37 -0800 Subject: [PATCH 5/8] Fix the error check mistake. --- azurerm/resource_arm_storage_account.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index c99bae757ba8..b7d5e7227699 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -990,7 +990,7 @@ func flattenAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primar if v := primary.Blob; v != nil { blobEndpoint = *v - if u, err := url.Parse(*v); err != nil { + if u, err := url.Parse(*v); err == nil { blobHost = u.Host } else { return fmt.Errorf("invalid blob endpoint for parsing: %q", *v) @@ -1006,7 +1006,7 @@ func flattenAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primar if v := primary.Queue; v != nil { queueEndpoint = *v - if u, err := url.Parse(*v); err != nil { + if u, err := url.Parse(*v); err == nil { queueHost = u.Host } else { return fmt.Errorf("invalid queue endpoint for parsing: %q", *v) @@ -1019,7 +1019,7 @@ func flattenAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primar if v := primary.Table; v != nil { tableEndpoint = *v - if u, err := url.Parse(*v); err != nil { + if u, err := url.Parse(*v); err == nil { tableHost = u.Host } else { return fmt.Errorf("invalid table endpoint for parsing: %q", *v) @@ -1032,7 +1032,7 @@ func flattenAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primar if v := primary.File; v != nil { fileEndpoint = *v - if u, err := url.Parse(*v); err != nil { + if u, err := url.Parse(*v); err == nil { fileHost = u.Host } else { return fmt.Errorf("invalid file endpoint for parsing: %q", *v) @@ -1046,14 +1046,14 @@ func flattenAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primar func flattenAzureRmStorageAccountSecondaryEndpoints(d *schema.ResourceData, secondary *storage.Endpoints, acctName *string, acctKey *string) error { if secondary == nil { - return fmt.Errorf("secondary Endpoints should not be empty") + return nil } var blobEndpoint, blobHost, blobConnectionStr string if v := secondary.Blob; v != nil { blobEndpoint = *v - if u, err := url.Parse(*v); err != nil { + if u, err := url.Parse(*v); err == nil { blobHost = u.Host } else { return fmt.Errorf("invalid blob endpoint for parsing: %q", *v) @@ -1069,7 +1069,7 @@ func flattenAzureRmStorageAccountSecondaryEndpoints(d *schema.ResourceData, seco if v := secondary.Queue; v != nil { queueEndpoint = *v - if u, err := url.Parse(*v); err != nil { + if u, err := url.Parse(*v); err == nil { queueHost = u.Host } else { return fmt.Errorf("invalid queue endpoint for parsing: %q", *v) @@ -1082,7 +1082,7 @@ func flattenAzureRmStorageAccountSecondaryEndpoints(d *schema.ResourceData, seco if v := secondary.Table; v != nil { tableEndpoint = *v - if u, err := url.Parse(*v); err != nil { + if u, err := url.Parse(*v); err == nil { tableHost = u.Host } else { return fmt.Errorf("invalid table endpoint for parsing: %q", *v) From 1b6fd9ce06b144e756506ac3b8027aca3b0a50bd Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Tue, 19 Feb 2019 15:05:58 +0800 Subject: [PATCH 6/8] Update the code to address comments in PR. --- azurerm/data_source_storage_account.go | 16 +++- azurerm/resource_arm_storage_account.go | 119 ++++++++++++++---------- 2 files changed, 83 insertions(+), 52 deletions(-) diff --git a/azurerm/data_source_storage_account.go b/azurerm/data_source_storage_account.go index dab36d733ded..dfbb8e2906b7 100644 --- a/azurerm/data_source_storage_account.go +++ b/azurerm/data_source_storage_account.go @@ -269,13 +269,25 @@ func dataSourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) e d.Set("secondary_connection_string", scs) } - if err := flattenAzureRmStorageAccountPrimaryEndpoints(d, props.PrimaryEndpoints, resp.Name, accessKeys[0].Value); err != nil { + if err := flattenAndSetAzureRmStorageAccountPrimaryEndpoints(d, props.PrimaryEndpoints); err != nil { return fmt.Errorf("error setting primary endpoints and hosts for blob, queue, table and file: %+v", err) } - if err := flattenAzureRmStorageAccountSecondaryEndpoints(d, props.SecondaryEndpoints, resp.Name, accessKeys[1].Value); err != nil { + var primaryBlobConnectStr string + if v := props.PrimaryEndpoints; v != nil { + primaryBlobConnectStr = getBlobConnectionString(v.Blob, resp.Name, accessKeys[0].Value) + } + d.Set("primary_blob_connection_string", primaryBlobConnectStr) + + if err := flattenAndSetAzureRmStorageAccountSecondaryEndpoints(d, props.SecondaryEndpoints); err != nil { return fmt.Errorf("error setting secondary endpoints and hosts for blob, queue, table: %+v", err) } + + var secondaryBlobConnectStr string + if v := props.SecondaryEndpoints; v != nil { + secondaryBlobConnectStr = getBlobConnectionString(v.Blob, resp.Name, accessKeys[1].Value) + } + d.Set("secondary_blob_connection_string", secondaryBlobConnectStr) } d.Set("primary_access_key", accessKeys[0].Value) diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index b7d5e7227699..bff5a59f89ff 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -698,14 +698,26 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err d.Set("secondary_connection_string", scs) } - if err := flattenAzureRmStorageAccountPrimaryEndpoints(d, props.PrimaryEndpoints, resp.Name, accessKeys[0].Value); err != nil { + if err := flattenAndSetAzureRmStorageAccountPrimaryEndpoints(d, props.PrimaryEndpoints); err != nil { return fmt.Errorf("error setting primary endpoints and hosts for blob, queue, table and file: %+v", err) } - if err := flattenAzureRmStorageAccountSecondaryEndpoints(d, props.SecondaryEndpoints, resp.Name, accessKeys[1].Value); err != nil { + var primaryBlobConnectStr string + if v := props.PrimaryEndpoints; v != nil { + primaryBlobConnectStr = getBlobConnectionString(v.Blob, resp.Name, accessKeys[0].Value) + } + d.Set("primary_blob_connection_string", primaryBlobConnectStr) + + if err := flattenAndSetAzureRmStorageAccountSecondaryEndpoints(d, props.SecondaryEndpoints); err != nil { return fmt.Errorf("error setting secondary endpoints and hosts for blob, queue, table: %+v", err) } + var secondaryBlobConnectStr string + if v := props.SecondaryEndpoints; v != nil { + secondaryBlobConnectStr = getBlobConnectionString(v.Blob, resp.Name, accessKeys[1].Value) + } + d.Set("secondary_blob_connection_string", secondaryBlobConnectStr) + networkRules := props.NetworkRuleSet if networkRules != nil { if err := d.Set("network_rules", flattenStorageAccountNetworkRules(networkRules)); err != nil { @@ -973,44 +985,52 @@ func flattenAzureRmStorageAccountIdentity(identity *storage.Identity) []interfac return []interface{}{result} } -func flattenAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primary *storage.Endpoints, acctName *string, acctKey *string) error { - if primary == nil { - return fmt.Errorf("primary endpoints should not be empty") +func getBlobConnectionString(blobEndpoint *string, acctName *string, acctKey *string) string { + var endpoint string + if blobEndpoint != nil { + endpoint = *blobEndpoint + } + + var name string + if acctName != nil { + name = *acctName } - if acctName == nil { - return fmt.Errorf("account name should not be nil") + var key string + if acctKey != nil { + key = *acctKey } - if acctKey == nil { - return fmt.Errorf("account key should not be nil") + return fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s", endpoint, name, key) +} + +func flattenAndSetAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primary *storage.Endpoints) error { + if primary == nil { + return fmt.Errorf("primary endpoints should not be empty") } - var blobEndpoint, blobHost, blobConnectionStr string + var blobEndpoint, blobHost string if v := primary.Blob; v != nil { blobEndpoint = *v - if u, err := url.Parse(*v); err == nil { - blobHost = u.Host - } else { + u, err := url.Parse(*v) + if err != nil { return fmt.Errorf("invalid blob endpoint for parsing: %q", *v) } - - blobConnectionStr = fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s", blobEndpoint, *acctName, *acctKey) + blobHost = u.Host } d.Set("primary_blob_endpoint", blobEndpoint) d.Set("primary_blob_host", blobHost) - d.Set("primary_blob_connection_string", blobConnectionStr) var queueEndpoint, queueHost string if v := primary.Queue; v != nil { queueEndpoint = *v - if u, err := url.Parse(*v); err == nil { - queueHost = u.Host - } else { + u, err := url.Parse(*v) + if err != nil { return fmt.Errorf("invalid queue endpoint for parsing: %q", *v) } + queueHost = u.Host } d.Set("primary_queue_endpoint", queueEndpoint) d.Set("primary_queue_host", queueHost) @@ -1019,11 +1039,11 @@ func flattenAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primar if v := primary.Table; v != nil { tableEndpoint = *v - if u, err := url.Parse(*v); err == nil { - tableHost = u.Host - } else { + u, err := url.Parse(*v) + if err != nil { return fmt.Errorf("invalid table endpoint for parsing: %q", *v) } + tableHost = u.Host } d.Set("primary_table_endpoint", tableEndpoint) d.Set("primary_table_host", tableHost) @@ -1032,11 +1052,11 @@ func flattenAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primar if v := primary.File; v != nil { fileEndpoint = *v - if u, err := url.Parse(*v); err == nil { - fileHost = u.Host - } else { + u, err := url.Parse(*v) + if err != nil { return fmt.Errorf("invalid file endpoint for parsing: %q", *v) } + fileHost = u.Host } d.Set("primary_file_endpoint", fileEndpoint) d.Set("primary_file_host", fileHost) @@ -1044,48 +1064,47 @@ func flattenAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primar return nil } -func flattenAzureRmStorageAccountSecondaryEndpoints(d *schema.ResourceData, secondary *storage.Endpoints, acctName *string, acctKey *string) error { - if secondary == nil { - return nil - } - - var blobEndpoint, blobHost, blobConnectionStr string - if v := secondary.Blob; v != nil { - blobEndpoint = *v +func flattenAndSetAzureRmStorageAccountSecondaryEndpoints(d *schema.ResourceData, secondary *storage.Endpoints) error { + var blobEndpoint, blobHost string + if secondary != nil { + if v := secondary.Blob; v != nil { + blobEndpoint = *v - if u, err := url.Parse(*v); err == nil { - blobHost = u.Host - } else { - return fmt.Errorf("invalid blob endpoint for parsing: %q", *v) + if u, err := url.Parse(*v); err == nil { + blobHost = u.Host + } else { + return fmt.Errorf("invalid blob endpoint for parsing: %q", *v) + } } - - blobConnectionStr = fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s", blobEndpoint, *acctName, *acctKey) } d.Set("secondary_blob_endpoint", blobEndpoint) d.Set("secondary_blob_host", blobHost) - d.Set("secondary_blob_connection_string", blobConnectionStr) var queueEndpoint, queueHost string - if v := secondary.Queue; v != nil { - queueEndpoint = *v + if secondary != nil { + if v := secondary.Queue; v != nil { + queueEndpoint = *v - if u, err := url.Parse(*v); err == nil { + u, err := url.Parse(*v) + if err != nil { + return fmt.Errorf("invalid queue endpoint for parsing: %q", *v) + } queueHost = u.Host - } else { - return fmt.Errorf("invalid queue endpoint for parsing: %q", *v) } } d.Set("secondary_queue_endpoint", queueEndpoint) d.Set("secondary_queue_host", queueHost) var tableEndpoint, tableHost string - if v := secondary.Table; v != nil { - tableEndpoint = *v + if secondary != nil { + if v := secondary.Table; v != nil { + tableEndpoint = *v - if u, err := url.Parse(*v); err == nil { + u, err := url.Parse(*v) + if err != nil { + return fmt.Errorf("invalid table endpoint for parsing: %q", *v) + } tableHost = u.Host - } else { - return fmt.Errorf("invalid table endpoint for parsing: %q", *v) } } d.Set("secondary_table_endpoint", tableEndpoint) From 2476263826c945338619c06db7d310848bc5f17c Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Tue, 19 Feb 2019 17:02:43 +0800 Subject: [PATCH 7/8] Set empty value for primary endpoints. --- azurerm/resource_arm_storage_account.go | 64 ++++++++++++++----------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index bff5a59f89ff..4718db51573f 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -1005,62 +1005,70 @@ func getBlobConnectionString(blobEndpoint *string, acctName *string, acctKey *st } func flattenAndSetAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primary *storage.Endpoints) error { - if primary == nil { - return fmt.Errorf("primary endpoints should not be empty") - } - var blobEndpoint, blobHost string - if v := primary.Blob; v != nil { - blobEndpoint = *v + if primary != nil { + if v := primary.Blob; v != nil { + blobEndpoint = *v - u, err := url.Parse(*v) - if err != nil { - return fmt.Errorf("invalid blob endpoint for parsing: %q", *v) + u, err := url.Parse(*v) + if err != nil { + return fmt.Errorf("invalid blob endpoint for parsing: %q", *v) + } + blobHost = u.Host } - blobHost = u.Host } d.Set("primary_blob_endpoint", blobEndpoint) d.Set("primary_blob_host", blobHost) var queueEndpoint, queueHost string - if v := primary.Queue; v != nil { - queueEndpoint = *v + if primary != nil { + if v := primary.Queue; v != nil { + queueEndpoint = *v - u, err := url.Parse(*v) - if err != nil { - return fmt.Errorf("invalid queue endpoint for parsing: %q", *v) + u, err := url.Parse(*v) + if err != nil { + return fmt.Errorf("invalid queue endpoint for parsing: %q", *v) + } + queueHost = u.Host } - queueHost = u.Host } d.Set("primary_queue_endpoint", queueEndpoint) d.Set("primary_queue_host", queueHost) var tableEndpoint, tableHost string - if v := primary.Table; v != nil { - tableEndpoint = *v + if primary != nil { + if v := primary.Table; v != nil { + tableEndpoint = *v - u, err := url.Parse(*v) - if err != nil { - return fmt.Errorf("invalid table endpoint for parsing: %q", *v) + u, err := url.Parse(*v) + if err != nil { + return fmt.Errorf("invalid table endpoint for parsing: %q", *v) + } + tableHost = u.Host } - tableHost = u.Host } d.Set("primary_table_endpoint", tableEndpoint) d.Set("primary_table_host", tableHost) var fileEndpoint, fileHost string - if v := primary.File; v != nil { - fileEndpoint = *v + if primary != nil { + if v := primary.File; v != nil { + fileEndpoint = *v - u, err := url.Parse(*v) - if err != nil { - return fmt.Errorf("invalid file endpoint for parsing: %q", *v) + u, err := url.Parse(*v) + if err != nil { + return fmt.Errorf("invalid file endpoint for parsing: %q", *v) + } + fileHost = u.Host } - fileHost = u.Host } d.Set("primary_file_endpoint", fileEndpoint) d.Set("primary_file_host", fileHost) + if primary == nil { + return fmt.Errorf("primary endpoints should not be empty") + } + return nil } From 913d5199f3f35a439cb738572f6a5d96f7d0f929 Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Tue, 19 Feb 2019 17:11:37 +0800 Subject: [PATCH 8/8] Update the document for both data source and resource for storage account. --- website/docs/d/storage_account.html.markdown | 14 +++++++------- website/docs/r/storage_account.html.markdown | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/website/docs/d/storage_account.html.markdown b/website/docs/d/storage_account.html.markdown index 254756842579..107cb343124e 100644 --- a/website/docs/d/storage_account.html.markdown +++ b/website/docs/d/storage_account.html.markdown @@ -64,31 +64,31 @@ output "storage_account_tier" { * `primary_blob_endpoint` - The endpoint URL for blob storage in the primary location. -* `primary_blob_host` - The `host` or `host:port` for blob storage in the primary location. +* `primary_blob_host` - The hostname with port if applicable for blob storage in the primary location. * `secondary_blob_endpoint` - The endpoint URL for blob storage in the secondary location. -* `secondary_blob_host` - The `host` or `host:port` for blob storage in the secondary location. +* `secondary_blob_host` - The hostname with port if applicable for blob storage in the secondary location. * `primary_queue_endpoint` - The endpoint URL for queue storage in the primary location. -* `primary_queue_host` - The `host` or `host:port` for queue storage in the primary location. +* `primary_queue_host` - The hostname with port if applicable for queue storage in the primary location. * `secondary_queue_endpoint` - The endpoint URL for queue storage in the secondary location. -* `secondary_queue_host` - The `host` or `host:port` for queue storage in the secondary location. +* `secondary_queue_host` - The hostname with port if applicable for queue storage in the secondary location. * `primary_table_endpoint` - The endpoint URL for table storage in the primary location. -* `primary_table_host` - The `host` or `host:port` for table storage in the primary location. +* `primary_table_host` - The hostname with port if applicable for table storage in the primary location. * `secondary_table_endpoint` - The endpoint URL for table storage in the secondary location. -* `secondary_table_host` - The `host` or `host:port` for table storage in the secondary location. +* `secondary_table_host` - The hostname with port if applicable for table storage in the secondary location. * `primary_file_endpoint` - The endpoint URL for file storage in the primary location. -* `primary_file_host` - The `host` or `host:port` for file storage in the primary location. +* `primary_file_host` - The hostname with port if applicable for file storage in the primary location. * `primary_access_key` - The primary access key for the Storage Account. diff --git a/website/docs/r/storage_account.html.markdown b/website/docs/r/storage_account.html.markdown index 4d44fd812f75..bebd7b98320b 100644 --- a/website/docs/r/storage_account.html.markdown +++ b/website/docs/r/storage_account.html.markdown @@ -153,31 +153,31 @@ The following attributes are exported in addition to the arguments listed above: * `primary_blob_endpoint` - The endpoint URL for blob storage in the primary location. -* `primary_blob_host` - The `host` or `host:port` for blob storage in the primary location. +* `primary_blob_host` - The hostname with port if applicable for blob storage in the primary location. * `secondary_blob_endpoint` - The endpoint URL for blob storage in the secondary location. -* `secondary_blob_host` - The `host` or `host:port`for blob storage in the secondary location. +* `secondary_blob_host` - The hostname with port if applicable for blob storage in the secondary location. * `primary_queue_endpoint` - The endpoint URL for queue storage in the primary location. -* `primary_queue_host` - The `host` or `host:port`for queue storage in the primary location. +* `primary_queue_host` - The hostname with port if applicable for queue storage in the primary location. * `secondary_queue_endpoint` - The endpoint URL for queue storage in the secondary location. -* `secondary_queue_host` - The `host` or `host:port`for queue storage in the secondary location. +* `secondary_queue_host` - The hostname with port if applicable for queue storage in the secondary location. * `primary_table_endpoint` - The endpoint URL for table storage in the primary location. -* `primary_table_host` - The `host` or `host:port`for table storage in the primary location. +* `primary_table_host` - The hostname with port if applicable for table storage in the primary location. * `secondary_table_endpoint` - The endpoint URL for table storage in the secondary location. -* `secondary_table_host` - The `host` or `host:port`for table storage in the secondary location. +* `secondary_table_host` - The hostname with port if applicable for table storage in the secondary location. * `primary_file_endpoint` - The endpoint URL for file storage in the primary location. -* `primary_file_host` - The `host` or `host:port`for file storage in the primary location. +* `primary_file_host` - The hostname with port if applicable for file storage in the primary location. * `primary_access_key` - The primary access key for the storage account.