rudy 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. data/CHANGES.txt +54 -30
  2. data/README.rdoc +100 -12
  3. data/Rakefile +103 -8
  4. data/Rudyfile +119 -0
  5. data/bin/ird +175 -0
  6. data/bin/rudy +259 -156
  7. data/bin/rudy-ec2 +228 -95
  8. data/bin/rudy-s3 +76 -0
  9. data/bin/rudy-sdb +67 -0
  10. data/lib/annoy.rb +270 -0
  11. data/lib/console.rb +30 -9
  12. data/lib/escape.rb +305 -0
  13. data/lib/rudy.rb +151 -182
  14. data/lib/rudy/aws.rb +56 -49
  15. data/lib/rudy/aws/ec2.rb +47 -292
  16. data/lib/rudy/aws/ec2/address.rb +157 -0
  17. data/lib/rudy/aws/ec2/group.rb +301 -0
  18. data/lib/rudy/aws/ec2/image.rb +168 -0
  19. data/lib/rudy/aws/ec2/instance.rb +434 -0
  20. data/lib/rudy/aws/ec2/keypair.rb +104 -0
  21. data/lib/rudy/aws/ec2/snapshot.rb +98 -0
  22. data/lib/rudy/aws/ec2/volume.rb +230 -0
  23. data/lib/rudy/aws/ec2/zone.rb +77 -0
  24. data/lib/rudy/aws/s3.rb +54 -0
  25. data/lib/rudy/aws/sdb.rb +298 -0
  26. data/lib/rudy/aws/sdb/error.rb +46 -0
  27. data/lib/rudy/{metadata/backup.rb → backup.rb} +26 -51
  28. data/lib/rudy/cli.rb +157 -0
  29. data/lib/rudy/cli/aws/ec2/addresses.rb +105 -0
  30. data/lib/rudy/cli/aws/ec2/candy.rb +208 -0
  31. data/lib/rudy/cli/aws/ec2/groups.rb +121 -0
  32. data/lib/rudy/cli/aws/ec2/images.rb +196 -0
  33. data/lib/rudy/cli/aws/ec2/instances.rb +194 -0
  34. data/lib/rudy/cli/aws/ec2/keypairs.rb +53 -0
  35. data/lib/rudy/cli/aws/ec2/snapshots.rb +49 -0
  36. data/lib/rudy/cli/aws/ec2/volumes.rb +104 -0
  37. data/lib/rudy/cli/aws/ec2/zones.rb +22 -0
  38. data/lib/rudy/cli/aws/s3/buckets.rb +50 -0
  39. data/lib/rudy/cli/aws/s3/store.rb +22 -0
  40. data/lib/rudy/cli/aws/sdb/domains.rb +41 -0
  41. data/lib/rudy/cli/candy.rb +8 -0
  42. data/lib/rudy/{command → cli}/config.rb +34 -24
  43. data/lib/rudy/cli/disks.rb +35 -0
  44. data/lib/rudy/cli/machines.rb +94 -0
  45. data/lib/rudy/cli/routines.rb +57 -0
  46. data/lib/rudy/config.rb +77 -72
  47. data/lib/rudy/config/objects.rb +29 -0
  48. data/lib/rudy/disks.rb +248 -0
  49. data/lib/rudy/global.rb +121 -0
  50. data/lib/rudy/huxtable.rb +340 -0
  51. data/lib/rudy/machines.rb +245 -0
  52. data/lib/rudy/metadata.rb +123 -13
  53. data/lib/rudy/routines.rb +47 -0
  54. data/lib/rudy/routines/helpers/diskhelper.rb +101 -0
  55. data/lib/rudy/routines/helpers/scripthelper.rb +91 -0
  56. data/lib/rudy/routines/release.rb +34 -0
  57. data/lib/rudy/routines/shutdown.rb +57 -0
  58. data/lib/rudy/routines/startup.rb +58 -0
  59. data/lib/rudy/scm/svn.rb +1 -1
  60. data/lib/rudy/utils.rb +322 -4
  61. data/lib/storable.rb +26 -17
  62. data/lib/sysinfo.rb +274 -0
  63. data/lib/tryouts.rb +6 -13
  64. data/rudy.gemspec +128 -42
  65. data/support/randomize-root-password +45 -0
  66. data/support/rudy-ec2-startup +9 -9
  67. data/support/update-ec2-ami-tools +20 -0
  68. data/test/05_config/00_setup_test.rb +20 -0
  69. data/test/05_config/30_machines_test.rb +69 -0
  70. data/test/20_sdb/00_setup_test.rb +16 -0
  71. data/test/20_sdb/10_domains_test.rb +115 -0
  72. data/test/25_ec2/00_setup_test.rb +29 -0
  73. data/test/25_ec2/10_keypairs_test.rb +41 -0
  74. data/test/25_ec2/20_groups_test.rb +131 -0
  75. data/test/25_ec2/30_addresses_test.rb +38 -0
  76. data/test/25_ec2/40_volumes_test.rb +49 -0
  77. data/test/25_ec2/50_snapshots_test.rb +74 -0
  78. data/test/26_ec2_instances/00_setup_test.rb +28 -0
  79. data/test/26_ec2_instances/10_instances_test.rb +83 -0
  80. data/test/26_ec2_instances/50_images_test.rb +13 -0
  81. data/test/30_sdb_metadata/00_setup_test.rb +21 -0
  82. data/test/30_sdb_metadata/10_disks_test.rb +109 -0
  83. data/test/30_sdb_metadata/20_backups_test.rb +102 -0
  84. data/test/coverage.txt +51 -0
  85. data/test/helper.rb +36 -0
  86. data/vendor/highline-1.5.1/CHANGELOG +222 -0
  87. data/vendor/highline-1.5.1/INSTALL +35 -0
  88. data/vendor/highline-1.5.1/LICENSE +7 -0
  89. data/vendor/highline-1.5.1/README +63 -0
  90. data/vendor/highline-1.5.1/Rakefile +82 -0
  91. data/vendor/highline-1.5.1/TODO +6 -0
  92. data/vendor/highline-1.5.1/examples/ansi_colors.rb +38 -0
  93. data/vendor/highline-1.5.1/examples/asking_for_arrays.rb +18 -0
  94. data/vendor/highline-1.5.1/examples/basic_usage.rb +75 -0
  95. data/vendor/highline-1.5.1/examples/color_scheme.rb +32 -0
  96. data/vendor/highline-1.5.1/examples/limit.rb +12 -0
  97. data/vendor/highline-1.5.1/examples/menus.rb +65 -0
  98. data/vendor/highline-1.5.1/examples/overwrite.rb +19 -0
  99. data/vendor/highline-1.5.1/examples/page_and_wrap.rb +322 -0
  100. data/vendor/highline-1.5.1/examples/password.rb +7 -0
  101. data/vendor/highline-1.5.1/examples/trapping_eof.rb +22 -0
  102. data/vendor/highline-1.5.1/examples/using_readline.rb +17 -0
  103. data/vendor/highline-1.5.1/lib/highline.rb +758 -0
  104. data/vendor/highline-1.5.1/lib/highline/color_scheme.rb +120 -0
  105. data/vendor/highline-1.5.1/lib/highline/compatibility.rb +17 -0
  106. data/vendor/highline-1.5.1/lib/highline/import.rb +43 -0
  107. data/vendor/highline-1.5.1/lib/highline/menu.rb +395 -0
  108. data/vendor/highline-1.5.1/lib/highline/question.rb +463 -0
  109. data/vendor/highline-1.5.1/lib/highline/system_extensions.rb +193 -0
  110. data/vendor/highline-1.5.1/setup.rb +1360 -0
  111. data/vendor/highline-1.5.1/test/tc_color_scheme.rb +56 -0
  112. data/vendor/highline-1.5.1/test/tc_highline.rb +823 -0
  113. data/vendor/highline-1.5.1/test/tc_import.rb +54 -0
  114. data/vendor/highline-1.5.1/test/tc_menu.rb +429 -0
  115. data/vendor/highline-1.5.1/test/ts_all.rb +15 -0
  116. metadata +141 -38
  117. data/lib/aws_sdb.rb +0 -3
  118. data/lib/aws_sdb/error.rb +0 -42
  119. data/lib/aws_sdb/service.rb +0 -215
  120. data/lib/rudy/aws/simpledb.rb +0 -53
  121. data/lib/rudy/command/addresses.rb +0 -46
  122. data/lib/rudy/command/backups.rb +0 -175
  123. data/lib/rudy/command/base.rb +0 -841
  124. data/lib/rudy/command/deploy.rb +0 -12
  125. data/lib/rudy/command/disks.rb +0 -213
  126. data/lib/rudy/command/environment.rb +0 -73
  127. data/lib/rudy/command/groups.rb +0 -61
  128. data/lib/rudy/command/images.rb +0 -91
  129. data/lib/rudy/command/instances.rb +0 -85
  130. data/lib/rudy/command/machines.rb +0 -161
  131. data/lib/rudy/command/metadata.rb +0 -41
  132. data/lib/rudy/command/release.rb +0 -174
  133. data/lib/rudy/command/volumes.rb +0 -66
  134. data/lib/rudy/metadata/disk.rb +0 -138
  135. data/tryouts/console_tryout.rb +0 -91
