added mac address parameter (#6966)

This commit is contained in:
thetuxkeeper 2016-06-02 01:38:56 +02:00 committed by Paul Stack
parent 38fd8d5d71
commit 2e49042d10
4 changed files with 105 additions and 6 deletions

View File

@ -36,6 +36,7 @@ type networkInterface struct {
ipv6PrefixLength int ipv6PrefixLength int
ipv6Gateway string ipv6Gateway string
adapterType string // TODO: Make "adapter_type" argument adapterType string // TODO: Make "adapter_type" argument
macAddress string
} }
type hardDisk struct { type hardDisk struct {
@ -317,6 +318,12 @@ func resourceVSphereVirtualMachine() *schema.Resource {
Optional: true, Optional: true,
ForceNew: true, ForceNew: true,
}, },
"mac_address": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
}, },
}, },
}, },
@ -719,6 +726,9 @@ func resourceVSphereVirtualMachineCreate(d *schema.ResourceData, meta interface{
if v, ok := network["ipv6_gateway"].(string); ok && v != "" { if v, ok := network["ipv6_gateway"].(string); ok && v != "" {
networks[i].ipv6Gateway = v networks[i].ipv6Gateway = v
} }
if v, ok := network["mac_address"].(string); ok && v != "" {
networks[i].macAddress = v
}
} }
vm.networkInterfaces = networks vm.networkInterfaces = networks
log.Printf("[DEBUG] network_interface init: %v", networks) log.Printf("[DEBUG] network_interface init: %v", networks)
@ -963,6 +973,7 @@ func resourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{})
log.Printf("[DEBUG] v.Network - %#v", v.Network) log.Printf("[DEBUG] v.Network - %#v", v.Network)
networkInterface := make(map[string]interface{}) networkInterface := make(map[string]interface{})
networkInterface["label"] = v.Network networkInterface["label"] = v.Network
networkInterface["mac_address"] = v.MacAddress
for _, ip := range v.IpConfig.IpAddress { for _, ip := range v.IpConfig.IpAddress {
p := net.ParseIP(ip.IpAddress) p := net.ParseIP(ip.IpAddress)
if p.To4() != nil { if p.To4() != nil {
@ -1221,7 +1232,7 @@ func addCdrom(vm *object.VirtualMachine, datastore, path string) error {
} }
// buildNetworkDevice builds VirtualDeviceConfigSpec for Network Device. // buildNetworkDevice builds VirtualDeviceConfigSpec for Network Device.
func buildNetworkDevice(f *find.Finder, label, adapterType string) (*types.VirtualDeviceConfigSpec, error) { func buildNetworkDevice(f *find.Finder, label, adapterType string, macAddress string) (*types.VirtualDeviceConfigSpec, error) {
network, err := f.Network(context.TODO(), "*"+label) network, err := f.Network(context.TODO(), "*"+label)
if err != nil { if err != nil {
return nil, err return nil, err
@ -1232,6 +1243,13 @@ func buildNetworkDevice(f *find.Finder, label, adapterType string) (*types.Virtu
return nil, err return nil, err
} }
var address_type string
if macAddress == "" {
address_type = string(types.VirtualEthernetCardMacTypeGenerated)
} else {
address_type = string(types.VirtualEthernetCardMacTypeManual)
}
if adapterType == "vmxnet3" { if adapterType == "vmxnet3" {
return &types.VirtualDeviceConfigSpec{ return &types.VirtualDeviceConfigSpec{
Operation: types.VirtualDeviceConfigSpecOperationAdd, Operation: types.VirtualDeviceConfigSpecOperationAdd,
@ -1242,7 +1260,8 @@ func buildNetworkDevice(f *find.Finder, label, adapterType string) (*types.Virtu
Key: -1, Key: -1,
Backing: backing, Backing: backing,
}, },
AddressType: string(types.VirtualEthernetCardMacTypeGenerated), AddressType: address_type,
MacAddress: macAddress,
}, },
}, },
}, },
@ -1256,7 +1275,8 @@ func buildNetworkDevice(f *find.Finder, label, adapterType string) (*types.Virtu
Key: -1, Key: -1,
Backing: backing, Backing: backing,
}, },
AddressType: string(types.VirtualEthernetCardMacTypeGenerated), AddressType: address_type,
MacAddress: macAddress,
}, },
}, },
}, nil }, nil
@ -1575,10 +1595,11 @@ func (vm *virtualMachine) setupVirtualMachine(c *govmomi.Client) error {
} else { } else {
networkDeviceType = "vmxnet3" networkDeviceType = "vmxnet3"
} }
nd, err := buildNetworkDevice(finder, network.label, networkDeviceType) nd, err := buildNetworkDevice(finder, network.label, networkDeviceType, network.macAddress)
if err != nil { if err != nil {
return err return err
} }
log.Printf("[DEBUG] network device: %+v", nd.Device)
networkDevices = append(networkDevices, nd) networkDevices = append(networkDevices, nd)
if vm.template != "" { if vm.template != "" {
@ -1632,8 +1653,8 @@ func (vm *virtualMachine) setupVirtualMachine(c *govmomi.Client) error {
networkConfigs = append(networkConfigs, config) networkConfigs = append(networkConfigs, config)
} }
} }
log.Printf("[DEBUG] network devices: %v", networkDevices) log.Printf("[DEBUG] network devices: %#v", networkDevices)
log.Printf("[DEBUG] network configs: %v", networkConfigs) log.Printf("[DEBUG] network configs: %#v", networkConfigs)
var task *object.Task var task *object.Task
if vm.template == "" { if vm.template == "" {

View File

@ -201,6 +201,65 @@ func TestAccVSphereVirtualMachine_dhcp(t *testing.T) {
}) })
} }
func TestAccVSphereVirtualMachine_mac_address(t *testing.T) {
var vm virtualMachine
var locationOpt string
var datastoreOpt string
if v := os.Getenv("VSPHERE_DATACENTER"); v != "" {
locationOpt += fmt.Sprintf(" datacenter = \"%s\"\n", v)
}
if v := os.Getenv("VSPHERE_CLUSTER"); v != "" {
locationOpt += fmt.Sprintf(" cluster = \"%s\"\n", v)
}
if v := os.Getenv("VSPHERE_RESOURCE_POOL"); v != "" {
locationOpt += fmt.Sprintf(" resource_pool = \"%s\"\n", v)
}
if v := os.Getenv("VSPHERE_DATASTORE"); v != "" {
datastoreOpt = fmt.Sprintf(" datastore = \"%s\"\n", v)
}
template := os.Getenv("VSPHERE_TEMPLATE")
label := os.Getenv("VSPHERE_NETWORK_LABEL_DHCP")
macAddress := os.Getenv("VSPHERE_NETWORK_MAC_ADDRESS")
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckVSphereVirtualMachineDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: fmt.Sprintf(
testAccCheckVSphereVirtualMachineConfig_mac_address,
locationOpt,
label,
macAddress,
datastoreOpt,
template,
),
Check: resource.ComposeTestCheckFunc(
testAccCheckVSphereVirtualMachineExists("vsphere_virtual_machine.mac_address", &vm),
resource.TestCheckResourceAttr(
"vsphere_virtual_machine.mac_address", "name", "terraform-mac-address"),
resource.TestCheckResourceAttr(
"vsphere_virtual_machine.mac_address", "vcpu", "2"),
resource.TestCheckResourceAttr(
"vsphere_virtual_machine.mac_address", "memory", "4096"),
resource.TestCheckResourceAttr(
"vsphere_virtual_machine.mac_address", "disk.#", "1"),
resource.TestCheckResourceAttr(
"vsphere_virtual_machine.mac_address", "disk.2166312600.template", template),
resource.TestCheckResourceAttr(
"vsphere_virtual_machine.mac_address", "network_interface.#", "1"),
resource.TestCheckResourceAttr(
"vsphere_virtual_machine.mac_address", "network_interface.0.label", label),
resource.TestCheckResourceAttr(
"vsphere_virtual_machine.mac_address", "network_interface.0.mac_address", macAddress),
),
},
},
})
}
func TestAccVSphereVirtualMachine_custom_configs(t *testing.T) { func TestAccVSphereVirtualMachine_custom_configs(t *testing.T) {
var vm virtualMachine var vm virtualMachine
var locationOpt string var locationOpt string
@ -1181,6 +1240,23 @@ resource "vsphere_virtual_machine" "bar" {
} }
` `
const testAccCheckVSphereVirtualMachineConfig_mac_address = `
resource "vsphere_virtual_machine" "mac_address" {
name = "terraform-mac-address"
%s
vcpu = 2
memory = 4096
network_interface {
label = "%s"
mac_address = "%s"
}
disk {
%s
template = "%s"
}
}
`
const testAccCheckVSphereVirtualMachineConfig_custom_configs = ` const testAccCheckVSphereVirtualMachineConfig_custom_configs = `
resource "vsphere_virtual_machine" "car" { resource "vsphere_virtual_machine" "car" {
name = "terraform-test-custom" name = "terraform-test-custom"

View File

@ -161,6 +161,7 @@ set to valid values for your VMware vSphere environment:
* VSPHERE\_NETWORK\_LABEL * VSPHERE\_NETWORK\_LABEL
* VSPHERE\_NETWORK\_LABEL\_DHCP * VSPHERE\_NETWORK\_LABEL\_DHCP
* VSPHERE\_TEMPLATE * VSPHERE\_TEMPLATE
* VSPHERE\_MAC\_ADDRESS
The following environment variables depend on your vSphere environment: The following environment variables depend on your vSphere environment:

View File

@ -90,6 +90,7 @@ The `network_interface` block supports:
* `ipv6_address` - (Optional) Static IPv6 to assign to this network interface. Interface will use DHCPv6 if this is left blank. * `ipv6_address` - (Optional) Static IPv6 to assign to this network interface. Interface will use DHCPv6 if this is left blank.
* `ipv6_prefix_length` - (Optional) prefix length to use when statically assigning an IPv6. * `ipv6_prefix_length` - (Optional) prefix length to use when statically assigning an IPv6.
* `ipv6_gateway` - (Optional) IPv6 gateway IP address to use. * `ipv6_gateway` - (Optional) IPv6 gateway IP address to use.
* `mac_address` - (Optional) Manual MAC address to assign to this network interface. Will be generated by VMware if not set. ([VMware KB: Setting a static MAC address for a virtual NIC (219)](https://kb.vmware.com/selfservice/microsites/search.do?cmd=displayKC&externalId=219))
The following arguments are maintained for backwards compatibility and may be The following arguments are maintained for backwards compatibility and may be
removed in a future version: removed in a future version: