Skip to content

Commit

Permalink
Merge pull request #189 from terraform-providers/f-dvs-portgroup-reso…
Browse files Browse the repository at this point in the history
…urce

New resource: vsphere_distributed_port_group
  • Loading branch information
vancluever authored Oct 10, 2017
2 parents 2844c05 + 78d6297 commit fffb786
Show file tree
Hide file tree
Showing 12 changed files with 1,331 additions and 48 deletions.
102 changes: 102 additions & 0 deletions vsphere/distributed_port_group_helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package vsphere

import (
"context"
"fmt"

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

// dvPortgroupFromUUID gets a portgroup object from its UUID.
func dvPortgroupFromUUID(client *govmomi.Client, dvsUUID, pgUUID string) (*object.DistributedVirtualPortgroup, error) {
dvsm := types.ManagedObjectReference{Type: "DistributedVirtualSwitchManager", Value: "DVSManager"}
req := &types.DVSManagerLookupDvPortGroup{
This: dvsm,
SwitchUuid: dvsUUID,
PortgroupKey: pgUUID,
}
ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
defer cancel()
resp, err := methods.DVSManagerLookupDvPortGroup(ctx, client, req)
if err != nil {
return nil, err
}

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

// dvPortgroupFromMOID locates a portgroup by its managed object reference ID.
func dvPortgroupFromMOID(client *govmomi.Client, id string) (*object.DistributedVirtualPortgroup, error) {
finder := find.NewFinder(client.Client, false)

ref := types.ManagedObjectReference{
Type: "DistributedVirtualPortgroup",
Value: id,
}

ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
defer cancel()
ds, err := finder.ObjectReference(ctx, ref)
if err != nil {
return nil, err
}
// Should be safe to return here. If our reference returned here and is not a
// DistributedVirtualPortgroup, then we have bigger problems and to be
// honest we should be panicking anyway.
return ds.(*object.DistributedVirtualPortgroup), nil
}

// dvPortgroupFromPath gets a portgroup object from its path.
func dvPortgroupFromPath(client *govmomi.Client, name string, dc *object.Datacenter) (*object.DistributedVirtualPortgroup, 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)
if err != nil {
return nil, err
}
if net.Reference().Type != "DistributedVirtualPortgroup" {
return nil, fmt.Errorf("network at path %q is not a portgroup (type %s)", name, net.Reference().Type)
}
return dvPortgroupFromMOID(client, net.Reference().Value)
}

// dvPortgroupProperties is a convenience method that wraps fetching the
// portgroup MO from its higher-level object.
func dvPortgroupProperties(pg *object.DistributedVirtualPortgroup) (*mo.DistributedVirtualPortgroup, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
defer cancel()
var props mo.DistributedVirtualPortgroup
if err := pg.Properties(ctx, pg.Reference(), nil, &props); err != nil {
return nil, err
}
return &props, nil
}

// createDVPortgroup exposes the CreateDVPortgroup_Task method of the
// DistributedVirtualSwitch MO. This local implementation may go away if this
// is exposed in the higher-level object upstream.
func createDVPortgroup(client *govmomi.Client, dvs *object.VmwareDistributedVirtualSwitch, spec types.DVPortgroupConfigSpec) (*object.Task, error) {
req := &types.CreateDVPortgroup_Task{
This: dvs.Reference(),
Spec: spec,
}

ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
defer cancel()
resp, err := methods.CreateDVPortgroup_Task(ctx, client, req)
if err != nil {
return nil, err
}

return object.NewTask(client.Client, resp.Returnval.Reference()), nil
}
198 changes: 198 additions & 0 deletions vsphere/distributed_port_group_structure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
package vsphere

import (
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/vmware/govmomi/vim25/types"
)

var distributedVirtualPortgroupPortgroupTypeAllowedValues = []string{
string(types.DistributedVirtualPortgroupPortgroupTypeEarlyBinding),
string(types.DistributedVirtualPortgroupPortgroupTypeEphemeral),
}

// schemaDVPortgroupConfigSpec returns schema items for resources that
// need to work with a DVPortgroupConfigSpec.
func schemaDVPortgroupConfigSpec() map[string]*schema.Schema {
s := map[string]*schema.Schema{
// VMwareDVSPortgroupPolicy
"block_override_allowed": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow the blocked setting of an individual port to override the setting in the portgroup.",
},
"live_port_moving_allowed": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow a live port to be moved in and out of the portgroup.",
},
"network_resource_pool_override_allowed": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow the network resource pool of an individual port to override the setting in the portgroup.",
},
"port_config_reset_at_disconnect": {
Type: schema.TypeBool,
Optional: true,
Description: "Reset the setting of any ports in this portgroup back to the default setting when the port disconnects.",
},
"shaping_override_allowed": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow the traffic shaping policies of an individual port to override the settings in the portgroup.",
},
"traffic_filter_override_allowed": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow any filter policies set on the individual port to override those in the portgroup.",
},
"netflow_override_allowed": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow the enabling or disabling of Netflow on a port, contrary to the policy in the portgroup.",
},
"security_policy_override_allowed": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow security policy settings on a port to override those on the portgroup.",
},
"uplink_teaming_override_allowed": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow the uplink teaming policies on a port to override those on the portgroup.",
},
"vlan_override_allowed": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow the VLAN configuration on a port to override those on the portgroup.",
},