@@ -0,0 +1,301 @@
1
+
2
+ module Rudy::AWS
3
+
4
+ class EC2::Group < Storable
5
+ class Rule < Storable
6
+ field :ports => Range # Port range
7
+ field :protocol => String
8
+
9
+ def to_s(with_title=false)
10
+ if self.ports.first == self.ports.last
11
+ "%s(%s)" % [self.protocol, self.ports.last]
12
+ else
13
+ "%s(%s..%s)" % [self.protocol, self.ports.first, self.ports.last]
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ class EC2::Group < Storable
20
+ field :name => String
21
+ field :description => String
22
+ field :owner_id => String
23
+ field :addresses => Hash # key: address/mask, value Array of Rule object
24
+ field :groups => Hash # key: group, value Array of Rule object
25
+
26
+
27
+ def liner_note
28
+ info = "(authorized accounts: #{@groups.keys.join(', ')})"
29
+ info = '' if @groups.empty?
30
+ "%s %s" % [@name.bright, info]
31
+ end
32
+
33
+
34
+ # Print info about a security group
35
+ #
36
+ # * +group+ is a Rudy::AWS::EC2::Group object
37
+ def to_s(with_title=false)
38
+ lines = [liner_note]
39
+ (self.addresses || {}).each_pair do |address,rules|
40
+ lines << "%18s -> %s" % [address.to_s, rules.collect { |p| p.to_s}.join(', ')]
41
+ end
42
+ lines.join($/)
43
+ end
44
+
45
+ def inspect
46
+ lines = [@name.bright]
47
+ field_names.each do |key|
48
+ next unless self.respond_to?(key)
49
+ next if [:addresses, :groups].member?(key)
50
+ val = self.send(key)
51
+ lines << sprintf(" %12s: %s", key, (val.is_a?(Array) ? val.join(', ') : val))
52
+ end
53
+ @addresses.each_pair do |a,r|
54
+ rules = r.collect { |r| r.to_s }.join(', ') if r
55
+ lines << sprintf(" %12s: %s (%s)", 'address', a.to_s, rules)
56
+ end
57
+ @groups.each_pair do |g,r|
58
+ rules = r.collect { |r| r.to_s }.join(', ')
59
+ lines << sprintf(" %12s: %s (%s)", 'group', g.to_s, rules)
60
+ end
61
+ lines.join($/)
62
+ end
63
+
64
+
65
+ # * +ipaddress+ is a String, ipaddress/mask/protocol
66
+ # * +rule+ is a Rule object
67
+ def add_address(ipaddress, rule)
68
+ return false unless rule.is_a?(Rule)
69
+ @addresses ||= {}
70
+ (@addresses[ipaddress] ||= []) << rule
71
+ rule
72
+ end
73
+
74
+ # * +group+ is a String, accountnum:group
75
+ # * +rule+ is a Rule object
76
+ def add_group(group, rule)
77
+ return false unless rule.is_a?(Rule)
78
+ @groups ||= {}
79
+ (@groups[group] ||= []) << rule
80
+ end
81
+
82
+ end
83
+
84
+
85
+
86
+ module EC2
87
+ class Groups
88
+ include Rudy::AWS::ObjectBase
89
+ include Rudy::AWS::EC2::Base
90
+
91
+ # Create a new EC2 security group
92
+ # Returns list of created groups
93
+ def create(name, desc=nil, addresses=[], ports=[], protocols=[], &each_group)
94
+ desc ||= "Security Group #{name}"
95
+ ret = @ec2.create_security_group(:group_name => name, :group_description => desc)
96
+ return false unless (ret && ret['return'] == 'true')
97
+ authorize(name, addresses, ports, protocols)
98
+ get(name, &each_group)
99
+ end
100
+
101
+ # Delete an EC2 security group
102
+ # Returns true/false whether successful
103
+ def destroy(name, &each_group)
104
+ list(name, &each_group) if each_group
105
+ ret = @ec2.delete_security_group(:group_name => name)
106
+ (ret && ret['return'] == 'true')
107
+ end
108
+
109
+ # Authorize a port/protocol for a specific IP address
110
+ def authorize(name, addresses=[], ports=[], protocols=[], &each_group)
111
+ modify_rules(:authorize, name, addresses, ports, protocols, &each_group)
112
+ end
113
+ alias :authorise :authorize
114
+
115
+ # Revoke a port/protocol for a specific IP address
116
+ # Takes the same arguments as authorize
117
+ def revoke(name, addresses=[], ports=[], protocols=[], &each_group)
118
+ modify_rules(:revoke, name, addresses, ports, protocols, &each_group)
119
+ end
120
+
121
+ def authorize_group(name, gname, owner, &each_group)
122
+ modify_group_rules(:authorize, name, gname, owner, &each_group)
123
+ end
124
+ alias :authorise_group :authorize_group
125
+
126
+ def revoke_group(name, gname, owner, &each_group)
127
+ modify_group_rules(:revoke, name, gname, owner, &each_group)
128
+ end
129
+
130
+ def list(group_names=[], &each_group)
131
+ group_names ||= []
132
+ groups = list_as_hash(group_names, &each_group)
133
+ groups &&= groups.values
134
+ groups
135
+ end
136
+
137
+ # * +group_names+ is a list of security group names to look for. If it's empty, all groups
138
+ # associated to the account will be returned.
139
+ #
140
+ # Returns an Array of Rudy::AWS::EC2::Group objects
141
+ def list_as_hash(group_names=[], &each_group)
142
+ group_names = [group_names].flatten.compact
143
+ glist = @ec2.describe_security_groups(:group_name => group_names) || {}
144
+ return unless glist['securityGroupInfo'].is_a?(Hash)
145
+ groups = {}
146
+ glist['securityGroupInfo']['item'].each do |oldg|
147
+ g = Groups.from_hash(oldg)
148
+ groups[g.name] = g
149
+ end
150
+ groups.each_value { |g| each_group.call(g) } if each_group
151
+ groups
152
+ end
153
+
154
+ def any?
155
+ groups = list || []
156
+ !groups.empty?
157
+ end
158
+
159
+ # * +name+ a string
160
+ def get(name)
161
+ (list([name]) || []).first
162
+ end
163
+
164
+ # +group+ a Rudy::AWS::EC2::Group object
165
+ #def save(group)
166
+ #
167
+ #end
168
+
169
+ # Does the security group +name+ exist?
170
+ def exists?(name)
171
+ begin
172
+ g = list([name.to_s])
173
+ rescue ::EC2::InvalidGroupNotFound
174
+ return false
175
+ end
176
+
177
+ !g.empty?
178
+ end
179
+
180
+
181
+
182
+
183
+ # * +ghash+ is an EC2::Base Security Group Hash. This is the format
184
+ # returned by EC2::Base#describe_security_groups
185
+ #
186
+ # groupName: stage-app
187
+ # groupDescription:
188
+ # ownerId: "207436219441"
189
+ # ipPermissions:
190
+ # item:
191
+ # - ipRanges:
192
+ # item:
193
+ # - cidrIp: 216.19.182.83/32
194
+ # - cidrIp: 24.5.71.201/32
195
+ # - cidrIp: 75.157.176.202/32
196
+ # - cidrIp: 84.28.52.172/32
197
+ # - cidrIp: 87.212.145.201/32
198
+ # - cidrIp: 96.49.129.178/32
199
+ # groups:
200
+ # item:
201
+ # - groupName: default
202
+ # userId: "207436219441"
203
+ # - groupName: stage-app
204
+ # userId: "207436219441"
205
+ # fromPort: "22"
206
+ # toPort: "22"
207
+ # ipProtocol: tcp
208
+ #
209
+ # Returns a Rudy::AWS::EC2::Group object
210
+ def self.from_hash(ghash)
211
+ newg = Rudy::AWS::EC2::Group.new
212
+ newg.name = ghash['groupName']
213
+ newg.description = ghash['groupDescription']
214
+ newg.owner_id = ghash['ownerId']
215
+ newg.addresses = {}
216
+ newg.groups = {}
217
+
218
+ return newg unless ghash['ipPermissions'].is_a?(Hash)
219
+
220
+ ghash['ipPermissions']['item'].each do |oldp|
221
+ newp = Rudy::AWS::EC2::Group::Rule.new
222
+ newp.ports = Range.new(oldp['fromPort'], oldp['toPort'])
223
+ newp.protocol = oldp['ipProtocol']
224
+ if oldp['groups'].is_a?(Hash)
225
+ oldp['groups']['item'].each do |oldpg|
226
+ name = [oldpg['userId'], oldpg['groupName']].join(':') # account_num:name
227
+ newg.add_group(name, newp)
228
+ end
229
+ end
230
+ if oldp['ipRanges'].is_a?(Hash)
231
+ oldp['ipRanges']['item'].each do |olda|
232
+ name = "#{olda['cidrIp']}"
233
+ newg.add_address(name, newp) # ipaddress/mask/protocol
234
+ end
235
+ end
236
+ end
237
+ newg
238
+ end
239
+
240
+
241
+ private
242
+
243
+
244
+ def modify_rules(meth, name, addresses, ports, protocols, &each_group)
245
+ list(name, &each_group) if each_group
246
+
247
+ ports = [[22,22],[80,80],[443,443]] if !ports || ports.empty?
248
+ protocols = ["tcp"] if !protocols || protocols.empty?
249
+ addresses = [Rudy::Utils::external_ip_address] if !addresses || addresses.empty?
250
+
251
+ # Make sure the IP addresses have ranges
252
+ addresses.collect! { |ip| (ip.match /\/\d+/) ? ip : "#{ip}/32" }
253
+ protocols.collect! { |p| p.to_s }
254
+ ret = false
255
+ protocols.each do |protocol|
256
+ addresses.each do |address|
257
+ ports.each do |port|
258
+ port_lo, port_hi = port.is_a?(Array) ? [port[0], port[1]] : [port, port]
259
+ @logger.puts "#{meth} for ports #{port[0]}:#{port[1]} (#{protocol}) for #{addresses.join(', ')}" if @logger
260
+ ret = modify_rule(meth, name, port[0].to_i, (port[1] || port[0]).to_i, protocol, address)
261
+ raise "Unknown error during #{meth}" unless ret
262
+ end
263
+ end
264
+ end
265
+
266
+ ret
267
+ end
268
+
269
+ def modify_rule(meth, name, from_port, to_port, protocol, ipa)
270
+ opts = {
271
+ :group_name => name,
272
+ :ip_protocol => protocol,
273
+ :from_port => from_port,
274
+ :to_port => to_port,
275
+ :cidr_ip => ipa
276
+ }
277
+ ret = @ec2.send("#{meth}_security_group_ingress", opts)
278
+ (ret && ret['return'] == 'true')
279
+ end
280
+
281
+
282
+ def modify_group_rules(meth, name, gname, gowner, &each_group)
283
+ list(name, &each_group) if each_group
284
+ # probably works, needs to be tested
285
+ #gowner &&= gowner.tr!('-', '') # Remove dashes from aws account number
286
+
287
+ opts = {
288
+ :group_name => name,
289
+ :source_security_group_name => gname,
290
+ :source_security_group_owner_id => gowner
291
+ }
292
+ ret = @ec2.send("#{meth}_security_group_ingress", opts)
293
+ (ret && ret['return'] == 'true')
294
+ end
295
+
296
+
297
+
298
+ end
299
+ end
300
+
301
+ end
@@ -0,0 +1,168 @@
1
+
2
+
3
+ module Rudy::AWS
4
+ class EC2::Image < Storable
5
+ @@sformat = " -> %8s; %12s; %12s; %12s; %8s"
6
+
7
+ field :awsid
8
+ field :owner
9
+ field :aki
10
+ field :ari
11
+ field :state
12
+ field :arch
13
+ field :visibility
14
+ field :location
15
+ field :kind
16
+
17
+ def liner_note
18
+ info = @location
19
+ # Highlight "debian-5" in /dir/debian-5.manifest.xml
20
+ #info = info.split(/\//)
21
+ #info[-1].gsub!(/(.+?)((\.img)?\.manifest\.xml)/) { |m,n| ($1 || "").bright << $2 }
22
+ #info = info.join('/')
23
+ "%s %-6s (%s)" % [self.awsid.bright, self.arch, info]
24
+ end
25
+
26
+ def to_s(with_title=false)
27
+ lines = []
28
+ lines << liner_note
29
+ #if self.available?
30
+ # p = public? ? "public" : "private"
31
+ # k, r = @aki || 'aki-unknown', @ari || 'ari-unknown'
32
+ # lines << @@sformat % %w{arch owner aki ari visibility} if with_title
33
+ # lines << @@sformat % [@arch, @owner, k, r, p]
34
+ #end
35
+ lines.join($/)
36
+ end
37
+
38
+ def inspect
39
+ lines = []
40
+ lines << liner_note
41
+ field_names.each do |key|
42
+ next unless self.respond_to?(key)
43
+ val = self.send(key)
44
+ lines << sprintf(" %22s: %s", key, (val.is_a?(Array) ? val.join(', ') : val))
45
+ end
46
+ lines.join($/)
47
+ end
48
+
49
+ def available?; @state && @state == "available"; end
50
+ def public?; @visibility && @visibility == 'public'; end
51
+ def private?; !public? end
52
+
53
+ end
54
+
55
+ module EC2
56
+
57
+ class Images
58
+ include Rudy::AWS::ObjectBase
59
+ include Rudy::AWS::EC2::Base
60
+
61
+ def list(owner=[], image_ids=[], executable_by=[], &each_image)
62
+ images = list_as_hash(owner, image_ids, executable_by)
63
+ images &&= images.values
64
+ images
65
+ end
66
+
67
+ def list_as_hash(owner=[], image_ids=[], executable_by=[], &each_image)
68
+ owner &&= [owner].flatten.compact
69
+ image_ids &&= [image_ids].flatten.compact
70
+ executable_by &&= [executable_by].flatten.compact
71
+
72
+ # Remove dashes from aws account numbers
73
+ owner &&= owner.collect { |o| o.tr('-', '') }
74
+ # If we got Image objects, we want just the IDs.
75
+ # This method always returns an Array.
76
+ image_ids = objects_to_image_ids(image_ids)
77
+
78
+ opts = {
79
+ :owner_id => owner || [],
80
+ :image_id => image_ids || [],
81
+ :executable_by => executable_by || []
82
+ }
83
+
84
+ response = execute_request({}) { @ec2.describe_images(opts) }
85
+
86
+ return nil unless response['imagesSet'].is_a?(Hash) # No instances
87
+
88
+ resids = []
89
+ images = {}
90
+ response['imagesSet']['item'].each do |res|
91
+ resids << res['reservationId']
92
+ img = Images.from_hash(res)
93
+ images[img.awsid] = img
94
+ end
95
+
96
+ images.each_value { |image| each_image.call(image) } if each_image
97
+
98
+ images = nil if images.empty? # Don't return an empty hash
99
+ images
100
+ end
101
+
102
+ # +id+ AMI ID to deregister (ami-XXXXXXX)
103
+ # Returns true when successful. Otherwise throws an exception.
104
+ def deregister(id)
105
+ opts = {
106
+ :image_id => id
107
+ }
108
+ ret = @ec2.deregister_image(opts)
109
+ puts ret.to_yaml
110
+ true
111
+ end
112
+
113
+ # +path+ the S3 path to the manifest (bucket/file.manifest.xml)
114
+ # Returns the AMI ID when successful, otherwise throws an exception.
115
+ def register(path)
116
+ opts = {
117
+ :image_location => path
118
+ }
119
+ ret = @ec2.register_image(opts)
120
+ puts ret.to_yaml
121
+ true
122
+ end
123
+
124
+ # imageOwnerId: "203338247012"
125
+ # kernelId: aki-a71cf9ce
126
+ # ramdiskId: ari-a51cf9cc
127
+ # imageState: available
128
+ # imageId: ami-dd34d3b4
129
+ # architecture: i386
130
+ # isPublic: "false"
131
+ # imageLocation: solutious-rudy-us/debian-squeeze-m1.small-v5.manifest.xml
132
+ # imageType: machine
133
+ def Images.from_hash(h)
134
+ img = Rudy::AWS::EC2::Image.new
135
+ img.owner = h['imageOwnerId']
136
+ img.aki = h['kernelId']
137
+ img.ari = h['ramdiskId']
138
+ img.state = h['imageState']
139
+ img.awsid = h['imageId']
140
+ img.arch = h['architecture']
141
+ img.visibility = h['isPublic'] == 'true' ? 'public' : 'private'
142
+ img.location = h['imageLocation']
143
+ img.kind = h['imageType']
144
+ img
145
+ end
146
+
147
+
148
+ private
149
+
150
+ # * +img_ids+ an Array of images IDs (Strings) or Image objects.
151
+ # Note: This method removes nil values and always returns an Array.
152
+ # Returns an Array of image IDs.
153
+ def objects_to_image_ids(img_ids)
154
+ img_ids = [img_ids].flatten # Make sure it's an Array
155
+ img_ids = img_ids.collect do |img|
156
+ next if img.nil? || img.to_s.empty?
157
+ if !img.is_a?(Rudy::AWS::EC2::Image) && !Rudy::Utils.is_id?(:image, img)
158
+ raise %Q("#{img}" is not an image ID or object)
159
+ end
160
+ img.is_a?(Rudy::AWS::EC2::Image) ? img.awsid : img
161
+ end
162
+ img_ids
163
+ end
164
+
165
+ end
166
+
167
+ end
168
+ end