github.com/ttysteale/packer@v0.8.2-0.20150708160520-e5f8ea386ed8/builder/amazon/common/ssh.go (about) 1 package common 2 3 import ( 4 "errors" 5 "fmt" 6 "time" 7 8 "github.com/aws/aws-sdk-go/service/ec2" 9 "github.com/mitchellh/multistep" 10 "golang.org/x/crypto/ssh" 11 ) 12 13 // SSHHost returns a function that can be given to the SSH communicator 14 // for determining the SSH address based on the instance DNS name. 15 func SSHHost(e *ec2.EC2, private bool) func(multistep.StateBag) (string, error) { 16 return func(state multistep.StateBag) (string, error) { 17 for j := 0; j < 2; j++ { 18 var host string 19 i := state.Get("instance").(*ec2.Instance) 20 if i.VPCID != nil && *i.VPCID != "" { 21 if i.PublicIPAddress != nil && *i.PublicIPAddress != "" && !private { 22 host = *i.PublicIPAddress 23 } else { 24 host = *i.PrivateIPAddress 25 } 26 } else if i.PublicDNSName != nil && *i.PublicDNSName != "" { 27 host = *i.PublicDNSName 28 } 29 30 if host != "" { 31 return host, nil 32 } 33 34 r, err := e.DescribeInstances(&ec2.DescribeInstancesInput{ 35 InstanceIDs: []*string{i.InstanceID}, 36 }) 37 if err != nil { 38 return "", err 39 } 40 41 if len(r.Reservations) == 0 || len(r.Reservations[0].Instances) == 0 { 42 return "", fmt.Errorf("instance not found: %s", *i.InstanceID) 43 } 44 45 state.Put("instance", &r.Reservations[0].Instances[0]) 46 time.Sleep(1 * time.Second) 47 } 48 49 return "", errors.New("couldn't determine IP address for instance") 50 } 51 } 52 53 // SSHConfig returns a function that can be used for the SSH communicator 54 // config for connecting to the instance created over SSH using the generated 55 // private key. 56 func SSHConfig(username string) func(multistep.StateBag) (*ssh.ClientConfig, error) { 57 return func(state multistep.StateBag) (*ssh.ClientConfig, error) { 58 privateKey := state.Get("privateKey").(string) 59 60 signer, err := ssh.ParsePrivateKey([]byte(privateKey)) 61 if err != nil { 62 return nil, fmt.Errorf("Error setting up SSH config: %s", err) 63 } 64 65 return &ssh.ClientConfig{ 66 User: username, 67 Auth: []ssh.AuthMethod{ 68 ssh.PublicKeys(signer), 69 }, 70 }, nil 71 } 72 }