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
|
||||
/// structure within this file. A driver implementation can
|
||||
/// reimplement these, though, if it wants.
|
||||
GetVmwareDriver() VmwareDriver
|
||||
|
||||
// Get the guest hw address for the vm
|
||||
GuestAddress(multistep.StateBag) (string, error)
|
||||
|
|
|
@ -173,3 +173,7 @@ const fusionSuppressPlist = `<?xml version="1.0" encoding="UTF-8"?>
|
|||
<true/>
|
||||
</dict>
|
||||
</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")
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Player5Driver) GetVmwareDriver() VmwareDriver {
|
||||
return d.VmwareDriver
|
||||
}
|
||||
|
|
|
@ -35,3 +35,7 @@ func (d *Player6Driver) Verify() error {
|
|||
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
// virtual machines. This driver can only manage one machine at a time.
|
||||
type ESX5Driver struct {
|
||||
vmwcommon.VmwareDriver
|
||||
base vmwcommon.VmwareDriver
|
||||
|
||||
Host string
|
||||
Port uint
|
||||
|
@ -173,6 +173,101 @@ func (d *ESX5Driver) HostIP(multistep.StateBag) (string, error) {
|
|||
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) {
|
||||
var vncPort uint
|
||||
|
||||
|
@ -530,6 +625,10 @@ func (d *ESX5Driver) esxcli(args ...string) (*esxcliReader, error) {
|
|||
return &esxcliReader{r, header}, nil
|
||||
}
|
||||
|
||||
func (d *ESX5Driver) GetVmwareDriver() vmwcommon.VmwareDriver {
|
||||
return d.base
|
||||
}
|
||||
|
||||
type esxcliReader struct {
|
||||
cr *csv.Reader
|
||||
header []string
|
||||
|
|
|
@ -370,7 +370,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
|
|||
|
||||
/// Check the network type that the user specified
|
||||
network := config.Network
|
||||
driver := state.Get("driver").(vmwcommon.VmwareDriver)
|
||||
driver := state.Get("driver").(vmwcommon.Driver).GetVmwareDriver()
|
||||
|
||||
// read netmap config
|
||||
pathNetmap := driver.NetmapConfPath()
|
||||
|
|
Loading…
Reference in New Issue