rudy 0.4.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +54 -30
- data/README.rdoc +100 -12
- data/Rakefile +103 -8
- data/Rudyfile +119 -0
- data/bin/ird +175 -0
- data/bin/rudy +259 -156
- data/bin/rudy-ec2 +228 -95
- data/bin/rudy-s3 +76 -0
- data/bin/rudy-sdb +67 -0
- data/lib/annoy.rb +270 -0
- data/lib/console.rb +30 -9
- data/lib/escape.rb +305 -0
- data/lib/rudy.rb +151 -182
- data/lib/rudy/aws.rb +56 -49
- data/lib/rudy/aws/ec2.rb +47 -292
- data/lib/rudy/aws/ec2/address.rb +157 -0
- data/lib/rudy/aws/ec2/group.rb +301 -0
- data/lib/rudy/aws/ec2/image.rb +168 -0
- data/lib/rudy/aws/ec2/instance.rb +434 -0
- data/lib/rudy/aws/ec2/keypair.rb +104 -0
- data/lib/rudy/aws/ec2/snapshot.rb +98 -0
- data/lib/rudy/aws/ec2/volume.rb +230 -0
- data/lib/rudy/aws/ec2/zone.rb +77 -0
- data/lib/rudy/aws/s3.rb +54 -0
- data/lib/rudy/aws/sdb.rb +298 -0
- data/lib/rudy/aws/sdb/error.rb +46 -0
- data/lib/rudy/{metadata/backup.rb → backup.rb} +26 -51
- data/lib/rudy/cli.rb +157 -0
- data/lib/rudy/cli/aws/ec2/addresses.rb +105 -0
- data/lib/rudy/cli/aws/ec2/candy.rb +208 -0
- data/lib/rudy/cli/aws/ec2/groups.rb +121 -0
- data/lib/rudy/cli/aws/ec2/images.rb +196 -0
- data/lib/rudy/cli/aws/ec2/instances.rb +194 -0
- data/lib/rudy/cli/aws/ec2/keypairs.rb +53 -0
- data/lib/rudy/cli/aws/ec2/snapshots.rb +49 -0
- data/lib/rudy/cli/aws/ec2/volumes.rb +104 -0
- data/lib/rudy/cli/aws/ec2/zones.rb +22 -0
- data/lib/rudy/cli/aws/s3/buckets.rb +50 -0
- data/lib/rudy/cli/aws/s3/store.rb +22 -0
- data/lib/rudy/cli/aws/sdb/domains.rb +41 -0
- data/lib/rudy/cli/candy.rb +8 -0
- data/lib/rudy/{command → cli}/config.rb +34 -24
- data/lib/rudy/cli/disks.rb +35 -0
- data/lib/rudy/cli/machines.rb +94 -0
- data/lib/rudy/cli/routines.rb +57 -0
- data/lib/rudy/config.rb +77 -72
- data/lib/rudy/config/objects.rb +29 -0
- data/lib/rudy/disks.rb +248 -0
- data/lib/rudy/global.rb +121 -0
- data/lib/rudy/huxtable.rb +340 -0
- data/lib/rudy/machines.rb +245 -0
- data/lib/rudy/metadata.rb +123 -13
- data/lib/rudy/routines.rb +47 -0
- data/lib/rudy/routines/helpers/diskhelper.rb +101 -0
- data/lib/rudy/routines/helpers/scripthelper.rb +91 -0
- data/lib/rudy/routines/release.rb +34 -0
- data/lib/rudy/routines/shutdown.rb +57 -0
- data/lib/rudy/routines/startup.rb +58 -0
- data/lib/rudy/scm/svn.rb +1 -1
- data/lib/rudy/utils.rb +322 -4
- data/lib/storable.rb +26 -17
- data/lib/sysinfo.rb +274 -0
- data/lib/tryouts.rb +6 -13
- data/rudy.gemspec +128 -42
- data/support/randomize-root-password +45 -0
- data/support/rudy-ec2-startup +9 -9
- data/support/update-ec2-ami-tools +20 -0
- data/test/05_config/00_setup_test.rb +20 -0
- data/test/05_config/30_machines_test.rb +69 -0
- data/test/20_sdb/00_setup_test.rb +16 -0
- data/test/20_sdb/10_domains_test.rb +115 -0
- data/test/25_ec2/00_setup_test.rb +29 -0
- data/test/25_ec2/10_keypairs_test.rb +41 -0
- data/test/25_ec2/20_groups_test.rb +131 -0
- data/test/25_ec2/30_addresses_test.rb +38 -0
- data/test/25_ec2/40_volumes_test.rb +49 -0
- data/test/25_ec2/50_snapshots_test.rb +74 -0
- data/test/26_ec2_instances/00_setup_test.rb +28 -0
- data/test/26_ec2_instances/10_instances_test.rb +83 -0
- data/test/26_ec2_instances/50_images_test.rb +13 -0
- data/test/30_sdb_metadata/00_setup_test.rb +21 -0
- data/test/30_sdb_metadata/10_disks_test.rb +109 -0
- data/test/30_sdb_metadata/20_backups_test.rb +102 -0
- data/test/coverage.txt +51 -0
- data/test/helper.rb +36 -0
- data/vendor/highline-1.5.1/CHANGELOG +222 -0
- data/vendor/highline-1.5.1/INSTALL +35 -0
- data/vendor/highline-1.5.1/LICENSE +7 -0
- data/vendor/highline-1.5.1/README +63 -0
- data/vendor/highline-1.5.1/Rakefile +82 -0
- data/vendor/highline-1.5.1/TODO +6 -0
- data/vendor/highline-1.5.1/examples/ansi_colors.rb +38 -0
- data/vendor/highline-1.5.1/examples/asking_for_arrays.rb +18 -0
- data/vendor/highline-1.5.1/examples/basic_usage.rb +75 -0
- data/vendor/highline-1.5.1/examples/color_scheme.rb +32 -0
- data/vendor/highline-1.5.1/examples/limit.rb +12 -0
- data/vendor/highline-1.5.1/examples/menus.rb +65 -0
- data/vendor/highline-1.5.1/examples/overwrite.rb +19 -0
- data/vendor/highline-1.5.1/examples/page_and_wrap.rb +322 -0
- data/vendor/highline-1.5.1/examples/password.rb +7 -0
- data/vendor/highline-1.5.1/examples/trapping_eof.rb +22 -0
- data/vendor/highline-1.5.1/examples/using_readline.rb +17 -0
- data/vendor/highline-1.5.1/lib/highline.rb +758 -0
- data/vendor/highline-1.5.1/lib/highline/color_scheme.rb +120 -0
- data/vendor/highline-1.5.1/lib/highline/compatibility.rb +17 -0
- data/vendor/highline-1.5.1/lib/highline/import.rb +43 -0
- data/vendor/highline-1.5.1/lib/highline/menu.rb +395 -0
- data/vendor/highline-1.5.1/lib/highline/question.rb +463 -0
- data/vendor/highline-1.5.1/lib/highline/system_extensions.rb +193 -0
- data/vendor/highline-1.5.1/setup.rb +1360 -0
- data/vendor/highline-1.5.1/test/tc_color_scheme.rb +56 -0
- data/vendor/highline-1.5.1/test/tc_highline.rb +823 -0
- data/vendor/highline-1.5.1/test/tc_import.rb +54 -0
- data/vendor/highline-1.5.1/test/tc_menu.rb +429 -0
- data/vendor/highline-1.5.1/test/ts_all.rb +15 -0
- metadata +141 -38
- data/lib/aws_sdb.rb +0 -3
- data/lib/aws_sdb/error.rb +0 -42
- data/lib/aws_sdb/service.rb +0 -215
- data/lib/rudy/aws/simpledb.rb +0 -53
- data/lib/rudy/command/addresses.rb +0 -46
- data/lib/rudy/command/backups.rb +0 -175
- data/lib/rudy/command/base.rb +0 -841
- data/lib/rudy/command/deploy.rb +0 -12
- data/lib/rudy/command/disks.rb +0 -213
- data/lib/rudy/command/environment.rb +0 -73
- data/lib/rudy/command/groups.rb +0 -61
- data/lib/rudy/command/images.rb +0 -91
- data/lib/rudy/command/instances.rb +0 -85
- data/lib/rudy/command/machines.rb +0 -161
- data/lib/rudy/command/metadata.rb +0 -41
- data/lib/rudy/command/release.rb +0 -174
- data/lib/rudy/command/volumes.rb +0 -66
- data/lib/rudy/metadata/disk.rb +0 -138
- 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
|