Skip to content

Commit

Permalink
network - update several resources to use hashicorp/go-azure-sdk (#…
Browse files Browse the repository at this point in the history
…25905)

* update to use hashicorp/go-azure-sdk

* use NewCompositeResourceID and swap more resources over

* update nat gateway data source to use hashicorp/go-azure-sdk

* tflint

* add exceptions to the gradually deprecated script

* add TODO comment to ip group cidr resource and extend context for destroy step in local network gateway resource tests

* double timeout for updating address space

* use CreateOrUpdate method to circumvent broken polling behaviour

* add custom poller for local network gateway

* goimports
  • Loading branch information
stephybun authored May 14, 2024
1 parent effe7a5 commit 5a9b9f1
Show file tree
Hide file tree
Showing 21 changed files with 891 additions and 840 deletions.
333 changes: 168 additions & 165 deletions internal/services/network/custom_ip_prefix_resource.go

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions internal/services/network/custom_ip_prefix_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import (
"fmt"
"testing"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/resource-manager/network/2023-09-01/customipprefixes"
"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 CustomIpPrefixResource struct{}
Expand Down Expand Up @@ -125,21 +126,21 @@ func testAccCustomIpPrefix_ipv6(t *testing.T) {
}

func (CustomIpPrefixResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := parse.CustomIpPrefixID(state.ID)
id, err := customipprefixes.ParseCustomIPPrefixID(state.ID)
if err != nil {
return nil, err
}

resp, err := client.Network.CustomIPPrefixesClient.Get(ctx, id.ResourceGroup, id.Name, "")
resp, err := client.Network.Client.CustomIPPrefixes.Get(ctx, *id, customipprefixes.DefaultGetOperationOptions())
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return utils.Bool(false), nil
if response.WasNotFound(resp.HttpResponse) {
return pointer.To(false), nil
}

return nil, fmt.Errorf("retrieving %s: %+v", *id, err)
}

return utils.Bool(true), nil
return pointer.To(true), nil
}

