From 6099f0ee787eeac7f73521506489b34ad5a90e4d Mon Sep 17 00:00:00 2001 From: Andrew Grande Date: Fri, 12 Jun 2015 16:30:09 -0400 Subject: [PATCH] New Feature: #1342 Get an internal IP of cloud hosted machine (actual implementation for GCE, placeholders for the rest currently) Signed-off-by: Andrew Grande --- commands/commands.go | 7 +++++ commands/ip.go | 13 +++++++- drivers/amazonec2/amazonec2.go | 5 +++ drivers/azure/azure.go | 4 +++ drivers/digitalocean/digitalocean.go | 5 +++ drivers/drivers.go | 3 ++ drivers/exoscale/exoscale.go | 5 +++ drivers/fakedriver/fakedriver.go | 5 +++ drivers/generic/generic.go | 5 +++ drivers/google/compute_util.go | 37 +++++++++++++++------- drivers/google/google.go | 45 +++++++++++++++++---------- drivers/none/none.go | 5 +++ drivers/openstack/openstack.go | 5 +++ drivers/softlayer/driver.go | 6 ++++ drivers/virtualbox/virtualbox.go | 4 +++ drivers/vmwarefusion/fusion_darwin.go | 5 +++ drivers/vmwarevcloudair/vcloudair.go | 5 +++ drivers/vmwarevsphere/vsphere.go | 5 +++ libmachine/host.go | 9 ++++++ 19 files changed, 148 insertions(+), 30 deletions(-) diff --git a/commands/commands.go b/commands/commands.go index bcfc9aeb15..306ea1179a 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -302,6 +302,12 @@ var Commands = []cli.Command{ Usage: "Get the IP address of a machine", Description: "Argument(s) are one or more machine names.", Action: cmdIp, + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "private, p", + Usage: "Return an instance's private IP address.", + }, + }, }, { Name: "kill", @@ -410,6 +416,7 @@ func machineCommand(actionName string, host *libmachine.Host, errorChan chan<- e "kill": host.Kill, "upgrade": host.Upgrade, "ip": host.PrintIP, + "privateIp": host.PrintPrivateIP, } log.Debugf("command=%s machine=%s", actionName, host.Name) diff --git a/commands/ip.go b/commands/ip.go index 5a8f68aece..2db1d93329 100644 --- a/commands/ip.go +++ b/commands/ip.go @@ -6,7 +6,18 @@ import ( ) func cmdIp(c *cli.Context) { - if err := runActionWithContext("ip", c); err != nil { + if len(c.Args()) == 0 { + cli.ShowCommandHelp(c, "ip") + log.Fatal("You must specify a machine name") + } + + ctx := "ip" + + if c.Bool("private") { + ctx = "privateIp" + } + + if err := runActionWithContext(ctx, c); err != nil { log.Fatal(err) } } diff --git a/drivers/amazonec2/amazonec2.go b/drivers/amazonec2/amazonec2.go index 60e9199bd0..0c8412bb08 100644 --- a/drivers/amazonec2/amazonec2.go +++ b/drivers/amazonec2/amazonec2.go @@ -3,6 +3,7 @@ package amazonec2 import ( "crypto/md5" "crypto/rand" + "errors" "fmt" "io" "io/ioutil" @@ -442,6 +443,10 @@ func (d *Driver) GetIP() (string, error) { return inst.IpAddress, nil } +func (d *Driver) GetPrivateIP() (string, error) { + return "", errors.New("not implemented") +} + func (d *Driver) GetState() (state.State, error) { inst, err := d.getInstance() if err != nil { diff --git a/drivers/azure/azure.go b/drivers/azure/azure.go index 73ef4774db..5556d4e2b4 100644 --- a/drivers/azure/azure.go +++ b/drivers/azure/azure.go @@ -263,6 +263,10 @@ func (d *Driver) GetIP() (string, error) { return d.getHostname(), nil } +func (d *Driver) GetPrivateIP() (string, error) { + return "", errors.New("not implemented") +} + func (d *Driver) GetState() (state.State, error) { if err := d.setUserSubscription(); err != nil { return state.Error, err diff --git a/drivers/digitalocean/digitalocean.go b/drivers/digitalocean/digitalocean.go index 3b65ca26f2..fd537b5e09 100644 --- a/drivers/digitalocean/digitalocean.go +++ b/drivers/digitalocean/digitalocean.go @@ -1,6 +1,7 @@ package digitalocean import ( + "errors" "fmt" "io/ioutil" "path/filepath" @@ -266,6 +267,10 @@ func (d *Driver) GetIP() (string, error) { return d.IPAddress, nil } +func (d *Driver) GetPrivateIP() (string, error) { + return "", errors.New("not implemented") +} + func (d *Driver) GetState() (state.State, error) { droplet, _, err := d.getClient().Droplets.Get(d.DropletID) if err != nil { diff --git a/drivers/drivers.go b/drivers/drivers.go index 0f17afa48d..bca22ac6f3 100644 --- a/drivers/drivers.go +++ b/drivers/drivers.go @@ -35,6 +35,9 @@ type Driver interface { // e.g. 1.2.3.4 or docker-host-d60b70a14d3a.cloudapp.net GetIP() (string, error) + // GetPrivateIP returns an internal host IP + GetPrivateIP() (string, error) + // GetMachineName returns the name of the machine GetMachineName() string diff --git a/drivers/exoscale/exoscale.go b/drivers/exoscale/exoscale.go index 5a62d3cdda..f2ab54089d 100644 --- a/drivers/exoscale/exoscale.go +++ b/drivers/exoscale/exoscale.go @@ -2,6 +2,7 @@ package exoscale import ( "bytes" + "errors" "fmt" "io/ioutil" "path/filepath" @@ -173,6 +174,10 @@ func (d *Driver) GetIP() (string, error) { return d.IPAddress, nil } +func (d *Driver) GetPrivateIP() (string, error) { + return "", errors.New("not implemented") +} + func (d *Driver) GetState() (state.State, error) { client := egoscale.NewClient(d.URL, d.ApiKey, d.ApiSecretKey) vm, err := client.GetVirtualMachine(d.Id) diff --git a/drivers/fakedriver/fakedriver.go b/drivers/fakedriver/fakedriver.go index 13eae5a109..74808ed2d1 100644 --- a/drivers/fakedriver/fakedriver.go +++ b/drivers/fakedriver/fakedriver.go @@ -1,6 +1,7 @@ package fakedriver import ( + "errors" "github.com/docker/machine/drivers" "github.com/docker/machine/state" ) @@ -37,6 +38,10 @@ func (d *FakeDriver) GetIP() (string, error) { return "1.2.3.4", nil } +func (d *Driver) GetPrivateIP() (string, error) { + errors.New("not implemented") +} + func (d *FakeDriver) GetSSHHostname() (string, error) { return "", nil } diff --git a/drivers/generic/generic.go b/drivers/generic/generic.go index ce7ba301fa..df370d4f02 100644 --- a/drivers/generic/generic.go +++ b/drivers/generic/generic.go @@ -1,6 +1,7 @@ package generic import ( + "errors" "fmt" "net" "os" @@ -164,6 +165,10 @@ func (d *Driver) GetIP() (string, error) { return d.IPAddress, nil } +func (d *Driver) GetPrivateIP() (string, error) { + return "", errors.New("not implemented") +} + func (d *Driver) GetState() (state.State, error) { addr := fmt.Sprintf("%s:%d", d.IPAddress, d.SSHPort) _, err := net.DialTimeout("tcp", addr, defaultTimeout) diff --git a/drivers/google/compute_util.go b/drivers/google/compute_util.go index bdf26672d7..db0b4b3316 100644 --- a/drivers/google/compute_util.go +++ b/drivers/google/compute_util.go @@ -14,18 +14,19 @@ import ( // ComputeUtil is used to wrap the raw GCE API code and store common parameters. type ComputeUtil struct { - zone string - instanceName string - userName string - project string - diskTypeURL string - service *raw.Service - zoneURL string - authTokenPath string - globalURL string - ipAddress string - SwarmMaster bool - SwarmHost string + zone string + instanceName string + userName string + project string + diskTypeURL string + service *raw.Service + zoneURL string + authTokenPath string + globalURL string + ipAddress string + privateIpAddress string + SwarmMaster bool + SwarmHost string } const ( @@ -305,3 +306,15 @@ func (c *ComputeUtil) ip() (string, error) { } return c.ipAddress, nil } + +// returns an internal IP address of the instance. +func (c *ComputeUtil) privateIp() (string, error) { + if c.privateIpAddress == "" { + instance, err := c.service.Instances.Get(c.project, c.zone, c.instanceName).Do() + if err != nil { + return "", err + } + c.privateIpAddress = instance.NetworkInterfaces[0].NetworkIP + } + return c.privateIpAddress, nil +} diff --git a/drivers/google/google.go b/drivers/google/google.go index 4ad7c62ca6..e9ce53ebe5 100644 --- a/drivers/google/google.go +++ b/drivers/google/google.go @@ -13,23 +13,24 @@ import ( // Driver is a struct compatible with the docker.hosts.drivers.Driver interface. type Driver struct { - IPAddress string - MachineName string - SSHUser string - SSHPort int - Zone string - MachineType string - DiskType string - Scopes string - DiskSize int - AuthTokenPath string - storePath string - Project string - CaCertPath string - PrivateKeyPath string - SwarmMaster bool - SwarmHost string - SwarmDiscovery string + IPAddress string + PrivateIPAddress string + MachineName string + SSHUser string + SSHPort int + Zone string + MachineType string + DiskType string + Scopes string + DiskSize int + AuthTokenPath string + storePath string + Project string + CaCertPath string + PrivateKeyPath string + SwarmMaster bool + SwarmHost string + SwarmDiscovery string } func init() { @@ -211,6 +212,15 @@ func (d *Driver) GetIP() (string, error) { return c.ip() } +// returns the internal IP address of the GCE instance. +func (d *Driver) GetPrivateIP() (string, error) { + c, err := newComputeUtil(d) + if err != nil { + return "", err + } + return c.privateIp() +} + // GetState returns a docker.hosts.state.State value representing the current state of the host. func (d *Driver) GetState() (state.State, error) { c, err := newComputeUtil(d) @@ -250,6 +260,7 @@ func (d *Driver) Start() error { return err } d.IPAddress, err = d.GetIP() + d.PrivateIPAddress, err = d.GetPrivateIP() return err } diff --git a/drivers/none/none.go b/drivers/none/none.go index f816f456ff..3ce9df8226 100644 --- a/drivers/none/none.go +++ b/drivers/none/none.go @@ -1,6 +1,7 @@ package none import ( + "errors" "fmt" neturl "net/url" @@ -58,6 +59,10 @@ func (d *Driver) GetIP() (string, error) { return d.IPAddress, nil } +func (d *Driver) GetPrivateIP() (string, error) { + return "", errors.New("not implemented") +} + func (d *Driver) GetMachineName() string { return "" } diff --git a/drivers/openstack/openstack.go b/drivers/openstack/openstack.go index 3bae763e9a..57a5c6ff49 100644 --- a/drivers/openstack/openstack.go +++ b/drivers/openstack/openstack.go @@ -1,6 +1,7 @@ package openstack import ( + "errors" "fmt" "io/ioutil" "path/filepath" @@ -312,6 +313,10 @@ func (d *Driver) GetIP() (string, error) { return "", fmt.Errorf("No IP found for the machine") } +func (d *Driver) GetPrivateIP() (string, error) { + return "", errors.New("not implemented") +} + func (d *Driver) GetState() (state.State, error) { log.WithField("MachineId", d.MachineId).Debug("Get status for OpenStack instance...") if err := d.initCompute(); err != nil { diff --git a/drivers/softlayer/driver.go b/drivers/softlayer/driver.go index 87d0a4de38..e5ee8be798 100644 --- a/drivers/softlayer/driver.go +++ b/drivers/softlayer/driver.go @@ -1,6 +1,7 @@ package softlayer import ( + "errors" "fmt" "io/ioutil" "os" @@ -305,6 +306,11 @@ func (d *Driver) GetIP() (string, error) { } } +func (d *Driver) GetPrivateIP() (string, error) { + // TODO there's some private ip code in GetIP(), review for applicability + return "", errors.New("not implemented") +} + func (d *Driver) GetState() (state.State, error) { s, err := d.getClient().VirtualGuest().PowerState(d.Id) if err != nil { diff --git a/drivers/virtualbox/virtualbox.go b/drivers/virtualbox/virtualbox.go index 7f5363d8df..65cfe75f72 100644 --- a/drivers/virtualbox/virtualbox.go +++ b/drivers/virtualbox/virtualbox.go @@ -524,6 +524,10 @@ func (d *Driver) GetIP() (string, error) { return "", fmt.Errorf("No IP address found %s", output) } +func (d *Driver) GetPrivateIP() (string, error) { + return "", errors.New("not implemented") +} + func (d *Driver) publicSSHKeyPath() string { return d.GetSSHKeyPath() + ".pub" } diff --git a/drivers/vmwarefusion/fusion_darwin.go b/drivers/vmwarefusion/fusion_darwin.go index 09bab79e41..d18a36dc50 100644 --- a/drivers/vmwarefusion/fusion_darwin.go +++ b/drivers/vmwarefusion/fusion_darwin.go @@ -6,6 +6,7 @@ package vmwarefusion import ( "archive/tar" + "errors" "fmt" "io/ioutil" "os" @@ -182,6 +183,10 @@ func (d *Driver) GetIP() (string, error) { return ip, nil } +func (d *Driver) GetPrivateIP() (string, error) { + return "", errors.New("not implemented") +} + func (d *Driver) GetState() (state.State, error) { // VMRUN only tells use if the vm is running or not if stdout, _, _ := vmrun("list"); strings.Contains(stdout, d.vmxPath()) { diff --git a/drivers/vmwarevcloudair/vcloudair.go b/drivers/vmwarevcloudair/vcloudair.go index c2604b3d36..9b1d7f6b86 100644 --- a/drivers/vmwarevcloudair/vcloudair.go +++ b/drivers/vmwarevcloudair/vcloudair.go @@ -5,6 +5,7 @@ package vmwarevcloudair import ( + "errors" "fmt" "io/ioutil" "path/filepath" @@ -243,6 +244,10 @@ func (d *Driver) GetIP() (string, error) { return d.PublicIP, nil } +func (d *Driver) GetPrivateIP() (string, error) { + return "", errors.New("not implemented") +} + func (d *Driver) GetState() (state.State, error) { p, err := govcloudair.NewClient() diff --git a/drivers/vmwarevsphere/vsphere.go b/drivers/vmwarevsphere/vsphere.go index a357ac69f2..1c61c168d9 100644 --- a/drivers/vmwarevsphere/vsphere.go +++ b/drivers/vmwarevsphere/vsphere.go @@ -6,6 +6,7 @@ package vmwarevsphere import ( "archive/tar" + sysErrors "errors" "fmt" "io/ioutil" "os" @@ -228,6 +229,10 @@ func (d *Driver) GetIP() (string, error) { return ip, nil } +func (d *Driver) GetPrivateIP() (string, error) { + return "", sysErrors.New("not implemented") +} + func (d *Driver) GetState() (state.State, error) { vcConn := NewVcConn(d) stdout, err := vcConn.VMInfo() diff --git a/libmachine/host.go b/libmachine/host.go index 95d0341519..0bed883e3f 100644 --- a/libmachine/host.go +++ b/libmachine/host.go @@ -362,6 +362,15 @@ func (h *Host) PrintIP() error { return nil } +func (h *Host) PrintPrivateIP() error { + if ip, err := h.Driver.GetPrivateIP(); err != nil { + return err + } else { + fmt.Println(ip) + } + return nil +} + func WaitForSSH(h *Host) error { return drivers.WaitForSSH(h.Driver) }