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