Merge pull request #2152 from abayer/gce-optional-internal-ip
builder/google: Adds support for using the internal IP rather than NAT IP in GCE
This commit is contained in:
commit
9bb7d0a2d5
|
@ -35,6 +35,7 @@ type Config struct {
|
||||||
SourceImageProjectId string `mapstructure:"source_image_project_id"`
|
SourceImageProjectId string `mapstructure:"source_image_project_id"`
|
||||||
RawStateTimeout string `mapstructure:"state_timeout"`
|
RawStateTimeout string `mapstructure:"state_timeout"`
|
||||||
Tags []string `mapstructure:"tags"`
|
Tags []string `mapstructure:"tags"`
|
||||||
|
UseInternalIP bool `mapstructure:"use_internal_ip"`
|
||||||
Zone string `mapstructure:"zone"`
|
Zone string `mapstructure:"zone"`
|
||||||
|
|
||||||
account accountFile
|
account accountFile
|
||||||
|
|
|
@ -116,6 +116,21 @@ func TestConfigPrepare(t *testing.T) {
|
||||||
"5s",
|
"5s",
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"use_internal_ip",
|
||||||
|
nil,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"use_internal_ip",
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"use_internal_ip",
|
||||||
|
"SO VERY BAD",
|
||||||
|
true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
|
|
|
@ -24,6 +24,9 @@ type Driver interface {
|
||||||
// GetNatIP gets the NAT IP address for the instance.
|
// GetNatIP gets the NAT IP address for the instance.
|
||||||
GetNatIP(zone, name string) (string, error)
|
GetNatIP(zone, name string) (string, error)
|
||||||
|
|
||||||
|
// GetInternalIP gets the GCE-internal IP address for the instance.
|
||||||
|
GetInternalIP(zone, name string) (string, error)
|
||||||
|
|
||||||
// RunInstance takes the given config and launches an instance.
|
// RunInstance takes the given config and launches an instance.
|
||||||
RunInstance(*InstanceConfig) (<-chan error, error)
|
RunInstance(*InstanceConfig) (<-chan error, error)
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,6 @@ func (d *driverGCE) GetNatIP(zone, name string) (string, error) {
|
||||||
if ni.AccessConfigs == nil {
|
if ni.AccessConfigs == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ac := range ni.AccessConfigs {
|
for _, ac := range ni.AccessConfigs {
|
||||||
if ac.NatIP != "" {
|
if ac.NatIP != "" {
|
||||||
return ac.NatIP, nil
|
return ac.NatIP, nil
|
||||||
|
@ -168,6 +167,22 @@ func (d *driverGCE) GetNatIP(zone, name string) (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *driverGCE) GetInternalIP(zone, name string) (string, error) {
|
||||||
|
instance, err := d.service.Instances.Get(d.projectId, zone, name).Do()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ni := range instance.NetworkInterfaces {
|
||||||
|
if ni.NetworkIP == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return ni.NetworkIP, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) {
|
func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) {
|
||||||
// Get the zone
|
// Get the zone
|
||||||
d.ui.Message(fmt.Sprintf("Loading zone: %s", c.Zone))
|
d.ui.Message(fmt.Sprintf("Loading zone: %s", c.Zone))
|
||||||
|
|
|
@ -30,6 +30,11 @@ type DriverMock struct {
|
||||||
GetNatIPResult string
|
GetNatIPResult string
|
||||||
GetNatIPErr error
|
GetNatIPErr error
|
||||||
|
|
||||||
|
GetInternalIPZone string
|
||||||
|
GetInternalIPName string
|
||||||
|
GetInternalIPResult string
|
||||||
|
GetInternalIPErr error
|
||||||
|
|
||||||
RunInstanceConfig *InstanceConfig
|
RunInstanceConfig *InstanceConfig
|
||||||
RunInstanceErrCh <-chan error
|
RunInstanceErrCh <-chan error
|
||||||
RunInstanceErr error
|
RunInstanceErr error
|
||||||
|
@ -108,6 +113,12 @@ func (d *DriverMock) GetNatIP(zone, name string) (string, error) {
|
||||||
return d.GetNatIPResult, d.GetNatIPErr
|
return d.GetNatIPResult, d.GetNatIPErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *DriverMock) GetInternalIP(zone, name string) (string, error) {
|
||||||
|
d.GetInternalIPZone = zone
|
||||||
|
d.GetInternalIPName = name
|
||||||
|
return d.GetInternalIPResult, d.GetInternalIPErr
|
||||||
|
}
|
||||||
|
|
||||||
func (d *DriverMock) RunInstance(c *InstanceConfig) (<-chan error, error) {
|
func (d *DriverMock) RunInstance(c *InstanceConfig) (<-chan error, error) {
|
||||||
d.RunInstanceConfig = c
|
d.RunInstanceConfig = c
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,24 @@ func (s *StepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.UseInternalIP {
|
||||||
|
ip, err := driver.GetInternalIP(config.Zone, instanceName)
|
||||||
|
if err != nil {
|
||||||
|
err := fmt.Errorf("Error retrieving instance internal ip address: %s", err)
|
||||||
|
state.Put("error", err)
|
||||||
|
ui.Error(err.Error())
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Debug {
|
||||||
|
if ip != "" {
|
||||||
|
ui.Message(fmt.Sprintf("Internal IP: %s", ip))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui.Message(fmt.Sprintf("IP: %s", ip))
|
||||||
|
state.Put("instance_ip", ip)
|
||||||
|
return multistep.ActionContinue
|
||||||
|
} else {
|
||||||
ip, err := driver.GetNatIP(config.Zone, instanceName)
|
ip, err := driver.GetNatIP(config.Zone, instanceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("Error retrieving instance nat ip address: %s", err)
|
err := fmt.Errorf("Error retrieving instance nat ip address: %s", err)
|
||||||
|
@ -53,11 +71,11 @@ func (s *StepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
ui.Message(fmt.Sprintf("Public IP: %s", ip))
|
ui.Message(fmt.Sprintf("Public IP: %s", ip))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.Message(fmt.Sprintf("IP: %s", ip))
|
ui.Message(fmt.Sprintf("IP: %s", ip))
|
||||||
state.Put("instance_ip", ip)
|
state.Put("instance_ip", ip)
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cleanup.
|
// Cleanup.
|
||||||
func (s *StepInstanceInfo) Cleanup(state multistep.StateBag) {}
|
func (s *StepInstanceInfo) Cleanup(state multistep.StateBag) {}
|
||||||
|
|
|
@ -49,6 +49,46 @@ func TestStepInstanceInfo(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStepInstanceInfo_InternalIP(t *testing.T) {
|
||||||
|
state := testState(t)
|
||||||
|
step := new(StepInstanceInfo)
|
||||||
|
defer step.Cleanup(state)
|
||||||
|
|
||||||
|
state.Put("instance_name", "foo")
|
||||||
|
|
||||||
|
config := state.Get("config").(*Config)
|
||||||
|
config.UseInternalIP = true
|
||||||
|
driver := state.Get("driver").(*DriverMock)
|
||||||
|
driver.GetNatIPResult = "1.2.3.4"
|
||||||
|
driver.GetInternalIPResult = "5.6.7.8"
|
||||||
|
|
||||||
|
// run the step
|
||||||
|
if action := step.Run(state); action != multistep.ActionContinue {
|
||||||
|
t.Fatalf("bad action: %#v", action)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify state
|
||||||
|
if driver.WaitForInstanceState != "RUNNING" {
|
||||||
|
t.Fatalf("bad: %#v", driver.WaitForInstanceState)
|
||||||
|
}
|
||||||
|
if driver.WaitForInstanceZone != config.Zone {
|
||||||
|
t.Fatalf("bad: %#v", driver.WaitForInstanceZone)
|
||||||
|
}
|
||||||
|
if driver.WaitForInstanceName != "foo" {
|
||||||
|
t.Fatalf("bad: %#v", driver.WaitForInstanceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
ipRaw, ok := state.GetOk("instance_ip")
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("should have ip")
|
||||||
|
}
|
||||||
|
if ip, ok := ipRaw.(string); !ok {
|
||||||
|
t.Fatal("ip is not a string")
|
||||||
|
} else if ip != "5.6.7.8" {
|
||||||
|
t.Fatalf("bad ip: %s", ip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestStepInstanceInfo_getNatIPError(t *testing.T) {
|
func TestStepInstanceInfo_getNatIPError(t *testing.T) {
|
||||||
state := testState(t)
|
state := testState(t)
|
||||||
step := new(StepInstanceInfo)
|
step := new(StepInstanceInfo)
|
||||||
|
|
Loading…
Reference in New Issue