Skip to content

Commit b6ad64b

Browse files
authored
azurerm_private_endpoint implement list (#31769)
[FEATURE] * `azurerm_private_endpoint` implement list resource (#31769)
1 parent f5a539c commit b6ad64b

File tree

5 files changed

+267
-27
lines changed

5 files changed

+267
-27
lines changed

internal/services/network/private_endpoint_resource.go

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -622,8 +622,6 @@ func resourcePrivateEndpointUpdate(d *pluginsdk.ResourceData, meta interface{})
622622

623623
func resourcePrivateEndpointRead(d *pluginsdk.ResourceData, meta interface{}) error {
624624
client := meta.(*clients.Client).Network.PrivateEndpoints
625-
nicsClient := meta.(*clients.Client).Network.NetworkInterfaces
626-
dnsClient := meta.(*clients.Client).Network.PrivateDnsZoneGroups
627625
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
628626
defer cancel()
629627

@@ -642,15 +640,17 @@ func resourcePrivateEndpointRead(d *pluginsdk.ResourceData, meta interface{}) er
642640
return fmt.Errorf("reading %s: %+v", id, err)
643641
}
644642

645-
privateDnsZoneIds, err := retrievePrivateDnsZoneGroupsForPrivateEndpoint(ctx, dnsClient, *id)
646-
if err != nil {
647-
return err
648-
}
643+
return resourcePrivateEndpointFlatten(ctx, meta.(*clients.Client), d, id, resp.Model, true)
644+
}
645+
646+
func resourcePrivateEndpointFlatten(ctx context.Context, metaClient *clients.Client, d *pluginsdk.ResourceData, id *privateendpoints.PrivateEndpointId, model *privateendpoints.PrivateEndpoint, fetchCompleteData bool) error {
647+
nicsClient := metaClient.Network.NetworkInterfaces
648+
dnsClient := metaClient.Network.PrivateDnsZoneGroups
649649

650650
d.Set("name", id.PrivateEndpointName)
651651
d.Set("resource_group_name", id.ResourceGroupName)
652652

653-
if model := resp.Model; model != nil {
653+
if model != nil {
654654
d.Set("location", location.NormalizeNilable(model.Location))
655655

656656
if props := model.Properties; props != nil {
@@ -693,33 +693,39 @@ func resourcePrivateEndpointRead(d *pluginsdk.ResourceData, meta interface{}) er
693693
customNicName = *props.CustomNetworkInterfaceName
694694
}
695695
d.Set("custom_network_interface_name", customNicName)
696-
}
697696

698-
privateDnsZoneConfigs := make([]interface{}, 0)
699-
privateDnsZoneGroups := make([]interface{}, 0)
700-
if privateDnsZoneIds != nil {
701-
for _, dnsZoneId := range *privateDnsZoneIds {
702-
flattened, err := retrieveAndFlattenPrivateDnsZone(ctx, dnsClient, dnsZoneId)
697+
if fetchCompleteData {
698+
privateDnsZoneIds, err := retrievePrivateDnsZoneGroupsForPrivateEndpoint(ctx, dnsClient, *id)
703699
if err != nil {
704-
return fmt.Errorf("reading %s for %s: %+v", dnsZoneId, id, err)
700+
return err
705701
}
706702

707-
// an exceptional case but no harm in handling
708-
if flattened == nil {
709-
continue
703+
privateDnsZoneConfigs := make([]interface{}, 0)
704+
privateDnsZoneGroups := make([]interface{}, 0)
705+
if privateDnsZoneIds != nil {
706+
for _, dnsZoneId := range *privateDnsZoneIds {
707+
flattened, err := retrieveAndFlattenPrivateDnsZone(ctx, dnsClient, dnsZoneId)
708+
if err != nil {
709+
return fmt.Errorf("reading %s for %s: %+v", dnsZoneId, id, err)
710+
}
711+
712+
// an exceptional case but no harm in handling
713+
if flattened == nil {
714+
continue
715+
}
716+
717+
privateDnsZoneConfigs = append(privateDnsZoneConfigs, flattened.DnsZoneConfig...)
718+
privateDnsZoneGroups = append(privateDnsZoneGroups, flattened.DnsZoneGroup)
719+
}
720+
}
721+
if err = d.Set("private_dns_zone_configs", privateDnsZoneConfigs); err != nil {
722+
return fmt.Errorf("setting `private_dns_zone_configs`: %+v", err)
723+
}
724+
if err = d.Set("private_dns_zone_group", privateDnsZoneGroups); err != nil {
725+
return fmt.Errorf("setting `private_dns_zone_group`: %+v", err)
710726
}
711-
712-
privateDnsZoneConfigs = append(privateDnsZoneConfigs, flattened.DnsZoneConfig...)
713-
privateDnsZoneGroups = append(privateDnsZoneGroups, flattened.DnsZoneGroup)
714727
}
715728
}
716-
if err = d.Set("private_dns_zone_configs", privateDnsZoneConfigs); err != nil {
717-
return fmt.Errorf("setting `private_dns_zone_configs`: %+v", err)
718-
}
719-
if err = d.Set("private_dns_zone_group", privateDnsZoneGroups); err != nil {
720-
return fmt.Errorf("setting `private_dns_zone_group`: %+v", err)
721-
}
722-
723729
if err := tags.FlattenAndSet(d, model.Tags); err != nil {
724730
return err
725731
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Copyright IBM Corp.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package network
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
"github.com/hashicorp/go-azure-helpers/lang/pointer"
11+
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
12+
"github.com/hashicorp/go-azure-sdk/resource-manager/network/2025-01-01/privateendpoints"
13+
"github.com/hashicorp/terraform-plugin-framework/list"
14+
"github.com/hashicorp/terraform-plugin-framework/resource"
15+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
16+
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
17+
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
18+
)
19+
20+
type PrivateEndpointListResource struct{}
21+
22+
var _ sdk.FrameworkListWrappedResource = new(PrivateEndpointListResource)
23+
24+
func (r PrivateEndpointListResource) ResourceFunc() *pluginsdk.Resource {
25+
return resourcePrivateEndpoint()
26+
}
27+
28+
func (r PrivateEndpointListResource) Metadata(_ context.Context, _ resource.MetadataRequest, response *resource.MetadataResponse) {
29+
response.TypeName = "azurerm_private_endpoint"
30+
}
31+
32+
func (r PrivateEndpointListResource) List(ctx context.Context, request list.ListRequest, stream *list.ListResultsStream, metadata sdk.ResourceMetadata) {
33+
client := metadata.Client.Network.PrivateEndpoints
34+
metaClient := metadata.Client
35+
36+
var data sdk.DefaultListModel
37+
diags := request.Config.Get(ctx, &data)
38+
if diags.HasError() {
39+
stream.Results = list.ListResultsStreamDiagnostics(diags)
40+
return
41+
}
42+
43+
results := make([]privateendpoints.PrivateEndpoint, 0)
44+
subscriptionID := metadata.SubscriptionId
45+
if !data.SubscriptionId.IsNull() {
46+
subscriptionID = data.SubscriptionId.ValueString()
47+
}
48+
49+
switch {
50+
case !data.ResourceGroupName.IsNull():
51+
resp, err := client.ListComplete(ctx, commonids.NewResourceGroupID(subscriptionID, data.ResourceGroupName.ValueString()))
52+
if err != nil {
53+
sdk.SetResponseErrorDiagnostic(stream, fmt.Sprintf("listing `%s`", `azurerm_private_endpoint`), err)
54+
return
55+
}
56+
57+
results = resp.Items
58+
default:
59+
resp, err := client.ListBySubscriptionComplete(ctx, commonids.NewSubscriptionID(subscriptionID))
60+
if err != nil {
61+
sdk.SetResponseErrorDiagnostic(stream, fmt.Sprintf("listing `%s`", `azurerm_private_endpoint`), err)
62+
return
63+
}
64+
65+
results = resp.Items
66+
}
67+
68+
deadline, ok := ctx.Deadline()
69+
if !ok {
70+
sdk.SetResponseErrorDiagnostic(stream, "internal-error", "context had no deadline")
71+
return
72+
}
73+
74+
stream.Results = func(push func(list.ListResult) bool) {
75+
ctx, cancel := context.WithDeadline(context.Background(), deadline)
76+
defer cancel()
77+
78+
for _, privateendpoint := range results {
79+
result := request.NewListResult(ctx)
80+
81+
result.DisplayName = pointer.From(privateendpoint.Name)
82+
83+
rd := resourcePrivateEndpoint().Data(&terraform.InstanceState{})
84+
85+
id, err := privateendpoints.ParsePrivateEndpointID(pointer.From(privateendpoint.Id))
86+
if err != nil {
87+
sdk.SetErrorDiagnosticAndPushListResult(result, push, "parsing PrivateEndpoint ID", err)
88+
return
89+
}
90+
91+
rd.SetId(id.ID())
92+
93+
if err := resourcePrivateEndpointFlatten(ctx, metaClient, rd, id, &privateendpoint, request.IncludeResource); err != nil {
94+
sdk.SetErrorDiagnosticAndPushListResult(result, push, fmt.Sprintf("encoding `%s` resource data", "azurerm_private_endpoint"), err)
95+
return
96+
}
97+
98+
sdk.EncodeListResult(ctx, rd, &result)
99+
if result.Diagnostics.HasError() {
100+
push(result)
101+
return
102+
}
103+
if !push(result) {
104+
return
105+
}
106+
}
107+
}
108+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package network_test
2+
3+
import (
4+
"context"
5+
"regexp"
6+
"strconv"
7+
"testing"
8+
9+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
10+
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
11+
"github.com/hashicorp/terraform-plugin-testing/querycheck"
12+
"github.com/hashicorp/terraform-plugin-testing/tfversion"
13+
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
14+
"github.com/hashicorp/terraform-provider-azurerm/internal/provider/framework"
15+
)
16+
17+
func TestAccVirtualPrivateEndpoint_listBySubscriptionAndRG(t *testing.T) {
18+
data := acceptance.BuildTestData(t, "azurerm_private_endpoint", "testlist1")
19+
r := PrivateEndpointResource{}
20+
21+
resource.Test(t, resource.TestCase{
22+
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
23+
tfversion.SkipBelow(tfversion.Version1_14_0),
24+
},
25+
ProtoV5ProviderFactories: framework.ProtoV5ProviderFactoriesInit(context.Background(), "azurerm"),
26+
Steps: []resource.TestStep{
27+
{
28+
Config: r.basic(data),
29+
},
30+
{
31+
Query: true,
32+
Config: r.basicQuery(),
33+
QueryResultChecks: []querycheck.QueryResultCheck{
34+
querycheck.ExpectLengthAtLeast("azurerm_private_endpoint.list", 1), // expect at least the 1 we created
35+
querycheck.ExpectIdentity(
36+
"azurerm_private_endpoint.list",
37+
map[string]knownvalue.Check{
38+
"name": knownvalue.StringRegexp(regexp.MustCompile(strconv.Itoa(data.RandomInteger))),
39+
"resource_group_name": knownvalue.StringRegexp(regexp.MustCompile(strconv.Itoa(data.RandomInteger))),
40+
"subscription_id": knownvalue.StringExact(data.Subscriptions.Primary),
41+
},
42+
),
43+
},
44+
},
45+
{
46+
Query: true,
47+
Config: r.basicQueryByResourceGroupName(),
48+
QueryResultChecks: []querycheck.QueryResultCheck{
49+
querycheck.ExpectLength("azurerm_private_endpoint.list", 1), // expect at least the 1 we created
50+
querycheck.ExpectIdentity(
51+
"azurerm_private_endpoint.list",
52+
map[string]knownvalue.Check{
53+
"name": knownvalue.StringRegexp(regexp.MustCompile(strconv.Itoa(data.RandomInteger))),
54+
"resource_group_name": knownvalue.StringRegexp(regexp.MustCompile(strconv.Itoa(data.RandomInteger))),
55+
"subscription_id": knownvalue.StringExact(data.Subscriptions.Primary),
56+
},
57+
),
58+
},
59+
},
60+
},
61+
})
62+
}
63+
64+
func (r PrivateEndpointResource) basicQuery() string {
65+
return `
66+
list "azurerm_private_endpoint" "list" {
67+
provider = azurerm
68+
config {
69+
}
70+
}
71+
`
72+
}
73+
74+
func (r PrivateEndpointResource) basicQueryByResourceGroupName() string {
75+
return `
76+
list "azurerm_private_endpoint" "list" {
77+
provider = azurerm
78+
config {
79+
resource_group_name = azurerm_resource_group.test.name
80+
}
81+
}
82+
`
83+
}

internal/services/network/registration.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ func (r Registration) ListResources() []sdk.FrameworkListWrappedResource {
214214
NetworkProfileListResource{},
215215
NetworkSecurityGroupListResource{},
216216
NetworkSecurityRuleListResource{},
217+
PrivateEndpointListResource{},
217218
PublicIpListResource{},
218219
RouteListResource{},
219220
RouteTableListResource{},
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
subcategory: "Network"
3+
layout: "azurerm"
4+
page_title: "Azure Resource Manager: azurerm_private_endpoint"
5+
description: |-
6+
Lists Private Endpoint resources.
7+
---
8+
9+
# List resource: azurerm_private_endpoint
10+
11+
Lists Private Endpoint resources.
12+
13+
## Example Usage
14+
15+
### List all Private Endpoints in the subscription
16+
17+
```hcl
18+
list "azurerm_private_endpoint" "example" {
19+
provider = azurerm
20+
config {
21+
}
22+
}
23+
```
24+
25+
### List all Private Endpoints in a Resource Group
26+
27+
```hcl
28+
list "azurerm_private_endpoint" "example" {
29+
provider = azurerm
30+
config {
31+
resource_group_name = "example-rg"
32+
}
33+
}
34+
```
35+
36+
## Argument Reference
37+
38+
This list resource supports the following arguments:
39+
40+
* `subscription_id` - (Optional) The ID of the Subscription to query. Defaults to the value specified in the Provider Configuration.
41+
42+
* `resource_group_name` - (Optional) The name of the Resource Group to query.

0 commit comments

Comments
 (0)