Example #1
0
func (s *ServerTests) TestGroupFiltering(c *C) {
	g := make([]ec2.SecurityGroup, 3)
	for i := range g {
		resp, err := s.ec2.CreateSecurityGroup(uniqueName(s.ec2, fmt.Sprintf("testgroup%d", i)), fmt.Sprintf("testdescription%d", i))
		c.Assert(err, IsNil)
		g[i] = resp.SecurityGroup
		defer s.ec2.DeleteSecurityGroup(g[i])
	}
	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 {
		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                // results may be incomplete.
		err        string              // expected error.
	}
	filterCheck := func(name, val string, gs []ec2.SecurityGroup) groupTest {
		return groupTest{
			nil,
			[]filterSpec{{name, []string{val}}},
			gs,
			false,
			"",
		}
	}
	tests := []groupTest{
		// check that SecurityGroups returns all groups.
		{
			nil,
			nil,
			groups(0, 1, 2),
			true,
			"",
		},
		// check that specifying two group ids returns them.
		{
			idsOnly(groups(0, 2)),
			nil,
			groups(0, 2),
			false,
			"",
		},
		// check that specifying names only works
		{
			namesOnly(groups(0, 2)),
			nil,
			groups(0, 2),
			false,
			"",
		},
		// check that specifying a non-existent group id gives an error
		{
			append(groups(0), ec2.SecurityGroup{Id: "sg-eeeeeeeee"}),
			nil,
			nil,
			false,
			`.*\(InvalidGroup\.NotFound\)`,
		},
		// check that a filter allowed two groups returns both of them.
		{
			nil,
			[]filterSpec{
				{"group-id", []string{g[0].Id, g[2].Id}},
			},
			groups(0, 2),
			false,
			"",
		},
		// check that the previous filter works when specifying a list
		// of ids.
		{
			groups(1, 2),
			[]filterSpec{
				{"group-id", []string{g[0].Id, g[2].Id}},
			},
			groups(2),
			false,
			"",
		},
		// check that a filter allowing no groups returns none
		{
			nil,
			[]filterSpec{
				{"group-id", []string{"sg-eeeeeeeee"}},
			},
			nil,
			false,
			"",
		},
		// test the various other group filters
		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.from-port", "200", groups(1, 2)),
		filterCheck("ip-permission.to-port", "200", groups(0)),
		filterCheck("ip-permission.protocol", "udp", groups(2)),
		// TODO owner-id
	}
	for i, t := range tests {
		c.Logf("test %d", i)
		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 !t.allowExtra {
			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))
		}
	}
}
Example #2
0
func (s *ServerTests) TestInstanceFiltering(c *C) {
	groupResp, err := s.ec2.CreateSecurityGroup(uniqueName(s.ec2, "testgroup1"), "testgroup one description")
	c.Assert(err, IsNil)
	group1 := groupResp.SecurityGroup
	defer s.ec2.DeleteSecurityGroup(group1)

	groupResp, err = s.ec2.CreateSecurityGroup(uniqueName(s.ec2, "testgroup2"), "testgroup two description")
	c.Assert(err, IsNil)
	group2 := groupResp.SecurityGroup
	defer s.ec2.DeleteSecurityGroup(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]
	defer terminateInstances(c, s.ec2, insts)

	imageId2 := "ami-e358958a" // Natty server, i386, EBS store
	inst, err = s.ec2.RunInstances(&ec2.RunInstances{
		ImageId:        imageId2,
		InstanceType:   "t1.micro",
		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
	}

	tests := []struct {
		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.
	}{
		// check that Instances returns all instances.
		{
			resultIds:  ids(0, 1, 2),
			allowExtra: true,
		},
		// check that specifying two instance ids returns them.
		{
			instanceIds: ids(0, 2),
			resultIds:   ids(0, 2),
		},
		// check that specifying a non-existent instance id gives an error
		{
			instanceIds: append(ids(0), "i-deadbeef12345"),
			err:         `.*\(InvalidInstanceID\.NotFound\)`,
		},
		// check that a filter allowed both instances returns both of them.
		{
			filters: []filterSpec{
				{"instance-id", ids(0, 2)},
			},
			resultIds: ids(0, 2),
		},
		// check that a filter allowing only one instance returns it.
		{
			filters: []filterSpec{
				{"instance-id", ids(1)},
			},
			resultIds: ids(1),
		},
		// check that a filter allowing no instances returns none
		{
			filters: []filterSpec{
				{"instance-id", []string{"i-deadbeef12345"}},
			},
		},
		{
			filters: []filterSpec{
				{"group-id", []string{group1.Id}},
			},
			resultIds: ids(0, 1),
		},
		{
			filters: []filterSpec{
				{"group-name", []string{group1.Name}},
			},
			resultIds: ids(0, 1),
		},
		{
			filters: []filterSpec{
				{"image-id", []string{imageId}},
			},
			resultIds:  ids(0, 1),
			allowExtra: true,
		},
		// combination filters.
		{
			filters: []filterSpec{
				{"image-id", []string{imageId, imageId2}},
				{"group-name", []string{group1.Name}},
			},
			resultIds: ids(0, 1),
		},
		{
			filters: []filterSpec{
				{"image-id", []string{imageId2}},
				{"group-name", []string{group1.Name}},
			},
		},
	}
	for i, t := range tests {
		c.Logf("test %d", i)
		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))
		}
	}
}