Beispiel #1
0
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)
}
Beispiel #5
0
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
}
Beispiel #6
0
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)
}
Beispiel #8
0
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
}
Beispiel #9
0
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
}
Beispiel #10
0
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")
}
Beispiel #11
0
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 ""
}
Beispiel #12
0
// 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
}
Beispiel #13
0
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
}
Beispiel #14
0
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
	}
}
Beispiel #15
0
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")
}
Beispiel #17
0
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)
}
Beispiel #18
0
// 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")
}
Beispiel #20
0
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))
		}
	}
}
Beispiel #21
0
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)
}
Beispiel #22
0
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)
}
Beispiel #23
0
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)
}
Beispiel #24
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))
		}
	}
}
Beispiel #25
0
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)
}
Beispiel #27
0
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")
}