github.com/daniellockard/packer@v0.7.6-0.20141210173435-5a9390934716/builder/openstack/ssh.go (about)

     1  package openstack
     2  
     3  import (
     4  	"code.google.com/p/go.crypto/ssh"
     5  	"errors"
     6  	"fmt"
     7  	"github.com/mitchellh/multistep"
     8  	"time"
     9  
    10  	"github.com/mitchellh/gophercloud-fork-40444fb"
    11  )
    12  
    13  // SSHAddress returns a function that can be given to the SSH communicator
    14  // for determining the SSH address based on the server AccessIPv4 setting..
    15  func SSHAddress(csp gophercloud.CloudServersProvider, port int) func(multistep.StateBag) (string, error) {
    16  	return func(state multistep.StateBag) (string, error) {
    17  		s := state.Get("server").(*gophercloud.Server)
    18  
    19  		if ip := state.Get("access_ip").(gophercloud.FloatingIp); ip.Ip != "" {
    20  			return fmt.Sprintf("%s:%d", ip.Ip, port), nil
    21  		}
    22  
    23  		ip_pools, err := s.AllAddressPools()
    24  		if err != nil {
    25  			return "", errors.New("Error parsing SSH addresses")
    26  		}
    27  		for pool, addresses := range ip_pools {
    28  			if pool != "" {
    29  				for _, address := range addresses {
    30  					if address.Addr != "" && address.Version == 4 {
    31  						return fmt.Sprintf("%s:%d", address.Addr, port), nil
    32  					}
    33  				}
    34  			}
    35  		}
    36  
    37  		serverState, err := csp.ServerById(s.Id)
    38  
    39  		if err != nil {
    40  			return "", err
    41  		}
    42  
    43  		state.Put("server", serverState)
    44  		time.Sleep(1 * time.Second)
    45  
    46  		return "", errors.New("couldn't determine IP address for server")
    47  	}
    48  }
    49  
    50  // SSHConfig returns a function that can be used for the SSH communicator
    51  // config for connecting to the instance created over SSH using the generated
    52  // private key.
    53  func SSHConfig(username string) func(multistep.StateBag) (*ssh.ClientConfig, error) {
    54  	return func(state multistep.StateBag) (*ssh.ClientConfig, error) {
    55  		privateKey := state.Get("privateKey").(string)
    56  
    57  		signer, err := ssh.ParsePrivateKey([]byte(privateKey))
    58  		if err != nil {
    59  			return nil, fmt.Errorf("Error setting up SSH config: %s", err)
    60  		}
    61  
    62  		return &ssh.ClientConfig{
    63  			User: username,
    64  			Auth: []ssh.AuthMethod{
    65  				ssh.PublicKeys(signer),
    66  			},
    67  		}, nil
    68  	}
    69  }