Merge lp:~mirtchovski/goamz/ec2 into lp:~gophers/goamz/trunk
- ec2
- Merge into trunk
Status: | Needs review |
---|---|
Proposed branch: | lp:~mirtchovski/goamz/ec2 |
Merge into: | lp:~gophers/goamz/trunk |
Diff against target: |
525 lines (+376/-21) 7 files modified
ec2/ec2.go (+119/-18) ec2/ec2_test.go (+38/-0) ec2/ec2i_test.go (+69/-0) ec2/ec2test/filter.go (+2/-2) ec2/ec2test/server.go (+1/-1) ec2/responses_test.go (+16/-0) ec2/volume.go (+131/-0) |
To merge this branch: | bzr merge lp:~mirtchovski/goamz/ec2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
The Go Language Gophers | Pending | ||
Review via email: mp+129325@code.launchpad.net |
Commit message
Description of the change
Gustavo Niemeyer (niemeyer) wrote : | # |
This is looking great. We just need some testing.
andrey mirtchovski (mirtchovski) wrote : | # |
> This is looking great. We just need some testing.
done. PTAL :)
andrey mirtchovski (mirtchovski) wrote : | # |
Reviewers: mp+129325_
Message:
Please take a look.
Description:
https:/
(do not edit description out of merge proposal)
Please review this at https:/
Affected files:
A [revision details]
M ec2/ec2i_test.go
Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: <email address hidden>
+New revision: <email address hidden>
Index: ec2/ec2i_test.go
=== modified file 'ec2/ec2i_test.go'
--- ec2/ec2i_test.go 2012-10-17 22:47:42 +0000
+++ ec2/ec2i_test.go 2012-10-18 19:44:38 +0000
@@ -203,3 +203,72 @@
}
}
}
+
+// Cost: unknown
+func (s *ClientTests) TestImages(c *C) {
+ filter := ec2.NewFilter()
+ filter.
+ filter.
+ filter.
+ filter.
+
+ id := []string{
+
+ resp1, err := s.ec2.Images(id, filter)
+ c.Assert(err, IsNil)
+
+ i0 := resp1.Images[0]
+ c.Check(i0.Id, Equals, "ami-fd20ff94")
+ c.Check(i0.Name,
Equals, "bitnami-
+ c.Check(
+ c.Check(i0.Type, Equals, "machine")
+ c.Check(i0.State, Equals, "available")
+ c.Check(
Equals, "aws-marketplac
+ c.Check(i0.Public, Equals, true)
+ c.Check(
+ c.Check(
+ c.Check(
+ c.Check(
+ c.Check(
+ c.Check(
+ c.Check(i0.OwnerId, Equals, "679593333241")
+ c.Check(
+ c.Check(
+ c.Check(
+ c.Check(
+ c.Check(
+
+ c.Assert(
+ c.Assert(
+ c.Assert(
+ c.Assert(
+ c.Assert(
+ c.Assert(
+ c.Assert(
+}
+
+// Cost: unknown
+func (s *ClientTests) TestSnapshots(c *C) {
+ filter := ec2.NewFilter()
+ filter.
+ filter.
+ filter.
+
+ id := []string{
+
+ resp, err := s.ec2.Snapshots(id, filter)
+ c.Assert(err, IsNil)
+ c.Check(
+
+ s0 := resp.Snapshots[0]
+ c.Check(s0.Id, Equals, "snap-9df717f4")
+ c.Check(
+ c.Check(s0.Status, Equals, "completed")
+ c.Check(
andrey mirtchovski (mirtchovski) wrote : | # |
here's what my own command returns (pretty-printed). these public images
were the basis for the tests:
// $ ./aws images -all architecture=i386
description="http://
ec2.Image{
ImageId:
Location:
State:
Owner:
Public:true,
Architectur
ImageType:
KernelId:
StateReason:"",
OwnerAlias:
Name:"bitnami-
Description:"http://
RootDeviceT
RootDeviceN
Virtualizat
Hypervisor:
BlockDevice
ec2.
DeviceNam
VirtualNa
Ebs:
Iops:0
}
}
}
}
// $ ./aws snapshots snapshot-
start-time=
ec2.Snapshot{
SnapshotId:
VolumeId:
Status:
StartTime:
Progress:
OwnerId:
VolumeSize:"2",
Description
OwnerAlias:
Tags:
}
- 22. By Dave Cheney
-
ec2: sort keys before encoding
Fixes issue #1061941.
R=niemeyer
CC=
https://codereview. appspot. com/6734043 - 23. By Francisco Souza
-
iam: add iamtest package
For now, it implements two actions: CreateUser and DeleteUser. More actions
will come in future CLs.R=niemeyer
CC=
https://codereview. appspot. com/6631063
andrey mirtchovski (mirtchovski) wrote : | # |
Please take a look.
andrey mirtchovski (mirtchovski) wrote : | # |
On 2012/11/08 19:17:30, aam wrote:
> Please take a look.
the new thing here is CreateImage and related tests. the rest are
gofmt-induced changes.
andrey mirtchovski (mirtchovski) wrote : | # |
Please take a look.
- 24. By Dave Cheney
-
aws: add ap-southeast-2 region
Welcome to Sydney.
R=TheMue, rog
CC=
https://codereview. appspot. com/6846050 - 25. By Dave Cheney
-
s3: add support for 409 responses
Required to fix LP 1042107
R=fwereade, jameinel, rog
CC=
https://codereview. appspot. com/6901061 - 26. By andrey mirtchovski
-
Volume management for ec2
- 27. By andrey mirtchovski
-
merge
Unmerged revisions
- 27. By andrey mirtchovski
-
merge
- 26. By andrey mirtchovski
-
Volume management for ec2
Preview Diff
1 | === modified file 'ec2/ec2.go' | |||
2 | --- ec2/ec2.go 2012-10-28 16:05:46 +0000 | |||
3 | +++ ec2/ec2.go 2013-01-21 23:50:27 +0000 | |||
4 | @@ -86,7 +86,7 @@ | |||
5 | 86 | // ---------------------------------------------------------------------------- | 86 | // ---------------------------------------------------------------------------- |
6 | 87 | // Request dispatching logic. | 87 | // Request dispatching logic. |
7 | 88 | 88 | ||
9 | 89 | // Error encapsulates an error returned by EC2. | 89 | // Error encapsulates an error returned by EC2. |
10 | 90 | // | 90 | // |
11 | 91 | // See http://goo.gl/VZGuC for more details. | 91 | // See http://goo.gl/VZGuC for more details. |
12 | 92 | type Error struct { | 92 | type Error struct { |
13 | @@ -425,15 +425,15 @@ | |||
14 | 425 | // | 425 | // |
15 | 426 | // See http://goo.gl/wnDBf for more details. | 426 | // See http://goo.gl/wnDBf for more details. |
16 | 427 | type BlockDeviceMapping struct { | 427 | type BlockDeviceMapping struct { |
23 | 428 | DeviceName string `xml:"deviceName"` | 428 | DeviceName string `xml:"deviceName"` |
24 | 429 | VirtualName string `xml:"virtualName"` | 429 | VirtualName string `xml:"virtualName"` |
25 | 430 | SnapshotId string `xml:"ebs>snapshotId"` | 430 | SnapshotId string `xml:"ebs>snapshotId"` |
26 | 431 | VolumeType string `xml:"ebs>volumeType"` | 431 | VolumeType string `xml:"ebs>volumeType"` |
27 | 432 | VolumeSize int64 `xml:"ebs>volumeSize"` | 432 | VolumeSize int64 `xml:"ebs>volumeSize"` |
28 | 433 | DeleteOnTermination bool `xml:"ebs>deleteOnTermination"` | 433 | DeleteOnTermination bool `xml:"ebs>deleteOnTermination"` |
29 | 434 | 434 | ||
30 | 435 | // The number of I/O operations per second (IOPS) that the volume supports. | 435 | // The number of I/O operations per second (IOPS) that the volume supports. |
32 | 436 | IOPS int64 `xml:"ebs>iops"` | 436 | IOPS int64 `xml:"ebs>iops"` |
33 | 437 | } | 437 | } |
34 | 438 | 438 | ||
35 | 439 | // Image represents details about an image. | 439 | // Image represents details about an image. |
36 | @@ -467,7 +467,7 @@ | |||
37 | 467 | // For example, to get all the private images associated with this account set | 467 | // For example, to get all the private images associated with this account set |
38 | 468 | // the boolean filter "is-private" to true. | 468 | // the boolean filter "is-private" to true. |
39 | 469 | // | 469 | // |
41 | 470 | // Note: calling this function with nil ids and filter parameters will result in | 470 | // Note: calling this function with nil ids and filter parameters will result in |
42 | 471 | // a very large number of images being returned. | 471 | // a very large number of images being returned. |
43 | 472 | // | 472 | // |
44 | 473 | // See http://goo.gl/SRBhW for more details. | 473 | // See http://goo.gl/SRBhW for more details. |
45 | @@ -486,6 +486,67 @@ | |||
46 | 486 | return | 486 | return |
47 | 487 | } | 487 | } |
48 | 488 | 488 | ||
49 | 489 | // The CreateImage type encapsulates options for the respective request in EC2. | ||
50 | 490 | // | ||
51 | 491 | // See http://goo.gl/He9Le for more details. | ||
52 | 492 | type CreateImage struct { | ||
53 | 493 | InstanceId string | ||
54 | 494 | Name string | ||
55 | 495 | Description string | ||
56 | 496 | NoReboot bool | ||
57 | 497 | BlockDevices []BlockDeviceMapping | ||
58 | 498 | } | ||
59 | 499 | |||
60 | 500 | // Response to a CreateImage request. | ||
61 | 501 | // | ||
62 | 502 | // See http://goo.gl/He9Le for more details. | ||
63 | 503 | type CreateImageResp struct { | ||
64 | 504 | RequestId string `xml:"requestId"` | ||
65 | 505 | Id string `xml:"imageId"` | ||
66 | 506 | } | ||
67 | 507 | |||
68 | 508 | // CreateImage creates an EBS-backed image from a running instance. | ||
69 | 509 | // | ||
70 | 510 | // See http://goo.gl/He9Le for more details. | ||
71 | 511 | func (ec2 *EC2) CreateImage(options *CreateImage) (resp *CreateImageResp, err error) { | ||
72 | 512 | params := makeParams("CreateImage") | ||
73 | 513 | params["InstanceId"] = options.InstanceId | ||
74 | 514 | params["Name"] = options.Name | ||
75 | 515 | params["Description"] = options.Description | ||
76 | 516 | params["NoReboot"] = strconv.FormatBool(options.NoReboot) | ||
77 | 517 | //params["BlockDevices"] = options.BlockDevices | ||
78 | 518 | |||
79 | 519 | resp = &CreateImageResp{} | ||
80 | 520 | err = ec2.query(params, resp) | ||
81 | 521 | if err != nil { | ||
82 | 522 | return nil, err | ||
83 | 523 | } | ||
84 | 524 | return | ||
85 | 525 | } | ||
86 | 526 | |||
87 | 527 | // The DeregisterImage type encapsulates options for the respective request in EC2. | ||
88 | 528 | // | ||
89 | 529 | // See http://goo.gl/JnVO7 for more details. | ||
90 | 530 | type DeregisterImage struct { | ||
91 | 531 | ImageId string | ||
92 | 532 | } | ||
93 | 533 | |||
94 | 534 | // DeregisterImage Deregisters the specified AMI. Once deregistered, the AMI | ||
95 | 535 | // cannot be used to launch new instances. | ||
96 | 536 | // | ||
97 | 537 | // See http://goo.gl/JnVO7 for more details. | ||
98 | 538 | func (ec2 *EC2) DeregisterImage(id string) (resp *SimpleResp, err error) { | ||
99 | 539 | params := makeParams("DeregisterImage") | ||
100 | 540 | params["ImageId"] = id | ||
101 | 541 | |||
102 | 542 | resp = &SimpleResp{} | ||
103 | 543 | err = ec2.query(params, resp) | ||
104 | 544 | if err != nil { | ||
105 | 545 | return nil, err | ||
106 | 546 | } | ||
107 | 547 | return | ||
108 | 548 | } | ||
109 | 549 | |||
110 | 489 | // Response to a CreateSnapshot request. | 550 | // Response to a CreateSnapshot request. |
111 | 490 | // | 551 | // |
112 | 491 | // See http://goo.gl/ttcda for more details. | 552 | // See http://goo.gl/ttcda for more details. |
113 | @@ -512,11 +573,11 @@ | |||
114 | 512 | 573 | ||
115 | 513 | // DeleteSnapshots deletes the volume snapshots with the given ids. | 574 | // DeleteSnapshots deletes the volume snapshots with the given ids. |
116 | 514 | // | 575 | // |
122 | 515 | // Note: If you make periodic snapshots of a volume, the snapshots are | 576 | // Note: If you make periodic snapshots of a volume, the snapshots are |
123 | 516 | // incremental so that only the blocks on the device that have changed | 577 | // incremental so that only the blocks on the device that have changed |
124 | 517 | // since your last snapshot are incrementally saved in the new snapshot. | 578 | // since your last snapshot are incrementally saved in the new snapshot. |
125 | 518 | // Even though snapshots are saved incrementally, the snapshot deletion | 579 | // Even though snapshots are saved incrementally, the snapshot deletion |
126 | 519 | // process is designed so that you need to retain only the most recent | 580 | // process is designed so that you need to retain only the most recent |
127 | 520 | // snapshot in order to restore the volume. | 581 | // snapshot in order to restore the volume. |
128 | 521 | // | 582 | // |
129 | 522 | // See http://goo.gl/vwU1y for more details. | 583 | // See http://goo.gl/vwU1y for more details. |
130 | @@ -558,7 +619,7 @@ | |||
131 | 558 | Tags []Tag `xml:"tagSet>item"` | 619 | Tags []Tag `xml:"tagSet>item"` |
132 | 559 | } | 620 | } |
133 | 560 | 621 | ||
135 | 561 | // Snapshots returns details about volume snapshots available to the user. | 622 | // Snapshots returns details about volume snapshots available to the user. |
136 | 562 | // The ids and filter parameters, if provided, limit the snapshots returned. | 623 | // The ids and filter parameters, if provided, limit the snapshots returned. |
137 | 563 | // | 624 | // |
138 | 564 | // See http://goo.gl/ogJL4 for more details. | 625 | // See http://goo.gl/ogJL4 for more details. |
139 | @@ -620,7 +681,7 @@ | |||
140 | 620 | Groups []SecurityGroupInfo `xml:"securityGroupInfo>item"` | 681 | Groups []SecurityGroupInfo `xml:"securityGroupInfo>item"` |
141 | 621 | } | 682 | } |
142 | 622 | 683 | ||
144 | 623 | // SecurityGroup encapsulates details for a security group in EC2. | 684 | // SecurityGroup encapsulates details for a security group in EC2. |
145 | 624 | // | 685 | // |
146 | 625 | // See http://goo.gl/CIdyP for more details. | 686 | // See http://goo.gl/CIdyP for more details. |
147 | 626 | type SecurityGroupInfo struct { | 687 | type SecurityGroupInfo struct { |
148 | @@ -785,7 +846,7 @@ | |||
149 | 785 | } | 846 | } |
150 | 786 | 847 | ||
151 | 787 | // CreateTags adds or overwrites one or more tags for the specified instance ids. | 848 | // CreateTags adds or overwrites one or more tags for the specified instance ids. |
153 | 788 | // | 849 | // |
154 | 789 | // See http://goo.gl/Vmkqc for more details | 850 | // See http://goo.gl/Vmkqc for more details |
155 | 790 | func (ec2 *EC2) CreateTags(instIds []string, tags []Tag) (resp *SimpleResp, err error) { | 851 | func (ec2 *EC2) CreateTags(instIds []string, tags []Tag) (resp *SimpleResp, err error) { |
156 | 791 | params := makeParams("CreateTags") | 852 | params := makeParams("CreateTags") |
157 | @@ -863,5 +924,45 @@ | |||
158 | 863 | if err != nil { | 924 | if err != nil { |
159 | 864 | return nil, err | 925 | return nil, err |
160 | 865 | } | 926 | } |
162 | 866 | return resp, nil | 927 | return |
163 | 928 | } | ||
164 | 929 | |||
165 | 930 | // Describes an availability zone | ||
166 | 931 | // | ||
167 | 932 | // See http://goo.gl/Hncxm for more details. | ||
168 | 933 | type AvailZone struct { | ||
169 | 934 | Name string `xml:"zoneName"` | ||
170 | 935 | State string `xml:"zoneState"` | ||
171 | 936 | Region string `xml:"regionName"` | ||
172 | 937 | Message []string `xml:"messageSet>item"` | ||
173 | 938 | } | ||
174 | 939 | |||
175 | 940 | // Response to a AvailZone request. | ||
176 | 941 | // | ||
177 | 942 | // See http://goo.gl/bt2rz for more details. | ||
178 | 943 | type AvailZoneResp struct { | ||
179 | 944 | RequestId string `xml:"requestId"` | ||
180 | 945 | Zones []AvailZone `xml:"availabilityZoneInfo>item"` | ||
181 | 946 | } | ||
182 | 947 | |||
183 | 948 | // AvailZones describes one or more of the Availability Zones that are currently | ||
184 | 949 | // available to the account. | ||
185 | 950 | // | ||
186 | 951 | // The results include zones only for the region you're currently using. | ||
187 | 952 | // | ||
188 | 953 | // Filter can contain: | ||
189 | 954 | // | ||
190 | 955 | // message, region-name, state, zone-name | ||
191 | 956 | // | ||
192 | 957 | // See http://goo.gl/bt2rz for more details. | ||
193 | 958 | func (ec2 *EC2) AvailZones(names []string, filter *Filter) (resp *AvailZoneResp, err error) { | ||
194 | 959 | params := makeParams("DescribeAvailabilityZones") | ||
195 | 960 | addParamsList(params, "ZoneName", names) | ||
196 | 961 | |||
197 | 962 | resp = &AvailZoneResp{} | ||
198 | 963 | err = ec2.query(params, resp) | ||
199 | 964 | if err != nil { | ||
200 | 965 | return nil, err | ||
201 | 966 | } | ||
202 | 967 | return | ||
203 | 867 | } | 968 | } |
204 | 868 | 969 | ||
205 | === modified file 'ec2/ec2_test.go' | |||
206 | --- ec2/ec2_test.go 2012-10-18 18:56:09 +0000 | |||
207 | +++ ec2/ec2_test.go 2013-01-21 23:50:27 +0000 | |||
208 | @@ -291,6 +291,44 @@ | |||
209 | 291 | c.Assert(i0.BlockDevices[0].DeleteOnTermination, Equals, true) | 291 | c.Assert(i0.BlockDevices[0].DeleteOnTermination, Equals, true) |
210 | 292 | } | 292 | } |
211 | 293 | 293 | ||
212 | 294 | func (s *S) TestCreateImageExample(c *C) { | ||
213 | 295 | testServer.PrepareResponse(200, nil, CreateImageExample) | ||
214 | 296 | |||
215 | 297 | options := ec2.CreateImage{ | ||
216 | 298 | InstanceId: "i-10a64379", | ||
217 | 299 | Name: "standard-web-server-v1.0", | ||
218 | 300 | Description: "Standard Web Server v1.0", | ||
219 | 301 | //NoReboot: false, | ||
220 | 302 | //BlockDevices: nil, | ||
221 | 303 | } | ||
222 | 304 | |||
223 | 305 | resp, err := s.ec2.CreateImage(&options) | ||
224 | 306 | |||
225 | 307 | req := testServer.WaitRequest() | ||
226 | 308 | c.Assert(req.Form["Action"], DeepEquals, []string{"CreateImage"}) | ||
227 | 309 | c.Assert(req.Form["InstanceId"], DeepEquals, []string{"i-10a64379"}) | ||
228 | 310 | c.Assert(req.Form["Name"], DeepEquals, []string{"standard-web-server-v1.0"}) | ||
229 | 311 | c.Assert(req.Form["Description"], DeepEquals, []string{"Standard Web Server v1.0"}) | ||
230 | 312 | c.Assert(req.Form["NoReboot"], DeepEquals, []string{"false"}) | ||
231 | 313 | |||
232 | 314 | c.Assert(err, IsNil) | ||
233 | 315 | c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") | ||
234 | 316 | c.Assert(resp.Id, Equals, "ami-4fa54026") | ||
235 | 317 | } | ||
236 | 318 | |||
237 | 319 | func (s *S) TestDeregisterImageExample(c *C) { | ||
238 | 320 | testServer.PrepareResponse(200, nil, DeregisterImageExample) | ||
239 | 321 | |||
240 | 322 | resp, err := s.ec2.DeregisterImage("ami-4fa54026") | ||
241 | 323 | |||
242 | 324 | req := testServer.WaitRequest() | ||
243 | 325 | c.Assert(req.Form["Action"], DeepEquals, []string{"DeregisterImage"}) | ||
244 | 326 | c.Assert(req.Form["ImageId"], DeepEquals, []string{"ami-4fa54026"}) | ||
245 | 327 | |||
246 | 328 | c.Assert(err, IsNil) | ||
247 | 329 | c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") | ||
248 | 330 | } | ||
249 | 331 | |||
250 | 294 | func (s *S) TestCreateSnapshotExample(c *C) { | 332 | func (s *S) TestCreateSnapshotExample(c *C) { |
251 | 295 | testServer.PrepareResponse(200, nil, CreateSnapshotExample) | 333 | testServer.PrepareResponse(200, nil, CreateSnapshotExample) |
252 | 296 | 334 | ||
253 | 297 | 335 | ||
254 | === modified file 'ec2/ec2i_test.go' | |||
255 | --- ec2/ec2i_test.go 2012-10-28 16:05:46 +0000 | |||
256 | +++ ec2/ec2i_test.go 2013-01-21 23:50:27 +0000 | |||
257 | @@ -203,3 +203,72 @@ | |||
258 | 203 | } | 203 | } |
259 | 204 | } | 204 | } |
260 | 205 | } | 205 | } |
261 | 206 | |||
262 | 207 | // Cost: unknown | ||
263 | 208 | func (s *ClientTests) TestImages(c *C) { | ||
264 | 209 | filter := ec2.NewFilter() | ||
265 | 210 | filter.Add("architecture", "i386") | ||
266 | 211 | filter.Add("image-type", "machine") | ||
267 | 212 | filter.Add("description", "http://bitnami.org") | ||
268 | 213 | filter.Add("is-public", "true") | ||
269 | 214 | |||
270 | 215 | id := []string{"ami-fd20ff94"} | ||
271 | 216 | |||
272 | 217 | resp1, err := s.ec2.Images(id, filter) | ||
273 | 218 | c.Assert(err, IsNil) | ||
274 | 219 | |||
275 | 220 | i0 := resp1.Images[0] | ||
276 | 221 | c.Check(i0.Id, Equals, "ami-fd20ff94") | ||
277 | 222 | c.Check(i0.Name, Equals, "bitnami-webpack-1.0-0-linux-ubuntu-10.04.3-i386-mp-0b295d82-395d-4b81-89df-5ac5f0b66975-ami-3820fc51.1") | ||
278 | 223 | c.Check(i0.Description, Equals, "http://bitnami.org") | ||
279 | 224 | c.Check(i0.Type, Equals, "machine") | ||
280 | 225 | c.Check(i0.State, Equals, "available") | ||
281 | 226 | c.Check(i0.Location, Equals, "aws-marketplace/bitnami-webpack-1.0-0-linux-ubuntu-10.04.3-i386-mp-0b295d82-395d-4b81-89df-5ac5f0b66975-ami-3820fc51.1") | ||
282 | 227 | c.Check(i0.Public, Equals, true) | ||
283 | 228 | c.Check(i0.Architecture, Equals, "i386") | ||
284 | 229 | c.Check(i0.Platform, Equals, "") | ||
285 | 230 | c.Check(i0.ProductCodes, HasLen, 0) | ||
286 | 231 | c.Check(i0.KernelId, Equals, "i386") | ||
287 | 232 | c.Check(i0.RamdiskId, Equals, "") | ||
288 | 233 | c.Check(i0.StateReason, Equals, "") | ||
289 | 234 | c.Check(i0.OwnerId, Equals, "679593333241") | ||
290 | 235 | c.Check(i0.OwnerAlias, Equals, "aws-marketplace") | ||
291 | 236 | c.Check(i0.RootDeviceType, Equals, "ebs") | ||
292 | 237 | c.Check(i0.RootDeviceName, Equals, "/dev/sda1") | ||
293 | 238 | c.Check(i0.VirtualizationType, Equals, "paravirtual") | ||
294 | 239 | c.Check(i0.Hypervisor, Equals, "xen") | ||
295 | 240 | |||
296 | 241 | c.Assert(i0.BlockDevices, HasLen, 1) | ||
297 | 242 | c.Assert(i0.BlockDevices[0].DeviceName, Equals, "/dev/sda1") | ||
298 | 243 | c.Assert(i0.BlockDevices[0].SnapshotId, Equals, "snap-5d581d27") | ||
299 | 244 | c.Assert(i0.BlockDevices[0].VolumeSize, Equals, int64(10)) | ||
300 | 245 | c.Assert(i0.BlockDevices[0].DeleteOnTermination, Equals, true) | ||
301 | 246 | c.Assert(i0.BlockDevices[0].VolumeType, Equals, "") | ||
302 | 247 | c.Assert(i0.BlockDevices[0].IOPS, Equals, int64(0)) | ||
303 | 248 | } | ||
304 | 249 | |||
305 | 250 | // Cost: unknown | ||
306 | 251 | func (s *ClientTests) TestSnapshots(c *C) { | ||
307 | 252 | filter := ec2.NewFilter() | ||
308 | 253 | filter.Add("volume-id", "vol-37ac485e") | ||
309 | 254 | filter.Add("status", "completed") | ||
310 | 255 | filter.Add("start-time", "2008-11-19T10:03:00.000Z") | ||
311 | 256 | |||
312 | 257 | id := []string{"snap-9df717f4"} | ||
313 | 258 | |||
314 | 259 | resp, err := s.ec2.Snapshots(id, filter) | ||
315 | 260 | c.Assert(err, IsNil) | ||
316 | 261 | c.Check(resp.Snapshots, HasLen, 1) | ||
317 | 262 | |||
318 | 263 | s0 := resp.Snapshots[0] | ||
319 | 264 | c.Check(s0.Id, Equals, "snap-9df717f4") | ||
320 | 265 | c.Check(s0.VolumeId, Equals, "vol-37ac485e") | ||
321 | 266 | c.Check(s0.Status, Equals, "completed") | ||
322 | 267 | c.Check(s0.StartTime, Equals, "2008-11-19T10:03:00.000Z") | ||
323 | 268 | c.Check(s0.Progress, Equals, "100%") | ||
324 | 269 | c.Check(s0.OwnerId, Equals, "947081328633") | ||
325 | 270 | c.Check(s0.VolumeSize, Equals, "2") | ||
326 | 271 | c.Check(s0.Description, Equals, "1980 US Census (Linux)") | ||
327 | 272 | c.Check(s0.OwnerAlias, Equals, "amazon") | ||
328 | 273 | c.Check(s0.Tags, HasLen, 0) | ||
329 | 274 | } | ||
330 | 206 | 275 | ||
331 | === modified file 'ec2/ec2test/filter.go' | |||
332 | --- ec2/ec2test/filter.go 2012-03-09 14:02:34 +0000 | |||
333 | +++ ec2/ec2test/filter.go 2013-01-21 23:50:27 +0000 | |||
334 | @@ -13,13 +13,13 @@ | |||
335 | 13 | type filter map[string][]string | 13 | type filter map[string][]string |
336 | 14 | 14 | ||
337 | 15 | // newFilter creates a new filter from the Filter fields in the url form. | 15 | // newFilter creates a new filter from the Filter fields in the url form. |
339 | 16 | // | 16 | // |
340 | 17 | // The filtering is specified through a map of name=>values, where the | 17 | // The filtering is specified through a map of name=>values, where the |
341 | 18 | // name is a well-defined key identifying the data to be matched, | 18 | // name is a well-defined key identifying the data to be matched, |
342 | 19 | // and the list of values holds the possible values the filtered | 19 | // and the list of values holds the possible values the filtered |
343 | 20 | // item can take for the key to be included in the | 20 | // item can take for the key to be included in the |
344 | 21 | // result set. For example: | 21 | // result set. For example: |
346 | 22 | // | 22 | // |
347 | 23 | // Filter.1.Name=instance-type | 23 | // Filter.1.Name=instance-type |
348 | 24 | // Filter.1.Value.1=m1.small | 24 | // Filter.1.Value.1=m1.small |
349 | 25 | // Filter.1.Value.2=m1.large | 25 | // Filter.1.Value.2=m1.large |
350 | 26 | 26 | ||
351 | === modified file 'ec2/ec2test/server.go' | |||
352 | --- ec2/ec2test/server.go 2012-09-11 14:10:43 +0000 | |||
353 | +++ ec2/ec2test/server.go 2013-01-21 23:50:27 +0000 | |||
354 | @@ -425,7 +425,7 @@ | |||
355 | 425 | // AvailZone ? | 425 | // AvailZone ? |
356 | 426 | // GroupName tag | 426 | // GroupName tag |
357 | 427 | // Monitoring ignore? | 427 | // Monitoring ignore? |
359 | 428 | // SubnetId ? | 428 | // SubnetId ? |
360 | 429 | // DisableAPITermination bool | 429 | // DisableAPITermination bool |
361 | 430 | // ShutdownBehavior string | 430 | // ShutdownBehavior string |
362 | 431 | // PrivateIPAddress string | 431 | // PrivateIPAddress string |
363 | 432 | 432 | ||
364 | === modified file 'ec2/responses_test.go' | |||
365 | --- ec2/responses_test.go 2012-10-17 22:47:42 +0000 | |||
366 | +++ ec2/responses_test.go 2013-01-21 23:50:27 +0000 | |||
367 | @@ -360,6 +360,22 @@ | |||
368 | 360 | </DescribeImagesResponse> | 360 | </DescribeImagesResponse> |
369 | 361 | ` | 361 | ` |
370 | 362 | 362 | ||
371 | 363 | // http://goo.gl/He9Le | ||
372 | 364 | var CreateImageExample = ` | ||
373 | 365 | <CreateImageResponse xmlns="http://ec2.amazonaws.com/doc/2012-10-01/"> | ||
374 | 366 | <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId> | ||
375 | 367 | <imageId>ami-4fa54026</imageId> | ||
376 | 368 | </CreateImageResponse> | ||
377 | 369 | ` | ||
378 | 370 | |||
379 | 371 | // http://goo.gl/JnVO7 | ||
380 | 372 | var DeregisterImageExample = ` | ||
381 | 373 | <DeregisterImageResponse xmlns="http://ec2.amazonaws.com/doc/2012-10-01/"> | ||
382 | 374 | <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId> | ||
383 | 375 | <return>true</return> | ||
384 | 376 | </DeregisterImageResponse> | ||
385 | 377 | ` | ||
386 | 378 | |||
387 | 363 | // http://goo.gl/ttcda | 379 | // http://goo.gl/ttcda |
388 | 364 | var CreateSnapshotExample = ` | 380 | var CreateSnapshotExample = ` |
389 | 365 | <CreateSnapshotResponse xmlns="http://ec2.amazonaws.com/doc/2012-10-01/"> | 381 | <CreateSnapshotResponse xmlns="http://ec2.amazonaws.com/doc/2012-10-01/"> |
390 | 366 | 382 | ||
391 | === added file 'ec2/volume.go' | |||
392 | --- ec2/volume.go 1970-01-01 00:00:00 +0000 | |||
393 | +++ ec2/volume.go 2013-01-21 23:50:27 +0000 | |||
394 | @@ -0,0 +1,131 @@ | |||
395 | 1 | package ec2 | ||
396 | 2 | |||
397 | 3 | import ( | ||
398 | 4 | "errors" | ||
399 | 5 | "strconv" | ||
400 | 6 | ) | ||
401 | 7 | |||
402 | 8 | // ---------------------------------------------------------------------------- | ||
403 | 9 | // Volume management functions. | ||
404 | 10 | |||
405 | 11 | // The CreateVolume type encapsulates options for the respective request in EC2. | ||
406 | 12 | // | ||
407 | 13 | // See http://goo.gl/iqyMB for more details. | ||
408 | 14 | type CreateVolume struct { | ||
409 | 15 | SnapshotId string | ||
410 | 16 | Size int64 // 1-1024, GiBs | ||
411 | 17 | AvailZone string | ||
412 | 18 | Type string // io1 | standard (default: standard) | ||
413 | 19 | IOPS int64 | ||
414 | 20 | } | ||
415 | 21 | |||
416 | 22 | // Response to a CreateVolume response. | ||
417 | 23 | // | ||
418 | 24 | // See http://goo.gl/iqyMB for more details. | ||
419 | 25 | type CreateVolumeResp struct { | ||
420 | 26 | RequestId string `xml:"requestId"` | ||
421 | 27 | Volume | ||
422 | 28 | } | ||
423 | 29 | |||
424 | 30 | // CreateVolume creates a volume snapshot and stores it in S3. | ||
425 | 31 | // | ||
426 | 32 | // See http://goo.gl/iqyMB for more details. | ||
427 | 33 | func (ec2 *EC2) CreateVolume(options *CreateVolume) (resp *CreateVolumeResp, err error) { | ||
428 | 34 | params := makeParams("CreateVolume") | ||
429 | 35 | if options.SnapshotId != "" { | ||
430 | 36 | params["SnapshotId"] = options.SnapshotId | ||
431 | 37 | } | ||
432 | 38 | if options.Size < 1 || options.Size > 1024 { | ||
433 | 39 | return nil, errors.New("size must be between 1 and 1024 GiBs") | ||
434 | 40 | } | ||
435 | 41 | params["Size"] = strconv.FormatInt(options.Size, 10) | ||
436 | 42 | |||
437 | 43 | if options.AvailZone != "" { | ||
438 | 44 | params["AvailabilityZone"] = options.AvailZone | ||
439 | 45 | } | ||
440 | 46 | if options.Type != "" { | ||
441 | 47 | params["VolumeType"] = options.Type | ||
442 | 48 | } | ||
443 | 49 | if options.IOPS != 0 { | ||
444 | 50 | params["Iops"] = strconv.FormatInt(options.IOPS, 10) | ||
445 | 51 | } | ||
446 | 52 | |||
447 | 53 | resp = &CreateVolumeResp{} | ||
448 | 54 | err = ec2.query(params, resp) | ||
449 | 55 | if err != nil { | ||
450 | 56 | return nil, err | ||
451 | 57 | } | ||
452 | 58 | return | ||
453 | 59 | } | ||
454 | 60 | |||
455 | 61 | // DeleteVolume deletes the volume with the given id. | ||
456 | 62 | // | ||
457 | 63 | // See http://goo.gl/vwU1y for more details. | ||
458 | 64 | func (ec2 *EC2) DeleteVolume(ids []string) (resp *SimpleResp, err error) { | ||
459 | 65 | params := makeParams("DeleteVolume") | ||
460 | 66 | for i, id := range ids { | ||
461 | 67 | params["VolumeId."+strconv.Itoa(i+1)] = id | ||
462 | 68 | } | ||
463 | 69 | |||
464 | 70 | resp = &SimpleResp{} | ||
465 | 71 | err = ec2.query(params, resp) | ||
466 | 72 | if err != nil { | ||
467 | 73 | return nil, err | ||
468 | 74 | } | ||
469 | 75 | return | ||
470 | 76 | } | ||
471 | 77 | |||
472 | 78 | // Response to a DescribeVolumess request. | ||
473 | 79 | // | ||
474 | 80 | // See http://goo.gl/nClDT for more details. | ||
475 | 81 | type VolumesResp struct { | ||
476 | 82 | RequestId string `xml:"requestId"` | ||
477 | 83 | Volumes []Volume `xml:"volumeSet>item"` | ||
478 | 84 | } | ||
479 | 85 | |||
480 | 86 | // Attachment represents details about a VM a volume is attached to | ||
481 | 87 | // | ||
482 | 88 | // Seee http://goo.gl/tQsRB for more details. | ||
483 | 89 | type Attachment struct { | ||
484 | 90 | VolumeId string `xml:"volumeId"` | ||
485 | 91 | InstanceId string `xml:"instanceId"` | ||
486 | 92 | SnapshotId string `xml:"snapshotId"` | ||
487 | 93 | Device string `xml:"device"` // "/dev/sdh" | ||
488 | 94 | Status string `xml:"status"` | ||
489 | 95 | AttachTime string `xml:"attachTime"` | ||
490 | 96 | DeleteOnTermination bool `xml:"deleteOnTermination"` | ||
491 | 97 | } | ||
492 | 98 | |||
493 | 99 | // Volume represents details about a volume snapshot. | ||
494 | 100 | // | ||
495 | 101 | // See http://goo.gl/lB3o2 for more details. | ||
496 | 102 | type Volume struct { | ||
497 | 103 | Id string `xml:"volumeId"` | ||
498 | 104 | Size string `xml:"size"` | ||
499 | 105 | SnapshotId string `xml:"snapshotId"` | ||
500 | 106 | Status string `xml:"status"` | ||
501 | 107 | Type string `xml:"volumeType"` | ||
502 | 108 | CreateTime string `xml:"createTime"` | ||
503 | 109 | Attachments []Attachment `xml:"attachmentSet>item"` | ||
504 | 110 | Tags []Tag `xml:"tagSet>item"` | ||
505 | 111 | IOPS int64 `xml:"iops"` | ||
506 | 112 | } | ||
507 | 113 | |||
508 | 114 | // Snapshots returns details about volume snapshots available to the user. | ||
509 | 115 | // The ids and filter parameters, if provided, limit the snapshots returned. | ||
510 | 116 | // | ||
511 | 117 | // See http://goo.gl/ogJL4 for more details. | ||
512 | 118 | func (ec2 *EC2) Volumes(ids []string, filter *Filter) (resp *VolumesResp, err error) { | ||
513 | 119 | params := makeParams("DescribeVolumes") | ||
514 | 120 | for i, id := range ids { | ||
515 | 121 | params["VolumeId."+strconv.Itoa(i+1)] = id | ||
516 | 122 | } | ||
517 | 123 | filter.addParams(params) | ||
518 | 124 | |||
519 | 125 | resp = &VolumesResp{} | ||
520 | 126 | err = ec2.query(params, resp) | ||
521 | 127 | if err != nil { | ||
522 | 128 | return nil, err | ||
523 | 129 | } | ||
524 | 130 | return | ||
525 | 131 | } |
This change adds the 'Images' command allowing clients to examine their, as well as public, images available on AWS.