// DVPortgroupConfigSpec
"auto_expand": {
Type: schema.TypeString,
Optional: true,
Default: true,
Description: "Auto-expands the port group beyond the port count configured in number_of_ports when necessary.",
},
"config_version": {
Type: schema.TypeString,
Computed: true,
Description: "Version string of the configuration that this spec is trying to change.",
},
"description": {
Type: schema.TypeString,
Optional: true,
Description: "The description of the portgroup.",
},
"name": {
Type: schema.TypeString,
Required: true,
Description: "The name of the portgroup.",
},
"number_of_ports": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "The number of ports in this portgroup. The DVS will expand and shrink by modifying this setting.",
ValidateFunc: validation.IntAtLeast(0),
},
"port_name_format": {
Type: schema.TypeString,
Optional: true,
Description: "A template string to use when creating ports in the portgroup.",
},
"type": {
Type: schema.TypeString,
Optional: true,
Default: string(types.DistributedVirtualPortgroupPortgroupTypeEarlyBinding),
Description: "The type of portgroup. Can be one of earlyBinding (static) or ephemeral.",
ValidateFunc: validation.StringInSlice(distributedVirtualPortgroupPortgroupTypeAllowedValues, false),
},
"network_resource_pool_key": {
Type: schema.TypeString,
Optional: true,
Default: "-1",
Description: "The key of a network resource pool to associate with this portgroup.",
},
}
mergeSchema(s, schemaVMwareDVSPortSetting())
return s
}

// expandVMwareDVSPortgroupPolicy reads certain ResourceData keys and
// returns a VMwareDVSPortgroupPolicy.
func expandVMwareDVSPortgroupPolicy(d *schema.ResourceData) *types.VMwareDVSPortgroupPolicy {
obj := &types.VMwareDVSPortgroupPolicy{
DVPortgroupPolicy: types.DVPortgroupPolicy{
BlockOverrideAllowed: d.Get("block_override_allowed").(bool),
ShapingOverrideAllowed: d.Get("shaping_override_allowed").(bool),
LivePortMovingAllowed: d.Get("live_port_moving_allowed").(bool),
PortConfigResetAtDisconnect: d.Get("port_config_reset_at_disconnect").(bool),
NetworkResourcePoolOverrideAllowed: getBoolPtr(d, "network_resource_pool_override_allowed"),
TrafficFilterOverrideAllowed: getBoolPtr(d, "traffic_filter_override_allowed"),
},
VlanOverrideAllowed: d.Get("vlan_override_allowed").(bool),
UplinkTeamingOverrideAllowed: d.Get("uplink_teaming_override_allowed").(bool),
SecurityPolicyOverrideAllowed: d.Get("security_policy_override_allowed").(bool),
IpfixOverrideAllowed: getBoolPtr(d, "netflow_override_allowed"),
}
return obj
}

// flattenVMwareDVSPortgroupPolicy reads various fields from a
// VMwareDVSPortgroupPolicy into the passed in ResourceData.
func flattenVMwareDVSPortgroupPolicy(d *schema.ResourceData, obj *types.VMwareDVSPortgroupPolicy) error {
d.Set("block_override_allowed", obj.BlockOverrideAllowed)
d.Set("shaping_override_allowed", obj.ShapingOverrideAllowed)
d.Set("live_port_moving_allowed", obj.LivePortMovingAllowed)
d.Set("port_config_reset_at_disconnect", obj.PortConfigResetAtDisconnect)
d.Set("vlan_override_allowed", obj.VlanOverrideAllowed)
d.Set("uplink_teaming_override_allowed", obj.UplinkTeamingOverrideAllowed)
d.Set("security_policy_override_allowed", obj.SecurityPolicyOverrideAllowed)

setBoolPtr(d, "network_resource_pool_override_allowed", obj.NetworkResourcePoolOverrideAllowed)
setBoolPtr(d, "traffic_filter_override_allowed", obj.TrafficFilterOverrideAllowed)
setBoolPtr(d, "netflow_override_allowed", obj.IpfixOverrideAllowed)
return nil
}

// expandDVPortgroupConfigSpec reads certain ResourceData keys and
// returns a DVPortgroupConfigSpec.
func expandDVPortgroupConfigSpec(d *schema.ResourceData) types.DVPortgroupConfigSpec {
obj := types.DVPortgroupConfigSpec{
ConfigVersion: d.Get("config_version").(string),
Name: d.Get("name").(string),
NumPorts: int32(d.Get("number_of_ports").(int)),
PortNameFormat: d.Get("port_name_format").(string),
DefaultPortConfig: expandVMwareDVSPortSetting(d),
Description: d.Get("description").(string),
Type: d.Get("type").(string),
Policy: expandVMwareDVSPortgroupPolicy(d),
AutoExpand: getBoolPtr(d, "auto_expand"),
VmVnicNetworkResourcePoolKey: d.Get("network_resource_pool_key").(string),
}
return obj
}

// flattenDVPortgroupConfigInfo reads various fields from a
// DVPortgroupConfigInfo into the passed in ResourceData.
//
// This is the flatten counterpart to expandDVPortgroupConfigSpec.
func flattenDVPortgroupConfigInfo(d *schema.ResourceData, obj types.DVPortgroupConfigInfo) error {
d.Set("config_version", obj.ConfigVersion)
d.Set("name", obj.Name)
d.Set("number_of_ports", obj.NumPorts)
d.Set("port_name_format", obj.PortNameFormat)
d.Set("description", obj.Description)
d.Set("type", obj.Type)
setBoolPtr(d, "auto_expand", obj.AutoExpand)
d.Set("network_resource_pool_key", obj.VmVnicNetworkResourcePoolKey)

if err := flattenVMwareDVSPortSetting(d, obj.DefaultPortConfig.(*types.VMwareDVSPortSetting)); err != nil {
return err
}
if err := flattenVMwareDVSPortgroupPolicy(d, obj.Policy.(*types.VMwareDVSPortgroupPolicy)); err != nil {
return err
}
return nil
}
Loading

0 comments on commit fffb786

Please # to comment.