builder/openstack: Support using SSH password.

This adds support for using ssh_password to connect to a OpenStack
instance. If ssh_password is defined creation of the temporary keypair
is skipped.
This commit is contained in:
Rickard von Essen 2016-10-08 23:18:19 +02:00
parent ae256b98d9
commit ba8cfbd222
No known key found for this signature in database
GPG Key ID: E0C0327388876CBA
4 changed files with 60 additions and 30 deletions

View File

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

View File

@ -7,6 +7,7 @@ import (
"time"
"github.com/mitchellh/multistep"
packerssh "github.com/mitchellh/packer/communicator/ssh"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip"
"github.com/rackspace/gophercloud/openstack/compute/v2/servers"
@ -60,23 +61,37 @@ func CommHost(
}
// SSHConfig returns a function that can be used for the SSH communicator
// config for connecting to the instance created over SSH using the generated
// private key.
func SSHConfig(username string) func(multistep.StateBag) (*ssh.ClientConfig, error) {
// config for connecting to the instance created over SSH using a private key
// or a password.
func SSHConfig(username, password string) func(multistep.StateBag) (*ssh.ClientConfig, error) {
return func(state multistep.StateBag) (*ssh.ClientConfig, error) {
privateKey := state.Get("privateKey").(string)
signer, err := ssh.ParsePrivateKey([]byte(privateKey))
if err != nil {
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
privateKey, hasKey := state.GetOk("privateKey")
if hasKey {
signer, err := ssh.ParsePrivateKey([]byte(privateKey.(string)))
if err != nil {
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
}
return &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
}, nil
} else {
return &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.Password(password),
ssh.KeyboardInteractive(
packerssh.PasswordKeyboardInteractive(password)),
}}, nil
}
return &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
}, nil
}
}

View File

@ -42,6 +42,11 @@ func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(Config)
ui := state.Get("ui").(packer.Ui)
if config.Comm.Type == "ssh" && config.Comm.SSHPassword != "" {
ui.Say("Not creating temporary keypair when using password.")
return multistep.ActionContinue
}
// We need the v2 compute client
computeClient, err := config.computeV2Client()
if err != nil {

View File

@ -27,7 +27,6 @@ type StepRunSourceServer struct {
func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(Config)
flavor := state.Get("flavor_id").(string)
keyName := state.Get("keyPair").(string)
ui := state.Get("ui").(packer.Ui)
// We need the v2 compute client
@ -54,21 +53,31 @@ func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction
}
ui.Say("Launching server...")
s.server, err = servers.Create(computeClient, keypairs.CreateOptsExt{
CreateOptsBuilder: servers.CreateOpts{
Name: s.Name,
ImageRef: s.SourceImage,
ImageName: s.SourceImageName,
FlavorRef: flavor,
SecurityGroups: s.SecurityGroups,
Networks: networks,
AvailabilityZone: s.AvailabilityZone,
UserData: userData,
ConfigDrive: s.ConfigDrive,
},
KeyName: keyName,
}).Extract()
serverOpts := servers.CreateOpts{
Name: s.Name,
ImageRef: s.SourceImage,
ImageName: s.SourceImageName,
FlavorRef: flavor,
SecurityGroups: s.SecurityGroups,
Networks: networks,
AvailabilityZone: s.AvailabilityZone,
UserData: userData,
ConfigDrive: s.ConfigDrive,
}
var serverOptsExt servers.CreateOptsBuilder
keyName, hasKey := state.GetOk("keyPair")
if hasKey {
serverOptsExt = keypairs.CreateOptsExt{
CreateOptsBuilder: serverOpts,
KeyName: keyName.(string),
}
} else {
serverOptsExt = serverOpts
}
s.server, err = servers.Create(computeClient, serverOptsExt).Extract()
if err != nil {
err := fmt.Errorf("Error launching source server: %s", err)
state.Put("error", err)