Merge lp:~mirtchovski/goamz/ec2 into lp:~gophers/goamz/trunk

Proposed by andrey mirtchovski
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
Reviewer Review Type Date Requested Status
The Go Language Gophers Pending
Review via email: mp+129325@code.launchpad.net

Description of the change

To post a comment you must log in.
Revision history for this message
andrey mirtchovski (mirtchovski) wrote :

This change adds the 'Images' command allowing clients to examine their, as well as public, images available on AWS.

Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :

This is looking great. We just need some testing.

Revision history for this message
andrey mirtchovski (mirtchovski) wrote :

> This is looking great. We just need some testing.

done. PTAL :)

Revision history for this message
andrey mirtchovski (mirtchovski) wrote :
Download full text (3.4 KiB)

Reviewers: mp+129325_code.launchpad.net,

Message:
Please take a look.

Description:

https://code.launchpad.net/~mirtchovski/goamz/ec2/+merge/129325

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/6745044/

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.Add("architecture", "i386")
+ filter.Add("image-type", "machine")
+ filter.Add("description", "http://bitnami.org")
+ filter.Add("is-public", "true")
+
+ id := []string{"ami-fd20ff94"}
+
+ 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-webpack-1.0-0-linux-ubuntu-10.04.3-i386-mp-0b295d82-395d-4b81-89df-5ac5f0b66975-ami-3820fc51.1")
+ c.Check(i0.Description, Equals, "http://bitnami.org")
+ c.Check(i0.Type, Equals, "machine")
+ c.Check(i0.State, Equals, "available")
+ 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")
+ c.Check(i0.Public, Equals, true)
+ c.Check(i0.Architecture, Equals, "i386")
+ c.Check(i0.Platform, Equals, "")
+ c.Check(i0.ProductCodes, HasLen, 0)
+ c.Check(i0.KernelId, Equals, "i386")
+ c.Check(i0.RamdiskId, Equals, "")
+ c.Check(i0.StateReason, Equals, "")
+ c.Check(i0.OwnerId, Equals, "679593333241")
+ c.Check(i0.OwnerAlias, Equals, "aws-marketplace")
+ c.Check(i0.RootDeviceType, Equals, "ebs")
+ c.Check(i0.RootDeviceName, Equals, "/dev/sda1")
+ c.Check(i0.VirtualizationType, Equals, "paravirtual")
+ c.Check(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-5d581d27")
+ c.Assert(i0.BlockDevices[0].VolumeSize, Equals, int64(10))
+ c.Assert(i0.BlockDevices[0].DeleteOnTermination, Equals, true)
+ c.Assert(i0.BlockDevices[0].VolumeType, Equals, "")
+ c.Assert(i0.BlockDevices[0].IOPS, Equals, int64(0))
+}
+
+// Cost: unknown
+func (s *ClientTests) TestSnapshots(c *C) {
+ filter := ec2.NewFilter()
+ filter.Add("volume-id", "vol-37ac485e")
+ filter.Add("status", "completed")
+ filter.Add("start-time", "2008-11-19T10:03:00.000Z")
+
+ id := []string{"snap-9df717f4"}
+
+ resp, err := s.ec2.Snapshots(id, filter)
+ c.Assert(err, IsNil)
+ c.Check(resp.Snapshots, HasLen, 1)
+
+ s0 := resp.Snapshots[0]
+ c.Check(s0.Id, Equals, "snap-9df717f4")
+ c.Check(s0.VolumeId, Equals, "vol-37ac485e")
+ c.Check(s0.Status, Equals, "completed")
+ c.Check(s0.StartTime, Equals, "20...

Read more...

Revision history for this message
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://bitnami.org" image-type="machine"
   ec2.Image{
    ImageId:"ami-fd20ff94",

Location:"aws-marketplace/bitnami-webpack-1.0-0-linux-ubuntu-10.04.3-i386-mp-0b295d82-395d-4b81-89df-5ac5f0b66975-ami-3820fc51.1",

    State:"available",
    Owner:"679593333241",
    Public:true,
    Architecture:"i386",
    ImageType:"machine", ProductCodes:[]string(nil),
KernelId:"aki-805ea7e9", RamdiskId:"", Platform:"",
    StateReason:"",
    OwnerAlias:"aws-marketplace",

Name:"bitnami-webpack-1.0-0-linux-ubuntu-10.04.3-i386-mp-0b295d82-395d-4b81-89df-5ac5f0b66975-ami-3820fc51.1",

    Description:"http://bitnami.org",
    RootDeviceType:"ebs",
    RootDeviceName:"/dev/sda1",
    VirtualizationType:"paravirtual",
    Hypervisor:"xen",
    BlockDevices:[]ec2.BlockDeviceMapping{
     ec2.BlockDeviceMapping{
      DeviceName:"/dev/sda1",
      VirtualName:"",
      Ebs:ec2.EbsBlockDevice{
       SnapshotId:"snap-5d581d27",
       VolumeSize:10,
       DeleteOnTermination:true,
       VolumeType:"",
       Iops:0
      }
     }
    }
   }

   // $ ./aws snapshots snapshot-id=snap-9df717f4 status=completed
start-time=2008-11-19T10:03:00.000Z
   ec2.Snapshot{
    SnapshotId:"snap-9df717f4",
    VolumeId:"vol-37ac485e",
    Status:"completed",
    StartTime:"2008-11-19T10:03:00.000Z",
    Progress:"100%",
    OwnerId:"947081328633",
    VolumeSize:"2",
    Description:"1980 US Census (Linux)",
    OwnerAlias:"amazon",
    Tags:[]ec2.Tag(nil)
   }

https://codereview.appspot.com/6745044/

lp:~mirtchovski/goamz/ec2 updated
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

Revision history for this message
andrey mirtchovski (mirtchovski) wrote :
Revision history for this message
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.

https://codereview.appspot.com/6745044/

Revision history for this message
andrey mirtchovski (mirtchovski) wrote :
lp:~mirtchovski/goamz/ec2 updated
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

[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 2012-10-28 16:05:46 +0000
3+++ ec2/ec2.go 2013-01-21 23:50:27 +0000
4@@ -86,7 +86,7 @@
5 // ----------------------------------------------------------------------------
6 // Request dispatching logic.
7
8-// Error encapsulates an error returned by EC2.
9+// Error encapsulates an error returned by EC2.
10 //
11 // See http://goo.gl/VZGuC for more details.
12 type Error struct {
13@@ -425,15 +425,15 @@
14 //
15 // See http://goo.gl/wnDBf for more details.
16 type BlockDeviceMapping struct {
17- DeviceName string `xml:"deviceName"`
18- VirtualName string `xml:"virtualName"`
19- SnapshotId string `xml:"ebs>snapshotId"`
20- VolumeType string `xml:"ebs>volumeType"`
21- VolumeSize int64 `xml:"ebs>volumeSize"`
22- DeleteOnTermination bool `xml:"ebs>deleteOnTermination"`
23+ DeviceName string `xml:"deviceName"`
24+ VirtualName string `xml:"virtualName"`
25+ SnapshotId string `xml:"ebs>snapshotId"`
26+ VolumeType string `xml:"ebs>volumeType"`
27+ VolumeSize int64 `xml:"ebs>volumeSize"`
28+ DeleteOnTermination bool `xml:"ebs>deleteOnTermination"`
29
30 // The number of I/O operations per second (IOPS) that the volume supports.
31- IOPS int64 `xml:"ebs>iops"`
32+ IOPS int64 `xml:"ebs>iops"`
33 }
34
35 // Image represents details about an image.
36@@ -467,7 +467,7 @@
37 // For example, to get all the private images associated with this account set
38 // the boolean filter "is-private" to true.
39 //
40-// Note: calling this function with nil ids and filter parameters will result in
41+// Note: calling this function with nil ids and filter parameters will result in
42 // a very large number of images being returned.
43 //
44 // See http://goo.gl/SRBhW for more details.
45@@ -486,6 +486,67 @@
46 return
47 }
48
49+// The CreateImage type encapsulates options for the respective request in EC2.
50+//
51+// See http://goo.gl/He9Le for more details.
52+type CreateImage struct {
53+ InstanceId string
54+ Name string
55+ Description string
56+ NoReboot bool
57+ BlockDevices []BlockDeviceMapping
58+}
59+
60+// Response to a CreateImage request.
61+//
62+// See http://goo.gl/He9Le for more details.
63+type CreateImageResp struct {
64+ RequestId string `xml:"requestId"`
65+ Id string `xml:"imageId"`
66+}
67+
68+// CreateImage creates an EBS-backed image from a running instance.
69+//
70+// See http://goo.gl/He9Le for more details.
71+func (ec2 *EC2) CreateImage(options *CreateImage) (resp *CreateImageResp, err error) {
72+ params := makeParams("CreateImage")
73+ params["InstanceId"] = options.InstanceId
74+ params["Name"] = options.Name
75+ params["Description"] = options.Description
76+ params["NoReboot"] = strconv.FormatBool(options.NoReboot)
77+ //params["BlockDevices"] = options.BlockDevices
78+
79+ resp = &CreateImageResp{}
80+ err = ec2.query(params, resp)
81+ if err != nil {
82+ return nil, err
83+ }
84+ return
85+}
86+
87+// The DeregisterImage type encapsulates options for the respective request in EC2.
88+//
89+// See http://goo.gl/JnVO7 for more details.
90+type DeregisterImage struct {
91+ ImageId string
92+}
93+
94+// DeregisterImage Deregisters the specified AMI. Once deregistered, the AMI
95+// cannot be used to launch new instances.
96+//
97+// See http://goo.gl/JnVO7 for more details.
98+func (ec2 *EC2) DeregisterImage(id string) (resp *SimpleResp, err error) {
99+ params := makeParams("DeregisterImage")
100+ params["ImageId"] = id
101+
102+ resp = &SimpleResp{}
103+ err = ec2.query(params, resp)
104+ if err != nil {
105+ return nil, err
106+ }
107+ return
108+}
109+
110 // Response to a CreateSnapshot request.
111 //
112 // See http://goo.gl/ttcda for more details.
113@@ -512,11 +573,11 @@
114
115 // DeleteSnapshots deletes the volume snapshots with the given ids.
116 //
117-// Note: If you make periodic snapshots of a volume, the snapshots are
118-// incremental so that only the blocks on the device that have changed
119-// since your last snapshot are incrementally saved in the new snapshot.
120-// Even though snapshots are saved incrementally, the snapshot deletion
121-// process is designed so that you need to retain only the most recent
122+// Note: If you make periodic snapshots of a volume, the snapshots are
123+// incremental so that only the blocks on the device that have changed
124+// since your last snapshot are incrementally saved in the new snapshot.
125+// Even though snapshots are saved incrementally, the snapshot deletion
126+// process is designed so that you need to retain only the most recent
127 // snapshot in order to restore the volume.
128 //
129 // See http://goo.gl/vwU1y for more details.
130@@ -558,7 +619,7 @@
131 Tags []Tag `xml:"tagSet>item"`
132 }
133
134-// Snapshots returns details about volume snapshots available to the user.
135+// Snapshots returns details about volume snapshots available to the user.
136 // The ids and filter parameters, if provided, limit the snapshots returned.
137 //
138 // See http://goo.gl/ogJL4 for more details.
139@@ -620,7 +681,7 @@
140 Groups []SecurityGroupInfo `xml:"securityGroupInfo>item"`
141 }
142
143-// SecurityGroup encapsulates details for a security group in EC2.
144+// SecurityGroup encapsulates details for a security group in EC2.
145 //
146 // See http://goo.gl/CIdyP for more details.
147 type SecurityGroupInfo struct {
148@@ -785,7 +846,7 @@
149 }
150
151 // CreateTags adds or overwrites one or more tags for the specified instance ids.
152-//
153+//
154 // See http://goo.gl/Vmkqc for more details
155 func (ec2 *EC2) CreateTags(instIds []string, tags []Tag) (resp *SimpleResp, err error) {
156 params := makeParams("CreateTags")
157@@ -863,5 +924,45 @@
158 if err != nil {
159 return nil, err
160 }
161- return resp, nil
162+ return
163+}
164+
165+// Describes an availability zone
166+//
167+// See http://goo.gl/Hncxm for more details.
168+type AvailZone struct {
169+ Name string `xml:"zoneName"`
170+ State string `xml:"zoneState"`
171+ Region string `xml:"regionName"`
172+ Message []string `xml:"messageSet>item"`
173+}
174+
175+// Response to a AvailZone request.
176+//
177+// See http://goo.gl/bt2rz for more details.
178+type AvailZoneResp struct {
179+ RequestId string `xml:"requestId"`
180+ Zones []AvailZone `xml:"availabilityZoneInfo>item"`
181+}
182+
183+// AvailZones describes one or more of the Availability Zones that are currently
184+// available to the account.
185+//
186+// The results include zones only for the region you're currently using.
187+//
188+// Filter can contain:
189+//
190+// message, region-name, state, zone-name
191+//
192+// See http://goo.gl/bt2rz for more details.
193+func (ec2 *EC2) AvailZones(names []string, filter *Filter) (resp *AvailZoneResp, err error) {
194+ params := makeParams("DescribeAvailabilityZones")
195+ addParamsList(params, "ZoneName", names)
196+
197+ resp = &AvailZoneResp{}
198+ err = ec2.query(params, resp)
199+ if err != nil {
200+ return nil, err
201+ }
202+ return
203 }
204
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 c.Assert(i0.BlockDevices[0].DeleteOnTermination, Equals, true)
210 }
211
212+func (s *S) TestCreateImageExample(c *C) {
213+ testServer.PrepareResponse(200, nil, CreateImageExample)
214+
215+ options := ec2.CreateImage{
216+ InstanceId: "i-10a64379",
217+ Name: "standard-web-server-v1.0",
218+ Description: "Standard Web Server v1.0",
219+ //NoReboot: false,
220+ //BlockDevices: nil,
221+ }
222+
223+ resp, err := s.ec2.CreateImage(&options)
224+
225+ req := testServer.WaitRequest()
226+ c.Assert(req.Form["Action"], DeepEquals, []string{"CreateImage"})
227+ c.Assert(req.Form["InstanceId"], DeepEquals, []string{"i-10a64379"})
228+ c.Assert(req.Form["Name"], DeepEquals, []string{"standard-web-server-v1.0"})
229+ c.Assert(req.Form["Description"], DeepEquals, []string{"Standard Web Server v1.0"})
230+ c.Assert(req.Form["NoReboot"], DeepEquals, []string{"false"})
231+
232+ c.Assert(err, IsNil)
233+ c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE")
234+ c.Assert(resp.Id, Equals, "ami-4fa54026")
235+}
236+
237+func (s *S) TestDeregisterImageExample(c *C) {
238+ testServer.PrepareResponse(200, nil, DeregisterImageExample)
239+
240+ resp, err := s.ec2.DeregisterImage("ami-4fa54026")
241+
242+ req := testServer.WaitRequest()
243+ c.Assert(req.Form["Action"], DeepEquals, []string{"DeregisterImage"})
244+ c.Assert(req.Form["ImageId"], DeepEquals, []string{"ami-4fa54026"})
245+
246+ c.Assert(err, IsNil)
247+ c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE")
248+}
249+
250 func (s *S) TestCreateSnapshotExample(c *C) {
251 testServer.PrepareResponse(200, nil, CreateSnapshotExample)
252
253
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 }
259 }
260 }
261+
262+// Cost: unknown
263+func (s *ClientTests) TestImages(c *C) {
264+ filter := ec2.NewFilter()
265+ filter.Add("architecture", "i386")
266+ filter.Add("image-type", "machine")
267+ filter.Add("description", "http://bitnami.org")
268+ filter.Add("is-public", "true")
269+
270+ id := []string{"ami-fd20ff94"}
271+
272+ resp1, err := s.ec2.Images(id, filter)
273+ c.Assert(err, IsNil)
274+
275+ i0 := resp1.Images[0]
276+ c.Check(i0.Id, Equals, "ami-fd20ff94")
277+ 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+ c.Check(i0.Description, Equals, "http://bitnami.org")
279+ c.Check(i0.Type, Equals, "machine")
280+ c.Check(i0.State, Equals, "available")
281+ 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+ c.Check(i0.Public, Equals, true)
283+ c.Check(i0.Architecture, Equals, "i386")
284+ c.Check(i0.Platform, Equals, "")
285+ c.Check(i0.ProductCodes, HasLen, 0)
286+ c.Check(i0.KernelId, Equals, "i386")
287+ c.Check(i0.RamdiskId, Equals, "")
288+ c.Check(i0.StateReason, Equals, "")
289+ c.Check(i0.OwnerId, Equals, "679593333241")
290+ c.Check(i0.OwnerAlias, Equals, "aws-marketplace")
291+ c.Check(i0.RootDeviceType, Equals, "ebs")
292+ c.Check(i0.RootDeviceName, Equals, "/dev/sda1")
293+ c.Check(i0.VirtualizationType, Equals, "paravirtual")
294+ c.Check(i0.Hypervisor, Equals, "xen")
295+
296+ c.Assert(i0.BlockDevices, HasLen, 1)
297+ c.Assert(i0.BlockDevices[0].DeviceName, Equals, "/dev/sda1")
298+ c.Assert(i0.BlockDevices[0].SnapshotId, Equals, "snap-5d581d27")
299+ c.Assert(i0.BlockDevices[0].VolumeSize, Equals, int64(10))
300+ c.Assert(i0.BlockDevices[0].DeleteOnTermination, Equals, true)
301+ c.Assert(i0.BlockDevices[0].VolumeType, Equals, "")
302+ c.Assert(i0.BlockDevices[0].IOPS, Equals, int64(0))
303+}
304+
305+// Cost: unknown
306+func (s *ClientTests) TestSnapshots(c *C) {
307+ filter := ec2.NewFilter()
308+ filter.Add("volume-id", "vol-37ac485e")
309+ filter.Add("status", "completed")
310+ filter.Add("start-time", "2008-11-19T10:03:00.000Z")
311+
312+ id := []string{"snap-9df717f4"}
313+
314+ resp, err := s.ec2.Snapshots(id, filter)
315+ c.Assert(err, IsNil)
316+ c.Check(resp.Snapshots, HasLen, 1)
317+
318+ s0 := resp.Snapshots[0]
319+ c.Check(s0.Id, Equals, "snap-9df717f4")
320+ c.Check(s0.VolumeId, Equals, "vol-37ac485e")
321+ c.Check(s0.Status, Equals, "completed")
322+ c.Check(s0.StartTime, Equals, "2008-11-19T10:03:00.000Z")
323+ c.Check(s0.Progress, Equals, "100%")
324+ c.Check(s0.OwnerId, Equals, "947081328633")
325+ c.Check(s0.VolumeSize, Equals, "2")
326+ c.Check(s0.Description, Equals, "1980 US Census (Linux)")
327+ c.Check(s0.OwnerAlias, Equals, "amazon")
328+ c.Check(s0.Tags, HasLen, 0)
329+}
330
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 type filter map[string][]string
336
337 // newFilter creates a new filter from the Filter fields in the url form.
338-//
339+//
340 // The filtering is specified through a map of name=>values, where the
341 // name is a well-defined key identifying the data to be matched,
342 // and the list of values holds the possible values the filtered
343 // item can take for the key to be included in the
344 // result set. For example:
345-//
346+//
347 // Filter.1.Name=instance-type
348 // Filter.1.Value.1=m1.small
349 // Filter.1.Value.2=m1.large
350
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 // AvailZone ?
356 // GroupName tag
357 // Monitoring ignore?
358- // SubnetId ?
359+ // SubnetId ?
360 // DisableAPITermination bool
361 // ShutdownBehavior string
362 // PrivateIPAddress string
363
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 </DescribeImagesResponse>
369 `
370
371+// http://goo.gl/He9Le
372+var CreateImageExample = `
373+<CreateImageResponse xmlns="http://ec2.amazonaws.com/doc/2012-10-01/">
374+ <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
375+ <imageId>ami-4fa54026</imageId>
376+</CreateImageResponse>
377+`
378+
379+// http://goo.gl/JnVO7
380+var DeregisterImageExample = `
381+<DeregisterImageResponse xmlns="http://ec2.amazonaws.com/doc/2012-10-01/">
382+ <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
383+ <return>true</return>
384+</DeregisterImageResponse>
385+`
386+
387 // http://goo.gl/ttcda
388 var CreateSnapshotExample = `
389 <CreateSnapshotResponse xmlns="http://ec2.amazonaws.com/doc/2012-10-01/">
390
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+package ec2
396+
397+import (
398+ "errors"
399+ "strconv"
400+)
401+
402+// ----------------------------------------------------------------------------
403+// Volume management functions.
404+
405+// The CreateVolume type encapsulates options for the respective request in EC2.
406+//
407+// See http://goo.gl/iqyMB for more details.
408+type CreateVolume struct {
409+ SnapshotId string
410+ Size int64 // 1-1024, GiBs
411+ AvailZone string
412+ Type string // io1 | standard (default: standard)
413+ IOPS int64
414+}
415+
416+// Response to a CreateVolume response.
417+//
418+// See http://goo.gl/iqyMB for more details.
419+type CreateVolumeResp struct {
420+ RequestId string `xml:"requestId"`
421+ Volume
422+}
423+
424+// CreateVolume creates a volume snapshot and stores it in S3.
425+//
426+// See http://goo.gl/iqyMB for more details.
427+func (ec2 *EC2) CreateVolume(options *CreateVolume) (resp *CreateVolumeResp, err error) {
428+ params := makeParams("CreateVolume")
429+ if options.SnapshotId != "" {
430+ params["SnapshotId"] = options.SnapshotId
431+ }
432+ if options.Size < 1 || options.Size > 1024 {
433+ return nil, errors.New("size must be between 1 and 1024 GiBs")
434+ }
435+ params["Size"] = strconv.FormatInt(options.Size, 10)
436+
437+ if options.AvailZone != "" {
438+ params["AvailabilityZone"] = options.AvailZone
439+ }
440+ if options.Type != "" {
441+ params["VolumeType"] = options.Type
442+ }
443+ if options.IOPS != 0 {
444+ params["Iops"] = strconv.FormatInt(options.IOPS, 10)
445+ }
446+
447+ resp = &CreateVolumeResp{}
448+ err = ec2.query(params, resp)
449+ if err != nil {
450+ return nil, err
451+ }
452+ return
453+}
454+
455+// DeleteVolume deletes the volume with the given id.
456+//
457+// See http://goo.gl/vwU1y for more details.
458+func (ec2 *EC2) DeleteVolume(ids []string) (resp *SimpleResp, err error) {
459+ params := makeParams("DeleteVolume")
460+ for i, id := range ids {
461+ params["VolumeId."+strconv.Itoa(i+1)] = id
462+ }
463+
464+ resp = &SimpleResp{}
465+ err = ec2.query(params, resp)
466+ if err != nil {
467+ return nil, err
468+ }
469+ return
470+}
471+
472+// Response to a DescribeVolumess request.
473+//
474+// See http://goo.gl/nClDT for more details.
475+type VolumesResp struct {
476+ RequestId string `xml:"requestId"`
477+ Volumes []Volume `xml:"volumeSet>item"`
478+}
479+
480+// Attachment represents details about a VM a volume is attached to
481+//
482+// Seee http://goo.gl/tQsRB for more details.
483+type Attachment struct {
484+ VolumeId string `xml:"volumeId"`
485+ InstanceId string `xml:"instanceId"`
486+ SnapshotId string `xml:"snapshotId"`
487+ Device string `xml:"device"` // "/dev/sdh"
488+ Status string `xml:"status"`
489+ AttachTime string `xml:"attachTime"`
490+ DeleteOnTermination bool `xml:"deleteOnTermination"`
491+}
492+
493+// Volume represents details about a volume snapshot.
494+//
495+// See http://goo.gl/lB3o2 for more details.
496+type Volume struct {
497+ Id string `xml:"volumeId"`
498+ Size string `xml:"size"`
499+ SnapshotId string `xml:"snapshotId"`
500+ Status string `xml:"status"`
501+ Type string `xml:"volumeType"`
502+ CreateTime string `xml:"createTime"`
503+ Attachments []Attachment `xml:"attachmentSet>item"`
504+ Tags []Tag `xml:"tagSet>item"`
505+ IOPS int64 `xml:"iops"`
506+}
507+
508+// Snapshots returns details about volume snapshots available to the user.
509+// The ids and filter parameters, if provided, limit the snapshots returned.
510+//
511+// See http://goo.gl/ogJL4 for more details.
512+func (ec2 *EC2) Volumes(ids []string, filter *Filter) (resp *VolumesResp, err error) {
513+ params := makeParams("DescribeVolumes")
514+ for i, id := range ids {
515+ params["VolumeId."+strconv.Itoa(i+1)] = id
516+ }
517+ filter.addParams(params)
518+
519+ resp = &VolumesResp{}
520+ err = ec2.query(params, resp)
521+ if err != nil {
522+ return nil, err
523+ }
524+ return
525+}

Subscribers

People subscribed via source and target branches