Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New data source: vsphere_network #201

Merged
merged 1 commit into from
Oct 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions vsphere/data_source_vsphere_network.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package vsphere

import (
"fmt"

"github.com/hashicorp/terraform/helper/schema"
)

func dataSourceVSphereNetwork() *schema.Resource {
return &schema.Resource{
Read: dataSourceVSphereNetworkRead,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Description: "The name or path of the network.",
Required: true,
},
"datacenter_id": {
Type: schema.TypeString,
Description: "The managed object ID of the datacenter the network is in. This is required if the supplied path is not an absolute path containing a datacenter and there are multiple datacenters in your infrastructure.",
Optional: true,
},
"type": {
Type: schema.TypeString,
Description: "The managed object type of the network.",
Computed: true,
},
},
}
}

func dataSourceVSphereNetworkRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*VSphereClient).vimClient
if err := validateVirtualCenter(client); err != nil {
return err
}

name := d.Get("name").(string)
dc, err := datacenterFromID(client, d.Get("datacenter_id").(string))
if err != nil {
return fmt.Errorf("cannot locate datacenter: %s", err)
}
net, err := networkFromPath(client, name, dc)
if err != nil {
return fmt.Errorf("error fetching network: %s", err)
}

d.SetId(net.Reference().Value)
d.Set("type", net.Reference().Type)
return nil
}
152 changes: 152 additions & 0 deletions vsphere/data_source_vsphere_network_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package vsphere

import (
"fmt"
"os"
"testing"

"github.com/hashicorp/terraform/helper/resource"
)

func TestAccDataSourceVSphereNetwork(t *testing.T) {
var tp *testing.T
testAccDataSourceVSphereNetworkCases := []struct {
name string
testCase resource.TestCase
}{
{
"DVS portgroup",
resource.TestCase{
PreCheck: func() {
testAccPreCheck(tp)
testAccDataSourceVSphereNetworkPreCheck(tp)
},
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceVSphereNetworkConfigDVSPortgroup(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.vsphere_network.net", "type", "DistributedVirtualPortgroup"),
resource.TestCheckResourceAttrPair(
"data.vsphere_network.net", "id",
"vsphere_distributed_port_group.pg", "id",
),
),
},
},
},
},
{
"host portgroups",
resource.TestCase{
PreCheck: func() {
testAccPreCheck(tp)
testAccDataSourceVSphereNetworkPreCheck(tp)
},
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceVSphereNetworkConfigHostPortgroup(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.vsphere_network.net", "type", "Network"),
),
},
},
},
},
}

for _, tc := range testAccDataSourceVSphereNetworkCases {
t.Run(tc.name, func(t *testing.T) {
tp = t
resource.Test(t, tc.testCase)
})
}
}

func testAccDataSourceVSphereNetworkPreCheck(t *testing.T) {
if os.Getenv("VSPHERE_HOST_NIC0") == "" {
t.Skip("set VSPHERE_HOST_NIC0 to run vsphere_host_port_group acceptance tests")
}
if os.Getenv("VSPHERE_HOST_NIC1") == "" {
t.Skip("set VSPHERE_HOST_NIC1 to run vsphere_host_port_group acceptance tests")
}
if os.Getenv("VSPHERE_ESXI_HOST") == "" {
t.Skip("set VSPHERE_ESXI_HOST to run vsphere_host_port_group acceptance tests")
}
}

func testAccDataSourceVSphereNetworkConfigDVSPortgroup() string {
return fmt.Sprintf(`
variable "datacenter" {
default = "%s"
}

data "vsphere_datacenter" "dc" {
name = "${var.datacenter}"
}

resource "vsphere_distributed_virtual_switch" "dvs" {
name = "terraform-test-dvs"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

resource "vsphere_distributed_port_group" "pg" {
name = "terraform-test-pg"
distributed_virtual_switch_uuid = "${vsphere_distributed_virtual_switch.dvs.id}"
}

data "vsphere_network" "net" {
name = "${vsphere_distributed_port_group.pg.name}"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
`,
os.Getenv("VSPHERE_DATACENTER"),
)
}

