From d008f11637d7b19b29b2de1f2ae7e2912b1ecf0e Mon Sep 17 00:00:00 2001 From: stephybun Date: Tue, 4 Jun 2024 16:33:08 +0200 Subject: [PATCH] update private link resources and data sources to use go-azure-sdk (#26212) --- .../private_link_service_data_source.go | 73 +++--- ...ervice_endpoint_connections_data_source.go | 53 +++-- .../network/private_link_service_resource.go | 212 +++++++++--------- .../private_link_service_resource_test.go | 12 +- 4 files changed, 171 insertions(+), 179 deletions(-) diff --git a/internal/services/network/private_link_service_data_source.go b/internal/services/network/private_link_service_data_source.go index 11fdffcff5ae..5c2055c890c9 100644 --- a/internal/services/network/private_link_service_data_source.go +++ b/internal/services/network/private_link_service_data_source.go @@ -7,16 +7,16 @@ import ( "fmt" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" "github.com/hashicorp/go-azure-helpers/resourcemanager/location" + "github.com/hashicorp/go-azure-helpers/resourcemanager/tags" + "github.com/hashicorp/go-azure-sdk/resource-manager/network/2023-11-01/privatelinkservices" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/validate" - "github.com/hashicorp/terraform-provider-azurerm/internal/tags" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/kermit/sdk/network/2022-07-01/network" ) func dataSourcePrivateLinkService() *pluginsdk.Resource { @@ -96,72 +96,75 @@ func dataSourcePrivateLinkService() *pluginsdk.Resource { Computed: true, }, - "tags": tags.SchemaDataSource(), + "tags": commonschema.TagsDataSource(), }, } } func dataSourcePrivateLinkServiceRead(d *pluginsdk.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Network.PrivateLinkServiceClient + client := meta.(*clients.Client).Network.PrivateLinkServices subscriptionId := meta.(*clients.Client).Account.SubscriptionId ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id := parse.NewPrivateLinkServiceID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string)) + id := privatelinkservices.NewPrivateLinkServiceID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string)) - resp, err := client.Get(ctx, id.ResourceGroup, id.Name, "") + resp, err := client.Get(ctx, id, privatelinkservices.DefaultGetOperationOptions()) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + if response.WasNotFound(resp.HttpResponse) { return fmt.Errorf("%s was not found", id) } - return fmt.Errorf("reading %s: %+v", id, err) + return fmt.Errorf("retrieving %s: %+v", id, err) } - d.Set("name", resp.Name) - d.Set("resource_group_name", id.ResourceGroup) + d.Set("name", id.PrivateLinkServiceName) + d.Set("resource_group_name", id.ResourceGroupName) - d.Set("location", location.NormalizeNilable(resp.Location)) + if model := resp.Model; model != nil { + d.Set("location", location.NormalizeNilable(model.Location)) - if props := resp.PrivateLinkServiceProperties; props != nil { - d.Set("alias", props.Alias) - d.Set("enable_proxy_protocol", props.EnableProxyProtocol) + if props := model.Properties; props != nil { + d.Set("alias", props.Alias) + d.Set("enable_proxy_protocol", props.EnableProxyProtocol) - if autoApproval := props.AutoApproval; autoApproval != nil { - if err := d.Set("auto_approval_subscription_ids", utils.FlattenStringSlice(autoApproval.Subscriptions)); err != nil { - return fmt.Errorf("setting `auto_approval_subscription_ids`: %+v", err) + if autoApproval := props.AutoApproval; autoApproval != nil { + if err := d.Set("auto_approval_subscription_ids", utils.FlattenStringSlice(autoApproval.Subscriptions)); err != nil { + return fmt.Errorf("setting `auto_approval_subscription_ids`: %+v", err) + } } - } - if visibility := props.Visibility; visibility != nil { - if err := d.Set("visibility_subscription_ids", utils.FlattenStringSlice(visibility.Subscriptions)); err != nil { - return fmt.Errorf("setting `visibility_subscription_ids`: %+v", err) + if visibility := props.Visibility; visibility != nil { + if err := d.Set("visibility_subscription_ids", utils.FlattenStringSlice(visibility.Subscriptions)); err != nil { + return fmt.Errorf("setting `visibility_subscription_ids`: %+v", err) + } } - } - if props.IPConfigurations != nil { - if err := d.Set("nat_ip_configuration", flattenPrivateLinkServiceIPConfiguration(props.IPConfigurations)); err != nil { - return fmt.Errorf("setting `nat_ip_configuration`: %+v", err) + if props.IPConfigurations != nil { + if err := d.Set("nat_ip_configuration", flattenPrivateLinkServiceIPConfiguration(props.IPConfigurations)); err != nil { + return fmt.Errorf("setting `nat_ip_configuration`: %+v", err) + } } - } - if props.LoadBalancerFrontendIPConfigurations != nil { - if err := d.Set("load_balancer_frontend_ip_configuration_ids", dataSourceFlattenPrivateLinkServiceFrontendIPConfiguration(props.LoadBalancerFrontendIPConfigurations)); err != nil { - return fmt.Errorf("setting `load_balancer_frontend_ip_configuration_ids`: %+v", err) + if props.LoadBalancerFrontendIPConfigurations != nil { + if err := d.Set("load_balancer_frontend_ip_configuration_ids", dataSourceFlattenPrivateLinkServiceFrontendIPConfiguration(props.LoadBalancerFrontendIPConfigurations)); err != nil { + return fmt.Errorf("setting `load_balancer_frontend_ip_configuration_ids`: %+v", err) + } } } + if err := tags.FlattenAndSet(d, model.Tags); err != nil { + return fmt.Errorf("setting `tags`: %+v", err) + } } - d.SetId(id.ID()) - - return tags.FlattenAndSet(d, resp.Tags) + return nil } -func dataSourceFlattenPrivateLinkServiceFrontendIPConfiguration(input *[]network.FrontendIPConfiguration) []string { +func dataSourceFlattenPrivateLinkServiceFrontendIPConfiguration(input *[]privatelinkservices.FrontendIPConfiguration) []string { results := make([]string, 0) if input == nil { return results } for _, item := range *input { - if id := item.ID; id != nil { + if id := item.Id; id != nil { results = append(results, *id) } } diff --git a/internal/services/network/private_link_service_endpoint_connections_data_source.go b/internal/services/network/private_link_service_endpoint_connections_data_source.go index ca9da85d1813..e1471edf2c5d 100644 --- a/internal/services/network/private_link_service_endpoint_connections_data_source.go +++ b/internal/services/network/private_link_service_endpoint_connections_data_source.go @@ -7,16 +7,14 @@ import ( "fmt" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" "github.com/hashicorp/go-azure-helpers/resourcemanager/location" "github.com/hashicorp/go-azure-sdk/resource-manager/network/2023-09-01/privateendpoints" - "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" + "github.com/hashicorp/go-azure-sdk/resource-manager/network/2023-11-01/privatelinkservices" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/kermit/sdk/network/2022-07-01/network" ) func dataSourcePrivateLinkServiceEndpointConnections() *pluginsdk.Resource { @@ -30,7 +28,7 @@ func dataSourcePrivateLinkServiceEndpointConnections() *pluginsdk.Resource { "service_id": { Type: pluginsdk.TypeString, Required: true, - ValidateFunc: azure.ValidateResourceID, + ValidateFunc: privatelinkservices.ValidatePrivateLinkServiceID, }, "service_name": { @@ -83,46 +81,47 @@ func dataSourcePrivateLinkServiceEndpointConnections() *pluginsdk.Resource { } func dataSourcePrivateLinkServiceEndpointConnectionsRead(d *pluginsdk.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Network.PrivateLinkServiceClient + client := meta.(*clients.Client).Network.PrivateLinkServices ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() serviceId := d.Get("service_id").(string) - id, err := parse.PrivateLinkServiceID(serviceId) + id, err := privatelinkservices.ParsePrivateLinkServiceID(serviceId) if err != nil { - return fmt.Errorf("parsing %q: %s", serviceId, err) + return err } - resp, err := client.Get(ctx, id.ResourceGroup, id.Name, "") + resp, err := client.Get(ctx, *id, privatelinkservices.DefaultGetOperationOptions()) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("Error: %s was not found", *id) + if response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("%s was not found", id) } - return fmt.Errorf("reading %s: %+v", *id, err) - } - if resp.ID == nil || *resp.ID == "" { - return fmt.Errorf("API returns a nil/empty id on %s: %+v", *id, err) + return fmt.Errorf("retrieving %s: %+v", id, err) } - d.Set("service_id", serviceId) - d.Set("service_name", id.Name) - d.Set("resource_group_name", id.ResourceGroup) + d.Set("service_id", id.ID()) + d.Set("service_name", id.PrivateLinkServiceName) + d.Set("resource_group_name", id.ResourceGroupName) - d.Set("location", location.NormalizeNilable(resp.Location)) + if model := resp.Model; model != nil { + d.Set("location", location.NormalizeNilable(model.Location)) - if props := resp.PrivateLinkServiceProperties; props != nil { - if err := d.Set("private_endpoint_connections", dataSourceflattenPrivateLinkServicePrivateEndpointConnections(props.PrivateEndpointConnections)); err != nil { - return fmt.Errorf("setting `private_endpoint_connections`: %+v", err) + if props := model.Properties; props != nil { + if err := d.Set("private_endpoint_connections", dataSourceflattenPrivateLinkServicePrivateEndpointConnections(props.PrivateEndpointConnections)); err != nil { + return fmt.Errorf("setting `private_endpoint_connections`: %+v", err) + } } } - d.SetId(fmt.Sprintf("%s/privateLinkServiceEndpointConnections/%s", *resp.ID, id.Name)) + privateEndpointId := privatelinkservices.NewPrivateEndpointConnectionID(id.SubscriptionId, id.ResourceGroupName, id.PrivateLinkServiceName, id.PrivateLinkServiceName) + + d.SetId(privateEndpointId.ID()) return nil } -func dataSourceflattenPrivateLinkServicePrivateEndpointConnections(input *[]network.PrivateEndpointConnection) []interface{} { +func dataSourceflattenPrivateLinkServicePrivateEndpointConnections(input *[]privatelinkservices.PrivateEndpointConnection) []interface{} { results := make([]interface{}, 0) if input == nil { return results @@ -130,16 +129,16 @@ func dataSourceflattenPrivateLinkServicePrivateEndpointConnections(input *[]netw for _, item := range *input { v := make(map[string]interface{}) - if id := item.ID; id != nil { + if id := item.Id; id != nil { v["connection_id"] = *id } if name := item.Name; name != nil { v["connection_name"] = *name } - if props := item.PrivateEndpointConnectionProperties; props != nil { + if props := item.Properties; props != nil { if p := props.PrivateEndpoint; p != nil { - if id := p.ID; id != nil { + if id := p.Id; id != nil { v["private_endpoint_id"] = *id id, _ := privateendpoints.ParsePrivateEndpointID(*id) diff --git a/internal/services/network/private_link_service_resource.go b/internal/services/network/private_link_service_resource.go index 5e0799aecd45..c6dcdebd445d 100644 --- a/internal/services/network/private_link_service_resource.go +++ b/internal/services/network/private_link_service_resource.go @@ -9,20 +9,22 @@ import ( "log" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "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/location" + "github.com/hashicorp/go-azure-helpers/resourcemanager/tags" + "github.com/hashicorp/go-azure-sdk/resource-manager/network/2023-11-01/privatelinkservices" "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/helpers/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" networkValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/validate" - "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" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/kermit/sdk/network/2022-07-01/network" ) func resourcePrivateLinkService() *pluginsdk.Resource { @@ -32,7 +34,7 @@ func resourcePrivateLinkService() *pluginsdk.Resource { Update: resourcePrivateLinkServiceCreateUpdate, Delete: resourcePrivateLinkServiceDelete, Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := parse.PrivateLinkServiceID(id) + _, err := privatelinkservices.ParsePrivateLinkServiceID(id) return err }), @@ -116,9 +118,9 @@ func resourcePrivateLinkService() *pluginsdk.Resource { Type: pluginsdk.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{ - string(network.IPVersionIPv4), + string(privatelinkservices.IPVersionIPvFour), }, false), - Default: string(network.IPVersionIPv4), + Default: string(privatelinkservices.IPVersionIPvFour), }, "subnet_id": { Type: pluginsdk.TypeString, @@ -151,7 +153,7 @@ func resourcePrivateLinkService() *pluginsdk.Resource { Computed: true, }, - "tags": tags.Schema(), + "tags": commonschema.Tags(), }, CustomizeDiff: pluginsdk.CustomizeDiffShim(func(ctx context.Context, d *pluginsdk.ResourceDiff, v interface{}) error { @@ -165,57 +167,45 @@ func resourcePrivateLinkService() *pluginsdk.Resource { } func resourcePrivateLinkServiceCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Network.PrivateLinkServiceClient + client := meta.(*clients.Client).Network.PrivateLinkServices subscriptionId := meta.(*clients.Client).Account.SubscriptionId ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id := parse.NewPrivateLinkServiceID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string)) + id := privatelinkservices.NewPrivateLinkServiceID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string)) if d.IsNewResource() { - existing, err := client.Get(ctx, id.ResourceGroup, id.Name, "") + existing, err := client.Get(ctx, id, privatelinkservices.DefaultGetOperationOptions()) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { + if !response.WasNotFound(existing.HttpResponse) { return fmt.Errorf("checking for presence of existing %s: %s", id, err) } } - if !utils.ResponseWasNotFound(existing.Response) { + if !response.WasNotFound(existing.HttpResponse) { return tf.ImportAsExistsError("azurerm_private_link_service", id.ID()) } } - location := azure.NormalizeLocation(d.Get("location").(string)) - autoApproval := d.Get("auto_approval_subscription_ids").(*pluginsdk.Set).List() - enableProxyProtocol := d.Get("enable_proxy_protocol").(bool) - primaryIpConfiguration := d.Get("nat_ip_configuration").([]interface{}) - loadBalancerFrontendIpConfigurations := d.Get("load_balancer_frontend_ip_configuration_ids").(*pluginsdk.Set).List() - visibility := d.Get("visibility_subscription_ids").(*pluginsdk.Set).List() - t := d.Get("tags").(map[string]interface{}) - - parameters := network.PrivateLinkService{ - Location: utils.String(location), - PrivateLinkServiceProperties: &network.PrivateLinkServiceProperties{ - AutoApproval: &network.PrivateLinkServicePropertiesAutoApproval{ - Subscriptions: utils.ExpandStringSlice(autoApproval), + parameters := privatelinkservices.PrivateLinkService{ + Location: pointer.To(location.Normalize(d.Get("location").(string))), + Properties: &privatelinkservices.PrivateLinkServiceProperties{ + AutoApproval: &privatelinkservices.ResourceSet{ + Subscriptions: utils.ExpandStringSlice(d.Get("auto_approval_subscription_ids").(*pluginsdk.Set).List()), }, - EnableProxyProtocol: utils.Bool(enableProxyProtocol), - Visibility: &network.PrivateLinkServicePropertiesVisibility{ - Subscriptions: utils.ExpandStringSlice(visibility), + EnableProxyProtocol: pointer.To(d.Get("enable_proxy_protocol").(bool)), + Visibility: &privatelinkservices.ResourceSet{ + Subscriptions: utils.ExpandStringSlice(d.Get("visibility_subscription_ids").(*pluginsdk.Set).List()), }, - IPConfigurations: expandPrivateLinkServiceIPConfiguration(primaryIpConfiguration), - LoadBalancerFrontendIPConfigurations: expandPrivateLinkServiceFrontendIPConfiguration(loadBalancerFrontendIpConfigurations), + IPConfigurations: expandPrivateLinkServiceIPConfiguration(d.Get("nat_ip_configuration").([]interface{})), + LoadBalancerFrontendIPConfigurations: expandPrivateLinkServiceFrontendIPConfiguration(d.Get("load_balancer_frontend_ip_configuration_ids").(*pluginsdk.Set).List()), Fqdns: utils.ExpandStringSlice(d.Get("fqdns").([]interface{})), }, - Tags: tags.Expand(t), + Tags: tags.Expand(d.Get("tags").(map[string]interface{})), } - future, err := client.CreateOrUpdate(ctx, id.ResourceGroup, id.Name, parameters) - if err != nil { + if err := client.CreateOrUpdateThenPoll(ctx, id, parameters); err != nil { return fmt.Errorf("creating %s: %+v", id, err) } - if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("waiting for creation of %s: %+v", id, err) - } // we can't rely on the use of the Future here due to the resource being successfully completed but now the service is applying those values. // currently being tracked with issue #6466: https://github.com/Azure/azure-sdk-for-go/issues/6466 @@ -223,7 +213,7 @@ func resourcePrivateLinkServiceCreateUpdate(d *pluginsdk.ResourceData, meta inte stateConf := &pluginsdk.StateChangeConf{ Pending: []string{"Pending", "Updating", "Creating"}, Target: []string{"Succeeded"}, - Refresh: privateLinkServiceWaitForReadyRefreshFunc(ctx, client, id.ResourceGroup, id.Name), + Refresh: privateLinkServiceWaitForReadyRefreshFunc(ctx, client, id), MinTimeout: 15 * time.Second, } @@ -243,93 +233,90 @@ func resourcePrivateLinkServiceCreateUpdate(d *pluginsdk.ResourceData, meta inte } func resourcePrivateLinkServiceRead(d *pluginsdk.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Network.PrivateLinkServiceClient + client := meta.(*clients.Client).Network.PrivateLinkServices ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.PrivateLinkServiceID(d.Id()) + id, err := privatelinkservices.ParsePrivateLinkServiceID(d.Id()) if err != nil { return err } - resp, err := client.Get(ctx, id.ResourceGroup, id.Name, "") + resp, err := client.Get(ctx, *id, privatelinkservices.DefaultGetOperationOptions()) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[INFO] Private Link Service %q does not exist - removing from state", d.Id()) + if response.WasNotFound(resp.HttpResponse) { + log.Printf("[INFO] %s does not exist - removing from state", d.Id()) d.SetId("") return nil } - return fmt.Errorf("reading %s: %+v", *id, err) + return fmt.Errorf("retrieving %s: %+v", *id, err) } - d.Set("name", id.Name) - d.Set("resource_group_name", id.ResourceGroup) - d.Set("location", azure.NormalizeLocation(*resp.Location)) + d.Set("name", id.PrivateLinkServiceName) + d.Set("resource_group_name", id.ResourceGroupName) - if props := resp.PrivateLinkServiceProperties; props != nil { - d.Set("alias", props.Alias) - d.Set("enable_proxy_protocol", props.EnableProxyProtocol) + if model := resp.Model; model != nil { + d.Set("location", location.NormalizeNilable(model.Location)) + if props := model.Properties; props != nil { + d.Set("alias", props.Alias) + d.Set("enable_proxy_protocol", props.EnableProxyProtocol) - var autoApprovalSub []interface{} - if autoApproval := props.AutoApproval; autoApproval != nil { - autoApprovalSub = utils.FlattenStringSlice(autoApproval.Subscriptions) - } - if err := d.Set("auto_approval_subscription_ids", autoApprovalSub); err != nil { - return fmt.Errorf("setting `auto_approval_subscription_ids`: %+v", err) - } + var autoApprovalSub []interface{} + if autoApproval := props.AutoApproval; autoApproval != nil { + autoApprovalSub = utils.FlattenStringSlice(autoApproval.Subscriptions) + } + if err := d.Set("auto_approval_subscription_ids", autoApprovalSub); err != nil { + return fmt.Errorf("setting `auto_approval_subscription_ids`: %+v", err) + } - var subscriptions []interface{} - if visibility := props.Visibility; visibility != nil { - subscriptions = utils.FlattenStringSlice(visibility.Subscriptions) - } - if err := d.Set("visibility_subscription_ids", subscriptions); err != nil { - return fmt.Errorf("setting `visibility_subscription_ids`: %+v", err) - } + var subscriptions []interface{} + if visibility := props.Visibility; visibility != nil { + subscriptions = utils.FlattenStringSlice(visibility.Subscriptions) + } + if err := d.Set("visibility_subscription_ids", subscriptions); err != nil { + return fmt.Errorf("setting `visibility_subscription_ids`: %+v", err) + } - if err := d.Set("fqdns", utils.FlattenStringSlice(props.Fqdns)); err != nil { - return fmt.Errorf("setting `fqdns`: %+v", err) - } + if err := d.Set("fqdns", utils.FlattenStringSlice(props.Fqdns)); err != nil { + return fmt.Errorf("setting `fqdns`: %+v", err) + } - if err := d.Set("nat_ip_configuration", flattenPrivateLinkServiceIPConfiguration(props.IPConfigurations)); err != nil { - return fmt.Errorf("setting `nat_ip_configuration`: %+v", err) - } + if err := d.Set("nat_ip_configuration", flattenPrivateLinkServiceIPConfiguration(props.IPConfigurations)); err != nil { + return fmt.Errorf("setting `nat_ip_configuration`: %+v", err) + } - if err := d.Set("load_balancer_frontend_ip_configuration_ids", flattenPrivateLinkServiceFrontendIPConfiguration(props.LoadBalancerFrontendIPConfigurations)); err != nil { - return fmt.Errorf("setting `load_balancer_frontend_ip_configuration_ids`: %+v", err) + if err := d.Set("load_balancer_frontend_ip_configuration_ids", flattenPrivateLinkServiceFrontendIPConfiguration(props.LoadBalancerFrontendIPConfigurations)); err != nil { + return fmt.Errorf("setting `load_balancer_frontend_ip_configuration_ids`: %+v", err) + } } + return tags.FlattenAndSet(d, model.Tags) } - - return tags.FlattenAndSet(d, resp.Tags) + return nil } func resourcePrivateLinkServiceDelete(d *pluginsdk.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Network.PrivateLinkServiceClient + client := meta.(*clients.Client).Network.PrivateLinkServices ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.PrivateLinkServiceID(d.Id()) + id, err := privatelinkservices.ParsePrivateLinkServiceID(d.Id()) if err != nil { return err } - future, err := client.Delete(ctx, id.ResourceGroup, id.Name) - if err != nil { + if err := client.DeleteThenPoll(ctx, *id); err != nil { return fmt.Errorf("deleting %s: %+v", *id, err) } - if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("waiting for the deletion of %s: %+v", *id, err) - } - return nil } -func expandPrivateLinkServiceIPConfiguration(input []interface{}) *[]network.PrivateLinkServiceIPConfiguration { +func expandPrivateLinkServiceIPConfiguration(input []interface{}) *[]privatelinkservices.PrivateLinkServiceIPConfiguration { if len(input) == 0 { return nil } - results := make([]network.PrivateLinkServiceIPConfiguration, 0) + results := make([]privatelinkservices.PrivateLinkServiceIPConfiguration, 0) for _, item := range input { v := item.(map[string]interface{}) @@ -339,22 +326,22 @@ func expandPrivateLinkServiceIPConfiguration(input []interface{}) *[]network.Pri name := v["name"].(string) primary := v["primary"].(bool) - result := network.PrivateLinkServiceIPConfiguration{ - Name: utils.String(name), - PrivateLinkServiceIPConfigurationProperties: &network.PrivateLinkServiceIPConfigurationProperties{ - PrivateIPAddress: utils.String(privateIpAddress), - PrivateIPAddressVersion: network.IPVersion(privateIpAddressVersion), - Subnet: &network.Subnet{ - ID: utils.String(subnetId), + result := privatelinkservices.PrivateLinkServiceIPConfiguration{ + Name: pointer.To(name), + Properties: &privatelinkservices.PrivateLinkServiceIPConfigurationProperties{ + PrivateIPAddress: pointer.To(privateIpAddress), + PrivateIPAddressVersion: pointer.To(privatelinkservices.IPVersion(privateIpAddressVersion)), + Subnet: &privatelinkservices.Subnet{ + Id: pointer.To(subnetId), }, - Primary: utils.Bool(primary), + Primary: pointer.To(primary), }, } if privateIpAddress != "" { - result.PrivateLinkServiceIPConfigurationProperties.PrivateIPAllocationMethod = network.IPAllocationMethodStatic + result.Properties.PrivateIPAllocationMethod = pointer.To(privatelinkservices.IPAllocationMethodStatic) } else { - result.PrivateLinkServiceIPConfigurationProperties.PrivateIPAllocationMethod = network.IPAllocationMethodDynamic + result.Properties.PrivateIPAllocationMethod = pointer.To(privatelinkservices.IPAllocationMethodDynamic) } results = append(results, result) @@ -363,16 +350,16 @@ func expandPrivateLinkServiceIPConfiguration(input []interface{}) *[]network.Pri return &results } -func expandPrivateLinkServiceFrontendIPConfiguration(input []interface{}) *[]network.FrontendIPConfiguration { +func expandPrivateLinkServiceFrontendIPConfiguration(input []interface{}) *[]privatelinkservices.FrontendIPConfiguration { if len(input) == 0 { return nil } - results := make([]network.FrontendIPConfiguration, 0) + results := make([]privatelinkservices.FrontendIPConfiguration, 0) for _, item := range input { - result := network.FrontendIPConfiguration{ - ID: utils.String(item.(string)), + result := privatelinkservices.FrontendIPConfiguration{ + Id: pointer.To(item.(string)), } results = append(results, result) @@ -381,7 +368,7 @@ func expandPrivateLinkServiceFrontendIPConfiguration(input []interface{}) *[]net return &results } -func flattenPrivateLinkServiceIPConfiguration(input *[]network.PrivateLinkServiceIPConfiguration) []interface{} { +func flattenPrivateLinkServiceIPConfiguration(input *[]privatelinkservices.PrivateLinkServiceIPConfiguration) []interface{} { results := make([]interface{}, 0) if input == nil { return results @@ -398,15 +385,15 @@ func flattenPrivateLinkServiceIPConfiguration(input *[]network.PrivateLinkServic subnetId := "" primary := false - if props := item.PrivateLinkServiceIPConfigurationProperties; props != nil { + if props := item.Properties; props != nil { if props.PrivateIPAddress != nil { privateIpAddress = *props.PrivateIPAddress } - privateIpVersion = string(props.PrivateIPAddressVersion) + privateIpVersion = string(pointer.From(props.PrivateIPAddressVersion)) - if props.Subnet != nil && props.Subnet.ID != nil { - subnetId = *props.Subnet.ID + if props.Subnet != nil && props.Subnet.Id != nil { + subnetId = *props.Subnet.Id } if props.Primary != nil { @@ -426,14 +413,14 @@ func flattenPrivateLinkServiceIPConfiguration(input *[]network.PrivateLinkServic return results } -func flattenPrivateLinkServiceFrontendIPConfiguration(input *[]network.FrontendIPConfiguration) *pluginsdk.Set { +func flattenPrivateLinkServiceFrontendIPConfiguration(input *[]privatelinkservices.FrontendIPConfiguration) *pluginsdk.Set { results := &pluginsdk.Set{F: pluginsdk.HashString} if input == nil { return results } for _, item := range *input { - if id := item.ID; id != nil { + if id := item.Id; id != nil { results.Add(*id) } } @@ -441,20 +428,23 @@ func flattenPrivateLinkServiceFrontendIPConfiguration(input *[]network.FrontendI return results } -func privateLinkServiceWaitForReadyRefreshFunc(ctx context.Context, client *network.PrivateLinkServicesClient, resourceGroupName string, name string) pluginsdk.StateRefreshFunc { +func privateLinkServiceWaitForReadyRefreshFunc(ctx context.Context, client *privatelinkservices.PrivateLinkServicesClient, id privatelinkservices.PrivateLinkServiceId) pluginsdk.StateRefreshFunc { return func() (interface{}, string, error) { - res, err := client.Get(ctx, resourceGroupName, name, "") + res, err := client.Get(ctx, id, privatelinkservices.DefaultGetOperationOptions()) if err != nil { // the API is eventually consistent during recreates.. - if utils.ResponseWasNotFound(res.Response) { + if response.WasNotFound(res.HttpResponse) { return res, "Pending", nil } - return nil, "Error", fmt.Errorf("issuing read request in privateLinkServiceWaitForReadyRefreshFunc %q (Resource Group %q): %s", name, resourceGroupName, err) + return nil, "Error", fmt.Errorf("retrieving %s: %+v", id, err) } - if props := res.PrivateLinkServiceProperties; props != nil { - if state := props.ProvisioningState; state != "" { - return res, string(state), nil + + if model := res.Model; model != nil { + if props := model.Properties; props != nil && props.ProvisioningState != nil { + if state := *props.ProvisioningState; state != "" { + return res, string(state), nil + } } } diff --git a/internal/services/network/private_link_service_resource_test.go b/internal/services/network/private_link_service_resource_test.go index 15a608a64b1d..96fd0c9bb16a 100644 --- a/internal/services/network/private_link_service_resource_test.go +++ b/internal/services/network/private_link_service_resource_test.go @@ -8,12 +8,12 @@ import ( "fmt" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/resource-manager/network/2023-11-01/privatelinkservices" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azurerm/utils" ) type PrivateLinkServiceResource struct{} @@ -231,17 +231,17 @@ func TestAccPrivateLinkService_withAlias(t *testing.T) { } func (t PrivateLinkServiceResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.PrivateLinkServiceID(state.ID) + id, err := privatelinkservices.ParsePrivateLinkServiceID(state.ID) if err != nil { return nil, err } - resp, err := clients.Network.PrivateLinkServiceClient.Get(ctx, id.ResourceGroup, id.Name, "") + resp, err := clients.Network.PrivateLinkServices.Get(ctx, *id, privatelinkservices.DefaultGetOperationOptions()) if err != nil { - return nil, fmt.Errorf("reading %s: %+v", *id, err) + return nil, fmt.Errorf("retrieving %s: %+v", *id, err) } - return utils.Bool(resp.ID != nil), nil + return pointer.To(resp.Model != nil), nil } func (r PrivateLinkServiceResource) basic(data acceptance.TestData) string {