Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

d/private_dns_zone: refactoring to use the ListBySubscription API rather than the Resources API #24024

Merged
merged 3 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions internal/services/privatedns/client/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package client

import (
"context"
"fmt"

"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-sdk/resource-manager/privatedns/2020-06-01/privatezones"
"github.com/hashicorp/go-azure-sdk/resource-manager/resources/2023-07-01/resourcegroups"
)

func (c *Client) FindPrivateDnsZoneId(ctx context.Context, resourceGroupsClient *resourcegroups.ResourceGroupsClient, subscriptionId commonids.SubscriptionId, name string) (*privatezones.PrivateDnsZoneId, error) {
opts := privatezones.DefaultListOperationOptions()
results, err := c.PrivateZonesClient.ListComplete(ctx, subscriptionId, opts)
if err != nil {
return nil, fmt.Errorf("listing the Private DNS Zones within %s: %+v", subscriptionId, err)
}

for _, item := range results.Items {
if item.Id == nil {
continue
}

itemId := *item.Id
parsed, err := privatezones.ParsePrivateDnsZoneIDInsensitively(itemId)
if err != nil {
return nil, fmt.Errorf("parsing %q as a Private DNS Zone ID: %+v", itemId, err)
}

if parsed.PrivateDnsZoneName != name {
continue
}

// however the Resource Group name isn't necessarily cased correctly, so now that we've found the Resource
// Group name let's pull the canonical casing from the Resource Groups API
resourceGroupId := commonids.NewResourceGroupID(parsed.SubscriptionId, parsed.ResourceGroupName)
resp, err := resourceGroupsClient.Get(ctx, resourceGroupId)
if err != nil {
return nil, fmt.Errorf("retrieving %s: %+v", resourceGroupId, err)
}
if model := resp.Model; model != nil && model.Name != nil {
parsed.ResourceGroupName = *model.Name
}
return parsed, nil
}

return nil, fmt.Errorf("No Private DNS Zones found with name: %q", name)
}
91 changes: 27 additions & 64 deletions internal/services/privatedns/private_dns_zone_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
package privatedns

import (
"context"
"fmt"
"time"

"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2020-06-01/resources" // nolint: staticcheck
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/tags"
"github.com/hashicorp/go-azure-sdk/resource-manager/privatedns/2020-06-01/privatezones"
Expand Down Expand Up @@ -64,90 +63,54 @@ func dataSourcePrivateDnsZone() *pluginsdk.Resource {
}

func dataSourcePrivateDnsZoneRead(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).PrivateDns.PrivateZonesClient
client := meta.(*clients.Client).PrivateDns
resourceGroupsClient := meta.(*clients.Client).Resource.ResourceGroupsClient
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id := privatezones.NewPrivateDnsZoneID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string))

var resp *privatezones.PrivateZone
if id.ResourceGroupName != "" {
zone, err := client.Get(ctx, id)
if err != nil || zone.Model == nil {
if response.WasNotFound(zone.HttpResponse) {
return fmt.Errorf("%s was not found", id)
}
return fmt.Errorf("reading %s: %+v", id, err)
}
resp = zone.Model
} else {
resourcesClient := meta.(*clients.Client).Resource.ResourcesClient

zone, err := findPrivateZone(ctx, client, resourcesClient, id.PrivateDnsZoneName)
if id.ResourceGroupName == "" {
// we need to discover the Private DNS Zone's resource group
subscriptionResourceId := commonids.NewSubscriptionID(subscriptionId)
zoneId, err := client.FindPrivateDnsZoneId(ctx, resourceGroupsClient, subscriptionResourceId, id.PrivateDnsZoneName)
if err != nil {
return err
}

if zone == nil {
if zoneId == nil {
return fmt.Errorf("unable to determine the Resource Group for Private DNS Zone %q in Subscription %q", id.PrivateDnsZoneName, id.SubscriptionId)
}

id.ResourceGroupName = zoneId.ResourceGroupName
}

resp, err := client.PrivateZonesClient.Get(ctx, id)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
return fmt.Errorf("%s was not found", id)
}

resp = &zone.zone
id.ResourceGroupName = zone.resourceGroup
return fmt.Errorf("reading %s: %+v", id, err)
}

