github.phpd.cn/hashicorp/packer@v1.3.2/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/hashicorp/packer/helper/multistep" 10 ) 11 12 type ec2Describer interface { 13 DescribeInstances(*ec2.DescribeInstancesInput) (*ec2.DescribeInstancesOutput, error) 14 } 15 16 var ( 17 // modified in tests 18 sshHostSleepDuration = time.Second 19 ) 20 21 // SSHHost returns a function that can be given to the SSH communicator 22 // for determining the SSH address based on the instance DNS name. 23 func SSHHost(e ec2Describer, sshInterface string) func(multistep.StateBag) (string, error) { 24 return func(state multistep.StateBag) (string, error) { 25 const tries = 2 26 // <= with current structure to check result of describing `tries` times 27 for j := 0; j <= tries; j++ { 28 var host string 29 i := state.Get("instance").(*ec2.Instance) 30 if sshInterface != "" { 31 switch sshInterface { 32 case "public_ip": 33 if i.PublicIpAddress != nil { 34 host = *i.PublicIpAddress 35 } 36 case "private_ip": 37 if i.PrivateIpAddress != nil { 38 host = *i.PrivateIpAddress 39 } 40 case "public_dns": 41 if i.PublicDnsName != nil { 42 host = *i.PublicDnsName 43 } 44 case "private_dns": 45 if i.PrivateDnsName != nil { 46 host = *i.PrivateDnsName 47 } 48 default: 49 panic(fmt.Sprintf("Unknown interface type: %s", sshInterface)) 50 } 51 } else if i.VpcId != nil && *i.VpcId != "" { 52 if i.PublicIpAddress != nil && *i.PublicIpAddress != "" { 53 host = *i.PublicIpAddress 54 } else if i.PrivateIpAddress != nil && *i.PrivateIpAddress != "" { 55 host = *i.PrivateIpAddress 56 } 57 } else if i.PublicDnsName != nil && *i.PublicDnsName != "" { 58 host = *i.PublicDnsName 59 } 60 61 if host != "" { 62 return host, nil 63 } 64 65 r, err := e.DescribeInstances(&ec2.DescribeInstancesInput{ 66 InstanceIds: []*string{i.InstanceId}, 67 }) 68 if err != nil { 69 return "", err 70 } 71 72 if len(r.Reservations) == 0 || len(r.Reservations[0].Instances) == 0 { 73 return "", fmt.Errorf("instance not found: %s", *i.InstanceId) 74 } 75 76 state.Put("instance", r.Reservations[0].Instances[0]) 77 time.Sleep(sshHostSleepDuration) 78 } 79 80 return "", errors.New("couldn't determine address for instance") 81 } 82 }