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)) } } }
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)) } } }