Replaced a hacky type assertion in the VMware builder with a call to Driver.GetVmwareDriver() that returns the driver-specific structure for ip and addressing information. Also implemented the addressing functions for the ESXi driver interface.
This fixes an issue where a driver might not have defined a VmwareDriver by forcing a developer to implement it via the standard Driver interface.
This commit is contained in:
parent
898b27c16d
commit
75fbfa0763
|
@ -64,6 +64,7 @@ type Driver interface {
|
||||||
/// These methods are generally implemented by the VmwareDriver
|
/// These methods are generally implemented by the VmwareDriver
|
||||||
/// structure within this file. A driver implementation can
|
/// structure within this file. A driver implementation can
|
||||||
/// reimplement these, though, if it wants.
|
/// reimplement these, though, if it wants.
|
||||||
|
GetVmwareDriver() VmwareDriver
|
||||||
|
|
||||||
// Get the guest hw address for the vm
|
// Get the guest hw address for the vm
|
||||||
GuestAddress(multistep.StateBag) (string, error)
|
GuestAddress(multistep.StateBag) (string, error)
|
||||||
|
|
|
@ -173,3 +173,7 @@ const fusionSuppressPlist = `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>`
|
</plist>`
|
||||||
|
|
||||||
|
func (d *Fusion5Driver) GetVmwareDriver() VmwareDriver {
|
||||||
|
return d.VmwareDriver
|
||||||
|
}
|
||||||
|
|
|
@ -68,3 +68,7 @@ func (d *Fusion6Driver) Verify() error {
|
||||||
|
|
||||||
return compareVersions(matches[1], VMWARE_FUSION_VERSION, "Fusion Professional")
|
return compareVersions(matches[1], VMWARE_FUSION_VERSION, "Fusion Professional")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Fusion6Driver) GetVmwareDriver() VmwareDriver {
|
||||||
|
return d.Fusion5Driver.VmwareDriver
|
||||||
|
}
|
||||||
|
|
|
@ -209,3 +209,7 @@ func (d *Player5Driver) ToolsIsoPath(flavor string) string {
|
||||||
func (d *Player5Driver) ToolsInstall() error {
|
func (d *Player5Driver) ToolsInstall() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Player5Driver) GetVmwareDriver() VmwareDriver {
|
||||||
|
return d.VmwareDriver
|
||||||
|
}
|
||||||
|
|
|
@ -35,3 +35,7 @@ func (d *Player6Driver) Verify() error {
|
||||||
|
|
||||||
return playerVerifyVersion(VMWARE_PLAYER_VERSION)
|
return playerVerifyVersion(VMWARE_PLAYER_VERSION)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Player6Driver) GetVmwareDriver() VmwareDriver {
|
||||||
|
return d.Player5Driver.VmwareDriver
|
||||||
|
}
|
||||||
|
|
|
@ -33,3 +33,7 @@ func (d *Workstation10Driver) Verify() error {
|
||||||
|
|
||||||
return workstationVerifyVersion(VMWARE_WS_VERSION)
|
return workstationVerifyVersion(VMWARE_WS_VERSION)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Workstation10Driver) GetVmwareDriver() VmwareDriver {
|
||||||
|
return d.Workstation9Driver.VmwareDriver
|
||||||
|
}
|
||||||
|
|
|
@ -170,3 +170,7 @@ func (d *Workstation9Driver) ToolsIsoPath(flavor string) string {
|
||||||
func (d *Workstation9Driver) ToolsInstall() error {
|
func (d *Workstation9Driver) ToolsInstall() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Workstation9Driver) GetVmwareDriver() VmwareDriver {
|
||||||
|
return d.VmwareDriver
|
||||||
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import (
|
||||||
// ESX5 driver talks to an ESXi5 hypervisor remotely over SSH to build
|
// ESX5 driver talks to an ESXi5 hypervisor remotely over SSH to build
|
||||||
// virtual machines. This driver can only manage one machine at a time.
|
// virtual machines. This driver can only manage one machine at a time.
|
||||||
type ESX5Driver struct {
|
type ESX5Driver struct {
|
||||||
vmwcommon.VmwareDriver
|
base vmwcommon.VmwareDriver
|
||||||
|
|
||||||
Host string
|
Host string
|
||||||
Port uint
|
Port uint
|
||||||
|
@ -173,6 +173,101 @@ func (d *ESX5Driver) HostIP(multistep.StateBag) (string, error) {
|
||||||
return host, err
|
return host, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *ESX5Driver) GuestIP(multistep.StateBag) (string, error) {
|
||||||
|
// GuestIP is defined by the user as d.Host..but let's validate it just to be sure
|
||||||
|
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", d.Host, d.Port))
|
||||||
|
defer conn.Close()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
host, _, err := net.SplitHostPort(conn.RemoteAddr().String())
|
||||||
|
return host, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *ESX5Driver) HostAddress(multistep.StateBag) (string, error) {
|
||||||
|
// make a connection
|
||||||
|
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", d.Host, d.Port))
|
||||||
|
defer conn.Close()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the local address (the host)
|
||||||
|
host, _, err := net.SplitHostPort(conn.LocalAddr().String())
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Unable to determine host address for ESXi: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate through all the interfaces..
|
||||||
|
interfaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Unable to enumerate host interfaces : %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, intf := range interfaces {
|
||||||
|
addrs, err := intf.Addrs()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// ..checking to see if any if it's addrs match the host address
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if addr.String() == host { // FIXME: Is this the proper way to compare two HardwareAddrs?
|
||||||
|
return intf.HardwareAddr.String(), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ..unfortunately nothing was found
|
||||||
|
return "", fmt.Errorf("Unable to locate interface matching host address in ESXi: %v", host)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *ESX5Driver) GuestAddress(multistep.StateBag) (string, error) {
|
||||||
|
// list all the interfaces on the esx host
|
||||||
|
r, err := d.esxcli("network", "ip", "interface", "list")
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Could not retrieve network interfaces for ESXi: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// rip out the interface name and the MAC address from the csv output
|
||||||
|
addrs := make(map[string]string)
|
||||||
|
for record, err := r.read(); record != nil && err == nil; record, err = r.read() {
|
||||||
|
if strings.ToUpper(record["Enabled"]) != "TRUE" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
addrs[record["Name"]] = record["MAC Address"]
|
||||||
|
}
|
||||||
|
|
||||||
|
// list all the addresses on the esx host
|
||||||
|
r, err = d.esxcli("network", "ip", "interface", "ipv4", "get")
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Could not retrieve network addresses for ESXi: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// figure out the interface name that matches the specified d.Host address
|
||||||
|
var intf string
|
||||||
|
intf = ""
|
||||||
|
for record, err := r.read(); record != nil && err == nil; record, err = r.read() {
|
||||||
|
if record["IPv4 Address"] == d.Host && record["Name"] != "" {
|
||||||
|
intf = record["Name"]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if intf == "" {
|
||||||
|
return "", fmt.Errorf("Unable to find matching address for ESXi guest")
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the MAC address according to the interface name
|
||||||
|
result, ok := addrs[intf]
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("Unable to find address for ESXi guest interface")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ..and we're good
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *ESX5Driver) VNCAddress(_ string, portMin, portMax uint) (string, uint, error) {
|
func (d *ESX5Driver) VNCAddress(_ string, portMin, portMax uint) (string, uint, error) {
|
||||||
var vncPort uint
|
var vncPort uint
|
||||||
|
|
||||||
|
@ -530,6 +625,10 @@ func (d *ESX5Driver) esxcli(args ...string) (*esxcliReader, error) {
|
||||||
return &esxcliReader{r, header}, nil
|
return &esxcliReader{r, header}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *ESX5Driver) GetVmwareDriver() vmwcommon.VmwareDriver {
|
||||||
|
return d.base
|
||||||
|
}
|
||||||
|
|
||||||
type esxcliReader struct {
|
type esxcliReader struct {
|
||||||
cr *csv.Reader
|
cr *csv.Reader
|
||||||
header []string
|
header []string
|
||||||
|
|
|
@ -370,7 +370,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
|
||||||
|
|
||||||
/// Check the network type that the user specified
|
/// Check the network type that the user specified
|
||||||
network := config.Network
|
network := config.Network
|
||||||
driver := state.Get("driver").(vmwcommon.VmwareDriver)
|
driver := state.Get("driver").(vmwcommon.Driver).GetVmwareDriver()
|
||||||
|
|
||||||
// read netmap config
|
// read netmap config
|
||||||
pathNetmap := driver.NetmapConfPath()
|
pathNetmap := driver.NetmapConfPath()
|
||||||
|
|
Loading…
Reference in New Issue