func (p *EC2CachePool) discoverPeers() ([]string, error) { f := ec2.NewFilter() f.Add("tag:server-type", "image-proxy") resp, err := p.Instances(nil, f) if err != nil { return nil, err } var ips []string for _, reserv := range resp.Reservations { for _, instance := range reserv.Instances { if instance.State.Name == "running" { ips = append(ips, instance.PrivateIPAddress) } } } peerIPs := make([]string, len(ips)) _ = copy(peerIPs, ips) for i := range peerIPs { peerIPs[i] = fmt.Sprintf("http://%s:%s", peerIPs[i], *cacheport) } log.Println("Setting peers:", peerIPs) p.Set(peerIPs...) return ips, nil }
func getInstances() []*Instance { auth := aws.Auth{aws_access_key, aws_secret_key} c = ec2.New(auth, aws.Regions[ec2_region]) filter := ec2.NewFilter() filter.Add("instance-state-name", "running") resp, err := c.Instances(nil, filter) if err != nil { fmt.Println(err) os.Exit(1) } instances := []*Instance{} for _, reservation := range resp.Reservations { for _, instance := range reservation.Instances { name := "" for _, tag := range instance.Tags { if tag.Key == "Name" { name = tag.Value break } } if name != "" { i := &Instance{instance.DNSName, name} instances = append(instances, i) } } } return instances }
func (s *S) TestDescribeInstancesExample1(c *C) { testServer.Response(200, nil, DescribeInstancesExample1) filter := ec2.NewFilter() filter.Add("key1", "value1") filter.Add("key2", "value2", "value3") resp, err := s.ec2.Instances([]string{"i-1", "i-2"}, nil) req := testServer.WaitRequest() c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeInstances"}) c.Assert(req.Form["InstanceId.1"], DeepEquals, []string{"i-1"}) c.Assert(req.Form["InstanceId.2"], DeepEquals, []string{"i-2"}) c.Assert(err, IsNil) c.Assert(resp.RequestId, Equals, "98e3c9a4-848c-4d6d-8e8a-b1bdEXAMPLE") c.Assert(resp.Reservations, HasLen, 2) expectedGroups := []ec2.SecurityGroup{{Name: "default", Id: "sg-67ad940e"}} r0 := resp.Reservations[0] c.Assert(r0.ReservationId, Equals, "r-b27e30d9") c.Assert(r0.OwnerId, Equals, "999988887777") c.Assert(r0.RequesterId, Equals, "854251627541") c.Assert(r0.SecurityGroups, DeepEquals, expectedGroups) c.Assert(r0.Instances, HasLen, 1) r0i := r0.Instances[0] c.Assert(r0i.InstanceId, Equals, "i-c5cd56af") c.Assert(r0i.PrivateDNSName, Equals, "domU-12-31-39-10-56-34.compute-1.internal") c.Assert(r0i.DNSName, Equals, "ec2-174-129-165-232.compute-1.amazonaws.com") c.Assert(r0i.PrivateIPAddress, Equals, "10.198.85.190") c.Assert(r0i.IPAddress, Equals, "174.129.165.232") c.Assert(r0i.AvailZone, Equals, "us-east-1b") c.Assert(r0i.SecurityGroups, DeepEquals, expectedGroups) }
func (s *S) TestDescribeSecurityGroupsExampleWithFilter(c *C) { testServer.Response(200, nil, DescribeSecurityGroupsExample) filter := ec2.NewFilter() filter.Add("ip-permission.protocol", "tcp") filter.Add("ip-permission.from-port", "22") filter.Add("ip-permission.to-port", "22") filter.Add("ip-permission.group-name", "app_server_group", "database_group") _, err := s.ec2.SecurityGroups(nil, filter) req := testServer.WaitRequest() c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeSecurityGroups"}) c.Assert(req.Form["Filter.1.Name"], DeepEquals, []string{"ip-permission.from-port"}) c.Assert(req.Form["Filter.1.Value.1"], DeepEquals, []string{"22"}) c.Assert(req.Form["Filter.2.Name"], DeepEquals, []string{"ip-permission.group-name"}) c.Assert(req.Form["Filter.2.Value.1"], DeepEquals, []string{"app_server_group"}) c.Assert(req.Form["Filter.2.Value.2"], DeepEquals, []string{"database_group"}) c.Assert(req.Form["Filter.3.Name"], DeepEquals, []string{"ip-permission.protocol"}) c.Assert(req.Form["Filter.3.Value.1"], DeepEquals, []string{"tcp"}) c.Assert(req.Form["Filter.4.Name"], DeepEquals, []string{"ip-permission.to-port"}) c.Assert(req.Form["Filter.4.Value.1"], DeepEquals, []string{"22"}) c.Assert(err, IsNil) }
func defaultAMI(conn *ec2.EC2) (string, error) { filter := ec2.NewFilter() imageName := "amzn-ami-hvm-2014.03.2.x86_64-ebs" filter.Add("name", imageName) resp, _ := conn.Images(nil, filter) if len(resp.Images) == 0 { return "", fmt.Errorf("Unable to retrieve ami id for image name: %s", imageName) } return resp.Images[0].Id, nil }
func searchByFilter(e *ec2.EC2, key, value string) (*ec2.Instance, error) { filter := ec2.NewFilter() filter.Add(key, value) resp, err := e.Instances(nil, filter) if err != nil { return nil, errors.New("EC2 API call failed. " + "Check your AWS credentials and system clock") } if len(resp.Reservations) != 1 { return nil, errors.New("no instance with " + key + "=" + value) } return &resp.Reservations[0].Instances[0], nil }
func (s *S) TestDescribeImagesExample(c *C) { testServer.Response(200, nil, DescribeImagesExample) filter := ec2.NewFilter() filter.Add("key1", "value1") filter.Add("key2", "value2", "value3") resp, err := s.ec2.Images([]string{"ami-1", "ami-2"}, filter) req := testServer.WaitRequest() c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeImages"}) c.Assert(req.Form["ImageId.1"], DeepEquals, []string{"ami-1"}) c.Assert(req.Form["ImageId.2"], DeepEquals, []string{"ami-2"}) c.Assert(req.Form["Filter.1.Name"], DeepEquals, []string{"key1"}) c.Assert(req.Form["Filter.1.Value.1"], DeepEquals, []string{"value1"}) c.Assert(req.Form["Filter.1.Value.2"], IsNil) c.Assert(req.Form["Filter.2.Name"], DeepEquals, []string{"key2"}) c.Assert(req.Form["Filter.2.Value.1"], DeepEquals, []string{"value2"}) c.Assert(req.Form["Filter.2.Value.2"], DeepEquals, []string{"value3"}) c.Assert(err, IsNil) c.Assert(resp.RequestId, Equals, "4a4a27a2-2e7c-475d-b35b-ca822EXAMPLE") c.Assert(resp.Images, HasLen, 1) i0 := resp.Images[0] c.Assert(i0.Id, Equals, "ami-a2469acf") c.Assert(i0.Type, Equals, "machine") c.Assert(i0.Name, Equals, "example-marketplace-amzn-ami.1") c.Assert(i0.Description, Equals, "Amazon Linux AMI i386 EBS") c.Assert(i0.Location, Equals, "aws-marketplace/example-marketplace-amzn-ami.1") c.Assert(i0.State, Equals, "available") c.Assert(i0.Public, Equals, true) c.Assert(i0.OwnerId, Equals, "123456789999") c.Assert(i0.OwnerAlias, Equals, "aws-marketplace") c.Assert(i0.Architecture, Equals, "i386") c.Assert(i0.KernelId, Equals, "aki-805ea7e9") c.Assert(i0.RootDeviceType, Equals, "ebs") c.Assert(i0.RootDeviceName, Equals, "/dev/sda1") c.Assert(i0.VirtualizationType, Equals, "paravirtual") c.Assert(i0.Hypervisor, Equals, "xen") c.Assert(i0.BlockDevices, HasLen, 1) c.Assert(i0.BlockDevices[0].DeviceName, Equals, "/dev/sda1") c.Assert(i0.BlockDevices[0].SnapshotId, Equals, "snap-787e9403") c.Assert(i0.BlockDevices[0].VolumeSize, Equals, int64(8)) c.Assert(i0.BlockDevices[0].DeleteOnTermination, Equals, true) }
func (e *environ) AllInstances() ([]environs.Instance, error) { filter := ec2.NewFilter() filter.Add("instance-state-name", "pending", "running") filter.Add("group-name", e.jujuGroupName()) resp, err := e.ec2().Instances(nil, filter) if err != nil { return nil, err } var insts []environs.Instance for _, r := range resp.Reservations { for i := range r.Instances { inst := r.Instances[i] insts = append(insts, &instance{e, &inst}) } } return insts, nil }
func (e *environ) AllInstances() ([]instance.Instance, error) { filter := ec2.NewFilter() filter.Add("instance-state-name", "pending", "running") filter.Add("group-name", e.jujuGroupName()) resp, err := e.ec2().Instances(nil, filter) if err != nil { return nil, err } var insts []instance.Instance for _, r := range resp.Reservations { for i := range r.Instances { inst := r.Instances[i] // TODO(wallyworld): lookup the details to fill in the instance type data insts = append(insts, &ec2Instance{e: e, Instance: &inst}) } } return insts, nil }
func (s *LocalServerSuite) TestAvailabilityZones(c *C) { s.srv.srv.SetAvailabilityZones([]ec2.AvailabilityZoneInfo{{ AvailabilityZone: ec2.AvailabilityZone{ Name: "us-east-1a", Region: "us-east-1", }, State: "available", }, { AvailabilityZone: ec2.AvailabilityZone{ Name: "us-east-1b", Region: "us-east-1", }, State: "impaired", }, { AvailabilityZone: ec2.AvailabilityZone{ Name: "us-west-1a", Region: "us-west-1", }, State: "available", }, { AvailabilityZone: ec2.AvailabilityZone{ Name: "us-west-1b", Region: "us-west-1", }, State: "unavailable", MessageSet: []string{"down for maintenance"}, }}) resp, err := s.ec2.AvailabilityZones(nil) c.Assert(err, IsNil) c.Assert(resp.Zones, HasLen, 4) c.Assert(resp.Zones[0].Name, Equals, "us-east-1a") c.Assert(resp.Zones[1].Name, Equals, "us-east-1b") c.Assert(resp.Zones[2].Name, Equals, "us-west-1a") c.Assert(resp.Zones[3].Name, Equals, "us-west-1b") filter := ec2.NewFilter() filter.Add("region-name", "us-east-1") resp, err = s.ec2.AvailabilityZones(filter) c.Assert(err, IsNil) c.Assert(resp.Zones, HasLen, 2) c.Assert(resp.Zones[0].Name, Equals, "us-east-1a") c.Assert(resp.Zones[1].Name, Equals, "us-east-1b") }
func getLocalIP(ec2conn *ec2.EC2) string { f := ec2.NewFilter() f.Add("tag:server-type", "image-proxy") resp, err := ec2conn.Instances(nil, f) if err != nil { return "" } for _, reserv := range resp.Reservations { for _, instance := range reserv.Instances { if localAddress(instance.PrivateIPAddress) { return instance.PrivateIPAddress } } } return "" }
// gatherInstances tries to get information on each instance // id whose corresponding insts slot is nil. // It returns environs.ErrPartialInstances if the insts // slice has not been completely filled. func (e *environ) gatherInstances(ids []instance.Id, insts []instance.Instance) error { var need []string for i, inst := range insts { if inst == nil { need = append(need, string(ids[i])) } } if len(need) == 0 { return nil } filter := ec2.NewFilter() filter.Add("instance-state-name", "pending", "running") filter.Add("group-name", e.jujuGroupName()) filter.Add("instance-id", need...) resp, err := e.ec2().Instances(nil, filter) if err != nil { return err } n := 0 // For each requested id, add it to the returned instances // if we find it in the response. for i, id := range ids { if insts[i] != nil { continue } for j := range resp.Reservations { r := &resp.Reservations[j] for k := range r.Instances { if r.Instances[k].InstanceId == string(id) { inst := r.Instances[k] // TODO(wallyworld): lookup the details to fill in the instance type data insts[i] = &ec2Instance{e: e, Instance: &inst} n++ } } } } if n < len(ids) { return environs.ErrPartialInstances } return nil }
func waitForDnsName(ec2Inst *ec2.EC2, instance *ec2.Instance) (*ec2.Instance, error) { t0 := time.Now() for instance.DNSName == "" { instId := instance.InstanceId if time.Now().Sub(t0) > maxWaitTime { return nil, fmt.Errorf("ec2: time out waiting for instance %s to start", instId) } log.Debugf("ec2: waiting for dnsname for instance %s", instId) time.Sleep(500 * time.Millisecond) resp, err := ec2Inst.Instances([]string{instance.InstanceId}, ec2.NewFilter()) if err != nil { return nil, err } if len(resp.Reservations) == 0 || len(resp.Reservations[0].Instances) == 0 { return nil, fmt.Errorf("No instances returned") } instance = &resp.Reservations[0].Instances[0] } return instance, nil }
func (c *ec2Client) findInstance() (instance *ec2.Instance, err error) { filter := ec2.NewFilter() filter.Add("tag:Name", c.config.tag) resp, err := c.ec2Conn.Instances([]string{}, filter) if err != nil { return nil, err } else { if resp.Reservations == nil { return nil, nil } instance := resp.Reservations[0].Instances[0] if instance.State.Name == "running" || instance.State.Name == "pending" { return &instance, nil } return nil, nil } }
func (c *ec2Client) startInstance() error { // TODO: allow more than one sg in the future options := ec2.RunInstances{ SubnetId: c.config.subnetId, ImageId: c.config.ami, InstanceType: c.config.instanceType, KeyName: c.config.keypair, AvailZone: c.config.zone, SecurityGroups: []ec2.SecurityGroup{ec2.SecurityGroup{Id: c.config.securityGroupId}}, UserData: []byte(userdata), } resp, err := c.ec2Conn.RunInstances(&options) if err != nil { return err } // TODO (aaron): this really could be multiple instances, not just 1 i := resp.Instances[0] for i.State.Name != "running" { time.Sleep(3 * time.Second) fmt.Printf("Waiting for instance to come up. Current State: %s\n", i.State.Name) resp, err := c.ec2Conn.Instances([]string{i.InstanceId}, ec2.NewFilter()) if err != nil { return err } i = resp.Reservations[0].Instances[0] } c.instance = &i fmt.Printf("Instance up and running - id: %s\n", i.InstanceId) return nil }
func (s *S) TestDescribeSnapshotsExample(c *C) { testServer.Response(200, nil, DescribeSnapshotsExample) filter := ec2.NewFilter() filter.Add("key1", "value1") filter.Add("key2", "value2", "value3") resp, err := s.ec2.Snapshots([]string{"snap-1", "snap-2"}, filter) req := testServer.WaitRequest() c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeSnapshots"}) c.Assert(req.Form["SnapshotId.1"], DeepEquals, []string{"snap-1"}) c.Assert(req.Form["SnapshotId.2"], DeepEquals, []string{"snap-2"}) c.Assert(req.Form["Filter.1.Name"], DeepEquals, []string{"key1"}) c.Assert(req.Form["Filter.1.Value.1"], DeepEquals, []string{"value1"}) c.Assert(req.Form["Filter.1.Value.2"], IsNil) c.Assert(req.Form["Filter.2.Name"], DeepEquals, []string{"key2"}) c.Assert(req.Form["Filter.2.Value.1"], DeepEquals, []string{"value2"}) c.Assert(req.Form["Filter.2.Value.2"], DeepEquals, []string{"value3"}) c.Assert(err, IsNil) c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") c.Assert(resp.Snapshots, HasLen, 1) s0 := resp.Snapshots[0] c.Assert(s0.Id, Equals, "snap-1a2b3c4d") c.Assert(s0.VolumeId, Equals, "vol-8875daef") c.Assert(s0.VolumeSize, Equals, "15") c.Assert(s0.Status, Equals, "pending") c.Assert(s0.StartTime, Equals, "2010-07-29T04:12:01.000Z") c.Assert(s0.Progress, Equals, "30%") c.Assert(s0.OwnerId, Equals, "111122223333") c.Assert(s0.Description, Equals, "Daily Backup") c.Assert(s0.Tags, HasLen, 1) c.Assert(s0.Tags[0].Key, Equals, "Purpose") c.Assert(s0.Tags[0].Value, Equals, "demo_db_14_backup") }
func terminateInstances(c *C, e *ec2.EC2, ids []string) { _, err := e.TerminateInstances(ids) c.Assert(err, IsNil, Commentf("%v INSTANCES LEFT RUNNING!!!", ids)) // We need to wait until the instances are really off, because // entities that depend on them won't be deleted (i.e. groups, // NICs, subnets, etc.) testAttempt := aws.AttemptStrategy{ Total: 10 * time.Minute, Delay: 5 * time.Second, } f := ec2.NewFilter() f.Add("instance-state-name", "terminated") idsLeft := make(map[string]bool) for _, id := range ids { idsLeft[id] = true } for a := testAttempt.Start(); a.Next(); { c.Logf("waiting for %v to get terminated", ids) resp, err := e.Instances(ids, f) if err != nil { c.Fatalf("not waiting for %v to terminate: %v", ids, err) } for _, r := range resp.Reservations { for _, inst := range r.Instances { delete(idsLeft, inst.InstanceId) } } ids = []string{} for id, _ := range idsLeft { ids = append(ids, id) } if len(ids) == 0 { c.Logf("all instances terminated.") return } } c.Fatalf("%v INSTANCES LEFT RUNNING!!!", ids) }
// getDefaultVPCIdAndSubnets returns the default VPC id and a list of // its default subnets. If fails if there is no default VPC or at // least one subnet in it. func (s *ServerTests) getDefaultVPCIdAndSubnets(c *C) (string, []ec2.Subnet) { resp1, err := s.ec2.AccountAttributes("default-vpc") c.Assert(err, IsNil) c.Assert(resp1.Attributes, HasLen, 1) c.Assert(resp1.Attributes[0].Name, Equals, "default-vpc") c.Assert(resp1.Attributes[0].Values, HasLen, 1) c.Assert(resp1.Attributes[0].Values[0], Not(Equals), "") defaultVPCId := resp1.Attributes[0].Values[0] if defaultVPCId == "none" { c.Fatalf("no default VPC for region %q", s.ec2.Region.Name) } filter := ec2.NewFilter() filter.Add("defaultForAz", "true") filter.Add("vpc-id", defaultVPCId) resp2, err := s.ec2.Subnets(nil, filter) c.Assert(err, IsNil) defaultSubnets := resp2.Subnets if len(defaultSubnets) < 1 { c.Fatalf("no default subnets for VPC %q", defaultVPCId) } return defaultVPCId, defaultSubnets }
func (s *S) TestDescribeInstancesExample2(c *C) { testServer.Response(200, nil, DescribeInstancesExample2) filter := ec2.NewFilter() filter.Add("key1", "value1") filter.Add("key2", "value2", "value3") resp, err := s.ec2.Instances([]string{"i-1", "i-2"}, filter) req := testServer.WaitRequest() c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeInstances"}) c.Assert(req.Form["InstanceId.1"], DeepEquals, []string{"i-1"}) c.Assert(req.Form["InstanceId.2"], DeepEquals, []string{"i-2"}) c.Assert(req.Form["Filter.1.Name"], DeepEquals, []string{"key1"}) c.Assert(req.Form["Filter.1.Value.1"], DeepEquals, []string{"value1"}) c.Assert(req.Form["Filter.1.Value.2"], IsNil) c.Assert(req.Form["Filter.2.Name"], DeepEquals, []string{"key2"}) c.Assert(req.Form["Filter.2.Value.1"], DeepEquals, []string{"value2"}) c.Assert(req.Form["Filter.2.Value.2"], DeepEquals, []string{"value3"}) c.Assert(err, IsNil) c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") c.Assert(resp.Reservations, HasLen, 1) r0 := resp.Reservations[0] r0i := r0.Instances[0] c.Assert(r0i.State.Code, Equals, 16) c.Assert(r0i.State.Name, Equals, "running") r0t0 := r0i.Tags[0] r0t1 := r0i.Tags[1] c.Assert(r0t0.Key, Equals, "webserver") c.Assert(r0t0.Value, Equals, "") c.Assert(r0t1.Key, Equals, "stack") c.Assert(r0t1.Value, Equals, "Production") }
func (s *ServerTests) TestInstanceFiltering(c *C) { vpcResp, err := s.ec2.CreateVPC("10.4.0.0/16", "") c.Assert(err, IsNil) vpcId := vpcResp.VPC.Id defer s.deleteVPCs(c, []string{vpcId}) subResp := s.createSubnet(c, vpcId, "10.4.1.0/24", "") subId := subResp.Subnet.Id defer s.deleteSubnets(c, []string{subId}) groupResp, err := s.ec2.CreateSecurityGroup( sessionName("testgroup1"), "testgroup one description", ) c.Assert(err, IsNil) group1 := groupResp.SecurityGroup groupResp, err = s.ec2.CreateSecurityGroupVPC( vpcId, sessionName("testgroup2"), "testgroup two description vpc", ) c.Assert(err, IsNil) group2 := groupResp.SecurityGroup defer s.deleteGroups(c, []ec2.SecurityGroup{group1, group2}) insts := make([]*ec2.Instance, 3) inst, err := s.ec2.RunInstances(&ec2.RunInstances{ MinCount: 2, ImageId: imageId, InstanceType: "t1.micro", SecurityGroups: []ec2.SecurityGroup{group1}, }) c.Assert(err, IsNil) insts[0] = &inst.Instances[0] insts[1] = &inst.Instances[1] imageId2 := "ami-e358958a" // Natty server, i386, EBS store inst, err = s.ec2.RunInstances(&ec2.RunInstances{ ImageId: imageId2, InstanceType: "t1.micro", SubnetId: subId, SecurityGroups: []ec2.SecurityGroup{group2}, }) c.Assert(err, IsNil) insts[2] = &inst.Instances[0] ids := func(indices ...int) (instIds []string) { for _, index := range indices { instIds = append(instIds, insts[index].InstanceId) } return } defer terminateInstances(c, s.ec2, ids(0, 1, 2)) tests := []struct { about string instanceIds []string // instanceIds argument to Instances method. filters []filterSpec // filters argument to Instances method. resultIds []string // set of instance ids of expected results. allowExtra bool // resultIds may be incomplete. err string // expected error. }{ { about: "check that Instances returns all instances", resultIds: ids(0, 1, 2), allowExtra: true, }, { about: "check that specifying two instance ids returns them", instanceIds: ids(0, 2), resultIds: ids(0, 2), }, { about: "check that specifying a non-existent instance id gives an error", instanceIds: append(ids(0), "i-deadbeef"), err: `.*\(InvalidInstanceID\.NotFound\)`, }, { about: "check that a filter allowed both instances returns both of them", filters: []filterSpec{ {"instance-id", ids(0, 2)}, }, resultIds: ids(0, 2), }, { about: "check that a filter allowing only one instance returns it", filters: []filterSpec{ {"instance-id", ids(1)}, }, resultIds: ids(1), }, { about: "check that a filter allowing no instances returns none", filters: []filterSpec{ {"instance-id", []string{"i-deadbeef12345"}}, }, }, { about: "check that filtering on group id works", filters: []filterSpec{ {"group-id", []string{group1.Id}}, }, resultIds: ids(0, 1), }, { about: "check that filtering on group id with instance prefix works", filters: []filterSpec{ {"instance.group-id", []string{group1.Id}}, }, resultIds: ids(0, 1), }, { about: "check that filtering on group name works", filters: []filterSpec{ {"group-name", []string{group1.Name}}, }, resultIds: ids(0, 1), }, { about: "check that filtering on group name with instance prefix works", filters: []filterSpec{ {"instance.group-name", []string{group1.Name}}, }, resultIds: ids(0, 1), }, { about: "check that filtering on image id works", filters: []filterSpec{ {"image-id", []string{imageId}}, }, resultIds: ids(0, 1), allowExtra: true, }, { about: "combination filters 1", filters: []filterSpec{ {"image-id", []string{imageId, imageId2}}, {"group-name", []string{group1.Name}}, }, resultIds: ids(0, 1), }, { about: "combination filters 2", filters: []filterSpec{ {"image-id", []string{imageId2}}, {"group-name", []string{group1.Name}}, }, }, { about: "VPC filters in combination", filters: []filterSpec{ {"vpc-id", []string{vpcId}}, {"subnet-id", []string{subId}}, }, resultIds: ids(2), }, } for i, t := range tests { c.Logf("%d. %s", i, t.about) var f *ec2.Filter if t.filters != nil { f = ec2.NewFilter() for _, spec := range t.filters { f.Add(spec.name, spec.values...) } } resp, err := s.ec2.Instances(t.instanceIds, f) if t.err != "" { c.Check(err, ErrorMatches, t.err) continue } c.Assert(err, IsNil) insts := make(map[string]*ec2.Instance) for _, r := range resp.Reservations { for j := range r.Instances { inst := &r.Instances[j] c.Check(insts[inst.InstanceId], IsNil, Commentf("duplicate instance id: %q", inst.InstanceId)) insts[inst.InstanceId] = inst } } if !t.allowExtra { c.Check(insts, HasLen, len(t.resultIds), Commentf("expected %d instances got %#v", len(t.resultIds), insts)) } for j, id := range t.resultIds { c.Check(insts[id], NotNil, Commentf("instance id %d (%q) not found; got %#v", j, id, insts)) } } }
func (s *ServerTests) TestSubnets(c *C) { resp, err := s.ec2.CreateVPC("10.2.0.0/16", "") c.Assert(err, IsNil) vpcId := resp.VPC.Id defer s.deleteVPCs(c, []string{vpcId}) resp1 := s.createSubnet(c, vpcId, "10.2.1.0/24", "") assertSubnet(c, resp1.Subnet, "", vpcId, "10.2.1.0/24") id1 := resp1.Subnet.Id resp2, err := s.ec2.CreateSubnet(vpcId, "10.2.2.0/24", "") c.Assert(err, IsNil) assertSubnet(c, resp2.Subnet, "", vpcId, "10.2.2.0/24") id2 := resp2.Subnet.Id // We only check for the subnets we just created, because the user // might have others in his account (when testing against the EC2 // servers). In some cases it takes a short while until both // subnets are created, so we need to retry a few times to make // sure. testAttempt := aws.AttemptStrategy{ Total: 2 * time.Minute, Delay: 5 * time.Second, } var list *ec2.SubnetsResp done := false for a := testAttempt.Start(); a.Next(); { c.Logf("waiting for %v to be created", []string{id1, id2}) list, err = s.ec2.Subnets(nil, nil) if err != nil { c.Logf("retrying; Subnets returned: %v", err) continue } found := 0 for _, subnet := range list.Subnets { c.Logf("found subnet %v", subnet) switch subnet.Id { case id1: assertSubnet(c, subnet, id1, vpcId, resp1.Subnet.CIDRBlock) found++ case id2: assertSubnet(c, subnet, id2, vpcId, resp2.Subnet.CIDRBlock) found++ } if found == 2 { done = true break } } if done { c.Logf("all subnets were created") break } } if !done { c.Fatalf("timeout while waiting for subnets %v", []string{id1, id2}) } list, err = s.ec2.Subnets([]string{id1}, nil) c.Assert(err, IsNil) c.Assert(list.Subnets, HasLen, 1) assertSubnet(c, list.Subnets[0], id1, vpcId, resp1.Subnet.CIDRBlock) f := ec2.NewFilter() f.Add("cidr", resp2.Subnet.CIDRBlock) list, err = s.ec2.Subnets(nil, f) c.Assert(err, IsNil) c.Assert(list.Subnets, HasLen, 1) assertSubnet(c, list.Subnets[0], id2, vpcId, resp2.Subnet.CIDRBlock) _, err = s.ec2.DeleteSubnet(id1) c.Assert(err, IsNil) _, err = s.ec2.DeleteSubnet(id2) c.Assert(err, IsNil) }
func (s *ServerTests) TestVPCs(c *C) { resp1, err := s.ec2.CreateVPC("10.0.0.0/16", "") c.Assert(err, IsNil) assertVPC(c, resp1.VPC, "", "10.0.0.0/16") id1 := resp1.VPC.Id resp2, err := s.ec2.CreateVPC("10.1.0.0/16", "default") c.Assert(err, IsNil) assertVPC(c, resp2.VPC, "", "10.1.0.0/16") id2 := resp2.VPC.Id // We only check for the VPCs we just created, because the user // might have others in his account (when testing against the EC2 // servers). In some cases it takes a short while until both VPCs // are created, so we need to retry a few times to make sure. var list *ec2.VPCsResp done := false testAttempt := aws.AttemptStrategy{ Total: 2 * time.Minute, Delay: 5 * time.Second, } for a := testAttempt.Start(); a.Next(); { c.Logf("waiting for %v to be created", []string{id1, id2}) list, err = s.ec2.VPCs(nil, nil) if err != nil { c.Logf("retrying; VPCs returned: %v", err) continue } found := 0 for _, vpc := range list.VPCs { c.Logf("found VPC %v", vpc) switch vpc.Id { case id1: assertVPC(c, vpc, id1, resp1.VPC.CIDRBlock) found++ case id2: assertVPC(c, vpc, id2, resp2.VPC.CIDRBlock) found++ } if found == 2 { done = true break } } if done { c.Logf("all VPCs were created") break } } if !done { c.Fatalf("timeout while waiting for VPCs %v", []string{id1, id2}) } list, err = s.ec2.VPCs([]string{id1}, nil) c.Assert(err, IsNil) c.Assert(list.VPCs, HasLen, 1) assertVPC(c, list.VPCs[0], id1, resp1.VPC.CIDRBlock) f := ec2.NewFilter() f.Add("cidr", resp2.VPC.CIDRBlock) list, err = s.ec2.VPCs(nil, f) c.Assert(err, IsNil) c.Assert(list.VPCs, HasLen, 1) assertVPC(c, list.VPCs[0], id2, resp2.VPC.CIDRBlock) _, err = s.ec2.DeleteVPC(id1) c.Assert(err, IsNil) _, err = s.ec2.DeleteVPC(id2) c.Assert(err, IsNil) }
func (s *ServerTests) TestIPPerms(c *C) { g0 := s.makeTestGroup(c, "goamz-test0", "ec2test group 0") g1 := s.makeTestGroup(c, "goamz-test1", "ec2test group 1") defer s.deleteGroups(c, []ec2.SecurityGroup{g0, g1}) resp, err := s.ec2.SecurityGroups([]ec2.SecurityGroup{g0, g1}, nil) c.Assert(err, IsNil) c.Assert(resp.Groups, HasLen, 2) c.Assert(resp.Groups[0].IPPerms, HasLen, 0) c.Assert(resp.Groups[1].IPPerms, HasLen, 0) ownerId := resp.Groups[0].OwnerId // test some invalid parameters // TODO more _, err = s.ec2.AuthorizeSecurityGroup(g0, []ec2.IPPerm{{ Protocol: "tcp", FromPort: 0, ToPort: 1024, SourceIPs: []string{"z127.0.0.1/24"}, }}) c.Assert(err, NotNil) c.Check(errorCode(err), Equals, "InvalidPermission.Malformed") // Check that AuthorizeSecurityGroup adds the correct authorizations. _, err = s.ec2.AuthorizeSecurityGroup(g0, []ec2.IPPerm{{ Protocol: "tcp", FromPort: 2000, ToPort: 2001, SourceIPs: []string{"127.0.0.0/24"}, SourceGroups: []ec2.UserSecurityGroup{{ Name: g1.Name, }, { Id: g0.Id, }}, }, { Protocol: "tcp", FromPort: 2000, ToPort: 2001, SourceIPs: []string{"200.1.1.34/32"}, }}) c.Assert(err, IsNil) resp, err = s.ec2.SecurityGroups([]ec2.SecurityGroup{g0}, nil) c.Assert(err, IsNil) c.Assert(resp.Groups, HasLen, 1) c.Assert(resp.Groups[0].IPPerms, HasLen, 1) perm := resp.Groups[0].IPPerms[0] srcg := perm.SourceGroups c.Assert(srcg, HasLen, 2) // Normalize so we don't care about returned order. if srcg[0].Name == g1.Name { srcg[0], srcg[1] = srcg[1], srcg[0] } c.Check(srcg[0].Name, Equals, g0.Name) c.Check(srcg[0].Id, Equals, g0.Id) c.Check(srcg[0].OwnerId, Equals, ownerId) c.Check(srcg[1].Name, Equals, g1.Name) c.Check(srcg[1].Id, Equals, g1.Id) c.Check(srcg[1].OwnerId, Equals, ownerId) sort.Strings(perm.SourceIPs) c.Check(perm.SourceIPs, DeepEquals, []string{"127.0.0.0/24", "200.1.1.34/32"}) // Check that we can't delete g1 (because g0 is using it) _, err = s.ec2.DeleteSecurityGroup(g1) c.Assert(err, NotNil) c.Check(errorCode(err), Equals, "InvalidGroup.InUse") _, err = s.ec2.RevokeSecurityGroup(g0, []ec2.IPPerm{{ Protocol: "tcp", FromPort: 2000, ToPort: 2001, SourceGroups: []ec2.UserSecurityGroup{{Id: g1.Id}}, }, { Protocol: "tcp", FromPort: 2000, ToPort: 2001, SourceIPs: []string{"200.1.1.34/32"}, }}) c.Assert(err, IsNil) resp, err = s.ec2.SecurityGroups([]ec2.SecurityGroup{g0}, nil) c.Assert(err, IsNil) c.Assert(resp.Groups, HasLen, 1) c.Assert(resp.Groups[0].IPPerms, HasLen, 1) perm = resp.Groups[0].IPPerms[0] srcg = perm.SourceGroups c.Assert(srcg, HasLen, 1) c.Check(srcg[0].Name, Equals, g0.Name) c.Check(srcg[0].Id, Equals, g0.Id) c.Check(srcg[0].OwnerId, Equals, ownerId) c.Check(perm.SourceIPs, DeepEquals, []string{"127.0.0.0/24"}) // We should be able to delete g1 now because we've removed its only use. _, err = s.ec2.DeleteSecurityGroup(g1) c.Assert(err, IsNil) _, err = s.ec2.DeleteSecurityGroup(g0) c.Assert(err, IsNil) f := ec2.NewFilter() f.Add("group-id", g0.Id, g1.Id) resp, err = s.ec2.SecurityGroups(nil, f) c.Assert(err, IsNil) c.Assert(resp.Groups, HasLen, 0) }
func (s *ServerTests) TestGroupFiltering(c *C) { g := make([]ec2.SecurityGroup, 4) for i := range g[0:3] { resp, err := s.ec2.CreateSecurityGroup(sessionName(fmt.Sprintf("testgroup%d", i)), fmt.Sprintf("testdescription%d", i)) c.Assert(err, IsNil) g[i] = resp.SecurityGroup c.Logf("group %d: %v", i, g[i]) defer s.ec2.DeleteSecurityGroup(g[i]) } // Get the default group. resp, err := s.ec2.SecurityGroups([]ec2.SecurityGroup{{Name: "default"}}, nil) c.Assert(err, IsNil) g[3] = resp.Groups[0].SecurityGroup perms := [][]ec2.IPPerm{ {{ Protocol: "tcp", FromPort: 100, ToPort: 200, SourceIPs: []string{"1.2.3.4/32"}, }}, {{ Protocol: "tcp", FromPort: 200, ToPort: 300, SourceGroups: []ec2.UserSecurityGroup{{Id: g[1].Id}}, }}, {{ Protocol: "udp", FromPort: 200, ToPort: 400, SourceGroups: []ec2.UserSecurityGroup{{Id: g[1].Id}}, }}, } for i, ps := range perms { _, err := s.ec2.AuthorizeSecurityGroup(g[i], ps) c.Assert(err, IsNil) } groups := func(indices ...int) (gs []ec2.SecurityGroup) { for _, index := range indices { gs = append(gs, g[index]) } return } type groupTest struct { about string groups []ec2.SecurityGroup // groupIds argument to SecurityGroups method. filters []filterSpec // filters argument to SecurityGroups method. results []ec2.SecurityGroup // set of expected result groups. allowExtra bool // specified results may be incomplete. err string // expected error. } filterCheck := func(name, val string, gs []ec2.SecurityGroup) groupTest { return groupTest{ about: "filter check " + name, filters: []filterSpec{{name, []string{val}}}, results: gs, allowExtra: true, } } tests := []groupTest{ { about: "check that SecurityGroups returns all groups", results: groups(0, 1, 2, 3), allowExtra: true, }, { about: "check that specifying two group ids returns them", groups: idsOnly(groups(0, 2)), results: groups(0, 2), }, { about: "check that specifying names only works", groups: namesOnly(groups(0, 2)), results: groups(0, 2), }, { about: "check that specifying a non-existent group id gives an error", groups: append(groups(0), ec2.SecurityGroup{Id: "sg-eeeeeeeee"}), err: `.*\(InvalidGroup\.NotFound\)`, }, { about: "check that a filter allowed two groups returns both of them", filters: []filterSpec{ {"group-id", []string{g[0].Id, g[2].Id}}, }, results: groups(0, 2), }, { about: "check that the previous filter works when specifying a list of ids", groups: groups(1, 2), filters: []filterSpec{ {"group-id", []string{g[0].Id, g[2].Id}}, }, results: groups(2), }, { about: "check that a filter allowing no groups returns none", filters: []filterSpec{ {"group-id", []string{"sg-eeeeeeeee"}}, }, }, filterCheck("description", "testdescription1", groups(1)), filterCheck("group-name", g[2].Name, groups(2)), filterCheck("ip-permission.cidr", "1.2.3.4/32", groups(0)), filterCheck("ip-permission.group-name", g[1].Name, groups(1, 2)), filterCheck("ip-permission.protocol", "udp", groups(2, 3)), filterCheck("ip-permission.from-port", "200", groups(1, 2)), filterCheck("ip-permission.to-port", "200", groups(0)), // TODO owner-id } for i, t := range tests { c.Logf("%d. %s", i, t.about) var f *ec2.Filter if t.filters != nil { f = ec2.NewFilter() for _, spec := range t.filters { f.Add(spec.name, spec.values...) } } resp, err := s.ec2.SecurityGroups(t.groups, f) if t.err != "" { c.Check(err, ErrorMatches, t.err) continue } c.Assert(err, IsNil) groups := make(map[string]*ec2.SecurityGroup) for j := range resp.Groups { group := &resp.Groups[j].SecurityGroup c.Check(groups[group.Id], IsNil, Commentf("duplicate group id: %q", group.Id)) groups[group.Id] = group } // If extra groups may be returned, eliminate all groups that // we did not create in this session apart from the default group. if t.allowExtra { namePat := regexp.MustCompile(sessionName("testgroup[0-9]")) for id, g := range groups { if g.Name != "default" && !namePat.MatchString(g.Name) { delete(groups, id) } } } c.Check(groups, HasLen, len(t.results)) for j, g := range t.results { rg := groups[g.Id] c.Assert(rg, NotNil, Commentf("group %d (%v) not found; got %#v", j, g, groups)) c.Check(rg.Name, Equals, g.Name, Commentf("group %d (%v)", j, g)) } } }
func (s *ServerTests) TestGroupFiltering(c *C) { vpcResp, err := s.ec2.CreateVPC("10.5.0.0/16", "") c.Assert(err, IsNil) vpcId := vpcResp.VPC.Id defer s.deleteVPCs(c, []string{vpcId}) subResp := s.createSubnet(c, vpcId, "10.5.1.0/24", "") subId := subResp.Subnet.Id defer s.deleteSubnets(c, []string{subId}) g := make([]ec2.SecurityGroup, 5) for i := range g { var resp *ec2.CreateSecurityGroupResp gid := sessionName(fmt.Sprintf("testgroup%d", i)) desc := fmt.Sprintf("testdescription%d", i) if i == 0 { // Create the first one as a VPC group. gid += " vpc" desc += " vpc" resp, err = s.ec2.CreateSecurityGroupVPC(vpcId, gid, desc) } else { resp, err = s.ec2.CreateSecurityGroup(gid, desc) } c.Assert(err, IsNil) g[i] = resp.SecurityGroup c.Logf("group %d: %v", i, g[i]) } // Reorder the groups below, so that g[3] is first (some of the // reset depend on it, so they can't be deleted before g[3]). A // slight optimization for local live tests, so that we don't need // to wait 5s each time deleteGroups runs. defer s.deleteGroups(c, []ec2.SecurityGroup{g[3], g[0], g[1], g[2], g[4]}) perms := [][]ec2.IPPerm{ {{ Protocol: "tcp", FromPort: 100, ToPort: 200, SourceIPs: []string{"1.2.3.4/32"}, }}, {{ Protocol: "tcp", FromPort: 200, ToPort: 300, SourceGroups: []ec2.UserSecurityGroup{{Id: g[2].Id}}, }}, {{ Protocol: "udp", FromPort: 200, ToPort: 400, SourceGroups: []ec2.UserSecurityGroup{{Id: g[2].Id}}, }}, } for i, ps := range perms { _, err := s.ec2.AuthorizeSecurityGroup(g[i+1], ps) c.Assert(err, IsNil) } groups := func(indices ...int) (gs []ec2.SecurityGroup) { for _, index := range indices { gs = append(gs, g[index]) } return } type groupTest struct { about string groups []ec2.SecurityGroup // groupIds argument to SecurityGroups method. filters []filterSpec // filters argument to SecurityGroups method. results []ec2.SecurityGroup // set of expected result groups. allowExtra bool // specified results may be incomplete. err string // expected error. } filterCheck := func(name, val string, gs []ec2.SecurityGroup) groupTest { return groupTest{ about: "filter check " + name, filters: []filterSpec{{name, []string{val}}}, results: gs, allowExtra: true, } } tests := []groupTest{ { about: "check that SecurityGroups returns all groups", results: groups(0, 1, 2, 3, 4), allowExtra: true, }, { about: "check that specifying two group ids returns them", groups: idsOnly(groups(0, 2)), results: groups(0, 2), }, { about: "check that specifying names only works", groups: namesOnly(groups(1, 2)), results: groups(1, 2), }, { about: "check that specifying a non-existent group id gives an error", groups: append(groups(0), ec2.SecurityGroup{Id: "sg-eeeeeeeee"}), err: `.*\(InvalidGroup\.NotFound\)`, }, { about: "check that a filter allowed two groups returns both of them", filters: []filterSpec{ {"group-id", []string{g[0].Id, g[2].Id}}, }, results: groups(0, 2), }, { about: "check that the previous filter works when specifying a list of ids", groups: groups(1, 2), filters: []filterSpec{ {"group-id", []string{g[0].Id, g[2].Id}}, }, results: groups(2), }, { about: "check that a filter allowing no groups returns none", filters: []filterSpec{ {"group-id", []string{"sg-eeeeeeeee"}}, }, }, filterCheck("description", "testdescription1", groups(1)), filterCheck("group-name", g[2].Name, groups(2)), filterCheck("ip-permission.cidr", "1.2.3.4/32", groups(1)), filterCheck("ip-permission.group-name", g[2].Name, groups(2, 3)), filterCheck("ip-permission.protocol", "udp", groups(3)), filterCheck("ip-permission.from-port", "200", groups(2, 3)), filterCheck("ip-permission.to-port", "200", groups(1)), filterCheck("vpc-id", vpcId, groups(0)), // TODO owner-id } for i, t := range tests { c.Logf("%d. %s", i, t.about) var f *ec2.Filter if t.filters != nil { f = ec2.NewFilter() for _, spec := range t.filters { f.Add(spec.name, spec.values...) } } resp, err := s.ec2.SecurityGroups(t.groups, f) if t.err != "" { c.Check(err, ErrorMatches, t.err) continue } c.Assert(err, IsNil) groups := make(map[string]*ec2.SecurityGroup) for j := range resp.Groups { group := &resp.Groups[j].SecurityGroup c.Check(groups[group.Id], IsNil, Commentf("duplicate group id: %q", group.Id)) groups[group.Id] = group } // If extra groups may be returned, eliminate all groups that // we did not create in this session apart from the default group. if t.allowExtra { namePat := regexp.MustCompile(sessionName("testgroup[0-9]")) for id, g := range groups { if !namePat.MatchString(g.Name) { delete(groups, id) } } } c.Check(groups, HasLen, len(t.results)) for j, g := range t.results { rg := groups[g.Id] c.Assert(rg, NotNil, Commentf("group %d (%v) not found; got %#v", j, g, groups)) c.Check(rg.Name, Equals, g.Name, Commentf("group %d (%v)", j, g)) } } }
func (s *ServerTests) TestAssignUnassignPrivateIPs(c *C) { vpcResp, err := s.ec2.CreateVPC("10.7.0.0/16", "") c.Assert(err, IsNil) vpcId := vpcResp.VPC.Id defer s.deleteVPCs(c, []string{vpcId}) subResp := s.createSubnet(c, vpcId, "10.7.1.0/24", "") subId := subResp.Subnet.Id defer s.deleteSubnets(c, []string{subId}) // Launch a m1.medium instance, so we can later assign up to 6 // private IPs per NIC. instList, err := s.ec2.RunInstances(&ec2.RunInstances{ ImageId: imageId, InstanceType: "m1.medium", SubnetId: subId, }) c.Assert(err, IsNil) inst := instList.Instances[0] c.Assert(inst, NotNil) instId := inst.InstanceId defer terminateInstances(c, s.ec2, []string{instId}) // We need to wait for the instance to change state to 'running', // so its automatically created network interface on the created // subnet will appear. testAttempt := aws.AttemptStrategy{ Total: 5 * time.Minute, Delay: 5 * time.Second, } var newNIC *ec2.NetworkInterface f := ec2.NewFilter() f.Add("subnet-id", subId) for a := testAttempt.Start(); a.Next(); { resp, err := s.ec2.NetworkInterfaces(nil, f) if err != nil { c.Logf("NetworkInterfaces returned: %v; retrying...", err) continue } for _, iface := range resp.Interfaces { c.Logf("found NIC %v", iface) if iface.Attachment.InstanceId == instId { c.Logf("found instance %v NIC", instId) newNIC = &iface break } } if newNIC != nil { break } } if newNIC == nil { c.Fatalf("timeout while waiting for the NIC to appear") } c.Check(newNIC.PrivateIPAddress, Matches, `^10\.7\.1\.\d+$`) c.Check(newNIC.PrivateIPs, HasLen, 1) // Now let's try assigning some more private IPs. ips := []string{"10.7.1.25", "10.7.1.30"} _, err = s.ec2.AssignPrivateIPAddresses(newNIC.Id, ips, 0, false) c.Assert(err, IsNil) expectIPs := append([]string{newNIC.PrivateIPAddress}, ips...) s.waitForAddresses(c, newNIC.Id, expectIPs, false) // Try using SecondaryPrivateIPCount. _, err = s.ec2.AssignPrivateIPAddresses(newNIC.Id, nil, 2, false) c.Assert(err, IsNil) expectIPs = append(expectIPs, []string{"10.7.1.*", "10.7.1.*"}...) ips = s.waitForAddresses(c, newNIC.Id, expectIPs, true) // And finally, unassign them all, except the primary. _, err = s.ec2.UnassignPrivateIPAddresses(newNIC.Id, ips) c.Assert(err, IsNil) expectIPs = []string{newNIC.PrivateIPAddress} s.waitForAddresses(c, newNIC.Id, expectIPs, false) }
func (s *AmazonServerSuite) TestRunInstancesVPC(c *C) { vpcResp, err := s.ec2.CreateVPC("10.6.0.0/16", "") c.Assert(err, IsNil) vpcId := vpcResp.VPC.Id defer s.deleteVPCs(c, []string{vpcId}) subResp := s.createSubnet(c, vpcId, "10.6.1.0/24", "") subId := subResp.Subnet.Id defer s.deleteSubnets(c, []string{subId}) groupResp, err := s.ec2.CreateSecurityGroupVPC( vpcId, sessionName("testgroup1 vpc"), "testgroup description vpc", ) c.Assert(err, IsNil) group := groupResp.SecurityGroup defer s.deleteGroups(c, []ec2.SecurityGroup{group}) // Run a single instance with a new network interface. ips := []ec2.PrivateIP{ {Address: "10.6.1.10", IsPrimary: true}, {Address: "10.6.1.20", IsPrimary: false}, } instResp, err := s.ec2.RunInstances(&ec2.RunInstances{ MinCount: 1, ImageId: imageId, InstanceType: "t1.micro", NetworkInterfaces: []ec2.RunNetworkInterface{{ DeviceIndex: 0, SubnetId: subId, PrivateIPs: ips, SecurityGroupIds: []string{group.Id}, DeleteOnTermination: true, }}, }) c.Assert(err, IsNil) inst := &instResp.Instances[0] defer terminateInstances(c, s.ec2, []string{inst.InstanceId}) // Now list the network interfaces and find ours. testAttempt := aws.AttemptStrategy{ Total: 5 * time.Minute, Delay: 5 * time.Second, } f := ec2.NewFilter() f.Add("subnet-id", subId) var newNIC *ec2.NetworkInterface for a := testAttempt.Start(); a.Next(); { c.Logf("waiting for NIC to become available") listNICs, err := s.ec2.NetworkInterfaces(nil, f) if err != nil { c.Logf("retrying; NetworkInterfaces returned: %v", err) continue } for _, iface := range listNICs.Interfaces { c.Logf("found NIC %v", iface) if iface.Attachment.InstanceId == inst.InstanceId { c.Logf("instance %v new NIC appeared", inst.InstanceId) newNIC = &iface break } } if newNIC != nil { break } } if newNIC == nil { c.Fatalf("timeout while waiting for NIC to appear.") } c.Check(newNIC.Id, Matches, `^eni-[0-9a-f]+$`) c.Check(newNIC.SubnetId, Equals, subId) c.Check(newNIC.VPCId, Equals, vpcId) c.Check(newNIC.Status, Matches, `^(attaching|in-use)$`) c.Check(newNIC.PrivateIPAddress, Equals, ips[0].Address) c.Check(newNIC.PrivateIPs, DeepEquals, ips) c.Check(newNIC.Groups, HasLen, 1) c.Check(newNIC.Groups[0].Id, Equals, group.Id) c.Check(newNIC.Attachment.Status, Matches, `^(attaching|attached)$`) c.Check(newNIC.Attachment.DeviceIndex, Equals, 0) c.Check(newNIC.Attachment.DeleteOnTermination, Equals, true) }
func (s *ServerTests) TestNetworkInterfaces(c *C) { vpcResp, err := s.ec2.CreateVPC("10.3.0.0/16", "") c.Assert(err, IsNil) vpcId := vpcResp.VPC.Id defer s.deleteVPCs(c, []string{vpcId}) subResp := s.createSubnet(c, vpcId, "10.3.1.0/24", "") subId := subResp.Subnet.Id defer s.deleteSubnets(c, []string{subId}) sg := s.makeTestGroupVPC(c, vpcId, "vpc-sg-1", "vpc test group1") defer s.deleteGroups(c, []ec2.SecurityGroup{sg}) instList, err := s.ec2.RunInstances(&ec2.RunInstances{ ImageId: imageId, InstanceType: "t1.micro", SubnetId: subId, }) c.Assert(err, IsNil) inst := instList.Instances[0] c.Assert(inst, NotNil) instId := inst.InstanceId defer terminateInstances(c, s.ec2, []string{instId}) ips1 := []ec2.PrivateIP{{Address: "10.3.1.10", IsPrimary: true}} resp1, err := s.ec2.CreateNetworkInterface(ec2.CreateNetworkInterface{ SubnetId: subId, PrivateIPs: ips1, Description: "My first iface", }) c.Assert(err, IsNil) assertNetworkInterface(c, resp1.NetworkInterface, "", subId, ips1) c.Check(resp1.NetworkInterface.Description, Equals, "My first iface") id1 := resp1.NetworkInterface.Id ips2 := []ec2.PrivateIP{ {Address: "10.3.1.20", IsPrimary: true}, {Address: "10.3.1.22", IsPrimary: false}, } resp2, err := s.ec2.CreateNetworkInterface(ec2.CreateNetworkInterface{ SubnetId: subId, PrivateIPs: ips2, SecurityGroupIds: []string{sg.Id}, }) c.Assert(err, IsNil) assertNetworkInterface(c, resp2.NetworkInterface, "", subId, ips2) c.Assert(resp2.NetworkInterface.Groups, DeepEquals, []ec2.SecurityGroup{sg}) id2 := resp2.NetworkInterface.Id // We only check for the network interfaces we just created, // because the user might have others in his account (when testing // against the EC2 servers). In some cases it takes a short while // until both interfaces are created, so we need to retry a few // times to make sure. testAttempt := aws.AttemptStrategy{ Total: 5 * time.Minute, Delay: 5 * time.Second, } var list *ec2.NetworkInterfacesResp done := false for a := testAttempt.Start(); a.Next(); { c.Logf("waiting for %v to be created", []string{id1, id2}) list, err = s.ec2.NetworkInterfaces(nil, nil) if err != nil { c.Logf("retrying; NetworkInterfaces returned: %v", err) continue } found := 0 for _, iface := range list.Interfaces { c.Logf("found NIC %v", iface) switch iface.Id { case id1: assertNetworkInterface(c, iface, id1, subId, ips1) found++ case id2: assertNetworkInterface(c, iface, id2, subId, ips2) found++ } if found == 2 { done = true break } } if done { c.Logf("all NICs were created") break } } if !done { c.Fatalf("timeout while waiting for NICs %v", []string{id1, id2}) } list, err = s.ec2.NetworkInterfaces([]string{id1}, nil) c.Assert(err, IsNil) c.Assert(list.Interfaces, HasLen, 1) assertNetworkInterface(c, list.Interfaces[0], id1, subId, ips1) f := ec2.NewFilter() f.Add("network-interface-id", id2) list, err = s.ec2.NetworkInterfaces(nil, f) c.Assert(err, IsNil) c.Assert(list.Interfaces, HasLen, 1) assertNetworkInterface(c, list.Interfaces[0], id2, subId, ips2) // Attachment might fail if the instance is not running yet, // so we retry for a while until it succeeds. var attResp *ec2.AttachNetworkInterfaceResp for a := testAttempt.Start(); a.Next(); { attResp, err = s.ec2.AttachNetworkInterface(id2, instId, 1) if err != nil { c.Logf("AttachNetworkInterface returned: %v; retrying...", err) attResp = nil continue } c.Logf("AttachNetworkInterface succeeded") c.Check(attResp.AttachmentId, Not(Equals), "") break } if attResp == nil { c.Fatalf("timeout while waiting for AttachNetworkInterface to succeed") } list, err = s.ec2.NetworkInterfaces([]string{id2}, nil) c.Assert(err, IsNil) att := list.Interfaces[0].Attachment c.Check(att.Id, Equals, attResp.AttachmentId) c.Check(att.InstanceId, Equals, instId) c.Check(att.DeviceIndex, Equals, 1) c.Check(att.Status, Matches, "(attaching|in-use)") _, err = s.ec2.DetachNetworkInterface(att.Id, true) c.Check(err, IsNil) _, err = s.ec2.DeleteNetworkInterface(id1) c.Assert(err, IsNil) // We might not be able to delete the interface until the // detachment is completed, so we need to retry here as well. for a := testAttempt.Start(); a.Next(); { _, err = s.ec2.DeleteNetworkInterface(id2) if err != nil { c.Logf("DeleteNetworkInterface returned: %v; retrying...", err) continue } c.Logf("DeleteNetworkInterface succeeded") return } c.Fatalf("timeout while waiting for DeleteNetworkInterface to succeed") }