-
Notifications
You must be signed in to change notification settings - Fork 452
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 resource: vsphere_host_virtual_switch #138
Changes from 1 commit
edb0836
b061d07
26ce39a
f5bd248
1f40c63
5aaade0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,286 @@ | ||
package vsphere | ||
|
||
import ( | ||
"github.com/hashicorp/terraform/helper/schema" | ||
"github.com/hashicorp/terraform/helper/validation" | ||
"github.com/vmware/govmomi/vim25/types" | ||
) | ||
|
||
const ( | ||
hostNetworkPolicyNicTeamingPolicyModeLoadbalanceIP = "loadbalance_ip" | ||
hostNetworkPolicyNicTeamingPolicyModeLoadbalanceSrcMac = "loadbalance_srcmac" | ||
hostNetworkPolicyNicTeamingPolicyModeLoadbalanceSrcID = "loadbalance_srcid" | ||
hostNetworkPolicyNicTeamingPolicyModeFailoverExplicit = "failover_explicit" | ||
) | ||
|
||
var hostNetworkPolicyNicTeamingPolicyAllowedValues = []string{ | ||
hostNetworkPolicyNicTeamingPolicyModeLoadbalanceIP, | ||
hostNetworkPolicyNicTeamingPolicyModeLoadbalanceSrcMac, | ||
hostNetworkPolicyNicTeamingPolicyModeLoadbalanceSrcID, | ||
hostNetworkPolicyNicTeamingPolicyModeFailoverExplicit, | ||
} | ||
|
||
// schemaHostNetworkPolicy returns schema items for resources that need to work | ||
// with a HostNetworkPolicy, such as virtual switches and port groups. | ||
func schemaHostNetworkPolicy() map[string]*schema.Schema { | ||
return map[string]*schema.Schema{ | ||
// HostNicTeamingPolicy/HostNicFailureCriteria | ||
"check_beacon": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Description: "Enable beacon probing. Requires that the vSwitch has been configured to use a beacon. If disabled, link status is used only.", | ||
}, | ||
|
||
// HostNicTeamingPolicy/HostNicOrderPolicy | ||
"active_nics": &schema.Schema{ | ||
Type: schema.TypeList, | ||
Description: "List of active network adapters used for load balancing.", | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
}, | ||
"standby_nics": &schema.Schema{ | ||
Type: schema.TypeList, | ||
Description: "List of standby network adapters used for failover.", | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
}, | ||
|
||
// HostNicTeamingPolicy | ||
"teaming_policy": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Description: "The network adapter teaming policy. Can be one of loadbalance_ip, loadbalance_srcmac, loadbalance_srcid, or failover_explicit.", | ||
ValidateFunc: validation.StringInSlice(hostNetworkPolicyNicTeamingPolicyAllowedValues, false), | ||
}, | ||
"notify_switches": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Description: "If true, the teaming policy will notify the broadcast network of a NIC failover, triggering cache updates.", | ||
}, | ||
"failback": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Description: "If true, the teaming policy will re-activate failed interfaces higher in precedence when they come back up.", | ||
}, | ||
|
||
// HostNetworkSecurityPolicy | ||
"allow_promiscuous": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Description: "Enable promiscuous mode on the network. This flag indicates whether or not all traffic is seen on a given port.", | ||
}, | ||
"allow_forged_transmits": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Description: "Controls whether or not the virtual network adapter is allowed to send network traffic with a different MAC address than that of its own.", | ||
}, | ||
"allow_mac_changes": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Description: "Controls whether or not the Media Access Control (MAC) address can be changed.", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would it make sense for this to be defaulted to a sensible value? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above |
||
}, | ||
|
||
// HostNetworkTrafficShapingPolicy | ||
"shaping_average_bandwidth": &schema.Schema{ | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Description: "The average bandwidth in bits per second if shaping is enabled on the port.", | ||
}, | ||
"shaping_burst_size": &schema.Schema{ | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Description: "The maximum burst size allowed in bytes if shaping is enabled on the port.", | ||
}, | ||
"shaping_enabled": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Description: "True if the traffic shaper is enabled on the port.", | ||
}, | ||
"shaping_peak_bandwidth": &schema.Schema{ | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Description: "The peak bandwidth during bursts in bits per second if traffic shaping is enabled on the port.", | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor I think this can be removed, since it's inferred? 🤔 |
||
} | ||
} | ||
|
||
// expandHostNicFailureCriteria reads certain ResourceData keys and returns a | ||
// HostNicFailureCriteria. | ||
func expandHostNicFailureCriteria(d *schema.ResourceData) *types.HostNicFailureCriteria { | ||
obj := &types.HostNicFailureCriteria{} | ||
|
||
if v, ok := d.GetOkExists("check_beacon"); ok { | ||
obj.CheckBeacon = &([]bool{v.(bool)}[0]) | ||
} | ||
|
||
// These fields are deprecated and are set only to make things work. They are | ||
// not exposed to Terraform. | ||
obj.CheckSpeed = "minimum" | ||
obj.Speed = 10 | ||
obj.CheckDuplex = &([]bool{false}[0]) | ||
obj.FullDuplex = &([]bool{false}[0]) | ||
obj.CheckErrorPercent = &([]bool{false}[0]) | ||
obj.Percentage = 0 | ||
|
||
return obj | ||
} | ||
|
||
// flattenHostNicFailureCriteria reads various fields from a | ||
// HostNicFailureCriteria into the passed in ResourceData. | ||
func flattenHostNicFailureCriteria(d *schema.ResourceData, obj *types.HostNicFailureCriteria) error { | ||
if obj.CheckBeacon != nil { | ||
d.Set("check_beacon", obj.CheckBeacon) | ||
} | ||
return nil | ||
} | ||
|
||
// expandHostNicOrderPolicy reads certain ResourceData keys and returns a | ||
// HostNicOrderPolicy. | ||
func expandHostNicOrderPolicy(d *schema.ResourceData) *types.HostNicOrderPolicy { | ||
obj := &types.HostNicOrderPolicy{} | ||
activeNics, activeOk := d.GetOkExists("active_nics") | ||
standbyNics, standbyOk := d.GetOkExists("standby_nics") | ||
if !activeOk && !standbyOk { | ||
return nil | ||
} | ||
obj.ActiveNic = sliceInterfacesToStrings(activeNics.([]interface{})) | ||
obj.StandbyNic = sliceInterfacesToStrings(standbyNics.([]interface{})) | ||
return obj | ||
} | ||
|
||
// flattenHostNicOrderPolicy reads various fields from a HostNicOrderPolicy | ||
// into the passed in ResourceData. | ||
func flattenHostNicOrderPolicy(d *schema.ResourceData, obj *types.HostNicOrderPolicy) error { | ||
if obj == nil { | ||
return nil | ||
} | ||
if err := d.Set("active_nics", sliceStringsToInterfaces(obj.ActiveNic)); err != nil { | ||
return err | ||
} | ||
if err := d.Set("standby_nics", sliceStringsToInterfaces(obj.StandbyNic)); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// expandHostNicTeamingPolicy reads certain ResourceData keys and returns a | ||
// HostNicTeamingPolicy. | ||
func expandHostNicTeamingPolicy(d *schema.ResourceData) *types.HostNicTeamingPolicy { | ||
obj := &types.HostNicTeamingPolicy{ | ||
Policy: d.Get("teaming_policy").(string), | ||
} | ||
if v, ok := d.GetOkExists("failback"); ok { | ||
obj.RollingOrder = &([]bool{!v.(bool)}[0]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we make this more readable via:
|
||
} | ||
if v, ok := d.GetOkExists("notify_switches"); ok { | ||
obj.NotifySwitches = &([]bool{v.(bool)}[0]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we make this more readable via:
|
||
} | ||
obj.FailureCriteria = expandHostNicFailureCriteria(d) | ||
obj.NicOrder = expandHostNicOrderPolicy(d) | ||
|
||
// These fields are deprecated and are set only to make things work. They are | ||
// not exposed to Terraform. | ||
obj.ReversePolicy = &([]bool{true}[0]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (same here) |
||
|
||
return obj | ||
} | ||
|
||
// flattenHostNicTeamingPolicy reads various fields from a HostNicTeamingPolicy | ||
// into the passed in ResourceData. | ||
func flattenHostNicTeamingPolicy(d *schema.ResourceData, obj *types.HostNicTeamingPolicy) error { | ||
if obj.RollingOrder != nil { | ||
d.Set("failback", !*obj.RollingOrder) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor can we make this more readable by splitting this out? |
||
} | ||
if obj.NotifySwitches != nil { | ||
d.Set("notify_switches", obj.NotifySwitches) | ||
} | ||
d.Set("teaming_policy", obj.Policy) | ||
if err := flattenHostNicFailureCriteria(d, obj.FailureCriteria); err != nil { | ||
return err | ||
} | ||
if err := flattenHostNicOrderPolicy(d, obj.NicOrder); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// expandHostNetworkSecurityPolicy reads certain ResourceData keys and returns | ||
// a HostNetworkSecurityPolicy. | ||
func expandHostNetworkSecurityPolicy(d *schema.ResourceData) *types.HostNetworkSecurityPolicy { | ||
obj := &types.HostNetworkSecurityPolicy{} | ||
if v, ok := d.GetOkExists("allow_promiscuous"); ok { | ||
obj.AllowPromiscuous = &([]bool{v.(bool)}[0]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (same here) |
||
} | ||
if v, ok := d.GetOkExists("allow_forged_transmits"); ok { | ||
obj.ForgedTransmits = &([]bool{v.(bool)}[0]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (same here) |
||
} | ||
if v, ok := d.GetOkExists("allow_mac_changes"); ok { | ||
obj.MacChanges = &([]bool{v.(bool)}[0]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (same here) |
||
} | ||
return obj | ||
} | ||
|
||
// flattenHostNetworkSecurityPolicy reads various fields from a | ||
// HostNetworkSecurityPolicy into the passed in ResourceData. | ||
func flattenHostNetworkSecurityPolicy(d *schema.ResourceData, obj *types.HostNetworkSecurityPolicy) error { | ||
if obj.AllowPromiscuous != nil { | ||
d.Set("allow_promiscuous", *obj.AllowPromiscuous) | ||
} | ||
if obj.ForgedTransmits != nil { | ||
d.Set("allow_forged_transmits", *obj.ForgedTransmits) | ||
} | ||
if obj.MacChanges != nil { | ||
d.Set("allow_mac_changes", *obj.MacChanges) | ||
} | ||
return nil | ||
} | ||
|
||
// expandHostNetworkTrafficShapingPolicy reads certain ResourceData keys and | ||
// returns a HostNetworkTrafficShapingPolicy. | ||
func expandHostNetworkTrafficShapingPolicy(d *schema.ResourceData) *types.HostNetworkTrafficShapingPolicy { | ||
obj := &types.HostNetworkTrafficShapingPolicy{ | ||
AverageBandwidth: int64(d.Get("shaping_average_bandwidth").(int)), | ||
BurstSize: int64(d.Get("shaping_burst_size").(int)), | ||
PeakBandwidth: int64(d.Get("shaping_peak_bandwidth").(int)), | ||
} | ||
if v, ok := d.GetOkExists("shaping_enabled"); ok { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be in a child-object? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey @tombuildsstuff, I have been trying to avoid unnecessary nesting whenever possible. I have lost too many dev hours on trying to work around the issues of dealing with nested config stuff in TF - the inheritance model of this resource in conjunction with FWIW the entire resource was originally a nested structure - but certain issues dealing with inheritance and more importantly default values for entire nested structures ultimately led me to throwing out that approach and just going with a (mostly) shared flat schema. |
||
obj.Enabled = &([]bool{v.(bool)}[0]) | ||
} | ||
return obj | ||
} | ||
|
||
// flattenHostNetworkTrafficShapingPolicy reads various fields from a | ||
// HostNetworkTrafficShapingPolicy into the passed in ResourceData. | ||
func flattenHostNetworkTrafficShapingPolicy(d *schema.ResourceData, obj *types.HostNetworkTrafficShapingPolicy) error { | ||
if obj.Enabled != nil { | ||
d.Set("shaping_enabled", *obj.Enabled) | ||
} | ||
d.Set("shaping_average_bandwidth", obj.AverageBandwidth) | ||
d.Set("shaping_burst_size", obj.BurstSize) | ||
d.Set("shaping_peak_bandwidth", obj.PeakBandwidth) | ||
return nil | ||
} | ||
|
||
// expandHostNetworkPolicy reads certain ResourceData keys and returns a | ||
// HostNetworkPolicy. | ||
func expandHostNetworkPolicy(d *schema.ResourceData) *types.HostNetworkPolicy { | ||
obj := &types.HostNetworkPolicy{ | ||
Security: expandHostNetworkSecurityPolicy(d), | ||
NicTeaming: expandHostNicTeamingPolicy(d), | ||
ShapingPolicy: expandHostNetworkTrafficShapingPolicy(d), | ||
} | ||
return obj | ||
} | ||
|
||
// flattenHostNetworkPolicy reads various fields from a HostNetworkPolicy into | ||
// the passed in ResourceData. | ||
func flattenHostNetworkPolicy(d *schema.ResourceData, obj *types.HostNetworkPolicy) error { | ||
if err := flattenHostNetworkSecurityPolicy(d, obj.Security); err != nil { | ||
return err | ||
} | ||
if err := flattenHostNicTeamingPolicy(d, obj.NicTeaming); err != nil { | ||
return err | ||
} | ||
if err := flattenHostNetworkTrafficShapingPolicy(d, obj.ShapingPolicy); err != nil { | ||
return err | ||
} | ||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package vsphere | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/vmware/govmomi" | ||
"github.com/vmware/govmomi/object" | ||
"github.com/vmware/govmomi/vim25/mo" | ||
"github.com/vmware/govmomi/vim25/types" | ||
) | ||
|
||
// hostNetworkSystemFromHostSystem locates a HostNetworkSystem from a specified | ||
// HostSystem. | ||
func hostNetworkSystemFromHostSystem(hs *object.HostSystem) (*object.HostNetworkSystem, error) { | ||
ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout) | ||
defer cancel() | ||
return hs.ConfigManager().NetworkSystem(ctx) | ||
} | ||
|
||
// hostNetworkSystemFromHostSystemID locates a HostNetworkSystem from a | ||
// specified HostSystem managed object ID. | ||
func hostNetworkSystemFromHostSystemID(client *govmomi.Client, hsID string) (*object.HostNetworkSystem, error) { | ||
hs, err := hostSystemFromID(client, hsID) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return hostNetworkSystemFromHostSystem(hs) | ||
} | ||
|
||
// hostVSwitchFromName locates a virtual switch on the supplied HostSystem by | ||
// name. | ||
func hostVSwitchFromName(client *govmomi.Client, ns *object.HostNetworkSystem, name string) (*types.HostVirtualSwitch, error) { | ||
var mns mo.HostNetworkSystem | ||
pc := client.PropertyCollector() | ||
ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout) | ||
defer cancel() | ||
if err := pc.RetrieveOne(ctx, ns.Reference(), []string{"networkInfo.vswitch"}, &mns); err != nil { | ||
return nil, fmt.Errorf("error fetching host network properties: %s", err) | ||
} | ||
|
||
for _, sw := range mns.NetworkInfo.Vswitch { | ||
if sw.Name == name { | ||
return &sw, nil | ||
} | ||
} | ||
|
||
return nil, fmt.Errorf("could not find virtual switch %s", name) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it make sense for this to be defaulted to a sensible value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @tombuildsstuff - these are defaulted in
resource_host_virtual_switch.go
. They need to be non-defaulted here so that the schema can be shared withvsphere_host_port_group
for inheritance purposes.