func (r CustomIpPrefixResource) ipv4Provisioned(data acceptance.TestData) string {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package custompollers

import (
"context"
"fmt"
"strings"
"time"

"github.com/hashicorp/go-azure-sdk/resource-manager/network/2023-09-01/localnetworkgateways"
"github.com/hashicorp/go-azure-sdk/sdk/client/pollers"
)

var _ pollers.PollerType = &localNetworkGatewayPoller{}

type localNetworkGatewayPoller struct {
client *localnetworkgateways.LocalNetworkGatewaysClient
id localnetworkgateways.LocalNetworkGatewayId
}

var (
pollingSuccess = pollers.PollResult{
Status: pollers.PollingStatusSucceeded,
PollInterval: 10 * time.Second,
}
pollingInProgress = pollers.PollResult{
Status: pollers.PollingStatusInProgress,
PollInterval: 10 * time.Second,
}
)

func NewLocalNetworkGatewayPoller(client *localnetworkgateways.LocalNetworkGatewaysClient, id localnetworkgateways.LocalNetworkGatewayId) *localNetworkGatewayPoller {
return &localNetworkGatewayPoller{
client: client,
id: id,
}
}

func (p localNetworkGatewayPoller) Poll(ctx context.Context) (*pollers.PollResult, error) {
resp, err := p.client.Get(ctx, p.id)
if err != nil {
return nil, fmt.Errorf("retrieving %s: %+v", p.id, err)
}

if resp.Model != nil {
if provisioningStatus := resp.Model.Properties.ProvisioningState; provisioningStatus != nil {
if !strings.EqualFold(string(*provisioningStatus), string(pollingSuccess.Status)) {
return &pollingInProgress, nil
}
}
}

return &pollingSuccess, nil
}
116 changes: 64 additions & 52 deletions internal/services/network/ip_group_cidr_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"strings"
"time"

"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/resource-manager/network/2023-09-01/ipgroups"
"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/locks"
Expand All @@ -17,12 +19,11 @@ import (
"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 resourceIpGroupCidr() *pluginsdk.Resource {
return &pluginsdk.Resource{
Create: resourceIpGroupCidrCreateUpdate,
Create: resourceIpGroupCidrCreate,
Read: resourceIpGroupCidrRead,
Delete: resourceIpGroupCidrDelete,

Expand Down Expand Up @@ -54,58 +55,58 @@ func resourceIpGroupCidr() *pluginsdk.Resource {
}
}

func resourceIpGroupCidrCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Network.IPGroupsClient
func resourceIpGroupCidrCreate(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Network.Client.IPGroups
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
defer cancel()

cidr := d.Get("cidr").(string)
cidrName := strings.ReplaceAll(cidr, "/", "_")
ipGroupId, err := parse.IpGroupID(d.Get("ip_group_id").(string))
ipGroupId, err := ipgroups.ParseIPGroupID(d.Get("ip_group_id").(string))
if err != nil {
return err
}
id := parse.NewIpGroupCidrID(subscriptionId, ipGroupId.ResourceGroup, ipGroupId.Name, cidrName)
id := parse.NewIpGroupCidrID(subscriptionId, ipGroupId.ResourceGroupName, ipGroupId.IpGroupName, cidrName)

locks.ByID(ipGroupId.ID())
defer locks.UnlockByID(ipGroupId.ID())

existing, err := client.Get(ctx, ipGroupId.ResourceGroup, ipGroupId.Name, "")
existing, err := client.Get(ctx, *ipGroupId, ipgroups.DefaultGetOperationOptions())
if err != nil {
if utils.ResponseWasNotFound(existing.Response) {
if response.WasNotFound(existing.HttpResponse) {
return fmt.Errorf("checking for presence of existing %s: %s", ipGroupId, err)
}
}

if d.IsNewResource() {
if utils.SliceContainsValue(*existing.IPAddresses, cidr) {
return tf.ImportAsExistsError("azurerm_ip_group_cidr", id.ID())
}
if existing.Model == nil {
return fmt.Errorf("retrieving %s: `model` was nil", ipGroupId)
}
if existing.Model.Properties == nil {
return fmt.Errorf("retrieving %s: `properties` was nil", ipGroupId)
}

if utils.SliceContainsValue(*existing.Model.Properties.IPAddresses, cidr) {
return tf.ImportAsExistsError("azurerm_ip_group_cidr", id.ID())
}

ipAddresses := make([]string, 0)
if existing.IPAddresses != nil {
ipAddresses = *existing.IPAddresses
if existing.Model.Properties.IPAddresses != nil {
ipAddresses = *existing.Model.Properties.IPAddresses
}
ipAddresses = append(ipAddresses, cidr)

params := network.IPGroup{
Name: &ipGroupId.Name,
Location: existing.Location,
Tags: existing.Tags,
IPGroupPropertiesFormat: &network.IPGroupPropertiesFormat{
params := ipgroups.IPGroup{
Name: &ipGroupId.IpGroupName,
Location: existing.Model.Location,
Tags: existing.Model.Tags,
Properties: &ipgroups.IPGroupPropertiesFormat{
IPAddresses: &ipAddresses,
},
}

future, err := client.CreateOrUpdate(ctx, ipGroupId.ResourceGroup, ipGroupId.Name, params)
if err != nil {
return fmt.Errorf("creating/updating %s: %+v", id, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("waiting for the completion of %s: %+v", id, err)
if err := client.CreateOrUpdateThenPoll(ctx, *ipGroupId, params); err != nil {
return fmt.Errorf("creating %s: %+v", id, err)
}

d.SetId(id.ID())
Expand All @@ -114,23 +115,29 @@ func resourceIpGroupCidrCreateUpdate(d *pluginsdk.ResourceData, meta interface{}
}

func resourceIpGroupCidrRead(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Network.IPGroupsClient
client := meta.(*clients.Client).Network.Client.IPGroups
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.IpGroupCidrID(d.Id())
if err != nil {
return err
}
ipGroupId := parse.NewIpGroupID(id.SubscriptionId, id.ResourceGroup, id.IpGroupName)
ipGroupId := ipgroups.NewIPGroupID(id.SubscriptionId, id.ResourceGroup, id.IpGroupName)
cidr := strings.ReplaceAll(id.CidrName, "_", "/")

resp, err := client.Get(ctx, id.ResourceGroup, id.IpGroupName, "")
resp, err := client.Get(ctx, ipGroupId, ipgroups.DefaultGetOperationOptions())
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("making Read request on IP Group %q (Resource Group %q): %+v", ipGroupId.Name, ipGroupId.ResourceGroup, err)
if response.WasNotFound(resp.HttpResponse) {
return fmt.Errorf("retrieving %s: %+v", ipGroupId, err)
}
if resp.Model == nil {
return fmt.Errorf("retrieving %s: `model` was nil", ipGroupId)
}
if resp.Model.Properties == nil {
return fmt.Errorf("retrieving %s: `properties` was nil", ipGroupId)
}
if !utils.SliceContainsValue(*resp.IPAddresses, cidr) {
if !utils.SliceContainsValue(*resp.Model.Properties.IPAddresses, cidr) {
d.SetId("")
return nil
}
Expand All @@ -143,45 +150,50 @@ func resourceIpGroupCidrRead(d *pluginsdk.ResourceData, meta interface{}) error
}

func resourceIpGroupCidrDelete(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Network.IPGroupsClient
client := meta.(*clients.Client).Network.Client.IPGroups
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

cidr := d.Get("cidr").(string)
ipGroupId, err := parse.IpGroupID(d.Get("ip_group_id").(string))
id, err := parse.IpGroupCidrID(d.Id())
if err != nil {
return err
}

// TODO this resource should use a composite resource ID to remove this instance of d.Get() in the Delete
// this file can then be removed from the exceptions list in the run-gradually-deprecated.sh script
cidr := d.Get("cidr").(string)
ipGroupId := ipgroups.NewIPGroupID(id.SubscriptionId, id.ResourceGroup, id.IpGroupName)

locks.ByID(ipGroupId.ID())
defer locks.UnlockByID(ipGroupId.ID())

existing, err := client.Get(ctx, ipGroupId.ResourceGroup, ipGroupId.Name, "")
existing, err := client.Get(ctx, ipGroupId, ipgroups.DefaultGetOperationOptions())
if err != nil {
if utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("reading existing %s: %s", ipGroupId, err)
if response.WasNotFound(existing.HttpResponse) {
return fmt.Errorf("retrieving %s: %s", ipGroupId, err)
}
}
if existing.Model == nil {
return fmt.Errorf("retrieving %s: `model` was nil", ipGroupId)
}
if existing.Model.Properties == nil {
return fmt.Errorf("retrieving %s: `properties` was nil", ipGroupId)
}

ipAddresses := *existing.IPAddresses
ipAddresses := *existing.Model.Properties.IPAddresses
ipAddresses = utils.RemoveFromStringArray(ipAddresses, cidr)

params := network.IPGroup{
Name: &ipGroupId.Name,
Location: existing.Location,
Tags: existing.Tags,
IPGroupPropertiesFormat: &network.IPGroupPropertiesFormat{
params := ipgroups.IPGroup{
Name: &ipGroupId.IpGroupName,
Location: existing.Model.Location,
Tags: existing.Model.Tags,
Properties: &ipgroups.IPGroupPropertiesFormat{
IPAddresses: &ipAddresses,
},
}

future, err := client.CreateOrUpdate(ctx, ipGroupId.ResourceGroup, ipGroupId.Name, params)
if err != nil {
return fmt.Errorf("creating/updating %s: %+v", ipGroupId.ID(), err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("deleting IP Group CIDR %q (IP Group %q - Resource Group %q): %+v", cidr, ipGroupId.Name, ipGroupId.ResourceGroup, err)
if err := client.CreateOrUpdateThenPoll(ctx, ipGroupId, params); err != nil {
return fmt.Errorf("updating %s: %+v", ipGroupId.ID(), err)
}

return err
Expand Down
21 changes: 16 additions & 5 deletions internal/services/network/ip_group_cidr_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"fmt"
"testing"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-sdk/resource-manager/network/2023-09-01/ipgroups"
"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"
Expand Down Expand Up @@ -79,16 +81,25 @@ func (t IPGroupCidrResource) Exists(ctx context.Context, clients *clients.Client
return nil, err
}

resp, err := clients.Network.IPGroupsClient.Get(ctx, id.ResourceGroup, id.IpGroupName, "")
ipGroupId := ipgroups.NewIPGroupID(id.SubscriptionId, id.ResourceGroup, id.IpGroupName)

resp, err := clients.Network.Client.IPGroups.Get(ctx, ipGroupId, ipgroups.DefaultGetOperationOptions())
if err != nil {
return nil, fmt.Errorf("reading IP Group (%s): %+v", id, err)
return nil, fmt.Errorf("retrieving %s: %+v", id, err)
}

if resp.Model == nil {
return nil, fmt.Errorf("retrieving %s: `model` was nil", ipGroupId)
}
if resp.Model.Properties == nil {
return nil, fmt.Errorf("retrieving %s: `properties` was nil", ipGroupId)
}

if !utils.SliceContainsValue(*resp.IPAddresses, state.Attributes["cidr"]) {
return utils.Bool(false), nil
if !utils.SliceContainsValue(*resp.Model.Properties.IPAddresses, state.Attributes["cidr"]) {
return pointer.To(false), nil
}

return utils.Bool(true), nil
return pointer.To(true), nil
}

func (IPGroupCidrResource) basic(data acceptance.TestData) string {
Expand Down
Loading

0 comments on commit 5a9b9f1

Please sign in to comment.