Adding ability to select IP version for SSH connections to OpenStack instances. Addresses #3047

This commit is contained in:
Nathan Mische 2016-02-13 15:53:46 -05:00 committed by Rickard von Essen
parent 043878ad7a
commit 8396a2db1e
4 changed files with 25 additions and 5 deletions

View File

@ -102,7 +102,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Config: &b.config.RunConfig.Comm,
Host: CommHost(
computeClient,
b.config.SSHInterface),
b.config.SSHInterface,
b.config.SSHIPVersion),
SSHConfig: SSHConfig(b.config.RunConfig.Comm.SSHUsername),
},
&common.StepProvision{},

View File

@ -13,6 +13,7 @@ type RunConfig struct {
Comm communicator.Config `mapstructure:",squash"`
SSHKeyPairName string `mapstructure:"ssh_keypair_name"`
SSHInterface string `mapstructure:"ssh_interface"`
SSHIPVersion string `mapstructure:"ssh_ip_version"`
SourceImage string `mapstructure:"source_image"`
SourceImageName string `mapstructure:"source_image_name"`

View File

@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"log"
"strconv"
"time"
"github.com/mitchellh/multistep"
@ -16,13 +17,14 @@ import (
// CommHost looks up the host for the communicator.
func CommHost(
client *gophercloud.ServiceClient,
sshinterface string) func(multistep.StateBag) (string, error) {
sshinterface string,
sshipversion string) func(multistep.StateBag) (string, error) {
return func(state multistep.StateBag) (string, error) {
s := state.Get("server").(*servers.Server)
// If we have a specific interface, try that
if sshinterface != "" {
if addr := sshAddrFromPool(s, sshinterface); addr != "" {
if addr := sshAddrFromPool(s, sshinterface, sshipversion); addr != "" {
log.Printf("[DEBUG] Using IP address %s from specified interface %s to connect", addr, sshinterface)
return addr, nil
}
@ -41,7 +43,7 @@ func CommHost(
}
// Try to get it from the requested interface
if addr := sshAddrFromPool(s, sshinterface); addr != "" {
if addr := sshAddrFromPool(s, sshinterface, sshipversion); addr != "" {
log.Printf("[DEBUG] Using IP address %s to connect", addr)
return addr, nil
}
@ -79,7 +81,13 @@ func SSHConfig(username string) func(multistep.StateBag) (*ssh.ClientConfig, err
}
}
func sshAddrFromPool(s *servers.Server, desired string) string {
func sshAddrFromPool(s *servers.Server, desired string, sshIPVersion string) string {
ipVersion, err := strconv.Atoi(sshIPVersion)
if err != nil {
log.Printf("[ERROR] Invalid ssh IP version: %s", sshIPVersion)
}
// Get all the addresses associated with this server. This
// was taken directly from Terraform.
for pool, networkAddresses := range s.Addresses {
@ -104,6 +112,14 @@ func sshAddrFromPool(s *servers.Server, desired string) string {
address := element.(map[string]interface{})
if address["OS-EXT-IPS:type"] == "floating" {
addr = address["addr"].(string)
} else if ipVersion == 4 {
if address["version"].(float64) == 4 {
addr = address["addr"].(string)
}
} else if ipVersion == 6 {
if address["version"].(float64) == 6 {
addr = fmt.Sprintf("[%s]", address["addr"].(string))
}
} else {
if address["version"].(float64) == 6 {
addr = fmt.Sprintf("[%s]", address["addr"].(string))

View File

@ -115,6 +115,8 @@ builder.
useful for Rackspace are "public" or "private", and the default behavior is
to connect via whichever is returned first from the OpenStack API.
- `ssh_ip_version` (string) - The IP version to use for SSH connections, valid values are `4` and `6`. Useful on dual stacked instances where the default behaviour is to connect via whichever IP address is returned first from the OpenStack API.
- `ssh_keypair_name` (string) - If specified, this is the key that will be
used for SSH with the machine. By default, this is blank, and Packer will
generate a temporary keypair.