Skip to content

Commit 87d853e

Browse files
feat: d/vsphere_network add support for network_type (#2281)
Added the feature to allow for port group to be found if there are two port groups with the same name but one is standard virtual port group vs distributed virtual port group. Signed-off-by: Jared Burns <[email protected]>
1 parent 39a21a8 commit 87d853e

File tree

4 files changed

+131
-4
lines changed

4 files changed

+131
-4
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# <!-- markdownlint-disable first-line-h1 no-inline-html -->
22

3+
## 2.10.0 (Not Released)
4+
5+
FEATURES:
6+
7+
- `data/vsphere_network`: Adds ability to add `filter` to find port groups based on network type of standard virtual port
8+
group, distributed virtual port group, or network port group.
9+
[#2281](https://github.com/hashicorp/terraform-provider-vsphere/pull/2281)
10+
311
## 2.9.3 (October 8, 2024)
412

513
BUG FIX:

vsphere/data_source_vsphere_network.go

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88

99
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1011
"github.com/hashicorp/terraform-provider-vsphere/vsphere/internal/helper/network"
1112
"github.com/vmware/govmomi/object"
1213
)
@@ -36,6 +37,21 @@ func dataSourceVSphereNetwork() *schema.Resource {
3637
Description: "Id of the distributed virtual switch of which the port group is a part of",
3738
Optional: true,
3839
},
40+
"filter": {
41+
Type: schema.TypeSet,
42+
Description: "Apply a filter for the discovered network.",
43+
Optional: true,
44+
Elem: &schema.Resource{
45+
Schema: map[string]*schema.Schema{
46+
"network_type": {
47+
Type: schema.TypeString,
48+
Description: "The type of the network (e.g., Network, DistributedVirtualPortgroup, OpaqueNetwork)",
49+
Optional: true,
50+
ValidateFunc: validation.StringInSlice(network.NetworkType, false),
51+
},
52+
},
53+
},
54+
},
3955
},
4056
}
4157
}
@@ -53,9 +69,34 @@ func dataSourceVSphereNetworkRead(d *schema.ResourceData, meta interface{}) erro
5369
return fmt.Errorf("cannot locate datacenter: %s", err)
5470
}
5571
}
56-
net, err := network.FromNameAndDVSUuid(client, name, dc, dvSwitchUUID)
57-
if err != nil {
58-
return fmt.Errorf("error fetching network: %s", err)
72+
var net object.NetworkReference
73+
var err error
74+
75+
vimClient := client.Client
76+
77+
// Read filter from the schema.
78+
filters := make(map[string]string)
79+
if v, ok := d.GetOk("filter"); ok {
80+
filterList := v.(*schema.Set).List()
81+
if len(filterList) > 0 {
82+
for key, value := range filterList[0].(map[string]interface{}) {
83+
filters[key] = value.(string)
84+
}
85+
}
86+
}
87+
88+
if dvSwitchUUID != "" {
89+
// Handle distributed virtual switch port group
90+
net, err = network.FromNameAndDVSUuid(client, name, dc, dvSwitchUUID)
91+
if err != nil {
92+
return fmt.Errorf("error fetching DVS network: %s", err)
93+
}
94+
} else {
95+
// Handle standard switch port group
96+
net, err = network.FromName(vimClient, name, dc, filters) // Pass the *vim25.Client
97+
if err != nil {
98+
return fmt.Errorf("error fetching network: %s", err)
99+
}
59100
}
60101

61102
d.SetId(net.Reference().Value)

vsphere/internal/helper/network/network_helper.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@ import (
1212
"github.com/vmware/govmomi/find"
1313
"github.com/vmware/govmomi/object"
1414
"github.com/vmware/govmomi/view"
15+
"github.com/vmware/govmomi/vim25"
1516
"github.com/vmware/govmomi/vim25/methods"
1617
"github.com/vmware/govmomi/vim25/mo"
1718
"github.com/vmware/govmomi/vim25/types"
1819
)
1920

21+
var NetworkType = []string{
22+
"Network",
23+
"DistributedVirtualPortgroup",
24+
"OpaqueNetwork",
25+
}
26+
2027
// FromPath loads a network via its path.
2128
//
2229
// A network is a usually one of three kinds of networks: a DVS port group, a
@@ -197,3 +204,56 @@ func dvsFromUUID(client *govmomi.Client, uuid string) (*object.VmwareDistributed
197204

198205
return dvsFromMOID(client, resp.Returnval.Reference().Value)
199206
}
207+
208+
// FromName fetches a network by name and applies additional filters.
209+
func FromName(client *vim25.Client, name string, dc *object.Datacenter, filters map[string]string) (object.NetworkReference, error) {
210+
ctx := context.TODO()
211+
finder := find.NewFinder(client, true)
212+
213+
// Set the datacenter
214+
if dc != nil {
215+
finder.SetDatacenter(dc)
216+
}
217+
218+
// Find the network by name
219+
networks, err := finder.NetworkList(ctx, name)
220+
if err != nil {
221+
return nil, fmt.Errorf("error finding network %s: %v", name, err)
222+
}
223+
224+
// If multiple networks are found and no filters are specified, return an error
225+
if len(networks) > 1 && len(filters) == 0 {
226+
return nil, fmt.Errorf("multiple networks found with the name '%s'. Please specify a filter to narrow down the results", name)
227+
}
228+
229+
// Filter networks by additional attributes
230+
for _, network := range networks {
231+
match := true
232+
for key, value := range filters {
233+
switch key {
234+
case "name":
235+
netObj, ok := network.(*object.Network)
236+
if !ok {
237+
match = false
238+
break
239+
}
240+
networkName, err := netObj.ObjectName(ctx)
241+
if err != nil || networkName != value {
242+
match = false
243+
}
244+
case "network_type":
245+
if network.Reference().Type != value {
246+
match = false
247+
}
248+
}
249+
if !match {
250+
break
251+
}
252+
}
253+
if match {
254+
return network, nil
255+
}
256+
}
257+
258+
return nil, fmt.Errorf("no network found matching the specified criteria")
259+
}

website/docs/d/network.html.markdown

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ data "vsphere_network" "network" {
2929
}
3030
```
3131

32+
## Example Usage
33+
34+
```hcl
35+
36+
data "vsphere_datacenter" "datacenter" {
37+
name = "dc-01"
38+
}
39+
40+
data "vsphere_network" "my_port_group" {
41+
datacenter_id = data.vsphere_datacenter.datacenter.id
42+
name = "VM Network"
43+
filter {
44+
network_type = "Network"
45+
}
46+
}
47+
```
48+
3249
## Argument Reference
3350

3451
The following arguments are supported:
@@ -43,7 +60,8 @@ The following arguments are supported:
4360
network objects, the ID of the distributed virtual switch for which the port
4461
group belongs. It is useful to differentiate port groups with same name using
4562
the distributed virtual switch ID.
46-
63+
* `filter` - (Optional) Apply a filter for the discovered network.
64+
* `network_type`: This is required if you have multiple port groups with the same name. This will be one of `DistributedVirtualPortgroup` for distributed port groups, `Network` for standard (host-based) port groups, or `OpaqueNetwork` for networks managed externally, such as those managed by NSX.
4765
[docs-about-morefs]: /docs/providers/vsphere/index.html#use-of-managed-object-references-by-the-vsphere-provider
4866

4967
## Attribute Reference

0 commit comments

Comments
 (0)