// Returns a single insance when given it's ID func getInstanceByID(instanceid string, ec2client *ec2.EC2) (ec2.Instance, error) { instanceReq := ec2.DescribeInstancesInput{ InstanceIds: []*string{ aws.String(instanceid), }, } instanceResp, err := ec2client.DescribeInstances(&instanceReq) if err != nil { return ec2.Instance{}, err } //We only requested one instance, so we should only get one if len(instanceResp.Reservations) != 1 { return ec2.Instance{}, errors.New("The total number of reservations did not match the request") } reservation := instanceResp.Reservations[0] // Now let's make sure we only got one instance in this reservation if len(reservation.Instances) != 1 { return ec2.Instance{}, errors.New("The total number of instances did not match the request for full instance data") } instance := reservation.Instances[0] return *instance, nil }
func findInstance(ec2HostConfig *config.Ec2HostConfig, svc *ec2.EC2) (*ec2.Instance, error) { region, name := ec2HostConfig.Region, ec2HostConfig.Name log.Printf("Searching for instance named %q in region %s", name, region) params := &ec2.DescribeInstancesInput{ Filters: []*ec2.Filter{ { Name: aws.String("tag:Name"), Values: []*string{ aws.String(ec2HostConfig.Name), }, }, }, } resp, err := svc.DescribeInstances(params) if err != nil { return nil, err } if len(resp.Reservations) < 1 { return nil, fmt.Errorf("no instance found in %s with name %s", region, name) } if len(resp.Reservations) > 1 || len(resp.Reservations[0].Instances) != 1 { return nil, fmt.Errorf("multiple instances found in %s with name %s", region, name) } return resp.Reservations[0].Instances[0], nil }
func waitForDetachedNetwork(svc *ec2.EC2, instanceid *string) error { iids := []*string{instanceid} dii := &ec2.DescribeInstancesInput{ InstanceIds: iids, } dio, err := svc.DescribeInstances(dii) if err != nil { panic(err) } //fmt.Println(dio) count := 0 for { dio, err = svc.DescribeInstances(dii) if err != nil { panic(err) } if len(dio.Reservations[0].Instances[0].NetworkInterfaces) == 0 { return nil } if count > 60 { break } time.Sleep(2 * time.Second) count++ } return errors.New(fmt.Sprintf("Waited too long for EC2 to remove networking.")) }
// GetContainerInstances will return a slice of ECS Container Instances within a cluster func GetContainerInstances(svc *ecs.ECS, ec2svc *ec2.EC2, cluster *string) (containerInstances []*ecs.ContainerInstance, instances []*ec2.Reservation, e error) { var ciArns []*string // List clusters reqParams := &ecs.ListContainerInstancesInput{ Cluster: cluster, MaxResults: aws.Int64(100), NextToken: aws.String(""), } // Loop through tokens until no more results remain for { resp, err := svc.ListContainerInstances(reqParams) // Error check if err != nil { return nil, nil, fmt.Errorf("ecs.ListContainerInstances: %s", err.Error()) } // Expand slice of container instances and append to our comprehensive list ciArns = append(ciArns, resp.ContainerInstanceArns...) // Cycle token if resp.NextToken != nil { reqParams.NextToken = resp.NextToken } else { // Kill loop ... out of response pages break } } // Describe the tasks that we just got back ciResponse, err := svc.DescribeContainerInstances(&ecs.DescribeContainerInstancesInput{ Cluster: cluster, ContainerInstances: ciArns, }) if err != nil { return nil, nil, fmt.Errorf("ecs.DescribeContainerInstances: %s", err.Error()) } var instanceIds []*string for _, k := range ciResponse.ContainerInstances { instanceIds = append(instanceIds, k.Ec2InstanceId) } // Create a map of container instances by ci arn... // Note: Will work for <= 1000 instances w/o having to use NextToken ec2Resp, err := ec2svc.DescribeInstances(&ec2.DescribeInstancesInput{ InstanceIds: instanceIds, }) if err != nil { return nil, nil, fmt.Errorf("ec2.DescribeInstances: %s", err.Error()) } return ciResponse.ContainerInstances, ec2Resp.Reservations, nil }
func getPrivateIPs(ec2region *ec2.EC2) []string { instances := []string{} filters, err := buildFilter(*tags) if err != nil { log.Println(err) } request := ec2.DescribeInstancesInput{Filters: filters} result, err := ec2region.DescribeInstances(&request) if err != nil { log.Println(err) } for _, reservation := range result.Reservations { for _, instance := range reservation.Instances { if instance.PrivateIpAddress != nil { if *debug { log.Printf("Adding %s to IP list\n", *instance.PrivateIpAddress) } instances = append(instances, *instance.PrivateIpAddress) } } } return instances }
func GetEc2PrivateIpsFromInstanceIds(ec2_obj *ec2.EC2, instance_ids []string, debug bool) ([]string, error) { params := &ec2.DescribeInstancesInput{ InstanceIds: aws.StringSlice(instance_ids), } resp, err := ec2_obj.DescribeInstances(params) if err != nil { return []string{}, fmt.Errorf("Cannot retrieve EC2 instance information: %s", FormatAwsError(err)) } if len(resp.Reservations) <= 0 { return []string{}, fmt.Errorf("No EC2 instances found (Reservations.*) with specified Instance IDs filter: ", strings.Join(instance_ids, ", ")) } if len(resp.Reservations[0].Instances) <= 0 { return []string{}, fmt.Errorf("No EC2 instances found (Reservations[0].* with specified Instance IDs filter: ", strings.Join(instance_ids, ", ")) } var result []string for idx, _ := range resp.Reservations { for _, value := range resp.Reservations[idx].Instances { if *value.State.Name == "running" { result = append(result, *value.PrivateIpAddress) } else { if debug == true { fmt.Println(*value.InstanceId, "is not in a running state, excluded from results.") } } } } if len(result) == 0 { return []string{}, fmt.Errorf("No running EC2 instances found in result set, cannot proceed.") } return result, nil }
// InstanceStateRefreshFunc returns a StateRefreshFunc that is used to watch // an EC2 instance. func InstanceStateRefreshFunc(conn *ec2.EC2, instanceId string) StateRefreshFunc { return func() (interface{}, string, error) { resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ InstanceIDs: []*string{&instanceId}, }) if err != nil { if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidInstanceID.NotFound" { // Set this to nil as if we didn't find anything. resp = nil } else if isTransientNetworkError(err) { // Transient network error, treat it as if we didn't find anything resp = nil } else { log.Printf("Error on InstanceStateRefresh: %s", err) return nil, "", err } } if resp == nil || len(resp.Reservations) == 0 || len(resp.Reservations[0].Instances) == 0 { // Sometimes AWS just has consistency issues and doesn't see // our instance yet. Return an empty state. return nil, "", nil } i := resp.Reservations[0].Instances[0] return i, *i.State.Name, nil } }
func (be *AwsVpcBackend) detectRouteTableID(instanceID string, ec2c *ec2.EC2) (string, error) { instancesInput := &ec2.DescribeInstancesInput{ InstanceIds: []*string{&instanceID}, } resp, err := ec2c.DescribeInstances(instancesInput) if err != nil { return "", fmt.Errorf("error getting instance info: %v", err) } if len(resp.Reservations) == 0 { return "", fmt.Errorf("no reservations found") } if len(resp.Reservations[0].Instances) == 0 { return "", fmt.Errorf("no matching instance found with id: %v", instanceID) } subnetID := resp.Reservations[0].Instances[0].SubnetId vpcID := resp.Reservations[0].Instances[0].VpcId log.Info("Subnet-ID: ", *subnetID) log.Info("VPC-ID: ", *vpcID) filter := newFilter() filter.Add("association.subnet-id", *subnetID) routeTablesInput := &ec2.DescribeRouteTablesInput{ Filters: filter, } res, err := ec2c.DescribeRouteTables(routeTablesInput) if err != nil { return "", fmt.Errorf("error describing routeTables for subnetID %s: %v", *subnetID, err) } if len(res.RouteTables) != 0 { return *res.RouteTables[0].RouteTableId, nil } filter = newFilter() filter.Add("association.main", "true") filter.Add("vpc-id", *vpcID) routeTablesInput = &ec2.DescribeRouteTablesInput{ Filters: filter, } res, err = ec2c.DescribeRouteTables(routeTablesInput) if err != nil { log.Info("error describing route tables: ", err) } if len(res.RouteTables) == 0 { return "", fmt.Errorf("main route table not found") } return *res.RouteTables[0].RouteTableId, nil }
func ec2connect(svc *ec2.EC2) (*ec2.DescribeInstancesOutput, error) { logger.Info("Attempting to connect...") resp, err := svc.DescribeInstances(nil) if err != nil { return nil, err } return resp, nil }
func (e *EC2) getInstance(id string, svc *ec2.EC2) (*ec2.Instance, error) { resp, err := svc.DescribeInstances(&ec2.DescribeInstancesInput{ InstanceIds: []*string{aws.String(id)}, }) if err != nil { return nil, err } else if len(resp.Reservations) != 1 || len(resp.Reservations[0].Instances) != 1 { return nil, fmt.Errorf("DescribeInstances did not return one reservation with one instance") } else { return resp.Reservations[0].Instances[0], nil } }
func awsGetInstances(ecc ec2.EC2) ([]*ec2.Instance, error) { instancelist := []*ec2.Instance{} resp, err := ecc.DescribeInstances(nil) if err != nil { return nil, fmt.Errorf("unable to describe EC2 Instances") } for _, reservation := range resp.Reservations { for _, instance := range reservation.Instances { instancelist = append(instancelist, instance) } } return instancelist, nil }
func privateIps(ec2 *ec2pkg.EC2, ids []*string) []*string { output, err := ec2.DescribeInstances(&ec2pkg.DescribeInstancesInput{ InstanceIds: ids, }) log.Check(err) var ips []*string for _, r := range output.Reservations { for _, i := range r.Instances { if i.PrivateIpAddress != nil { ips = append(ips, i.PrivateIpAddress) } } } return ips }
func GetVolumeId(i string, c *ec2.EC2) *string { opts := &ec2.DescribeInstancesInput{ DryRun: aws.Bool(false), InstanceIds: []*string{ aws.String(i), }, } instanceStatus, err := c.DescribeInstances(opts) if err != nil { fmt.Println("Error Occured :", err.Error()) os.Exit(1) } return instanceStatus.Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId }
// DescribeInstance gets an Instance object from AWS and returns it, stripping // out Reservation data. func DescribeInstance(c *ec2.EC2, i *string) (*ec2.Instance, error) { q := &ec2.DescribeInstancesInput{ InstanceIds: []*string{i}, } resp, err := c.DescribeInstances(q) if err != nil { return nil, err } if len(resp.Reservations[0].Instances) != 1 { return nil, errors.New("Found more than one instance. Bailing") } return resp.Reservations[0].Instances[0], nil }
func getVpcIDFromInstanceID(svc *ec2.EC2, s string) { params := &ec2.DescribeInstancesInput{ Filters: []*ec2.Filter{ { Name: aws.String("instance-id"), Values: []*string{aws.String(s)}, }, }, } resp, err := svc.DescribeInstances(params) if err != nil { panic(err) } if resp.Reservations[0].Instances[0].VpcId != nil { fmt.Println(*resp.Reservations[0].Instances[0].VpcId) } }
// get the current state for an EC2 instance func getInstanceState(instanceId string, svc *ec2.EC2) (string, error) { params := &ec2.DescribeInstancesInput{ InstanceIds: []*string{&instanceId}, } resp, err := svc.DescribeInstances(params) if err != nil { return "", err } if len(resp.Reservations) < 1 { return "", fmt.Errorf("instance %s not found", instanceId) } if len(resp.Reservations) > 1 || len(resp.Reservations[0].Instances) != 1 { return "", fmt.Errorf("Multiple instances %s found (?!)", instanceId) } return *resp.Reservations[0].Instances[0].State.Name, nil }
func queryInstance(service *ec2.EC2, filter string, filterVal string) interface{} { params := &ec2.DescribeInstancesInput{ Filters: []*ec2.Filter{ { Name: aws.String(filter), Values: []*string{ aws.String(filterVal), }, }, }, } resp, err := service.DescribeInstances(params) if len(resp.Reservations) > 0 { checkError(err) return resp } return nil }
// Helper function to get a subnet which an EC2 instance belong to. func GetSubnet(e *ec2.EC2, i string) (string, error) { describeParams := &ec2.DescribeInstancesInput{ InstanceIds: []*string{ aws.String(i), }, } describeResp, err := e.DescribeInstances(describeParams) if err != nil { return "", err } // Ensure we got a result from this query. if len(describeResp.Reservations) <= 0 { return "", errors.New("Cannot find this host by AWS EC2 DescribeInstances API") } if len(describeResp.Reservations[0].Instances) <= 0 { return "", errors.New("Cannot find this host by AWS EC2 DescribeInstances API") } return *describeResp.Reservations[0].Instances[0].SubnetId, nil }
func JumpTo(client *ec2.EC2) { ec2Instances, err := client.DescribeInstances(&ec2.DescribeInstancesInput{}) if err != nil { log.Fatal("DescribeInstances error:", err) } // Do this after querying the AWS endpoint (otherwise vulnerable to MITM.) ConfigureHTTP(false) instances := InstancesFromEC2Result(ec2Instances) ShowInstances(instances) n := GetInstanceFromUser(len(instances)) // +1 to account for final newline. CursorUp(len(instances) + N_TABLE_DECORATIONS + 1) ClearToEndOfScreen() InvokeSSH(instances[n]) }
func getInstancesByName(svc *ec2.EC2, tag string) []*ec2.Instance { keyname := "tag:Name" keyvalue := tag filter := ec2.Filter{ Name: &keyname, Values: []*string{&keyvalue}} filters := []*ec2.Filter{ &filter, } dii := &ec2.DescribeInstancesInput{ Filters: filters, } dio, err := svc.DescribeInstances(dii) if err != nil { panic(err) } //if len(dio.Reservations) == 0 { // return &ec2.Instance{} //} else if len(dio.Reservations) >= 2 { // fmt.Println("More than on instance found...") // return getNonTerminatedInstance(dio.Reservations[0].Instances) //} else { // return dio.Reservations[0].Instances[0] //} instances := make([]*ec2.Instance, 0) //instances := []*ec2.Instance for i := range dio.Reservations { for k := range dio.Reservations[i].Instances { instances = append(instances, dio.Reservations[i].Instances[k]) } } //fmt.Println(instances) return instances }
func Watch(c *ec2.EC2) { finish := make(chan struct{}) go func() { defer close(finish) // Await stdin closure io.Copy(ioutil.Discard, os.Stdin) }() goUp := func() {} for { queryStart := time.Now() ConfigureHTTP(true) ec2Instances, err := c.DescribeInstances(&ec2.DescribeInstancesInput{}) if err != nil { log.Fatal("DescribeInstances error:", err) } ConfigureHTTP(false) instances := InstancesFromEC2Result(ec2Instances) goUp() ShowInstances(instances) queryDuration := time.Since(queryStart) select { case <-time.After(1*time.Second - queryDuration): case <-finish: return } goUp = func() { CursorUp(len(instances) + N_TABLE_DECORATIONS) } } }
func waitForXState(svc *ec2.EC2, instanceid *string, state string) error { iids := []*string{instanceid} dii := &ec2.DescribeInstancesInput{ InstanceIds: iids, } dio, err := svc.DescribeInstances(dii) if err != nil { panic(err) } //fmt.Println("waiting for instance to leave state", state) //fmt.Println(dio) count := 0 for { dio, err = svc.DescribeInstances(dii) if err != nil { panic(err) } //fmt.Println(dio) if *dio.Reservations[0].Instances[0].State.Name == state { return nil } if count > 30 { break } time.Sleep(2 * time.Second) count++ //fmt.Println(dio) //fmt.Println("waiting for instance to leave state ", state) } return errors.New(fmt.Sprintf("Waited too long waiting for EC2 to enter %s state", state)) }
// 指定したEC2 Private IPからinstance idを返す func ipToInstanceID(svc *ec2.EC2, privateIpaddress string) string { findOpts := &ec2.DescribeInstancesInput{ Filters: []*ec2.Filter{ { Name: aws.String("private-ip-address"), Values: []*string{ aws.String(privateIpaddress), }, }, }, } resp, err := svc.DescribeInstances(findOpts) if err != nil { panic(err) } var instanceID string for _, idx := range resp.Reservations { for _, inst := range idx.Instances { instanceID = *inst.InstanceId } } return instanceID }
// SSHAddress returns a function that can be given to the SSH communicator // for determining the SSH address based on the instance DNS name. func SSHAddress(e *ec2.EC2, port int, private bool) func(multistep.StateBag) (string, error) { return func(state multistep.StateBag) (string, error) { for j := 0; j < 2; j++ { var host string i := state.Get("instance").(*ec2.Instance) if i.VPCID != nil && *i.VPCID != "" { if i.PublicIPAddress != nil && *i.PublicIPAddress != "" && !private { host = *i.PublicIPAddress } else { host = *i.PrivateIPAddress } } else if i.PublicDNSName != nil && *i.PublicDNSName != "" { host = *i.PublicDNSName } if host != "" { return fmt.Sprintf("%s:%d", host, port), nil } r, err := e.DescribeInstances(&ec2.DescribeInstancesInput{ InstanceIDs: []*string{i.InstanceID}, }) if err != nil { return "", err } if len(r.Reservations) == 0 || len(r.Reservations[0].Instances) == 0 { return "", fmt.Errorf("instance not found: %s", *i.InstanceID) } state.Put("instance", &r.Reservations[0].Instances[0]) time.Sleep(1 * time.Second) } return "", errors.New("couldn't determine IP address for instance") } }
func waitForNonPendingState(svc *ec2.EC2, instanceid *string) error { iids := []*string{instanceid} dii := &ec2.DescribeInstancesInput{ InstanceIds: iids, } dio, err := svc.DescribeInstances(dii) if err != nil { panic(err) } //fmt.Println("waiting for non pending state...") //fmt.Println(dio) count := 0 for { dio, err = svc.DescribeInstances(dii) if err != nil { panic(err) } if *dio.Reservations[0].Instances[0].State.Name != "pending" { return nil } if count > 20 { break } time.Sleep(2 * time.Second) count++ //fmt.Println(dio) //fmt.Println("waiting for non pending state...") } return errors.New("Waited too long for EC2 to leave pending state.") }