From 741848a8933df5fd284c30d2e87697a42e8bdfd6 Mon Sep 17 00:00:00 2001 From: pchanvallon Date: Tue, 10 Jan 2023 17:45:30 +0100 Subject: [PATCH 1/3] feat(private-resolver): new datasource azurerm_private_dns_resolver_outbound_endpoint --- ..._resolver_outbound_endpoint_data_source.go | 117 ++++++++++++++++ ...lver_outbound_endpoint_data_source_test.go | 130 ++++++++++++++++++ .../privatednsresolver/registration.go | 1 + ...s_resolver_outbound_endpoint.html.markdown | 46 +++++++ 4 files changed, 294 insertions(+) create mode 100644 internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source.go create mode 100644 internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go create mode 100644 website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown diff --git a/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source.go b/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source.go new file mode 100644 index 000000000000..b549ec3a09fd --- /dev/null +++ b/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source.go @@ -0,0 +1,117 @@ +package privatednsresolver + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" + "github.com/hashicorp/go-azure-helpers/resourcemanager/location" + "github.com/hashicorp/go-azure-sdk/resource-manager/dnsresolver/2022-07-01/dnsresolvers" + "github.com/hashicorp/go-azure-sdk/resource-manager/dnsresolver/2022-07-01/outboundendpoints" + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tags" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" +) + +type PrivateDNSResolverOutboundEndpointDataSourceModel struct { + Name string `tfschema:"name"` + PrivateDNSResolverId string `tfschema:"private_dns_resolver_id"` + Location string `tfschema:"location"` + SubnetId string `tfschema:"subnet_id"` + Tags map[string]string `tfschema:"tags"` +} + +type PrivateDNSResolverOutboundEndpointDataSource struct{} + +var _ sdk.DataSource = PrivateDNSResolverOutboundEndpointDataSource{} + +func (r PrivateDNSResolverOutboundEndpointDataSource) ResourceType() string { + return "azurerm_private_dns_resolver_outbound_endpoint" +} + +func (r PrivateDNSResolverOutboundEndpointDataSource) ModelObject() interface{} { + return &PrivateDNSResolverOutboundEndpointDataSourceModel{} +} + +func (r PrivateDNSResolverOutboundEndpointDataSource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return outboundendpoints.ValidateOutboundEndpointID +} + +func (r PrivateDNSResolverOutboundEndpointDataSource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "private_dns_resolver_id": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: dnsresolvers.ValidateDnsResolverID, + }, + } +} + +func (r PrivateDNSResolverOutboundEndpointDataSource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "subnet_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "location": commonschema.LocationComputed(), + + "tags": tags.SchemaDataSource(), + } +} + +func (r PrivateDNSResolverOutboundEndpointDataSource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.PrivateDnsResolver.OutboundEndpointsClient + + var state PrivateDNSResolverOutboundEndpointDataSourceModel + if err := metadata.Decode(&state); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + privateDnsResolverId, err := outboundendpoints.ParseDnsResolverID(state.PrivateDNSResolverId) + if err != nil { + return err + } + + var top int64 = 1 + resp, err := client.ListCompleteMatchingPredicate(ctx, *privateDnsResolverId, + outboundendpoints.ListOperationOptions{Top: &top}, + outboundendpoints.OutboundEndpointOperationPredicate{Name: &state.Name}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", state.Name, err) + } + if len(resp.Items) != int(top) { + return fmt.Errorf("retrieving %s: resource not found", state.Name) + } + + model := resp.Items[0] + id, err := outboundendpoints.ParseOutboundEndpointID(*model.Id) + if err != nil { + return err + } + + state.Location = location.Normalize(model.Location) + state.PrivateDNSResolverId = dnsresolvers.NewDnsResolverID(id.SubscriptionId, id.ResourceGroupName, id.DnsResolverName).ID() + state.SubnetId = model.Properties.Subnet.Id + + if model.Tags != nil { + state.Tags = *model.Tags + } + + metadata.SetID(id) + + return metadata.Encode(&state) + }, + } +} diff --git a/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go b/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go new file mode 100644 index 000000000000..31715c1e22ee --- /dev/null +++ b/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go @@ -0,0 +1,130 @@ +package privatednsresolver_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/location" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" +) + +type DNSResolverOutboundEndpointDataSource struct{} + +func TestAccDNSResolverOutboundEndpointDataSource_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_private_dns_resolver_outbound_endpoint", "test") + d := DNSResolverOutboundEndpointDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: d.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("name").Exists(), + check.That(data.ResourceName).Key("private_dns_resolver_id").Exists(), + check.That(data.ResourceName).Key("location").HasValue(location.Normalize(data.Locations.Primary)), + check.That(data.ResourceName).Key("subnet_id").Exists(), + ), + }, + }) +} + +func TestAccDNSResolverOutboundEndpointDataSource_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_private_dns_resolver_outbound_endpoint", "test") + d := DNSResolverOutboundEndpointDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: d.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("name").Exists(), + check.That(data.ResourceName).Key("private_dns_resolver_id").Exists(), + check.That(data.ResourceName).Key("location").HasValue(location.Normalize(data.Locations.Primary)), + check.That(data.ResourceName).Key("subnet_id").Exists(), + check.That(data.ResourceName).Key("tags.key").HasValue("value"), + ), + }, + }) +} + +func (d DNSResolverOutboundEndpointDataSource) template(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctest-rg-%[2]d" + location = "%[1]s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctest-rg-%[2]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + address_space = ["10.0.0.0/16"] +} + +resource "azurerm_subnet" "test" { + name = "outbounddns" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefixes = ["10.0.0.64/28"] + + delegation { + name = "Microsoft.Network.dnsResolvers" + service_delegation { + actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"] + name = "Microsoft.Network/dnsResolvers" + } + } +} + +resource "azurerm_private_dns_resolver" "test" { + name = "acctest-dr-%[2]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + virtual_network_id = azurerm_virtual_network.test.id +} +`, data.Locations.Primary, data.RandomInteger) +} + +func (d DNSResolverOutboundEndpointDataSource) basic(data acceptance.TestData) string { + template := d.template(data) + return fmt.Sprintf(` + %s + +resource "azurerm_private_dns_resolver_outbound_endpoint" "test" { + name = "acctest-droe-%d" + private_dns_resolver_id = azurerm_private_dns_resolver.test.id + location = azurerm_private_dns_resolver.test.location + subnet_id = azurerm_subnet.test.id +} + +data "azurerm_private_dns_resolver_outbound_endpoint" "test" { + name = azurerm_private_dns_resolver_outbound_endpoint.test.name + private_dns_resolver_id = azurerm_private_dns_resolver.test.id +} +`, template, data.RandomInteger) +} + +func (d DNSResolverOutboundEndpointDataSource) complete(data acceptance.TestData) string { + template := d.template(data) + return fmt.Sprintf(` + %s + +resource "azurerm_private_dns_resolver_outbound_endpoint" "test" { + name = "acctest-droe-%d" + private_dns_resolver_id = azurerm_private_dns_resolver.test.id + location = azurerm_private_dns_resolver.test.location + subnet_id = azurerm_subnet.test.id + tags = { + key = "value" + } +} + +data "azurerm_private_dns_resolver_outbound_endpoint" "test" { + name = azurerm_private_dns_resolver_outbound_endpoint.test.name + private_dns_resolver_id = azurerm_private_dns_resolver.test.id +} +`, template, data.RandomInteger) +} diff --git a/internal/services/privatednsresolver/registration.go b/internal/services/privatednsresolver/registration.go index 48787d55802a..a61efe18c499 100644 --- a/internal/services/privatednsresolver/registration.go +++ b/internal/services/privatednsresolver/registration.go @@ -42,6 +42,7 @@ func (r Registration) SupportedResources() map[string]*pluginsdk.Resource { func (r Registration) DataSources() []sdk.DataSource { return []sdk.DataSource{ PrivateDNSResolverDnsResolverDataSource{}, + PrivateDNSResolverOutboundEndpointDataSource{}, } } diff --git a/website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown b/website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown new file mode 100644 index 000000000000..ae559c8b26cc --- /dev/null +++ b/website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown @@ -0,0 +1,46 @@ +--- +subcategory: "Private DNS Resolver" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_private_dns_resolver_outbound_endpoint" +description: |- + Gets information about an existing Private DNS Resolver Outbound Endpoint. +--- + +# Data Source: azurerm_private_dns_resolver_outbound_endpoint + +Gets information about an existing Private DNS Resolver Outbound Endpoint. + +## Example Usage + +```hcl +data "azurerm_private_dns_resolver_outbound_endpoint" "example" { + name = "example-endpoint" + private_dns_resolver_id = "example-private-dns-resolver-id" +} +``` + +## Arguments Reference + +The following arguments are required: + +* `name` - Name of the Private DNS Resolver Outbound Endpoint. + +* `private_dns_resolver_id` - ID of the Private DNS Resolver Outbound Endpoint. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Private DNS Resolver Outbound Endpoint. + +* `location` - Azure Region where the Private DNS Resolver Outbound Endpoint exists. + +* `subnet_id` - ID of the Subnet that is linked to the Private DNS Resolver Outbound Endpoint. + +* `tags` - Mapping of tags assigned to the Private DNS Resolver Outbound Endpoint. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `read` - (Defaults to 5 minutes) Used when retrieving the Private DNS SRV Record. From 7bafe0d76d58a73f9fe484f8c8f398c83a231b46 Mon Sep 17 00:00:00 2001 From: pchanvallon Date: Wed, 11 Jan 2023 22:42:29 +0100 Subject: [PATCH 2/3] applying review suggestions --- ..._resolver_outbound_endpoint_data_source.go | 22 ++++---- ...lver_outbound_endpoint_data_source_test.go | 53 ++----------------- ...s_resolver_outbound_endpoint.html.markdown | 10 ++-- 3 files changed, 18 insertions(+), 67 deletions(-) diff --git a/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source.go b/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source.go index b549ec3a09fd..45978f27c96c 100644 --- a/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source.go +++ b/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source.go @@ -84,21 +84,19 @@ func (r PrivateDNSResolverOutboundEndpointDataSource) Read() sdk.ResourceFunc { return err } - var top int64 = 1 - resp, err := client.ListCompleteMatchingPredicate(ctx, *privateDnsResolverId, - outboundendpoints.ListOperationOptions{Top: &top}, - outboundendpoints.OutboundEndpointOperationPredicate{Name: &state.Name}) + id := outboundendpoints.NewOutboundEndpointID( + privateDnsResolverId.SubscriptionId, + privateDnsResolverId.ResourceGroupName, + privateDnsResolverId.DnsResolverName, + state.Name) + resp, err := client.Get(ctx, id) if err != nil { - return fmt.Errorf("retrieving %s: %+v", state.Name, err) - } - if len(resp.Items) != int(top) { - return fmt.Errorf("retrieving %s: resource not found", state.Name) + return fmt.Errorf("retrieving %s: %+v", id, err) } - model := resp.Items[0] - id, err := outboundendpoints.ParseOutboundEndpointID(*model.Id) - if err != nil { - return err + model := resp.Model + if model == nil { + return fmt.Errorf("retrieving %s: model was nil", id) } state.Location = location.Normalize(model.Location) diff --git a/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go b/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go index 31715c1e22ee..9b4bd1d16518 100644 --- a/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go +++ b/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go @@ -28,25 +28,7 @@ func TestAccDNSResolverOutboundEndpointDataSource_basic(t *testing.T) { }) } -func TestAccDNSResolverOutboundEndpointDataSource_complete(t *testing.T) { - data := acceptance.BuildTestData(t, "data.azurerm_private_dns_resolver_outbound_endpoint", "test") - d := DNSResolverOutboundEndpointDataSource{} - - data.DataSourceTest(t, []acceptance.TestStep{ - { - Config: d.complete(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).Key("name").Exists(), - check.That(data.ResourceName).Key("private_dns_resolver_id").Exists(), - check.That(data.ResourceName).Key("location").HasValue(location.Normalize(data.Locations.Primary)), - check.That(data.ResourceName).Key("subnet_id").Exists(), - check.That(data.ResourceName).Key("tags.key").HasValue("value"), - ), - }, - }) -} - -func (d DNSResolverOutboundEndpointDataSource) template(data acceptance.TestData) string { +func (d DNSResolverOutboundEndpointDataSource) basic(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} @@ -85,46 +67,17 @@ resource "azurerm_private_dns_resolver" "test" { location = azurerm_resource_group.test.location virtual_network_id = azurerm_virtual_network.test.id } -`, data.Locations.Primary, data.RandomInteger) -} - -func (d DNSResolverOutboundEndpointDataSource) basic(data acceptance.TestData) string { - template := d.template(data) - return fmt.Sprintf(` - %s - -resource "azurerm_private_dns_resolver_outbound_endpoint" "test" { - name = "acctest-droe-%d" - private_dns_resolver_id = azurerm_private_dns_resolver.test.id - location = azurerm_private_dns_resolver.test.location - subnet_id = azurerm_subnet.test.id -} - -data "azurerm_private_dns_resolver_outbound_endpoint" "test" { - name = azurerm_private_dns_resolver_outbound_endpoint.test.name - private_dns_resolver_id = azurerm_private_dns_resolver.test.id -} -`, template, data.RandomInteger) -} - -func (d DNSResolverOutboundEndpointDataSource) complete(data acceptance.TestData) string { - template := d.template(data) - return fmt.Sprintf(` - %s resource "azurerm_private_dns_resolver_outbound_endpoint" "test" { - name = "acctest-droe-%d" + name = "acctest-droe-%[2]d" private_dns_resolver_id = azurerm_private_dns_resolver.test.id location = azurerm_private_dns_resolver.test.location subnet_id = azurerm_subnet.test.id - tags = { - key = "value" - } } data "azurerm_private_dns_resolver_outbound_endpoint" "test" { name = azurerm_private_dns_resolver_outbound_endpoint.test.name private_dns_resolver_id = azurerm_private_dns_resolver.test.id } -`, template, data.RandomInteger) +`, data.Locations.Primary, data.RandomInteger) } diff --git a/website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown b/website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown index ae559c8b26cc..e45108c72dcd 100644 --- a/website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown +++ b/website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown @@ -21,11 +21,11 @@ data "azurerm_private_dns_resolver_outbound_endpoint" "example" { ## Arguments Reference -The following arguments are required: +The following arguments are supported: -* `name` - Name of the Private DNS Resolver Outbound Endpoint. +* `name` - (Required) Name of the Private DNS Resolver Outbound Endpoint. -* `private_dns_resolver_id` - ID of the Private DNS Resolver Outbound Endpoint. +* `private_dns_resolver_id` - (Required) ID of the Private DNS Resolver Outbound Endpoint. ## Attributes Reference @@ -33,9 +33,9 @@ In addition to the Arguments listed above - the following Attributes are exporte * `id` - The ID of the Private DNS Resolver Outbound Endpoint. -* `location` - Azure Region where the Private DNS Resolver Outbound Endpoint exists. +* `location` - The Azure Region where the Private DNS Resolver Outbound Endpoint exists. -* `subnet_id` - ID of the Subnet that is linked to the Private DNS Resolver Outbound Endpoint. +* `subnet_id` - The ID of the Subnet that is linked to the Private DNS Resolver Outbound Endpoint. * `tags` - Mapping of tags assigned to the Private DNS Resolver Outbound Endpoint. From 51ab09cfef1b91c8bcfbbcfe4f4c7bd3d8226c40 Mon Sep 17 00:00:00 2001 From: pchanvallon Date: Thu, 12 Jan 2023 09:26:38 +0100 Subject: [PATCH 3/3] updating documentation and tests following last comments --- ...lver_outbound_endpoint_data_source_test.go | 47 +------------------ ...s_resolver_outbound_endpoint.html.markdown | 4 +- 2 files changed, 4 insertions(+), 47 deletions(-) diff --git a/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go b/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go index 9b4bd1d16518..e49edf42c1f7 100644 --- a/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go +++ b/internal/services/privatednsresolver/private_dns_resolver_outbound_endpoint_data_source_test.go @@ -30,54 +30,11 @@ func TestAccDNSResolverOutboundEndpointDataSource_basic(t *testing.T) { func (d DNSResolverOutboundEndpointDataSource) basic(data acceptance.TestData) string { return fmt.Sprintf(` -provider "azurerm" { - features {} -} - -resource "azurerm_resource_group" "test" { - name = "acctest-rg-%[2]d" - location = "%[1]s" -} - -resource "azurerm_virtual_network" "test" { - name = "acctest-rg-%[2]d" - resource_group_name = azurerm_resource_group.test.name - location = azurerm_resource_group.test.location - address_space = ["10.0.0.0/16"] -} - -resource "azurerm_subnet" "test" { - name = "outbounddns" - resource_group_name = azurerm_resource_group.test.name - virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.0.0.64/28"] - - delegation { - name = "Microsoft.Network.dnsResolvers" - service_delegation { - actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"] - name = "Microsoft.Network/dnsResolvers" - } - } -} - -resource "azurerm_private_dns_resolver" "test" { - name = "acctest-dr-%[2]d" - resource_group_name = azurerm_resource_group.test.name - location = azurerm_resource_group.test.location - virtual_network_id = azurerm_virtual_network.test.id -} - -resource "azurerm_private_dns_resolver_outbound_endpoint" "test" { - name = "acctest-droe-%[2]d" - private_dns_resolver_id = azurerm_private_dns_resolver.test.id - location = azurerm_private_dns_resolver.test.location - subnet_id = azurerm_subnet.test.id -} +%s data "azurerm_private_dns_resolver_outbound_endpoint" "test" { name = azurerm_private_dns_resolver_outbound_endpoint.test.name private_dns_resolver_id = azurerm_private_dns_resolver.test.id } -`, data.Locations.Primary, data.RandomInteger) +`, DNSResolverOutboundEndpointResource{}.basic(data)) } diff --git a/website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown b/website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown index e45108c72dcd..67d1ec7c8bd3 100644 --- a/website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown +++ b/website/docs/d/private_dns_resolver_outbound_endpoint.html.markdown @@ -37,10 +37,10 @@ In addition to the Arguments listed above - the following Attributes are exporte * `subnet_id` - The ID of the Subnet that is linked to the Private DNS Resolver Outbound Endpoint. -* `tags` - Mapping of tags assigned to the Private DNS Resolver Outbound Endpoint. +* `tags` - The tags assigned to the Private DNS Resolver Outbound Endpoint. ## Timeouts The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: -* `read` - (Defaults to 5 minutes) Used when retrieving the Private DNS SRV Record. +* `read` - (Defaults to 5 minutes) Used when retrieving the Private DNS Resolver Outbound Endpoint.