Skip to content

Commit

Permalink
feat: d/vsphere_network add support for network_type (#2281)
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
burnsjared0415 authored Oct 16, 2024
1 parent 39a21a8 commit 87d853e
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 4 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# <!-- markdownlint-disable first-line-h1 no-inline-html -->

## 2.10.0 (Not Released)

FEATURES:

- `data/vsphere_network`: Adds ability to add `filter` to find port groups based on network type of standard virtual port
group, distributed virtual port group, or network port group.
[#2281](https://github.com/hashicorp/terraform-provider-vsphere/pull/2281)

## 2.9.3 (October 8, 2024)

BUG FIX:
Expand Down
47 changes: 44 additions & 3 deletions vsphere/data_source_vsphere_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-vsphere/vsphere/internal/helper/network"
"github.com/vmware/govmomi/object"
)
Expand Down Expand Up @@ -36,6 +37,21 @@ func dataSourceVSphereNetwork() *schema.Resource {
Description: "Id of the distributed virtual switch of which the port group is a part of",
Optional: true,
},
"filter": {
Type: schema.TypeSet,
Description: "Apply a filter for the discovered network.",
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"network_type": {
Type: schema.TypeString,
Description: "The type of the network (e.g., Network, DistributedVirtualPortgroup, OpaqueNetwork)",
Optional: true,
ValidateFunc: validation.StringInSlice(network.NetworkType, false),
},
},
},
},
},
}
}
Expand All @@ -53,9 +69,34 @@ func dataSourceVSphereNetworkRead(d *schema.ResourceData, meta interface{}) erro
return fmt.Errorf("cannot locate datacenter: %s", err)
}
}
net, err := network.FromNameAndDVSUuid(client, name, dc, dvSwitchUUID)
if err != nil {
return fmt.Errorf("error fetching network: %s", err)
var net object.NetworkReference
var err error

vimClient := client.Client

// Read filter from the schema.
filters := make(map[string]string)
if v, ok := d.GetOk("filter"); ok {
filterList := v.(*schema.Set).List()
if len(filterList) > 0 {
for key, value := range filterList[0].(map[string]interface{}) {
filters[key] = value.(string)
}
}
}

if dvSwitchUUID != "" {
// Handle distributed virtual switch port group
net, err = network.FromNameAndDVSUuid(client, name, dc, dvSwitchUUID)
if err != nil {
return fmt.Errorf("error fetching DVS network: %s", err)
}
} else {
// Handle standard switch port group
net, err = network.FromName(vimClient, name, dc, filters) // Pass the *vim25.Client
if err != nil {
return fmt.Errorf("error fetching network: %s", err)
}
}

d.SetId(net.Reference().Value)
Expand Down
60 changes: 60 additions & 0 deletions vsphere/internal/helper/network/network_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ import (
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/view"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)

var NetworkType = []string{
"Network",
"DistributedVirtualPortgroup",
"OpaqueNetwork",
}

// FromPath loads a network via its path.
//
// A network is a usually one of three kinds of networks: a DVS port group, a
Expand Down Expand Up @@ -197,3 +204,56 @@ func dvsFromUUID(client *govmomi.Client, uuid string) (*object.VmwareDistributed

return dvsFromMOID(client, resp.Returnval.Reference().Value)
}

// FromName fetches a network by name and applies additional filters.
func FromName(client *vim25.Client, name string, dc *object.Datacenter, filters map[string]string) (object.NetworkReference, error) {
ctx := context.TODO()
finder := find.NewFinder(client, true)

// Set the datacenter
if dc != nil {
finder.SetDatacenter(dc)
}

// Find the network by name
networks, err := finder.NetworkList(ctx, name)
if err != nil {
return nil, fmt.Errorf("error finding network %s: %v", name, err)
}

// If multiple networks are found and no filters are specified, return an error
if len(networks) > 1 && len(filters) == 0 {
return nil, fmt.Errorf("multiple networks found with the name '%s'. Please specify a filter to narrow down the results", name)
}

// Filter networks by additional attributes
for _, network := range networks {
match := true
for key, value := range filters {
switch key {
case "name":
netObj, ok := network.(*object.Network)
if !ok {
match = false
break
}
networkName, err := netObj.ObjectName(ctx)
if err != nil || networkName != value {
match = false
}
case "network_type":
if network.Reference().Type != value {
match = false
}
}
if !match {
break
}
}
if match {
return network, nil
}
}

return nil, fmt.Errorf("no network found matching the specified criteria")
}
20 changes: 19 additions & 1 deletion website/docs/d/network.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@ data "vsphere_network" "network" {
}
```

## Example Usage

```hcl
data "vsphere_datacenter" "datacenter" {
name = "dc-01"
}
data "vsphere_network" "my_port_group" {
datacenter_id = data.vsphere_datacenter.datacenter.id
name = "VM Network"
filter {
network_type = "Network"
}
}
```

## Argument Reference

The following arguments are supported:
Expand All @@ -43,7 +60,8 @@ The following arguments are supported:
network objects, the ID of the distributed virtual switch for which the port
group belongs. It is useful to differentiate port groups with same name using
the distributed virtual switch ID.

* `filter` - (Optional) Apply a filter for the discovered network.
* `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.
[docs-about-morefs]: /docs/providers/vsphere/index.html#use-of-managed-object-references-by-the-vsphere-provider

## Attribute Reference
Expand Down

0 comments on commit 87d853e

Please sign in to comment.