Merge lp:~axwalk/goamz/ec2-describeavailabilityzones into lp:goamz
- ec2-describeavailabilityzones
- Merge into trunk
Proposed by
Andrew Wilkins
Status: | Merged |
---|---|
Merged at revision: | 48 |
Proposed branch: | lp:~axwalk/goamz/ec2-describeavailabilityzones |
Merge into: | lp:goamz |
Diff against target: |
434 lines (+284/-8) 5 files modified
ec2/ec2.go (+41/-0) ec2/ec2_test.go (+62/-0) ec2/ec2t_test.go (+45/-0) ec2/ec2test/server.go (+80/-8) ec2/responses_test.go (+56/-0) |
To merge this branch: | bzr merge lp:~axwalk/goamz/ec2-describeavailabilityzones |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
goamz maintainers | Pending | ||
Review via email: mp+221508@code.launchpad.net |
Commit message
ec2: expose DescribeAvailab
Juju is growing support for manual
and automatic availability zone
distribution. Since availability zones
may differ between accounts, we need
to use DescribeAvailab
enumerate them.
Description of the change
ec2: expose DescribeAvailab
Juju is growing support for manual
and automatic availability zone
distribution. Since availability zones
may differ between accounts, we need
to use DescribeAvailab
enumerate them.
To post a comment you must log in.
Revision history for this message
Andrew Wilkins (axwalk) wrote : | # |
Revision history for this message
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
Revision history for this message
Ian Booth (wallyworld) wrote : | # |
Revision history for this message
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
Revision history for this message
Andrew Wilkins (axwalk) wrote : | # |
On 2014/07/08 15:44:00, axw wrote:
> Please take a look.
uh oh, ignore me
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'ec2/ec2.go' | |||
2 | --- ec2/ec2.go 2014-05-09 15:01:24 +0000 | |||
3 | +++ ec2/ec2.go 2014-05-30 09:44:09 +0000 | |||
4 | @@ -1012,6 +1012,47 @@ | |||
5 | 1012 | return resp, nil | 1012 | return resp, nil |
6 | 1013 | } | 1013 | } |
7 | 1014 | 1014 | ||
8 | 1015 | // ---------------------------------------------------------------------------- | ||
9 | 1016 | // Availability zone management functions and types. | ||
10 | 1017 | // See http://goo.gl/ylxT4R for more details. | ||
11 | 1018 | |||
12 | 1019 | // AvailabilityZonesResp represents a response to a DescribeAvailabilityZones | ||
13 | 1020 | // request in EC2. | ||
14 | 1021 | type AvailabilityZonesResp struct { | ||
15 | 1022 | RequestId string `xml:"requestId"` | ||
16 | 1023 | Zones []AvailabilityZoneInfo `xml:"availabilityZoneInfo>item"` | ||
17 | 1024 | } | ||
18 | 1025 | |||
19 | 1026 | // AvailabilityZoneInfo encapsulates details for an availability zone in EC2. | ||
20 | 1027 | type AvailabilityZoneInfo struct { | ||
21 | 1028 | AvailabilityZone | ||
22 | 1029 | State string `xml:"zoneState"` | ||
23 | 1030 | MessageSet []string `xml:"messageSet>item"` | ||
24 | 1031 | } | ||
25 | 1032 | |||
26 | 1033 | // AvailabilityZone represents an EC2 availability zone. | ||
27 | 1034 | type AvailabilityZone struct { | ||
28 | 1035 | Name string `xml:"zoneName"` | ||
29 | 1036 | Region string `xml:"regionName"` | ||
30 | 1037 | } | ||
31 | 1038 | |||
32 | 1039 | // AvailabilityZones returns details about availability zones in EC2. | ||
33 | 1040 | // The filter parameter is optional, and if provided will limit the | ||
34 | 1041 | // availability zones returned to those matching the given filtering | ||
35 | 1042 | // rules. | ||
36 | 1043 | // | ||
37 | 1044 | // See http://goo.gl/ylxT4R for more details. | ||
38 | 1045 | func (ec2 *EC2) AvailabilityZones(filter *Filter) (resp *AvailabilityZonesResp, err error) { | ||
39 | 1046 | params := makeParams("DescribeAvailabilityZones") | ||
40 | 1047 | filter.addParams(params) | ||
41 | 1048 | resp = &AvailabilityZonesResp{} | ||
42 | 1049 | err = ec2.query(params, resp) | ||
43 | 1050 | if err != nil { | ||
44 | 1051 | return nil, err | ||
45 | 1052 | } | ||
46 | 1053 | return | ||
47 | 1054 | } | ||
48 | 1055 | |||
49 | 1015 | // AccountAttribute holds information about an account attribute. | 1056 | // AccountAttribute holds information about an account attribute. |
50 | 1016 | // | 1057 | // |
51 | 1017 | // See http://goo.gl/hBc28j for more details. | 1058 | // See http://goo.gl/hBc28j for more details. |
52 | 1018 | 1059 | ||
53 | === modified file 'ec2/ec2_test.go' | |||
54 | --- ec2/ec2_test.go 2014-05-09 15:01:24 +0000 | |||
55 | +++ ec2/ec2_test.go 2014-05-30 09:44:09 +0000 | |||
56 | @@ -807,6 +807,68 @@ | |||
57 | 807 | c.Assert(req.Form["Signature"], DeepEquals, []string{"gdG/vEm+c6ehhhfkrJy3+wuVzw/rzKR42TYelMwti7M="}) | 807 | c.Assert(req.Form["Signature"], DeepEquals, []string{"gdG/vEm+c6ehhhfkrJy3+wuVzw/rzKR42TYelMwti7M="}) |
58 | 808 | } | 808 | } |
59 | 809 | 809 | ||
60 | 810 | func (s *S) TestAvailabilityZonesExample1(c *C) { | ||
61 | 811 | testServer.Response(200, nil, DescribeAvailabilityZonesExample1) | ||
62 | 812 | |||
63 | 813 | resp, err := s.ec2.AvailabilityZones(nil) | ||
64 | 814 | |||
65 | 815 | req := testServer.WaitRequest() | ||
66 | 816 | c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeAvailabilityZones"}) | ||
67 | 817 | |||
68 | 818 | c.Assert(err, IsNil) | ||
69 | 819 | c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") | ||
70 | 820 | c.Assert(resp.Zones, HasLen, 4) | ||
71 | 821 | |||
72 | 822 | z0 := resp.Zones[0] | ||
73 | 823 | c.Assert(z0.Name, Equals, "us-east-1a") | ||
74 | 824 | c.Assert(z0.Region, Equals, "us-east-1") | ||
75 | 825 | c.Assert(z0.State, Equals, "available") | ||
76 | 826 | c.Assert(z0.MessageSet, HasLen, 0) | ||
77 | 827 | |||
78 | 828 | z1 := resp.Zones[1] | ||
79 | 829 | c.Assert(z1.Name, Equals, "us-east-1b") | ||
80 | 830 | c.Assert(z1.Region, Equals, "us-east-1") | ||
81 | 831 | c.Assert(z1.State, Equals, "available") | ||
82 | 832 | c.Assert(z1.MessageSet, HasLen, 0) | ||
83 | 833 | |||
84 | 834 | z2 := resp.Zones[2] | ||
85 | 835 | c.Assert(z2.Name, Equals, "us-east-1c") | ||
86 | 836 | c.Assert(z2.Region, Equals, "us-east-1") | ||
87 | 837 | c.Assert(z2.State, Equals, "available") | ||
88 | 838 | c.Assert(z2.MessageSet, HasLen, 0) | ||
89 | 839 | |||
90 | 840 | z3 := resp.Zones[3] | ||
91 | 841 | c.Assert(z3.Name, Equals, "us-east-1d") | ||
92 | 842 | c.Assert(z3.Region, Equals, "us-east-1") | ||
93 | 843 | c.Assert(z3.State, Equals, "available") | ||
94 | 844 | c.Assert(z3.MessageSet, HasLen, 0) | ||
95 | 845 | } | ||
96 | 846 | |||
97 | 847 | func (s *S) TestAvailabilityZonesExample2(c *C) { | ||
98 | 848 | testServer.Response(200, nil, DescribeAvailabilityZonesExample2) | ||
99 | 849 | |||
100 | 850 | resp, err := s.ec2.AvailabilityZones(nil) | ||
101 | 851 | |||
102 | 852 | req := testServer.WaitRequest() | ||
103 | 853 | c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeAvailabilityZones"}) | ||
104 | 854 | |||
105 | 855 | c.Assert(err, IsNil) | ||
106 | 856 | c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") | ||
107 | 857 | c.Assert(resp.Zones, HasLen, 2) | ||
108 | 858 | |||
109 | 859 | z0 := resp.Zones[0] | ||
110 | 860 | c.Assert(z0.Name, Equals, "us-east-1a") | ||
111 | 861 | c.Assert(z0.Region, Equals, "us-east-1") | ||
112 | 862 | c.Assert(z0.State, Equals, "impaired") | ||
113 | 863 | c.Assert(z0.MessageSet, HasLen, 0) | ||
114 | 864 | |||
115 | 865 | z1 := resp.Zones[1] | ||
116 | 866 | c.Assert(z1.Name, Equals, "us-east-1b") | ||
117 | 867 | c.Assert(z1.Region, Equals, "us-east-1") | ||
118 | 868 | c.Assert(z1.State, Equals, "unavailable") | ||
119 | 869 | c.Assert(z1.MessageSet, DeepEquals, []string{"us-east-1b is currently down for maintenance."}) | ||
120 | 870 | } | ||
121 | 871 | |||
122 | 810 | func (s *S) TestDescribeAccountAttributesExamples(c *C) { | 872 | func (s *S) TestDescribeAccountAttributesExamples(c *C) { |
123 | 811 | testServer.Response(200, nil, DescribeAccountAttributesExample) | 873 | testServer.Response(200, nil, DescribeAccountAttributesExample) |
124 | 812 | 874 | ||
125 | 813 | 875 | ||
126 | === modified file 'ec2/ec2t_test.go' | |||
127 | --- ec2/ec2t_test.go 2014-05-21 13:52:28 +0000 | |||
128 | +++ ec2/ec2t_test.go 2014-05-30 09:44:09 +0000 | |||
129 | @@ -152,6 +152,51 @@ | |||
130 | 152 | return ip.String() | 152 | return ip.String() |
131 | 153 | } | 153 | } |
132 | 154 | 154 | ||
133 | 155 | func (s *LocalServerSuite) TestAvailabilityZones(c *C) { | ||
134 | 156 | s.srv.srv.SetAvailabilityZones([]ec2.AvailabilityZoneInfo{{ | ||
135 | 157 | AvailabilityZone: ec2.AvailabilityZone{ | ||
136 | 158 | Name: "us-east-1a", | ||
137 | 159 | Region: "us-east-1", | ||
138 | 160 | }, | ||
139 | 161 | State: "available", | ||
140 | 162 | }, { | ||
141 | 163 | AvailabilityZone: ec2.AvailabilityZone{ | ||
142 | 164 | Name: "us-east-1b", | ||
143 | 165 | Region: "us-east-1", | ||
144 | 166 | }, | ||
145 | 167 | State: "impaired", | ||
146 | 168 | }, { | ||
147 | 169 | AvailabilityZone: ec2.AvailabilityZone{ | ||
148 | 170 | Name: "us-west-1a", | ||
149 | 171 | Region: "us-west-1", | ||
150 | 172 | }, | ||
151 | 173 | State: "available", | ||
152 | 174 | }, { | ||
153 | 175 | AvailabilityZone: ec2.AvailabilityZone{ | ||
154 | 176 | Name: "us-west-1b", | ||
155 | 177 | Region: "us-west-1", | ||
156 | 178 | }, | ||
157 | 179 | State: "unavailable", | ||
158 | 180 | MessageSet: []string{"down for maintenance"}, | ||
159 | 181 | }}) | ||
160 | 182 | |||
161 | 183 | resp, err := s.ec2.AvailabilityZones(nil) | ||
162 | 184 | c.Assert(err, IsNil) | ||
163 | 185 | c.Assert(resp.Zones, HasLen, 4) | ||
164 | 186 | c.Assert(resp.Zones[0].Name, Equals, "us-east-1a") | ||
165 | 187 | c.Assert(resp.Zones[1].Name, Equals, "us-east-1b") | ||
166 | 188 | c.Assert(resp.Zones[2].Name, Equals, "us-west-1a") | ||
167 | 189 | c.Assert(resp.Zones[3].Name, Equals, "us-west-1b") | ||
168 | 190 | |||
169 | 191 | filter := ec2.NewFilter() | ||
170 | 192 | filter.Add("region-name", "us-east-1") | ||
171 | 193 | resp, err = s.ec2.AvailabilityZones(filter) | ||
172 | 194 | c.Assert(err, IsNil) | ||
173 | 195 | c.Assert(resp.Zones, HasLen, 2) | ||
174 | 196 | c.Assert(resp.Zones[0].Name, Equals, "us-east-1a") | ||
175 | 197 | c.Assert(resp.Zones[1].Name, Equals, "us-east-1b") | ||
176 | 198 | } | ||
177 | 199 | |||
178 | 155 | // AmazonServerSuite runs the ec2test server tests against a live EC2 server. | 200 | // AmazonServerSuite runs the ec2test server tests against a live EC2 server. |
179 | 156 | // It will only be activated if the -amazon flag is specified. | 201 | // It will only be activated if the -amazon flag is specified. |
180 | 157 | type AmazonServerSuite struct { | 202 | type AmazonServerSuite struct { |
181 | 158 | 203 | ||
182 | === modified file 'ec2/ec2test/server.go' | |||
183 | --- ec2/ec2test/server.go 2014-05-27 13:26:01 +0000 | |||
184 | +++ ec2/ec2test/server.go 2014-05-30 09:44:09 +0000 | |||
185 | @@ -53,10 +53,11 @@ | |||
186 | 53 | instances map[string]*Instance // id -> instance | 53 | instances map[string]*Instance // id -> instance |
187 | 54 | reservations map[string]*reservation // id -> reservation | 54 | reservations map[string]*reservation // id -> reservation |
188 | 55 | groups map[string]*securityGroup // id -> group | 55 | groups map[string]*securityGroup // id -> group |
193 | 56 | vpcs map[string]*vpc // id -> vpc | 56 | zones []availabilityZone |
194 | 57 | subnets map[string]*subnet // id -> subnet | 57 | vpcs map[string]*vpc // id -> vpc |
195 | 58 | ifaces map[string]*iface // id -> iface | 58 | subnets map[string]*subnet // id -> subnet |
196 | 59 | attachments map[string]*attachment // id -> attachment | 59 | ifaces map[string]*iface // id -> iface |
197 | 60 | attachments map[string]*attachment // id -> attachment | ||
198 | 60 | maxId counter | 61 | maxId counter |
199 | 61 | reqId counter | 62 | reqId counter |
200 | 62 | reservationId counter | 63 | reservationId counter |
201 | @@ -86,6 +87,7 @@ | |||
202 | 86 | imageId string | 87 | imageId string |
203 | 87 | reservation *reservation | 88 | reservation *reservation |
204 | 88 | instType string | 89 | instType string |
205 | 90 | availZone string | ||
206 | 89 | state ec2.InstanceState | 91 | state ec2.InstanceState |
207 | 90 | subnetId string | 92 | subnetId string |
208 | 91 | vpcId string | 93 | vpcId string |
209 | @@ -343,6 +345,7 @@ | |||
210 | 343 | "TerminateInstances": (*Server).terminateInstances, | 345 | "TerminateInstances": (*Server).terminateInstances, |
211 | 344 | "DescribeInstances": (*Server).describeInstances, | 346 | "DescribeInstances": (*Server).describeInstances, |
212 | 345 | "CreateSecurityGroup": (*Server).createSecurityGroup, | 347 | "CreateSecurityGroup": (*Server).createSecurityGroup, |
213 | 348 | "DescribeAvailabilityZones": (*Server).describeAvailabilityZones, | ||
214 | 346 | "DescribeSecurityGroups": (*Server).describeSecurityGroups, | 349 | "DescribeSecurityGroups": (*Server).describeSecurityGroups, |
215 | 347 | "DeleteSecurityGroup": (*Server).deleteSecurityGroup, | 350 | "DeleteSecurityGroup": (*Server).deleteSecurityGroup, |
216 | 348 | "AuthorizeSecurityGroupIngress": (*Server).authorizeSecurityGroupIngress, | 351 | "AuthorizeSecurityGroupIngress": (*Server).authorizeSecurityGroupIngress, |
217 | @@ -363,7 +366,10 @@ | |||
218 | 363 | "UnassignPrivateIpAddresses": (*Server).unassignPrivateIP, | 366 | "UnassignPrivateIpAddresses": (*Server).unassignPrivateIP, |
219 | 364 | } | 367 | } |
220 | 365 | 368 | ||
222 | 366 | const ownerId = "9876" | 369 | const ( |
223 | 370 | ownerId = "9876" | ||
224 | 371 | defaultAvailZone = "us-east-1a" | ||
225 | 372 | ) | ||
226 | 367 | 373 | ||
227 | 368 | // newAction allocates a new action and adds it to the | 374 | // newAction allocates a new action and adds it to the |
228 | 369 | // recorded list of server actions. | 375 | // recorded list of server actions. |
229 | @@ -418,6 +424,13 @@ | |||
230 | 418 | } | 424 | } |
231 | 419 | srv.groups[g.id] = g | 425 | srv.groups[g.id] = g |
232 | 420 | 426 | ||
233 | 427 | // Add a default availability zone. | ||
234 | 428 | var z availabilityZone | ||
235 | 429 | z.Name = defaultAvailZone | ||
236 | 430 | z.Region = "us-east-1" | ||
237 | 431 | z.State = "available" | ||
238 | 432 | srv.zones = []availabilityZone{z} | ||
239 | 433 | |||
240 | 421 | l, err := net.Listen("tcp", "localhost:0") | 434 | l, err := net.Listen("tcp", "localhost:0") |
241 | 422 | if err != nil { | 435 | if err != nil { |
242 | 423 | return nil, fmt.Errorf("cannot listen on localhost: %v", err) | 436 | return nil, fmt.Errorf("cannot listen on localhost: %v", err) |
243 | @@ -446,6 +459,15 @@ | |||
244 | 446 | srv.mu.Unlock() | 459 | srv.mu.Unlock() |
245 | 447 | } | 460 | } |
246 | 448 | 461 | ||
247 | 462 | func (srv *Server) SetAvailabilityZones(zones []ec2.AvailabilityZoneInfo) { | ||
248 | 463 | srv.mu.Lock() | ||
249 | 464 | srv.zones = make([]availabilityZone, len(zones)) | ||
250 | 465 | for i, z := range zones { | ||
251 | 466 | srv.zones[i] = availabilityZone{z} | ||
252 | 467 | } | ||
253 | 468 | srv.mu.Unlock() | ||
254 | 469 | } | ||
255 | 470 | |||
256 | 449 | // SetInitialAttributes sets the given account attributes on the server. | 471 | // SetInitialAttributes sets the given account attributes on the server. |
257 | 450 | func (srv *Server) SetInitialAttributes(attrs map[string][]string) { | 472 | func (srv *Server) SetInitialAttributes(attrs map[string][]string) { |
258 | 451 | for attrName, values := range attrs { | 473 | for attrName, values := range attrs { |
259 | @@ -855,6 +877,7 @@ | |||
260 | 855 | // make sure that form fields are correct before creating the reservation. | 877 | // make sure that form fields are correct before creating the reservation. |
261 | 856 | instType := req.Form.Get("InstanceType") | 878 | instType := req.Form.Get("InstanceType") |
262 | 857 | imageId := req.Form.Get("ImageId") | 879 | imageId := req.Form.Get("ImageId") |
263 | 880 | availZone := req.Form.Get("AvailZone") | ||
264 | 858 | 881 | ||
265 | 859 | r := srv.newReservation(srv.formToGroups(req.Form)) | 882 | r := srv.newReservation(srv.formToGroups(req.Form)) |
266 | 860 | 883 | ||
267 | @@ -892,7 +915,7 @@ | |||
268 | 892 | resp.OwnerId = ownerId | 915 | resp.OwnerId = ownerId |
269 | 893 | 916 | ||
270 | 894 | for i := 0; i < max; i++ { | 917 | for i := 0; i < max; i++ { |
272 | 895 | inst := srv.newInstance(r, instType, imageId, srv.initialInstanceState) | 918 | inst := srv.newInstance(r, instType, imageId, availZone, srv.initialInstanceState) |
273 | 896 | // Create any NICs on the instance subnet (if any), and then | 919 | // Create any NICs on the instance subnet (if any), and then |
274 | 897 | // save the VPC and subnet ids on the instance, as EC2 does. | 920 | // save the VPC and subnet ids on the instance, as EC2 does. |
275 | 898 | inst.ifaces = srv.createNICsOnRun(inst.id(), instSubnet, ifacesToCreate) | 921 | inst.ifaces = srv.createNICsOnRun(inst.id(), instSubnet, ifacesToCreate) |
276 | @@ -942,7 +965,7 @@ | |||
277 | 942 | 965 | ||
278 | 943 | ids := make([]string, n) | 966 | ids := make([]string, n) |
279 | 944 | for i := 0; i < n; i++ { | 967 | for i := 0; i < n; i++ { |
281 | 945 | inst := srv.newInstance(r, instType, imageId, state) | 968 | inst := srv.newInstance(r, instType, imageId, defaultAvailZone, state) |
282 | 946 | inst.vpcId = vpcId | 969 | inst.vpcId = vpcId |
283 | 947 | inst.subnetId = subnetId | 970 | inst.subnetId = subnetId |
284 | 948 | ids[i] = inst.id() | 971 | ids[i] = inst.id() |
285 | @@ -958,11 +981,12 @@ | |||
286 | 958 | return srv.NewInstancesVPC("", "", n, instType, imageId, state, groups) | 981 | return srv.NewInstancesVPC("", "", n, instType, imageId, state, groups) |
287 | 959 | } | 982 | } |
288 | 960 | 983 | ||
290 | 961 | func (srv *Server) newInstance(r *reservation, instType string, imageId string, state ec2.InstanceState) *Instance { | 984 | func (srv *Server) newInstance(r *reservation, instType string, imageId string, availZone string, state ec2.InstanceState) *Instance { |
291 | 962 | inst := &Instance{ | 985 | inst := &Instance{ |
292 | 963 | seq: srv.maxId.next(), | 986 | seq: srv.maxId.next(), |
293 | 964 | instType: instType, | 987 | instType: instType, |
294 | 965 | imageId: imageId, | 988 | imageId: imageId, |
295 | 989 | availZone: availZone, | ||
296 | 966 | state: state, | 990 | state: state, |
297 | 967 | reservation: r, | 991 | reservation: r, |
298 | 968 | } | 992 | } |
299 | @@ -1036,6 +1060,7 @@ | |||
300 | 1036 | IPAddress: fmt.Sprintf("8.0.0.%d", inst.seq%256), | 1060 | IPAddress: fmt.Sprintf("8.0.0.%d", inst.seq%256), |
301 | 1037 | PrivateIPAddress: fmt.Sprintf("127.0.0.%d", inst.seq%256), | 1061 | PrivateIPAddress: fmt.Sprintf("127.0.0.%d", inst.seq%256), |
302 | 1038 | State: inst.state, | 1062 | State: inst.state, |
303 | 1063 | AvailZone: inst.availZone, | ||
304 | 1039 | VPCId: inst.vpcId, | 1064 | VPCId: inst.vpcId, |
305 | 1040 | SubnetId: inst.subnetId, | 1065 | SubnetId: inst.subnetId, |
306 | 1041 | NetworkInterfaces: inst.ifaces, | 1066 | NetworkInterfaces: inst.ifaces, |
307 | @@ -1047,6 +1072,8 @@ | |||
308 | 1047 | switch attr { | 1072 | switch attr { |
309 | 1048 | case "architecture": | 1073 | case "architecture": |
310 | 1049 | return value == "i386", nil | 1074 | return value == "i386", nil |
311 | 1075 | case "availability-zone": | ||
312 | 1076 | return value == inst.availZone, nil | ||
313 | 1050 | case "instance-id": | 1077 | case "instance-id": |
314 | 1051 | return inst.id() == value, nil | 1078 | return inst.id() == value, nil |
315 | 1052 | case "subnet-id": | 1079 | case "subnet-id": |
316 | @@ -1467,6 +1494,51 @@ | |||
317 | 1467 | } | 1494 | } |
318 | 1468 | } | 1495 | } |
319 | 1469 | 1496 | ||
320 | 1497 | type availabilityZone struct { | ||
321 | 1498 | ec2.AvailabilityZoneInfo | ||
322 | 1499 | } | ||
323 | 1500 | |||
324 | 1501 | func (z *availabilityZone) matchAttr(attr, value string) (ok bool, err error) { | ||
325 | 1502 | switch attr { | ||
326 | 1503 | case "message": | ||
327 | 1504 | for _, m := range z.MessageSet { | ||
328 | 1505 | if m == value { | ||
329 | 1506 | return true, nil | ||
330 | 1507 | } | ||
331 | 1508 | } | ||
332 | 1509 | return false, nil | ||
333 | 1510 | case "region-name": | ||
334 | 1511 | return z.Region == value, nil | ||
335 | 1512 | case "state": | ||
336 | 1513 | switch value { | ||
337 | 1514 | case "available", "impaired", "unavailable": | ||
338 | 1515 | return z.State == value, nil | ||
339 | 1516 | } | ||
340 | 1517 | return false, fmt.Errorf("invalid state %q", value) | ||
341 | 1518 | case "zone-name": | ||
342 | 1519 | return z.Name == value, nil | ||
343 | 1520 | } | ||
344 | 1521 | return false, fmt.Errorf("unknown attribute %q", attr) | ||
345 | 1522 | } | ||
346 | 1523 | |||
347 | 1524 | func (srv *Server) describeAvailabilityZones(w http.ResponseWriter, req *http.Request, reqId string) interface{} { | ||
348 | 1525 | srv.mu.Lock() | ||
349 | 1526 | defer srv.mu.Unlock() | ||
350 | 1527 | |||
351 | 1528 | f := newFilter(req.Form) | ||
352 | 1529 | var resp ec2.AvailabilityZonesResp | ||
353 | 1530 | resp.RequestId = reqId | ||
354 | 1531 | for _, zone := range srv.zones { | ||
355 | 1532 | ok, err := f.ok(&zone) | ||
356 | 1533 | if ok { | ||
357 | 1534 | resp.Zones = append(resp.Zones, zone.AvailabilityZoneInfo) | ||
358 | 1535 | } else if err != nil { | ||
359 | 1536 | fatalf(400, "InvalidParameterValue", "describe availability zones: %v", err) | ||
360 | 1537 | } | ||
361 | 1538 | } | ||
362 | 1539 | return &resp | ||
363 | 1540 | } | ||
364 | 1541 | |||
365 | 1470 | func (srv *Server) createVpc(w http.ResponseWriter, req *http.Request, reqId string) interface{} { | 1542 | func (srv *Server) createVpc(w http.ResponseWriter, req *http.Request, reqId string) interface{} { |
366 | 1471 | cidrBlock := parseCidr(req.Form.Get("CidrBlock")) | 1543 | cidrBlock := parseCidr(req.Form.Get("CidrBlock")) |
367 | 1472 | tenancy := req.Form.Get("InstanceTenancy") | 1544 | tenancy := req.Form.Get("InstanceTenancy") |
368 | 1473 | 1545 | ||
369 | === modified file 'ec2/responses_test.go' | |||
370 | --- ec2/responses_test.go 2014-05-08 16:37:32 +0000 | |||
371 | +++ ec2/responses_test.go 2014-05-30 09:44:09 +0000 | |||
372 | @@ -662,6 +662,62 @@ | |||
373 | 662 | </RebootInstancesResponse> | 662 | </RebootInstancesResponse> |
374 | 663 | ` | 663 | ` |
375 | 664 | 664 | ||
376 | 665 | // http://goo.gl/ylxT4R | ||
377 | 666 | var DescribeAvailabilityZonesExample1 = ` | ||
378 | 667 | <DescribeAvailabilityZonesResponse xmlns="http://ec2.amazonaws.com/doc/2014-05-01/"> | ||
379 | 668 | <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId> | ||
380 | 669 | <availabilityZoneInfo> | ||
381 | 670 | <item> | ||
382 | 671 | <zoneName>us-east-1a</zoneName> | ||
383 | 672 | <zoneState>available</zoneState> | ||
384 | 673 | <regionName>us-east-1</regionName> | ||
385 | 674 | <messageSet/> | ||
386 | 675 | </item> | ||
387 | 676 | <item> | ||
388 | 677 | <zoneName>us-east-1b</zoneName> | ||
389 | 678 | <zoneState>available</zoneState> | ||
390 | 679 | <regionName>us-east-1</regionName> | ||
391 | 680 | <messageSet/> | ||
392 | 681 | </item> | ||
393 | 682 | <item> | ||
394 | 683 | <zoneName>us-east-1c</zoneName> | ||
395 | 684 | <zoneState>available</zoneState> | ||
396 | 685 | <regionName>us-east-1</regionName> | ||
397 | 686 | <messageSet/> | ||
398 | 687 | </item> | ||
399 | 688 | <item> | ||
400 | 689 | <zoneName>us-east-1d</zoneName> | ||
401 | 690 | <zoneState>available</zoneState> | ||
402 | 691 | <regionName>us-east-1</regionName> | ||
403 | 692 | <messageSet/> | ||
404 | 693 | </item> | ||
405 | 694 | </availabilityZoneInfo> | ||
406 | 695 | </DescribeAvailabilityZonesResponse> | ||
407 | 696 | ` | ||
408 | 697 | |||
409 | 698 | // http://goo.gl/ylxT4R | ||
410 | 699 | var DescribeAvailabilityZonesExample2 = ` | ||
411 | 700 | <DescribeAvailabilityZonesResponse xmlns="http://ec2.amazonaws.com/doc/2014-05-01/"> | ||
412 | 701 | <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId> | ||
413 | 702 | <availabilityZoneInfo> | ||
414 | 703 | <item> | ||
415 | 704 | <zoneName>us-east-1a</zoneName> | ||
416 | 705 | <zoneState>impaired</zoneState> | ||
417 | 706 | <regionName>us-east-1</regionName> | ||
418 | 707 | <messageSet/> | ||
419 | 708 | </item> | ||
420 | 709 | <item> | ||
421 | 710 | <zoneName>us-east-1b</zoneName> | ||
422 | 711 | <zoneState>unavailable</zoneState> | ||
423 | 712 | <regionName>us-east-1</regionName> | ||
424 | 713 | <messageSet> | ||
425 | 714 | <item>us-east-1b is currently down for maintenance.</item> | ||
426 | 715 | </messageSet> | ||
427 | 716 | </item> | ||
428 | 717 | </availabilityZoneInfo> | ||
429 | 718 | </DescribeAvailabilityZonesResponse> | ||
430 | 719 | ` | ||
431 | 720 | |||
432 | 665 | // http://goo.gl/nkwjv | 721 | // http://goo.gl/nkwjv |
433 | 666 | var CreateVpcExample = ` | 722 | var CreateVpcExample = ` |
434 | 667 | <CreateVpcResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/"> | 723 | <CreateVpcResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/"> |
Reviewers: mp+221508_ code.launchpad. net,
Message:
Please take a look.
Description: ilityZone
ec2: expose DescribeAvailab
Juju is growing support for manual ilityZones to
and automatic availability zone
distribution. Since availability zones
may differ between accounts, we need
to use DescribeAvailab
enumerate them.
https:/ /code.launchpad .net/~axwalk/ goamz/ec2- describeavailab ilityzones/ +merge/ 221508
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/101980044/
Affected files (+289, -11 lines): server. go test.go
A [revision details]
M ec2/ec2.go
M ec2/ec2_test.go
M ec2/ec2t_test.go
M ec2/ec2test/
M ec2/responses_