From f0a34a40373541dbd29b924ff3e1971376aeea20 Mon Sep 17 00:00:00 2001 From: Jack Batzner Date: Fri, 24 Jan 2020 10:36:26 -0600 Subject: [PATCH 1/4] New Data Source: 'azurerm_iothub_dps_shared_access_policy' --- ..._source_iothub_dps_shared_access_policy.go | 121 ++++++++++++++++++ .../internal/services/iothub/registration.go | 5 +- ...ce_iothub_dps_shared_access_policy_test.go | 45 +++++++ website/azurerm.erb | 4 + ...hub_dps_shared_access_policy.html.markdown | 45 +++++++ 5 files changed, 218 insertions(+), 2 deletions(-) create mode 100644 azurerm/internal/services/iothub/data_source_iothub_dps_shared_access_policy.go create mode 100644 azurerm/internal/services/iothub/tests/data_source_iothub_dps_shared_access_policy_test.go create mode 100644 website/docs/d/iothub_dps_shared_access_policy.html.markdown diff --git a/azurerm/internal/services/iothub/data_source_iothub_dps_shared_access_policy.go b/azurerm/internal/services/iothub/data_source_iothub_dps_shared_access_policy.go new file mode 100644 index 000000000000..b11728ce1c60 --- /dev/null +++ b/azurerm/internal/services/iothub/data_source_iothub_dps_shared_access_policy.go @@ -0,0 +1,121 @@ +package iothub + +import ( + "fmt" + "regexp" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceIotHubDPSSharedAccessPolicy() *schema.Resource { + return &schema.Resource{ + Read: dataSourceIotHubDPSSharedAccessPolicyRead, + + Timeouts: &schema.ResourceTimeout{ + Read: schema.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`[a-zA-Z0-9!._-]{1,64}`), ""+ + "The shared access policy key name must not be empty, and must not exceed 64 characters in length. The shared access policy key name can only contain alphanumeric characters, exclamation marks, periods, underscores and hyphens."), + }, + + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), + + "iothub_dps_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.IoTHubName, + }, + + "primary_key": { + Type: schema.TypeString, + Sensitive: true, + Computed: true, + }, + + "primary_connection_string": { + Type: schema.TypeString, + Sensitive: true, + Computed: true, + }, + + "secondary_key": { + Type: schema.TypeString, + Sensitive: true, + Computed: true, + }, + + "secondary_connection_string": { + Type: schema.TypeString, + Sensitive: true, + Computed: true, + }, + }, + } +} + +func dataSourceIotHubDPSSharedAccessPolicyRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).IoTHub.DPSResourceClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + keyName := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + iothubDpsName := d.Get("iothub_dps_name").(string) + + iothubDps, err := client.Get(ctx, iothubDpsName, resourceGroup) + if err != nil { + if utils.ResponseWasNotFound(iothubDps.Response) { + return fmt.Errorf("Error: IotHub DPS %q (Resource Group %q) was not found", iothubDpsName, resourceGroup) + } + + return fmt.Errorf("Error retrieving IotHub DPS %q (Resource Group %q): %+v", iothubDpsName, resourceGroup, err) + } + + accessPolicy, err := client.ListKeysForKeyName(ctx, iothubDpsName, keyName, resourceGroup) + if err != nil { + if utils.ResponseWasNotFound(accessPolicy.Response) { + return fmt.Errorf("Error: IotHub DPS Shared Access Policy %q (Resource Group %q) was not found", iothubDpsName, resourceGroup) + } + + return fmt.Errorf("Error loading IotHub DPS Shared Access Policy %q (IotHub DPS %q / Resource Group %q): %+v", keyName, iothubDpsName, resourceGroup, err) + } + + d.Set("name", keyName) + d.Set("resource_group_name", resourceGroup) + + resourceID := fmt.Sprintf("%s/keys/%s", *iothubDps.ID, keyName) + d.SetId(resourceID) + + d.Set("primary_key", accessPolicy.PrimaryKey) + d.Set("secondary_key", accessPolicy.SecondaryKey) + + if props := iothubDps.Properties; props != nil { + if host := props.ServiceOperationsHostName; host != nil { + if pKey := accessPolicy.PrimaryKey; pKey != nil { + if err := d.Set("primary_connection_string", getSAPConnectionString(*host, keyName, *pKey)); err != nil { + return fmt.Errorf("error setting `primary_connection_string`: %v", err) + } + } + + if sKey := accessPolicy.SecondaryKey; sKey != nil { + if err := d.Set("secondary_connection_string", getSAPConnectionString(*host, keyName, *sKey)); err != nil { + return fmt.Errorf("error setting `secondary_connection_string`: %v", err) + } + } + } + } + + return nil +} diff --git a/azurerm/internal/services/iothub/registration.go b/azurerm/internal/services/iothub/registration.go index e931067bded7..5bdcfdd49312 100644 --- a/azurerm/internal/services/iothub/registration.go +++ b/azurerm/internal/services/iothub/registration.go @@ -14,8 +14,9 @@ func (r Registration) Name() string { // SupportedDataSources returns the supported Data Sources supported by this Service func (r Registration) SupportedDataSources() map[string]*schema.Resource { return map[string]*schema.Resource{ - "azurerm_iothub_dps": dataSourceArmIotHubDPS(), - "azurerm_iothub_shared_access_policy": dataSourceArmIotHubSharedAccessPolicy(), + "azurerm_iothub_dps": dataSourceArmIotHubDPS(), + "azurerm_iothub_dps_shared_access_policy": dataSourceIotHubDPSSharedAccessPolicy(), + "azurerm_iothub_shared_access_policy": dataSourceArmIotHubSharedAccessPolicy(), } } diff --git a/azurerm/internal/services/iothub/tests/data_source_iothub_dps_shared_access_policy_test.go b/azurerm/internal/services/iothub/tests/data_source_iothub_dps_shared_access_policy_test.go new file mode 100644 index 000000000000..ca42890f69e7 --- /dev/null +++ b/azurerm/internal/services/iothub/tests/data_source_iothub_dps_shared_access_policy_test.go @@ -0,0 +1,45 @@ +package tests + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" +) + +func TestAccDataSourceAzureRMIotHubDpsSharedAccessPolicy_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_iothub_dps_shared_access_policy", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMIotHubDpsSharedAccessPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDatasourceAzureRMIotHubDpsSharedAccessPolicy_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubDpsSharedAccessPolicyExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "primary_key"), + resource.TestCheckResourceAttrSet(data.ResourceName, "primary_connection_string"), + resource.TestCheckResourceAttrSet(data.ResourceName, "secondary_key"), + resource.TestCheckResourceAttrSet(data.ResourceName, "secondary_connection_string"), + ), + }, + }, + }) +} + +func testAccDatasourceAzureRMIotHubDpsSharedAccessPolicy_basic(data acceptance.TestData) string { + template := testAccAzureRMIotHubDpsSharedAccessPolicy_basic(data) + + return fmt.Sprintf(` +%s + +data "azurerm_iothub_dps_shared_access_policy" "test" { + name = "${azurerm_iothub_dps_shared_access_policy.test.name}" + iothub_dps_name = "${azurerm_iothub_dps.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" +} +`, template) +} diff --git a/website/azurerm.erb b/website/azurerm.erb index 95e77be0e89a..97fe50b576d6 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -234,6 +234,10 @@ azurerm_iothub_dps +
  • + azurerm_iothub_dps_shared_access_policy +
  • +
  • azurerm_iothub_shared_access_policy
  • diff --git a/website/docs/d/iothub_dps_shared_access_policy.html.markdown b/website/docs/d/iothub_dps_shared_access_policy.html.markdown new file mode 100644 index 000000000000..4f7c1fb121dc --- /dev/null +++ b/website/docs/d/iothub_dps_shared_access_policy.html.markdown @@ -0,0 +1,45 @@ +--- +subcategory: "IoT Hub" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_iothub_dps_shared_access_policy" +description: |- + Gets information about an existing IotHub Device Provisioning Service Shared Access Policy +--- + +# Data Source: azurerm_iothub_dps_shared_access_policy + +Use this data source to access information about an existing IotHub Device Provisioning Service Shared Access Policy + +## Example Usage + +```hcl +data "azurerm_iothub_dps_shared_access_policy" "example" { + name = "example" + resource_group_name = azurerm_resource_group.example.name + iothub_dps_name = azurerm_iothub_dps.example.name +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the IotHub Shared Access Policy resource. + +* `resource_group_name` - (Required) The name of the resource group under which the IotHub Shared Access Policy resource has to be created. + +* `iothub_dps_name` - (Required) The name of the IoT Hub Device Provisioning service to which this Shared Access Policy belongs. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the IoT Hub Device Provisioning Service Shared Access Policy. + +* `primary_key` - The primary key used to create the authentication token. + +* `primary_connection_string` - The primary connection string of the Shared Access Policy. + +* `secondary_key` - The secondary key used to create the authentication token. + +* `secondary_connection_string` - The secondary connection string of the Shared Access Policy. \ No newline at end of file From eeb810cfc859fd5c711822f68058d81a79adc8c1 Mon Sep 17 00:00:00 2001 From: Jack Batzner Date: Mon, 27 Jan 2020 08:26:16 -0600 Subject: [PATCH 2/4] Fix formatting and update documentation --- ...ce_iothub_dps_shared_access_policy_test.go | 30 ++++++++++++++----- ...hub_dps_shared_access_policy.html.markdown | 6 ++-- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/azurerm/internal/services/iothub/tests/data_source_iothub_dps_shared_access_policy_test.go b/azurerm/internal/services/iothub/tests/data_source_iothub_dps_shared_access_policy_test.go index ca42890f69e7..5cf2c07d3013 100644 --- a/azurerm/internal/services/iothub/tests/data_source_iothub_dps_shared_access_policy_test.go +++ b/azurerm/internal/services/iothub/tests/data_source_iothub_dps_shared_access_policy_test.go @@ -17,7 +17,7 @@ func TestAccDataSourceAzureRMIotHubDpsSharedAccessPolicy_basic(t *testing.T) { CheckDestroy: testCheckAzureRMIotHubDpsSharedAccessPolicyDestroy, Steps: []resource.TestStep{ { - Config: testAccDatasourceAzureRMIotHubDpsSharedAccessPolicy_basic(data), + Config: testAccDataSourceAzureRMIotHubDpsSharedAccessPolicy_basic(data), Check: resource.ComposeTestCheckFunc( testCheckAzureRMIotHubDpsSharedAccessPolicyExists(data.ResourceName), resource.TestCheckResourceAttrSet(data.ResourceName, "primary_key"), @@ -30,16 +30,32 @@ func TestAccDataSourceAzureRMIotHubDpsSharedAccessPolicy_basic(t *testing.T) { }) } -func testAccDatasourceAzureRMIotHubDpsSharedAccessPolicy_basic(data acceptance.TestData) string { - template := testAccAzureRMIotHubDpsSharedAccessPolicy_basic(data) - +func testAccDataSourceAzureRMIotHubDpsSharedAccessPolicy_basic(data acceptance.TestData) string { return fmt.Sprintf(` -%s +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} +resource "azurerm_iothub_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + sku { + name = "S1" + capacity = "1" + } +} +resource "azurerm_iothub_dps_shared_access_policy" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + iothub_dps_name = "${azurerm_iothub_dps.test.name}" + name = "acctest" + service_config = true +} data "azurerm_iothub_dps_shared_access_policy" "test" { name = "${azurerm_iothub_dps_shared_access_policy.test.name}" - iothub_dps_name = "${azurerm_iothub_dps.test.name}" + iothub_dps_name = "${azurerm_iothub_dps.test.name}" resource_group_name = "${azurerm_resource_group.test.name}" } -`, template) +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } diff --git a/website/docs/d/iothub_dps_shared_access_policy.html.markdown b/website/docs/d/iothub_dps_shared_access_policy.html.markdown index 4f7c1fb121dc..ba7d01234df1 100644 --- a/website/docs/d/iothub_dps_shared_access_policy.html.markdown +++ b/website/docs/d/iothub_dps_shared_access_policy.html.markdown @@ -24,11 +24,11 @@ data "azurerm_iothub_dps_shared_access_policy" "example" { The following arguments are supported: -* `name` - (Required) Specifies the name of the IotHub Shared Access Policy resource. +* `name` - (Required) Specifies the name of the IotHub Shared Access Policy. -* `resource_group_name` - (Required) The name of the resource group under which the IotHub Shared Access Policy resource has to be created. +* `resource_group_name` - (Required) Specifies the name of the resource group under which the IotHub Shared Access Policy resource exists. -* `iothub_dps_name` - (Required) The name of the IoT Hub Device Provisioning service to which this Shared Access Policy belongs. +* `iothub_dps_name` - (Required) Specifies the name of the IoT Hub Device Provisioning service to which the Shared Access Policy belongs. ## Attributes Reference From e252b668f6a82678e061faa3954721e6e95873b7 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 7 Feb 2020 10:16:41 -0600 Subject: [PATCH 3/4] Remove (Required) from Argument Reference section --- .../docs/d/iothub_dps_shared_access_policy.html.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/d/iothub_dps_shared_access_policy.html.markdown b/website/docs/d/iothub_dps_shared_access_policy.html.markdown index ba7d01234df1..1db9c220e38c 100644 --- a/website/docs/d/iothub_dps_shared_access_policy.html.markdown +++ b/website/docs/d/iothub_dps_shared_access_policy.html.markdown @@ -24,11 +24,11 @@ data "azurerm_iothub_dps_shared_access_policy" "example" { The following arguments are supported: -* `name` - (Required) Specifies the name of the IotHub Shared Access Policy. +* `name` - Specifies the name of the IotHub Shared Access Policy. -* `resource_group_name` - (Required) Specifies the name of the resource group under which the IotHub Shared Access Policy resource exists. +* `resource_group_name` - Specifies the name of the resource group under which the IotHub Shared Access Policy resource exists. -* `iothub_dps_name` - (Required) Specifies the name of the IoT Hub Device Provisioning service to which the Shared Access Policy belongs. +* `iothub_dps_name` - Specifies the name of the IoT Hub Device Provisioning service to which the Shared Access Policy belongs. ## Attributes Reference @@ -42,4 +42,4 @@ The following attributes are exported: * `secondary_key` - The secondary key used to create the authentication token. -* `secondary_connection_string` - The secondary connection string of the Shared Access Policy. \ No newline at end of file +* `secondary_connection_string` - The secondary connection string of the Shared Access Policy. From 26cd458772ce92e6f288b2180d8939076a6bf8a6 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Tue, 11 Feb 2020 16:10:53 +0100 Subject: [PATCH 4/4] d/iot_hub_dps_shared_access_policy: fixing comments from code review --- ..._source_iothub_dps_shared_access_policy.go | 28 +++++++++---------- ...rce_arm_iothub_dps_shared_access_policy.go | 24 ++++++++-------- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/azurerm/internal/services/iothub/data_source_iothub_dps_shared_access_policy.go b/azurerm/internal/services/iothub/data_source_iothub_dps_shared_access_policy.go index b11728ce1c60..63dc608266c0 100644 --- a/azurerm/internal/services/iothub/data_source_iothub_dps_shared_access_policy.go +++ b/azurerm/internal/services/iothub/data_source_iothub_dps_shared_access_policy.go @@ -86,10 +86,10 @@ func dataSourceIotHubDPSSharedAccessPolicyRead(d *schema.ResourceData, meta inte accessPolicy, err := client.ListKeysForKeyName(ctx, iothubDpsName, keyName, resourceGroup) if err != nil { if utils.ResponseWasNotFound(accessPolicy.Response) { - return fmt.Errorf("Error: IotHub DPS Shared Access Policy %q (Resource Group %q) was not found", iothubDpsName, resourceGroup) + return fmt.Errorf("Error: Shared Access Policy %q (IotHub DPS %q / Resource Group %q) was not found", keyName, iothubDpsName, resourceGroup) } - return fmt.Errorf("Error loading IotHub DPS Shared Access Policy %q (IotHub DPS %q / Resource Group %q): %+v", keyName, iothubDpsName, resourceGroup, err) + return fmt.Errorf("Error loading Shared Access Policy %q (IotHub DPS %q / Resource Group %q): %+v", keyName, iothubDpsName, resourceGroup, err) } d.Set("name", keyName) @@ -101,21 +101,19 @@ func dataSourceIotHubDPSSharedAccessPolicyRead(d *schema.ResourceData, meta inte d.Set("primary_key", accessPolicy.PrimaryKey) d.Set("secondary_key", accessPolicy.SecondaryKey) - if props := iothubDps.Properties; props != nil { - if host := props.ServiceOperationsHostName; host != nil { - if pKey := accessPolicy.PrimaryKey; pKey != nil { - if err := d.Set("primary_connection_string", getSAPConnectionString(*host, keyName, *pKey)); err != nil { - return fmt.Errorf("error setting `primary_connection_string`: %v", err) - } - } - - if sKey := accessPolicy.SecondaryKey; sKey != nil { - if err := d.Set("secondary_connection_string", getSAPConnectionString(*host, keyName, *sKey)); err != nil { - return fmt.Errorf("error setting `secondary_connection_string`: %v", err) - } - } + primaryConnectionString := "" + secondaryConnectionString := "" + if iothubDps.Properties != nil && iothubDps.Properties.DeviceProvisioningHostName != nil { + hostname := iothubDps.Properties.DeviceProvisioningHostName + if primary := accessPolicy.PrimaryKey; primary != nil { + primaryConnectionString = getSAPConnectionString(*hostname, keyName, *primary) + } + if secondary := accessPolicy.SecondaryKey; secondary != nil { + secondaryConnectionString = getSAPConnectionString(*hostname, keyName, *secondary) } } + d.Set("primary_connection_string", primaryConnectionString) + d.Set("secondary_connection_string", secondaryConnectionString) return nil } diff --git a/azurerm/internal/services/iothub/resource_arm_iothub_dps_shared_access_policy.go b/azurerm/internal/services/iothub/resource_arm_iothub_dps_shared_access_policy.go index 324e3421e3a0..03e2b794b7fe 100644 --- a/azurerm/internal/services/iothub/resource_arm_iothub_dps_shared_access_policy.go +++ b/azurerm/internal/services/iothub/resource_arm_iothub_dps_shared_access_policy.go @@ -234,21 +234,19 @@ func resourceArmIotHubDPSSharedAccessPolicyRead(d *schema.ResourceData, meta int d.Set("primary_key", accessPolicy.PrimaryKey) d.Set("secondary_key", accessPolicy.SecondaryKey) - if props := iothubDps.Properties; props != nil { - if host := props.ServiceOperationsHostName; host != nil { - if pKey := accessPolicy.PrimaryKey; pKey != nil { - if err := d.Set("primary_connection_string", getSAPConnectionString(*host, keyName, *pKey)); err != nil { - return fmt.Errorf("error setting `primary_connection_string`: %v", err) - } - } - - if sKey := accessPolicy.SecondaryKey; sKey != nil { - if err := d.Set("secondary_connection_string", getSAPConnectionString(*host, keyName, *sKey)); err != nil { - return fmt.Errorf("error setting `secondary_connection_string`: %v", err) - } - } + primaryConnectionString := "" + secondaryConnectionString := "" + if iothubDps.Properties != nil && iothubDps.Properties.DeviceProvisioningHostName != nil { + hostname := iothubDps.Properties.DeviceProvisioningHostName + if primary := accessPolicy.PrimaryKey; primary != nil { + primaryConnectionString = getSAPConnectionString(*hostname, keyName, *primary) + } + if secondary := accessPolicy.SecondaryKey; secondary != nil { + secondaryConnectionString = getSAPConnectionString(*hostname, keyName, *secondary) } } + d.Set("primary_connection_string", primaryConnectionString) + d.Set("secondary_connection_string", secondaryConnectionString) rights := flattenDpsAccessRights(accessPolicy.Rights) d.Set("enrollment_read", rights.enrollmentRead)