d.SetId(id.ID())

d.Set("name", id.PrivateDnsZoneName)
d.Set("resource_group_name", id.ResourceGroupName)

if props := resp.Properties; props != nil {
d.Set("number_of_record_sets", props.NumberOfRecordSets)
d.Set("max_number_of_record_sets", props.MaxNumberOfRecordSets)
d.Set("max_number_of_virtual_network_links", props.MaxNumberOfVirtualNetworkLinks)
d.Set("max_number_of_virtual_network_links_with_registration", props.MaxNumberOfVirtualNetworkLinksWithRegistration)
}

return tags.FlattenAndSet(d, resp.Tags)
}

type privateDnsZone struct {
zone privatezones.PrivateZone
resourceGroup string
}

func findPrivateZone(ctx context.Context, client *privatezones.PrivateZonesClient, resourcesClient *resources.Client, name string) (*privateDnsZone, error) {
filter := fmt.Sprintf("resourceType eq 'Microsoft.Network/privateDnsZones' and name eq '%s'", name)
privateZones, err := resourcesClient.List(ctx, filter, "", nil)
if err != nil {
return nil, fmt.Errorf("listing Private DNS Zones: %+v", err)
}

if len(privateZones.Values()) > 1 {
return nil, fmt.Errorf("More than one Private DNS Zone found with name: %q", name)
}

for _, z := range privateZones.Values() {
if z.ID == nil {
continue
}

id, err := privatezones.ParsePrivateDnsZoneID(*z.ID)
if err != nil {
continue
if model := resp.Model; model != nil {
if props := model.Properties; props != nil {
d.Set("number_of_record_sets", props.NumberOfRecordSets)
d.Set("max_number_of_record_sets", props.MaxNumberOfRecordSets)
d.Set("max_number_of_virtual_network_links", props.MaxNumberOfVirtualNetworkLinks)
d.Set("max_number_of_virtual_network_links_with_registration", props.MaxNumberOfVirtualNetworkLinksWithRegistration)
}

zone, err := client.Get(ctx, *id)
if err != nil || zone.Model == nil {
return nil, fmt.Errorf("retrieving %s: %+v", id, err)
if err := tags.FlattenAndSet(d, model.Tags); err != nil {
return err
}

return &privateDnsZone{
zone: *zone.Model,
resourceGroup: id.ResourceGroupName,
}, nil
}

return nil, fmt.Errorf("No Private DNS Zones found with name: %q", name)
return nil
}
47 changes: 30 additions & 17 deletions internal/services/resource/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,32 @@ import (
"github.com/hashicorp/go-azure-sdk/resource-manager/resources/2021-07-01/features"
"github.com/hashicorp/go-azure-sdk/resource-manager/resources/2022-02-01/templatespecversions"
"github.com/hashicorp/go-azure-sdk/resource-manager/resources/2022-09-01/providers"
"github.com/hashicorp/go-azure-sdk/resource-manager/resources/2023-07-01/resourcegroups"
"github.com/hashicorp/terraform-provider-azurerm/internal/common"
)

type Client struct {
DeploymentsClient *resources.DeploymentsClient
DeploymentScriptsClient *deploymentscripts.DeploymentScriptsClient
FeaturesClient *features.FeaturesClient
GroupsClient *resources.GroupsClient
LocksClient *managementlocks.ManagementLocksClient
PrivateLinkAssociationClient *privatelinkassociation.PrivateLinkAssociationClient
ResourceGroupsClient *resourcegroups.ResourceGroupsClient
ResourceManagementPrivateLinkClient *resourcemanagementprivatelink.ResourceManagementPrivateLinkClient
ResourceProvidersClient *providers.ProvidersClient
ResourcesClient *resources.Client
TagsClient *resources.TagsClient
TemplateSpecsVersionsClient *templatespecversions.TemplateSpecVersionsClient

options *common.ClientOptions
// TODO: these SDK clients use `Azure/azure-sdk-for-go` - we should migrate to `hashicorp/go-azure-sdk`
// (above) as time allows.
DeploymentsClient *resources.DeploymentsClient
ResourcesClient *resources.Client
TagsClient *resources.TagsClient
options *common.ClientOptions

// Note that the Groups Client which requires additional coordination
GroupsClient *resources.GroupsClient
}

func NewClient(o *common.ClientOptions) (*Client, error) {
deploymentsClient := resources.NewDeploymentsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&deploymentsClient.Client, o.ResourceManagerAuthorizer)

deploymentScriptsClient, err := deploymentscripts.NewDeploymentScriptsClientWithBaseURI(o.Environment.ResourceManager)
if err != nil {
return nil, fmt.Errorf("building DeploymentScripts client: %+v", err)
Expand All @@ -49,8 +52,11 @@ func NewClient(o *common.ClientOptions) (*Client, error) {
}
o.Configure(featuresClient.Client, o.Authorizers.ResourceManager)

groupsClient := resources.NewGroupsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&groupsClient.Client, o.ResourceManagerAuthorizer)
resourceGroupsClient, err := resourcegroups.NewResourceGroupsClientWithBaseURI(o.Environment.ResourceManager)
if err != nil {
return nil, fmt.Errorf("building Features client: %+v", err)
}
o.Configure(resourceGroupsClient.Client, o.Authorizers.ResourceManager)

locksClient, err := managementlocks.NewManagementLocksClientWithBaseURI(o.Environment.ResourceManager)
if err != nil {
Expand All @@ -76,32 +82,39 @@ func NewClient(o *common.ClientOptions) (*Client, error) {
}
o.Configure(resourceProvidersClient.Client, o.Authorizers.ResourceManager)

resourcesClient := resources.NewClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&resourcesClient.Client, o.ResourceManagerAuthorizer)

templateSpecsVersionsClient, err := templatespecversions.NewTemplateSpecVersionsClientWithBaseURI(o.Environment.ResourceManager)
if err != nil {
return nil, fmt.Errorf("building TemplateSpecVersions client: %+v", err)
}
o.Configure(templateSpecsVersionsClient.Client, o.Authorizers.ResourceManager)

// NOTE: these clients use `Azure/azure-sdk-for-go` and can be removed in time
deploymentsClient := resources.NewDeploymentsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&deploymentsClient.Client, o.ResourceManagerAuthorizer)
groupsClient := resources.NewGroupsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&groupsClient.Client, o.ResourceManagerAuthorizer)
resourcesClient := resources.NewClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&resourcesClient.Client, o.ResourceManagerAuthorizer)
tagsClient := resources.NewTagsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&tagsClient.Client, o.ResourceManagerAuthorizer)

return &Client{
GroupsClient: &groupsClient,
// These come from `hashicorp/go-azure-sdk`
DeploymentsClient: &deploymentsClient,
DeploymentScriptsClient: deploymentScriptsClient,
FeaturesClient: featuresClient,
LocksClient: locksClient,
PrivateLinkAssociationClient: privateLinkAssociationClient,
ResourceManagementPrivateLinkClient: resourceManagementPrivateLinkClient,
ResourceGroupsClient: resourceGroupsClient,
ResourceProvidersClient: resourceProvidersClient,
ResourcesClient: &resourcesClient,
TagsClient: &tagsClient,
TemplateSpecsVersionsClient: templateSpecsVersionsClient,

options: o,
// These use `Azure/azure-sdk-for-go`
GroupsClient: &groupsClient,
ResourcesClient: &resourcesClient,
TagsClient: &tagsClient,
options: o,
}, nil
}

Expand Down
Loading
Loading