2013-06-05 23:53:34 -04:00
|
|
|
package vmware
|
|
|
|
|
2013-06-06 00:51:16 -04:00
|
|
|
import (
|
2013-07-16 14:05:47 -04:00
|
|
|
"errors"
|
2013-06-06 00:51:16 -04:00
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2013-06-05 23:53:34 -04:00
|
|
|
// Interface to help find the IP address of a running virtual machine.
|
|
|
|
type GuestIPFinder interface {
|
|
|
|
GuestIP() (string, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// DHCPLeaseGuestLookup looks up the IP address of a guest using DHCP
|
|
|
|
// lease information from the VMware network devices.
|
|
|
|
type DHCPLeaseGuestLookup struct {
|
2013-07-01 15:17:47 -04:00
|
|
|
// Driver that is being used (to find leases path)
|
|
|
|
Driver Driver
|
|
|
|
|
2013-06-05 23:53:34 -04:00
|
|
|
// Device that the guest is connected to.
|
2013-06-06 00:51:16 -04:00
|
|
|
Device string
|
2013-06-05 23:53:34 -04:00
|
|
|
|
|
|
|
// MAC address of the guest.
|
|
|
|
MACAddress string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *DHCPLeaseGuestLookup) GuestIP() (string, error) {
|
2013-07-01 15:17:47 -04:00
|
|
|
fh, err := os.Open(f.Driver.DhcpLeasesPath(f.Device))
|
2013-06-06 00:51:16 -04:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
defer fh.Close()
|
|
|
|
|
|
|
|
dhcpBytes, err := ioutil.ReadAll(fh)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
var lastIp string
|
|
|
|
var lastLeaseEnd time.Time
|
|
|
|
|
|
|
|
var curIp string
|
|
|
|
var curLeaseEnd time.Time
|
|
|
|
|
|
|
|
ipLineRe := regexp.MustCompile(`^lease (.+?) {$`)
|
|
|
|
endTimeLineRe := regexp.MustCompile(`^\s*ends \d (.+?);$`)
|
|
|
|
macLineRe := regexp.MustCompile(`^\s*hardware ethernet (.+?);$`)
|
|
|
|
|
|
|
|
for _, line := range strings.Split(string(dhcpBytes), "\n") {
|
2013-07-27 16:00:21 -04:00
|
|
|
// Need to trim off CR character when running in windows
|
|
|
|
line = strings.TrimRight(line, "\r");
|
|
|
|
|
2013-06-06 00:51:16 -04:00
|
|
|
matches := ipLineRe.FindStringSubmatch(line)
|
|
|
|
if matches != nil {
|
|
|
|
lastIp = matches[1]
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
matches = endTimeLineRe.FindStringSubmatch(line)
|
|
|
|
if matches != nil {
|
|
|
|
lastLeaseEnd, _ = time.Parse("2006/01/02 15:04:05", matches[1])
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the mac address matches and this lease ends farther in the
|
|
|
|
// future than the last match we might have, then choose it.
|
|
|
|
matches = macLineRe.FindStringSubmatch(line)
|
|
|
|
if matches != nil && matches[1] == f.MACAddress && curLeaseEnd.Before(lastLeaseEnd) {
|
|
|
|
curIp = lastIp
|
|
|
|
curLeaseEnd = lastLeaseEnd
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-16 14:05:47 -04:00
|
|
|
if curIp == "" {
|
|
|
|
return "", errors.New("IP not found for MAC in DHCP leases")
|
|
|
|
}
|
|
|
|
|
2013-06-06 00:51:16 -04:00
|
|
|
return curIp, nil
|
2013-06-05 23:53:34 -04:00
|
|
|
}
|