bschwartz-capsize 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +18 -0
- data/License.txt +67 -0
- data/Manifest.txt +24 -0
- data/README.textile +83 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +76 -0
- data/config/requirements.rb +18 -0
- data/examples/capsize.yml.template +67 -0
- data/examples/deploy.rb +29 -0
- data/lib/capsize/capsize.rb +101 -0
- data/lib/capsize/configuration.rb +44 -0
- data/lib/capsize/ec2.rb +654 -0
- data/lib/capsize/ec2_plugin.rb +618 -0
- data/lib/capsize/meta_tasks.rb +156 -0
- data/lib/capsize/sqs.rb +57 -0
- data/lib/capsize/sqs_plugin.rb +128 -0
- data/lib/capsize/version.rb +9 -0
- data/lib/capsize.rb +26 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +27 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/test_capsize.rb +12 -0
- data/test/test_helper.rb +10 -0
- metadata +130 -0
data/lib/capsize/ec2.rb
ADDED
@@ -0,0 +1,654 @@
|
|
1
|
+
Capistrano::Configuration.instance.load do
|
2
|
+
|
3
|
+
namespace :ec2 do
|
4
|
+
|
5
|
+
|
6
|
+
# CONSOLE TASKS
|
7
|
+
#########################################
|
8
|
+
|
9
|
+
namespace :console do
|
10
|
+
|
11
|
+
desc <<-DESC
|
12
|
+
Show instance console output.
|
13
|
+
You can view the console of a specific instance by doing one of the following:
|
14
|
+
- define an :instance_id in any Capsize config file with "set :instance_id, 'i-123456'"
|
15
|
+
- Override this on the command line with "cap ec2:console:output INSTANCE_ID='i-123456'"
|
16
|
+
- If neither of these are provided you will be prompted by Capistano for the instance ID you wish to terminate.
|
17
|
+
DESC
|
18
|
+
task :output do
|
19
|
+
|
20
|
+
capsize.get(:instance_id)
|
21
|
+
|
22
|
+
case instance_id
|
23
|
+
when nil, ""
|
24
|
+
puts "You don't seem to have set an instance ID..."
|
25
|
+
else
|
26
|
+
begin
|
27
|
+
capsize_ec2.get_console_output(:instance_id => instance_id).each_pair do |key, value|
|
28
|
+
puts "#{key} = #{value}" unless key == "xmlns"
|
29
|
+
end
|
30
|
+
rescue Exception => e
|
31
|
+
puts "The attempt to get the console output failed with error : " + e
|
32
|
+
raise e
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# KEYPAIR TASKS
|
42
|
+
#########################################
|
43
|
+
|
44
|
+
namespace :keypairs do
|
45
|
+
# FIXME : Bug with shadowing existing method
|
46
|
+
desc <<-DESC
|
47
|
+
Describes your keypairs.
|
48
|
+
This will return a text description of all of your personal keypairs created on EC2.
|
49
|
+
Remember that these keypairs are only usable if you have the private key material stored locally
|
50
|
+
and you specify this keypair as part of the run instances command. Only then will you be able to
|
51
|
+
take advantage of logging into remote servers using public key authentication. This command
|
52
|
+
will also display whether you have a locally installed private key that matches the key_name of
|
53
|
+
the public key being described.
|
54
|
+
DESC
|
55
|
+
task :show do
|
56
|
+
begin
|
57
|
+
capsize_ec2.describe_keypairs().keySet.item.each do |item|
|
58
|
+
puts "[#{item.keyName}] : keyName = " + item.keyName
|
59
|
+
puts "[#{item.keyName}] : keyFingerprint = " + item.keyFingerprint
|
60
|
+
|
61
|
+
key_file = capsize_ec2.get_key_file(:key_name => item.keyName)
|
62
|
+
|
63
|
+
puts "[#{item.keyName}] : OK : matching local private key found @ #{key_file}" if File.exists?(key_file)
|
64
|
+
puts "[#{item.keyName}] : WARNING : matching local private key NOT found @ #{key_file}" unless File.exists?(key_file)
|
65
|
+
puts ""
|
66
|
+
end
|
67
|
+
rescue Exception => e
|
68
|
+
puts "The attempt to show your keypairs failed with error : " + e
|
69
|
+
raise e
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
desc <<-DESC
|
75
|
+
Create and store a new keypair.
|
76
|
+
This command will generate a new keypair for you on EC2 and will also
|
77
|
+
save a local copy of your private key in the filepath specified by
|
78
|
+
KEY_DIR and KEY_NAME. By default the keypair will be named the
|
79
|
+
same as your Capistrano application's name, and the private key will
|
80
|
+
be stored in your capsize config dir. If a keypair already exists
|
81
|
+
on the EC2 servers or locally with the same name it will not be
|
82
|
+
overwritten.
|
83
|
+
|
84
|
+
WARNING : Keypair private keys should be protected the same as passwords.
|
85
|
+
If you have specified a key_name to use when running instances anyone who
|
86
|
+
has access to your keypair private key file contents and who knows the
|
87
|
+
public DNS name of your servers may be able to login to those servers
|
88
|
+
without providing a password. Use caution when storing the private key file
|
89
|
+
in source code control systems, and keep a backup of your private key file.
|
90
|
+
DESC
|
91
|
+
task :create do
|
92
|
+
begin
|
93
|
+
puts "Generating keypair... (this may take a few seconds)"
|
94
|
+
key_name, key_file = capsize_ec2.create_keypair()
|
95
|
+
puts "A keypair with the name \"#{key_name}\" has been generated and saved here:\n #{key_file}"
|
96
|
+
rescue Exception => e
|
97
|
+
puts "The attempt to create a keypair failed with the error : " + e
|
98
|
+
raise e
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
desc <<-DESC
|
104
|
+
Delete a keypair.
|
105
|
+
This command will delete a keypair from EC2 and will also
|
106
|
+
delete the local copy of your private key in the filepath specified by
|
107
|
+
KEY_DIR and KEY_NAME. By default the keypair deleted will be named the
|
108
|
+
same as your Capistrano application's name, and the private key will
|
109
|
+
be deleted from your capsize config dir. You will be prompted to confirm
|
110
|
+
deletion of your keypair before the action will proceed.
|
111
|
+
|
112
|
+
WARNING : Don't delete keypairs which may be associated with
|
113
|
+
running instances on EC2. If you do so you may lose the ability
|
114
|
+
to access these servers via SSH and Capistrano! Your last resort in
|
115
|
+
this case may be to terminate those running servers.
|
116
|
+
DESC
|
117
|
+
task :delete do
|
118
|
+
|
119
|
+
key_name = capsize.get(:key_name)
|
120
|
+
|
121
|
+
confirm = (Capistrano::CLI.ui.ask("WARNING! Are you sure you want to delete the local and remote parts of the keypair with the name \"#{key_name}\"?\nYou will no longer be able to access any running instances that depend on this keypair!? (y/N): ").downcase == 'y')
|
122
|
+
|
123
|
+
if confirm
|
124
|
+
begin
|
125
|
+
capsize_ec2.delete_keypair()
|
126
|
+
rescue Exception => e
|
127
|
+
puts "The attempt to delete the keypair failed with the error : " + e
|
128
|
+
raise e
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
# INSTANCES TASKS
|
137
|
+
#########################################
|
138
|
+
|
139
|
+
namespace :instances do
|
140
|
+
|
141
|
+
|
142
|
+
desc <<-DESC
|
143
|
+
Open an SSH shell to instance_id.
|
144
|
+
This command makes it easy to open an interactive SSH session with one
|
145
|
+
of your running instances. Just set instance_id in one of your config
|
146
|
+
files, or pass in INSTANCE_ID='i-123456' to this task and an SSH
|
147
|
+
connection to the public DNS name for that instance will be started.
|
148
|
+
SSH is configured to use try the public key pair associated with
|
149
|
+
your application for authentication assuming you started your instance
|
150
|
+
to be associated with that key_name. The option StrictHostKeyChecking=no
|
151
|
+
is passed to your local SSH command to avoid prompting the user regarding
|
152
|
+
adding the remote host signature to their SSH known_hosts file as these
|
153
|
+
server signatures will typically change often anyway in the EC2 environment.
|
154
|
+
Task assumes you have a local 'ssh' command on your shell path, and that you
|
155
|
+
are using OpenSSH. Your mileage may vary with other SSH implementations.
|
156
|
+
DESC
|
157
|
+
task :ssh do
|
158
|
+
|
159
|
+
capsize.get(:instance_id)
|
160
|
+
|
161
|
+
case instance_id
|
162
|
+
when nil, ""
|
163
|
+
puts "You don't seem to have set an instance_id in your config or passed an INSTANCE_ID environment variable..."
|
164
|
+
else
|
165
|
+
|
166
|
+
begin
|
167
|
+
dns_name = capsize_ec2.hostname_from_instance_id(capsize.get(:instance_id))
|
168
|
+
rescue Exception => e
|
169
|
+
puts "The attempt to get the DNS name for your instance failed with the error : " + e
|
170
|
+
end
|
171
|
+
|
172
|
+
key_file = capsize_ec2.get_key_file
|
173
|
+
|
174
|
+
# StrictHostKeyChecking=no ensures that you won't be prompted each time for adding
|
175
|
+
# the remote host to your ssh known_hosts file. This should be ok as the host IP
|
176
|
+
# and fingerprint will constantly change as you start and stop EC2 instances.
|
177
|
+
# For the ultra paranoid who are concerned about man-in-the-middle attacks you
|
178
|
+
# may want to do ssh manually, and perhaps not use no-password public key auth.
|
179
|
+
#
|
180
|
+
# example connect : ssh -o StrictHostKeyChecking=no -i config/id_rsa-myappkey root@ec2-72-44-51-000.z-1.compute-1.amazonaws.com
|
181
|
+
puts "Trying to connect with host with local shell command:"
|
182
|
+
puts "ssh -o StrictHostKeyChecking=no -i #{key_file} root@#{dns_name}"
|
183
|
+
puts "--\n"
|
184
|
+
system "ssh -o StrictHostKeyChecking=no -i #{key_file} root@#{dns_name}"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
desc <<-DESC
|
190
|
+
Start an EC2 instance.
|
191
|
+
Runs an instance of :image_id with the keypair :key_name and group :group_name.
|
192
|
+
DESC
|
193
|
+
task :run do
|
194
|
+
begin
|
195
|
+
|
196
|
+
response = capsize_ec2.run_instance
|
197
|
+
|
198
|
+
puts "An instance has been started with the following metadata:"
|
199
|
+
capsize_ec2.print_instance_description(response)
|
200
|
+
|
201
|
+
instance_id = response.reservationSet.item[0].instancesSet.item[0].instanceId
|
202
|
+
puts "SSH:"
|
203
|
+
puts "cap -s instance_id='#{instance_id}' ec2:instances:ssh"
|
204
|
+
puts ""
|
205
|
+
|
206
|
+
# TODO : Tell the user exactly what instance info they need to put in their deploy.rb
|
207
|
+
# to make the control of their server instances persistent!
|
208
|
+
#capsize_ec2.print_config_instructions(:response => response)
|
209
|
+
|
210
|
+
# TODO : I think this (set_default_roles_to_target_role) is only good if we are only
|
211
|
+
# dealing with one server. But the values are temporary. How should we handle multiple
|
212
|
+
# instances starting that need to be controlled? How should we handle storing this important data
|
213
|
+
# more persistently??
|
214
|
+
#
|
215
|
+
# override the roles set in deploy.rb with the server instance started here.
|
216
|
+
# This is temporary and only remains defined for the length of this
|
217
|
+
# capistrano run!
|
218
|
+
#set(:dns_name, response.reservationSet.item[0].instancesSet.item[0].dnsName)
|
219
|
+
#set_default_roles_to_target_role
|
220
|
+
|
221
|
+
rescue Exception => e
|
222
|
+
puts "The attempt to run an instance failed with the error : " + e
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
desc <<-DESC
|
228
|
+
Terminate an EC2 instance.
|
229
|
+
You can terminate a specific instance by doing one of the following:
|
230
|
+
- define an :instance_id in deploy.rb with "set :instance_id, 'i-123456'"
|
231
|
+
- Override this on the command line with "cap ec2:instances:terminate INSTANCE_ID='i-123456'"
|
232
|
+
- If neither of these are provided you will be prompted by Capistano for the instance ID you wish to terminate.
|
233
|
+
DESC
|
234
|
+
task :terminate do
|
235
|
+
|
236
|
+
capsize.get(:instance_id)
|
237
|
+
|
238
|
+
case instance_id
|
239
|
+
when nil, ""
|
240
|
+
puts "You don't seem to have set an instance ID..."
|
241
|
+
else
|
242
|
+
confirm = (Capistrano::CLI.ui.ask("WARNING! Really terminate instance \"#{instance_id}\"? (y/N): ").downcase == 'y')
|
243
|
+
if confirm
|
244
|
+
begin
|
245
|
+
response = capsize_ec2.terminate_instance({:instance_id => instance_id})
|
246
|
+
puts "The request to terminate instance_id #{instance_id} has been accepted. Monitor the status of the request with 'cap ec2:instances:show'"
|
247
|
+
rescue Exception => e
|
248
|
+
puts "The attempt to terminate the instance failed with error : " + e
|
249
|
+
raise e
|
250
|
+
end
|
251
|
+
else
|
252
|
+
puts "Your terminate instance request has been cancelled."
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
|
258
|
+
desc <<-DESC
|
259
|
+
Reboot an EC2 instance.
|
260
|
+
You can reboot a specific instance by doing one of the following:
|
261
|
+
- define an :instance_id in deploy.rb with "set :instance_id, 'i-123456'"
|
262
|
+
- Override this on the command line with "cap ec2:instances:reboot INSTANCE_ID='i-123456'"
|
263
|
+
- If neither of these are provided you will be prompted by Capistano for the instance ID you wish to reboot.
|
264
|
+
DESC
|
265
|
+
task :reboot do
|
266
|
+
|
267
|
+
capsize.get(:instance_id)
|
268
|
+
|
269
|
+
case instance_id
|
270
|
+
when nil, ""
|
271
|
+
puts "You don't seem to have set an instance ID..."
|
272
|
+
else
|
273
|
+
confirm = (Capistrano::CLI.ui.ask("WARNING! Really reboot instance \"#{instance_id}\"? (y/N): ").downcase == 'y')
|
274
|
+
if confirm
|
275
|
+
begin
|
276
|
+
response = capsize_ec2.reboot_instance({:instance_id => instance_id})
|
277
|
+
puts "The request to reboot instance_id \"#{instance_id}\" has been accepted. Monitor the status of the request with 'cap ec2:instances:show'"
|
278
|
+
rescue Exception => e
|
279
|
+
puts "The attempt to reboot the instance_id \"#{instance_id}\" failed with error : " + e
|
280
|
+
raise e
|
281
|
+
end
|
282
|
+
else
|
283
|
+
puts "Your reboot instance request has been cancelled."
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
|
289
|
+
desc <<-DESC
|
290
|
+
Show and describe current instances.
|
291
|
+
Will show the current metadata and status for all instances that you own.
|
292
|
+
DESC
|
293
|
+
task :show do
|
294
|
+
|
295
|
+
begin
|
296
|
+
result = capsize_ec2.describe_instances()
|
297
|
+
rescue Exception => e
|
298
|
+
puts "The attempt to show your instances failed with error : " + e
|
299
|
+
raise e
|
300
|
+
end
|
301
|
+
|
302
|
+
capsize_ec2.print_instance_description(result)
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|
306
|
+
|
307
|
+
|
308
|
+
# SECURITY GROUP TASKS
|
309
|
+
#########################################
|
310
|
+
|
311
|
+
|
312
|
+
namespace :security_groups do
|
313
|
+
|
314
|
+
desc <<-DESC
|
315
|
+
Create a security group.
|
316
|
+
Create a new security group specifying:
|
317
|
+
- :group_name or GROUP_NAME (defaults to application name)
|
318
|
+
- :group_description or GROUP_DESCRIPTION (defaults to generic description including application name)
|
319
|
+
DESC
|
320
|
+
task :create do
|
321
|
+
begin
|
322
|
+
capsize_ec2.create_security_group()
|
323
|
+
puts "The security group \"#{capsize.get(:group_name)}\" has been created."
|
324
|
+
rescue EC2::InternalError => e
|
325
|
+
# BUG : Bug in EC2. Is throwing InternalError instead of InvalidGroupDuplicate if you try to create a group that exists. Catch both.
|
326
|
+
# REMOVE THIS RESCUE WHEN BUG IS FIXED BY AWS
|
327
|
+
puts "The security group you specified for group name \"#{capsize.get(:group_name)}\" already exists (EC2::InternalError)."
|
328
|
+
# Don't re-raise this exception
|
329
|
+
rescue EC2::InvalidGroupDuplicate => e
|
330
|
+
puts "The security group you specified for group name \"#{capsize.get(:group_name)}\" already exists (EC2::InvalidGroupDuplicate)."
|
331
|
+
# Don't re-raise this exception
|
332
|
+
rescue Exception => e
|
333
|
+
puts "The attempt to create security group \"#{capsize.get(:group_name)}\" failed with the error : " + e
|
334
|
+
raise e
|
335
|
+
end
|
336
|
+
|
337
|
+
end
|
338
|
+
|
339
|
+
desc <<-DESC
|
340
|
+
Show and describes security groups.
|
341
|
+
This will return a description of your security groups on EC2.
|
342
|
+
Pass in GROUP_NAME to limit to a specific group.
|
343
|
+
DESC
|
344
|
+
task :show do
|
345
|
+
begin
|
346
|
+
capsize_ec2.describe_security_groups().securityGroupInfo.item.each do |group|
|
347
|
+
puts "[#{group.groupName}] : groupName = " + group.groupName
|
348
|
+
puts "[#{group.groupName}] : groupDescription = " + group.groupDescription
|
349
|
+
puts "[#{group.groupName}] : ownerId = " + group.ownerId
|
350
|
+
|
351
|
+
unless group.ipPermissions.nil?
|
352
|
+
group.ipPermissions.item.each do |permission|
|
353
|
+
puts " --"
|
354
|
+
puts " ipPermissions:ipProtocol = " + permission.ipProtocol unless permission.ipProtocol.nil?
|
355
|
+
puts " ipPermissions:fromPort = " + permission.fromPort unless permission.fromPort.nil?
|
356
|
+
puts " ipPermissions:toPort = " + permission.toPort unless permission.toPort.nil?
|
357
|
+
puts " ipPermissions:sourceSecurityGroupName = " + permission.groups.item.first.groupName unless permission.groups.nil?
|
358
|
+
puts " ipPermissions:sourceSecurityGroupOwnerId = " + permission.groups.item.first.userId unless permission.groups.nil?
|
359
|
+
|
360
|
+
unless permission.ipRanges.nil?
|
361
|
+
permission.ipRanges.item.each do |range|
|
362
|
+
puts " ipRanges:cidrIp = " + range.cidrIp unless range.cidrIp.nil?
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
puts ""
|
370
|
+
end
|
371
|
+
rescue Exception => e
|
372
|
+
puts "The attempt to show your security groups failed with error : " + e
|
373
|
+
raise e
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
|
378
|
+
desc <<-DESC
|
379
|
+
Delete a security group.
|
380
|
+
Delete a security group specifying:
|
381
|
+
- :group_name or GROUP_NAME (defaults to application name)
|
382
|
+
DESC
|
383
|
+
task :delete do
|
384
|
+
begin
|
385
|
+
capsize_ec2.delete_security_group()
|
386
|
+
puts "The security group \"#{capsize.get(:group_name)}\" has been deleted."
|
387
|
+
rescue Exception => e
|
388
|
+
puts "The attempt to delete security group \"#{capsize.get(:group_name)}\" failed with the error : " + e
|
389
|
+
raise e
|
390
|
+
end
|
391
|
+
|
392
|
+
end
|
393
|
+
|
394
|
+
|
395
|
+
desc <<-DESC
|
396
|
+
Authorize firewall ingress for the specified GROUP_NAME and FROM_PORT.
|
397
|
+
This calls authorize_ingress for the group defined in the :group_name variable
|
398
|
+
and the port specified in :from_port and :to_port. Any instances that were started and set to
|
399
|
+
use the security group :group_name will be affected as soon as possible. You can
|
400
|
+
specify a port range, instead of a single port if both FROM_PORT and TO_PORT are passed in.
|
401
|
+
DESC
|
402
|
+
task :authorize_ingress do
|
403
|
+
|
404
|
+
begin
|
405
|
+
capsize_ec2.authorize_ingress({:group_name => capsize.get(:group_name), :from_port => capsize.get(:from_port), :to_port => capsize.get(:to_port)})
|
406
|
+
puts "Firewall ingress granted"
|
407
|
+
rescue EC2::InvalidPermissionDuplicate => e
|
408
|
+
puts "The firewall ingress rule you specified for group name \"#{capsize.get(:group_name)}\" was already set (EC2::InvalidPermissionDuplicate)."
|
409
|
+
# Don't re-raise this exception
|
410
|
+
rescue Exception => e
|
411
|
+
puts "The attempt to allow firewall ingress for security group \"#{capsize.get(:group_name)}\" failed with the error : " + e
|
412
|
+
raise e
|
413
|
+
end
|
414
|
+
|
415
|
+
end
|
416
|
+
|
417
|
+
|
418
|
+
desc <<-DESC
|
419
|
+
Create security group and open web ports.
|
420
|
+
Will create a new group which is named by default the same as your application.
|
421
|
+
Will also authorize firewall ingress for the specified GROUP_NAME on standard web ports:
|
422
|
+
- 22 (SSH)
|
423
|
+
- 80 (HTTP)
|
424
|
+
- 443 (HTTPS)
|
425
|
+
By default the group name created is the same as your :application name
|
426
|
+
in deploy.rb. You can override the group name used by setting
|
427
|
+
:group_name or by passing in the environment variable GROUP_NAME=''
|
428
|
+
on the cap command line. Any instances that were started and set
|
429
|
+
to use the security group GROUP_NAME will be affected as soon as possible.
|
430
|
+
DESC
|
431
|
+
task :create_with_standard_ports do
|
432
|
+
|
433
|
+
begin
|
434
|
+
capsize_ec2.create_security_group()
|
435
|
+
puts "The security group \"#{capsize.get(:group_name)}\" has been created."
|
436
|
+
rescue EC2::InvalidGroupDuplicate => e
|
437
|
+
puts "The security group you specified for group name \"#{capsize.get(:group_name)}\" already exists (EC2::InvalidGroupDuplicate)."
|
438
|
+
# Don't re-raise this exception
|
439
|
+
rescue Exception => e
|
440
|
+
puts "The attempt to create security group \"#{capsize.get(:group_name)}\" failed with the error : " + e
|
441
|
+
raise e
|
442
|
+
end
|
443
|
+
|
444
|
+
ports = [22, 80, 443]
|
445
|
+
ports.each { |port|
|
446
|
+
begin
|
447
|
+
capsize_ec2.authorize_ingress({:group_name => capsize.get(:group_name), :from_port => "#{port}", :to_port => "#{port}"})
|
448
|
+
puts "Firewall ingress granted for #{capsize.get(:group_name)} on port #{port}"
|
449
|
+
rescue EC2::InvalidPermissionDuplicate => e
|
450
|
+
puts "The firewall ingress rule you specified for group name \"#{capsize.get(:group_name)}\" on port #{port} was already set (EC2::InvalidPermissionDuplicate)."
|
451
|
+
# Don't re-raise this exception
|
452
|
+
rescue Exception => e
|
453
|
+
puts "The attempt to allow firewall ingress on port #{port} for security group \"#{capsize.get(:group_name)}\" failed with the error : " + e
|
454
|
+
raise e
|
455
|
+
end
|
456
|
+
}
|
457
|
+
|
458
|
+
end
|
459
|
+
|
460
|
+
desc <<-DESC
|
461
|
+
Revoke firewall ingress for the specified GROUP_NAME and FROM_PORT.
|
462
|
+
This calls revoke_ingress for the group defined in the :group_name variable
|
463
|
+
and the port specified in :from_port and :to_port. Any instances that were started and set to
|
464
|
+
use the security group :group_name will be affected as soon as possible. You can
|
465
|
+
specify a port range, instead of a single port if both FROM_PORT and TO_PORT are passed in.
|
466
|
+
DESC
|
467
|
+
task :revoke_ingress do
|
468
|
+
|
469
|
+
begin
|
470
|
+
capsize_ec2.revoke_ingress({:group_name => capsize.get(:group_name), :from_port => capsize.get(:from_port), :to_port => capsize.get(:to_port)})
|
471
|
+
puts "Firewall ingress revoked for #{capsize.get(:group_name)}"
|
472
|
+
rescue Exception => e
|
473
|
+
puts "The attempt to revoke firewall ingress permissions for security group \"#{capsize.get(:group_name)}\" failed with the error : " + e
|
474
|
+
raise e
|
475
|
+
end
|
476
|
+
|
477
|
+
end
|
478
|
+
|
479
|
+
end
|
480
|
+
|
481
|
+
|
482
|
+
# IMAGE TASKS
|
483
|
+
#########################################
|
484
|
+
|
485
|
+
namespace :images do
|
486
|
+
|
487
|
+
desc <<-DESC
|
488
|
+
Show and describe machine images you can execute.
|
489
|
+
Will show all machine images you have permission to execute by default.
|
490
|
+
You can limit by passing in:
|
491
|
+
OWNER_ID='self', OWNER_ID='amazon', OWNER_ID='__SOME_OWNER_ID__'
|
492
|
+
EXECUTABLE_BY='__SOME_OWNER_ID__'
|
493
|
+
IMAGE_ID='__SOME_IMAGE_ID__'
|
494
|
+
DESC
|
495
|
+
task :show do
|
496
|
+
begin
|
497
|
+
capsize_ec2.describe_images().imagesSet.item.each do |item|
|
498
|
+
puts "imageId = " + item.imageId unless item.imageId.nil?
|
499
|
+
puts "imageLocation = " + item.imageLocation unless item.imageLocation.nil?
|
500
|
+
puts "imageOwnerId = " + item.imageOwnerId unless item.imageOwnerId.nil?
|
501
|
+
puts "imageState = " + item.imageState unless item.imageState.nil?
|
502
|
+
puts "isPublic = " + item.isPublic unless item.isPublic.nil?
|
503
|
+
puts ""
|
504
|
+
end
|
505
|
+
rescue Exception => e
|
506
|
+
puts "The attempt to show images failed with error : " + e
|
507
|
+
raise e
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
end
|
512
|
+
|
513
|
+
|
514
|
+
# ELASTIC IP (ADDRESSES) TASKS
|
515
|
+
#########################################
|
516
|
+
|
517
|
+
namespace :addresses do
|
518
|
+
|
519
|
+
desc <<-DESC
|
520
|
+
Show and describe elastic IP addresses assigned to your account.
|
521
|
+
DESC
|
522
|
+
task :show do
|
523
|
+
begin
|
524
|
+
result = capsize_ec2.describe_addresses()
|
525
|
+
rescue Exception => e
|
526
|
+
puts "The attempt to show elastic IP addresses failed with error : " + e
|
527
|
+
raise e
|
528
|
+
end
|
529
|
+
|
530
|
+
capsize_ec2.print_address_description(result)
|
531
|
+
end
|
532
|
+
|
533
|
+
desc <<-DESC
|
534
|
+
Acquire a new elastic IP address for use with your account.
|
535
|
+
DESC
|
536
|
+
task :allocate do
|
537
|
+
begin
|
538
|
+
print "Allocating elastic IP address ... "
|
539
|
+
$stdout.flush
|
540
|
+
response = capsize_ec2.allocate_address()
|
541
|
+
puts "success"
|
542
|
+
puts "Allocated address: #{response.publicIp}"
|
543
|
+
puts ""
|
544
|
+
rescue Exception => e
|
545
|
+
puts "failed"
|
546
|
+
puts "The attempt to allocate an elastic IP addresses failed with error : " + e
|
547
|
+
raise e
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
551
|
+
desc <<-DESC
|
552
|
+
Release an elastic IP from your account.
|
553
|
+
You can release a specific elastic IP by doing one of the following:
|
554
|
+
- define a :public_ip in deploy.rb with "set :public_ip, '123.1.2.3'"
|
555
|
+
- Override this on the command line with "cap ec2:addresses:release PUBLIC_IP='123.1.2.3'"
|
556
|
+
DESC
|
557
|
+
task :release do
|
558
|
+
|
559
|
+
capsize.get(:public_ip)
|
560
|
+
|
561
|
+
case public_ip
|
562
|
+
when nil, ""
|
563
|
+
puts "You don't seem to have set a public_ip ..."
|
564
|
+
else
|
565
|
+
confirm = (Capistrano::CLI.ui.ask("WARNING! Really release elastic IP address \"#{public_ip}\"? (y/N): ").downcase == 'y')
|
566
|
+
if confirm
|
567
|
+
begin
|
568
|
+
response = capsize_ec2.release_address({:public_ip => public_ip})
|
569
|
+
puts "The request to release elastic IP address #{public_ip} has been accepted. Monitor the status of the request with 'cap ec2:addresses:show'"
|
570
|
+
rescue Exception => e
|
571
|
+
puts "The attempt to release the elastic IP address failed with error : " + e
|
572
|
+
raise e
|
573
|
+
end
|
574
|
+
else
|
575
|
+
puts "Your address release request has been cancelled."
|
576
|
+
end
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
|
581
|
+
desc <<-DESC
|
582
|
+
Associate an elastic IP address with an instance.
|
583
|
+
If the IP address is currently assigned to another instance, the IP address
|
584
|
+
is assigned to the new instance.
|
585
|
+
|
586
|
+
You must supply both a public_ip (this is the elastic IP address you want to assign)
|
587
|
+
and an instance_id (this is the instance to which you want to assign the address)
|
588
|
+
|
589
|
+
You can associate an elastic IP with an instance by doing one of the following:
|
590
|
+
- Define these variables in deploy.rb with "set :public_ip, '123.1.2.3'; set :instance_id, 'i-12312312';"
|
591
|
+
- Override this on the command line with "cap ec2:addresses:associate PUBLIC_IP='123.1.2.3' INSTANCE_ID='i-12312312'"
|
592
|
+
- A combination of the above.
|
593
|
+
DESC
|
594
|
+
task :associate do
|
595
|
+
|
596
|
+
capsize.get(:public_ip)
|
597
|
+
capsize.get(:instance_id)
|
598
|
+
|
599
|
+
if !public_ip || public_ip == ''
|
600
|
+
puts "You don't seem to have set a public_ip ..."
|
601
|
+
elsif !instance_id || instance_id == ''
|
602
|
+
puts "You don't seem to have set an instance_id ..."
|
603
|
+
else
|
604
|
+
#TODO: check if this IP is already assigned to another instance and make
|
605
|
+
# the user confirm the new association if that's the case
|
606
|
+
begin
|
607
|
+
response = capsize_ec2.associate_address(:public_ip => public_ip, :instance_id => instance_id)
|
608
|
+
puts "The elastic IP address #{public_ip} has been associated with " +
|
609
|
+
"instance #{instance_id}."
|
610
|
+
puts "** It may take several minutes for this mapping to take effect."
|
611
|
+
rescue Exception => e
|
612
|
+
puts "The attempt to associate the elastic IP address failed with error : " + e
|
613
|
+
raise e
|
614
|
+
end
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
|
619
|
+
desc <<-DESC
|
620
|
+
Disassociates the specified elastic IP from whatever instance it's
|
621
|
+
currently associated with
|
622
|
+
|
623
|
+
You can disassociate a specific elastic IP by doing one of the following:
|
624
|
+
- define a :public_ip in deploy.rb with "set :public_ip, '123.1.2.3'"
|
625
|
+
- Override this on the command line with "cap ec2:addresses:disassociate PUBLIC_IP='123.1.2.3'"
|
626
|
+
- If neither of these are provided you will be prompted by Capistano for the IP you wish to disassociate.
|
627
|
+
DESC
|
628
|
+
task :disassociate do
|
629
|
+
|
630
|
+
capsize.get(:public_ip)
|
631
|
+
|
632
|
+
case public_ip
|
633
|
+
when nil, ""
|
634
|
+
puts "You don't seem to have set a public_ip ..."
|
635
|
+
else
|
636
|
+
confirm = (Capistrano::CLI.ui.ask("WARNING! Really disassociate elastic IP address \"#{public_ip}\"? (y/N): ").downcase == 'y')
|
637
|
+
if confirm
|
638
|
+
begin
|
639
|
+
response = capsize_ec2.disassociate_address({:public_ip => public_ip})
|
640
|
+
puts "The elastic IP address #{public_ip} has been disassociated."
|
641
|
+
rescue Exception => e
|
642
|
+
puts "The attempt to disassociate the elastic IP address failed with error : " + e
|
643
|
+
raise e
|
644
|
+
end
|
645
|
+
else
|
646
|
+
puts "Your address disassociation request has been cancelled."
|
647
|
+
end
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
end # end namespace :addresses
|
652
|
+
|
653
|
+
end # end namespace :ec2
|
654
|
+
end # end Capistrano::Configuration.instance.load
|