func testAccDataSourceVSphereNetworkConfigHostPortgroup() string {
return fmt.Sprintf(`
variable "host_nic0" {
default = "%s"
}

variable "host_nic1" {
default = "%s"
}

data "vsphere_datacenter" "datacenter" {
name = "%s"
}

data "vsphere_host" "esxi_host" {
name = "%s"
datacenter_id = "${data.vsphere_datacenter.datacenter.id}"
}

resource "vsphere_host_virtual_switch" "switch" {
name = "vSwitchTerraformTest"
host_system_id = "${data.vsphere_host.esxi_host.id}"

network_adapters = ["${var.host_nic0}", "${var.host_nic1}"]
active_nics = ["${var.host_nic0}", "${var.host_nic1}"]
standby_nics = []
}

resource "vsphere_host_port_group" "pg" {
name = "PGTerraformTest"
host_system_id = "${data.vsphere_host.esxi_host.id}"
virtual_switch_name = "${vsphere_host_virtual_switch.switch.name}"
}

data "vsphere_network" "net" {
name = "${vsphere_host_port_group.pg.name}"
datacenter_id = "${data.vsphere_datacenter.datacenter.id}"
}
`,
os.Getenv("VSPHERE_HOST_NIC0"),
os.Getenv("VSPHERE_HOST_NIC1"),
os.Getenv("VSPHERE_DATACENTER"),
os.Getenv("VSPHERE_ESXI_HOST"),
)
}
9 changes: 1 addition & 8 deletions vsphere/distributed_virtual_switch_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,7 @@ func dvsFromMOID(client *govmomi.Client, id string) (*object.VmwareDistributedVi

// dvsFromPath gets a DVS object from its path.
func dvsFromPath(client *govmomi.Client, name string, dc *object.Datacenter) (*object.VmwareDistributedVirtualSwitch, error) {
finder := find.NewFinder(client.Client, false)
if dc != nil {
finder.SetDatacenter(dc)
}

ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
defer cancel()
net, err := finder.Network(ctx, name)
net, err := networkFromPath(client, name, dc)
if err != nil {
return nil, err
}
Expand Down
19 changes: 0 additions & 19 deletions vsphere/host_network_system_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,25 +69,6 @@ func hostPortGroupFromName(client *govmomi.Client, ns *object.HostNetworkSystem,
return nil, fmt.Errorf("could not find port group %s", name)
}

// networkProperties gets the properties for a specific Network.
//
// The Network type usually represents a standard port group in vCenter - it
// has been set up on a host or a set of hosts, and is usually configured via
// through an appropriate HostNetworkSystem. vCenter, however, groups up these
// networks and displays them as a single network that VM can use across hosts,
// facilitating HA and vMotion for VMs that use standard port groups versus DVS
// port groups. Hence the "Network" object is mainly a read-only MO and is only
// useful for checking some very base level attributes.
func networkProperties(net *object.Network) (*mo.Network, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
defer cancel()
var props mo.Network
if err := net.Properties(ctx, net.Reference(), nil, &props); err != nil {
return nil, err
}
return &props, nil
}

// networkObjectFromHostSystem locates the network object in vCenter for a
// specific HostSystem and network name.
//
Expand Down
71 changes: 71 additions & 0 deletions vsphere/network_helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package vsphere

import (
"context"

"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/mo"
)

// networkFromPath loads a network via its path.
//
// A network is a usually one of three kinds of networks: a DVS port group, a
// host port group, or a "opaque" network, provided externally from something
// like NSX. All three of these can be used as a backing for a virtual ethernet
// card, which is usually what these helpers are used with.
//
// Datacenter is optional here - if not provided, it's expected that the path
// is sufficient enough for finder to determine the datacenter required.
func networkFromPath(client *govmomi.Client, name string, dc *object.Datacenter) (object.NetworkReference, error) {
finder := find.NewFinder(client.Client, false)
if dc != nil {
finder.SetDatacenter(dc)
}

ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
defer cancel()
return finder.Network(ctx, name)
}

// networkReferenceProperties is a convenience method that wraps fetching the
// Network MO from a NetworkReference.
//
// Note that regardless of the network type, this only fetches the Network MO
// and not any of the extended properties of that network.
func genericNetworkProperties(client *govmomi.Client, net object.NetworkReference) (*mo.Network, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
defer cancel()
var props mo.Network
nc := object.NewCommon(client.Client, net.Reference())
if err := nc.Properties(ctx, nc.Reference(), nil, &props); err != nil {
return nil, err
}
return &props, nil
}

// networkProperties gets the properties for a specific Network.
//
// By itself, the Network type usually represents a standard port group in
// vCenter - it has been set up on a host or a set of hosts, and is usually
// configured via through an appropriate HostNetworkSystem. vCenter, however,
// groups up these networks and displays them as a single network that VM can
// use across hosts, facilitating HA and vMotion for VMs that use standard port
// groups versus DVS port groups. Hence the "Network" object is mainly a
// read-only MO and is only useful for checking some very base level
// attributes.
//
// While other network MOs extend the base network object (such as DV port
// groups and opaque networks), this only works with the base object only.
// Refer to functions more specific to the MO to get a fully extended property
// set for the extended objects if you are dealing with those object types.
func networkProperties(net *object.Network) (*mo.Network, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
defer cancel()
var props mo.Network
if err := net.Properties(ctx, net.Reference(), nil, &props); err != nil {
return nil, err
}
return &props, nil
}
1 change: 1 addition & 0 deletions vsphere/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func Provider() terraform.ResourceProvider {
"vsphere_datacenter": dataSourceVSphereDatacenter(),
"vsphere_distributed_virtual_switch": dataSourceVSphereDistributedVirtualSwitch(),
"vsphere_host": dataSourceVSphereHost(),
"vsphere_network": dataSourceVSphereNetwork(),
"vsphere_tag": dataSourceVSphereTag(),
"vsphere_tag_category": dataSourceVSphereTagCategory(),
"vsphere_vmfs_disks": dataSourceVSphereVmfsDisks(),
Expand Down
51 changes: 51 additions & 0 deletions website/docs/d/network.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
layout: "vsphere"
page_title: "VMware vSphere: vsphere_network"
sidebar_current: "docs-vsphere-data-source-network"
description: |-
Provides a vSphere network data source. This can be used to get the general attributes of a vSphere network.
---

# vsphere\_network

The `vsphere_network` data source can be used to discover the ID of a network
in vSphere. This can be any network that can be used as the backing for a
network interface for `vsphere_virtual_machine` or any other vSphere resource
that requires a network. This includes standard (host-based) port groups, DVS
port groups, or opaque networks such as those managed by NSX.

~> **NOTE:** This data source requires vCenter and is not available on direct
ESXi connections.

## Example Usage

```hcl
data "vsphere_datacenter" "datacenter" {
name = "dc1"
}

data "vsphere_network" "net" {
name = "terraform-test-net"
datacenter_id = "${data.vsphere_datacenter.datacenter.id}"
}
```

## Argument Reference

The following arguments are supported:

* `name` - (Required) The name of the network. This can be a name or path.
* `datacenter_id` - (Optional) The managed object reference ID of the
datacenter the network is located in. This can be omitted if the search path
used in `name` is an absolute path, or if there is only one datacenter in the
vSphere infrastructure.

## Attribute Reference

The following attributes are exported:

* `id`: The managed object ID of the network in question.
* `type`: The managed object type for the discovered network. This will be one
of `DistributedVirtualPortgroup` for DVS port groups, `Network` for standard
(host-based) port groups, or `OpaqueNetwork` for networks managed externally
by features such as NSX.
3 changes: 3 additions & 0 deletions website/vsphere.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
<li<%= sidebar_current("docs-vsphere-data-source-host") %>>
<a href="/docs/providers/vsphere/d/host.html">vsphere_host</a>
</li>
<li<%= sidebar_current("docs-vsphere-data-source-network") %>>
<a href="/docs/providers/vsphere/d/network.html">vsphere_network</a>
</li>
<li<%= sidebar_current("docs-vsphere-data-source-tag-data-source") %>>
<a href="/docs/providers/vsphere/d/tag.html">vsphere_tag</a>
</li>
Expand Down