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 }