wasp 0.2.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.
- data/Gemfile +5 -0
- data/LICENSE +20 -0
- data/README.md +77 -0
- data/Rakefile +15 -0
- data/bin/wasp +6 -0
- data/config/aws.yml +4 -0
- data/lib/wasp.rb +14 -0
- data/lib/wasp/config.rb +11 -0
- data/lib/wasp/const.rb +21 -0
- data/lib/wasp/core_ext.rb +113 -0
- data/lib/wasp/ec2.rb +355 -0
- data/lib/wasp/nest.rb +321 -0
- data/lib/wasp/queenwasp.rb +7 -0
- data/lib/wasp/stingab.rb +355 -0
- data/lib/wasp/wasp.rb +514 -0
- data/report/makeplot.rb +131 -0
- data/test/test_wasp.rb +9 -0
- data/wasp.gemspec +38 -0
- metadata +112 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Ji-Hun Seol
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
WaspswithRainofStings
|
2
|
+
====================
|
3
|
+
|
4
|
+
By arkemiq (arkemiq@gmail.com)
|
5
|
+
|
6
|
+
Description
|
7
|
+
-----------
|
8
|
+
|
9
|
+
Wasp is a distributed heavy load generator in Ruby inspired by beeswithmachineguns(https://github.com/newsapps/beeswithmachineguns).
|
10
|
+
|
11
|
+
This is a utility of arming(create and install load program) many wasps (micro EC2 instances)
|
12
|
+
from multiple regions(EC2 zones) to attack (load test) targets(web applications).
|
13
|
+
|
14
|
+
Installation
|
15
|
+
------------
|
16
|
+
|
17
|
+
$ git clone https://github.com/arkemiq/wasp.git
|
18
|
+
$ cd wasp
|
19
|
+
$ bundle install
|
20
|
+
|
21
|
+
Configuring EC2 credentials
|
22
|
+
---------------------------
|
23
|
+
|
24
|
+
Wasps uses aws-sdk gem to communicate with EC2 and supports all the same methods of storing credentials that it does.
|
25
|
+
Set access key and secret key for config/aws.yml to access your EC2 account.
|
26
|
+
|
27
|
+
access_key_id: xxxxxxxxxxxxxxxxx
|
28
|
+
secret_access_key: xxxxxxxxxxxxxxxxx
|
29
|
+
|
30
|
+
Running
|
31
|
+
-------
|
32
|
+
|
33
|
+
Usage:
|
34
|
+
|
35
|
+
To set credentials:
|
36
|
+
$ wasp set [AWS Credential file]
|
37
|
+
|
38
|
+
To launch 6 wasps:
|
39
|
+
- launch 6 instances in us-east zone with private key named wasps
|
40
|
+
$ wasp up -k wasps -s 6
|
41
|
+
|
42
|
+
- launch 5 instances in us-west-2 zone with ami-8cb33ebc AMI, username ubuntu and private key named wasps
|
43
|
+
$ wasp up -k wasps -z us-west-2 -a ami-8cb33ebc -s 5 -l ubuntu
|
44
|
+
|
45
|
+
To check status:
|
46
|
+
$ wasp status
|
47
|
+
|
48
|
+
To equip weapon(default: apachebench):
|
49
|
+
$ wasp equip
|
50
|
+
|
51
|
+
To attack target with 1000 requests and 100 concurrent users per each wasp:
|
52
|
+
$ wasp attack -n 1000 -c 100 -u http://target_site
|
53
|
+
|
54
|
+
To attack target with incrementally increase wasps from 1 to 10000 during 60 seconds:
|
55
|
+
$ wasp rattack -p 10000:60 -u http://target_site
|
56
|
+
|
57
|
+
To sleep wasps:
|
58
|
+
$ wasp down
|
59
|
+
|
60
|
+
To see options:
|
61
|
+
$ wasp help
|
62
|
+
|
63
|
+
*Note*: the default EC2 security group is called 'wasps' and by default it locks out SSH access.
|
64
|
+
|
65
|
+
*Note*: if you didn't specify a zone for EC2 instances, it use default zone 'us-east'.
|
66
|
+
|
67
|
+
*Please remember to do this*--we aren't responsible for your EC2 bills.
|
68
|
+
|
69
|
+
Notice! (PLEASE READ)
|
70
|
+
---------------------
|
71
|
+
If you decide to use the Wasps, please keep in mind the following important notice: they are, more-or-less a distributed denial-of-service attack in a fancy package and, therefore, if you point them at any server you don’t own you will behaving *unethically*, have your Amazon Web Services account *locked-out*, and be *liable* in a court of law for any downtime you cause.
|
72
|
+
|
73
|
+
You have waspn warned.
|
74
|
+
|
75
|
+
License
|
76
|
+
-------
|
77
|
+
MIT.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
|
3
|
+
desc "Run rspec"
|
4
|
+
task :spec do
|
5
|
+
sh('bundle install')
|
6
|
+
require "rspec/core/rake_task"
|
7
|
+
RSpec::Core::RakeTask.new do |t|
|
8
|
+
t.rspec_opts = %w(-fs -c)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
task :default => :spec
|
12
|
+
|
13
|
+
Rake::TestTask.new do |t|
|
14
|
+
t.libs << 'test'
|
15
|
+
end
|
data/bin/wasp
ADDED
data/config/aws.yml
ADDED
data/lib/wasp.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
ROOT = File.expand_path(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
module WASP
|
4
|
+
autoload :Const, "#{ROOT}/wasp/const"
|
5
|
+
autoload :Wasp, "#{ROOT}/wasp/wasp"
|
6
|
+
autoload :QueenWasp, "#{ROOT}/wasp/queenwasp"
|
7
|
+
autoload :Nest, "#{ROOT}/wasp/nest"
|
8
|
+
autoload :Aws, "#{ROOT}/wasp/ec2"
|
9
|
+
autoload :Config, "#{ROOT}/wasp/config"
|
10
|
+
autoload :WeaponAB, "#{ROOT}/wasp/stingab"
|
11
|
+
end
|
12
|
+
|
13
|
+
require "#{ROOT}/wasp/core_ext"
|
14
|
+
require 'fileutils'
|
data/lib/wasp/config.rb
ADDED
data/lib/wasp/const.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module WASP
|
2
|
+
module Const
|
3
|
+
VERSION = '0.2.0'
|
4
|
+
|
5
|
+
DEFAULT_WASPS = 5
|
6
|
+
DEFAULT_GROUP = 'wasps'
|
7
|
+
DEFAULT_ZONE = 'us-east-1'
|
8
|
+
DEFAULT_AMI = 'ami-baba68d3'
|
9
|
+
DEFAULT_USER = 'ubuntu'
|
10
|
+
DEFAULT_KEY = 'wasp'
|
11
|
+
DEFAULT_NUMBER_OF_REQUESTS = 1000
|
12
|
+
DEFAULT_TIME = 10
|
13
|
+
DEFAULT_CONCURRENT_OF_CONNECTIONS = 100
|
14
|
+
DEFAULT_WEAPON = 'ab'
|
15
|
+
SSH_PORT = 22
|
16
|
+
NATS_PORT = 4222
|
17
|
+
DEFAULT_MAXIMUM_STINGS = 10000
|
18
|
+
DEFAULT_WAVE_TIME = 10
|
19
|
+
DEFAULT_COOLDOWN = 10
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module WASPExtensions
|
2
|
+
|
3
|
+
def say(message)
|
4
|
+
WASP::Config.output.puts(message) if WASP::Config.output
|
5
|
+
end
|
6
|
+
|
7
|
+
def header(message, filler = '-')
|
8
|
+
say "\n"
|
9
|
+
say message
|
10
|
+
say filler.to_s * message.size
|
11
|
+
end
|
12
|
+
|
13
|
+
def banner(message)
|
14
|
+
say "\n"
|
15
|
+
say message
|
16
|
+
end
|
17
|
+
|
18
|
+
def display(message, nl=true)
|
19
|
+
if nl
|
20
|
+
say message
|
21
|
+
else
|
22
|
+
if WASP::Config.output
|
23
|
+
WASP::Config.output.print(message)
|
24
|
+
WASP::Config.output.flush
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear(size=80)
|
30
|
+
return unless WASP::Config.output
|
31
|
+
WASP::Config.output.print("\r")
|
32
|
+
WASP::Config.output.print(" " * size)
|
33
|
+
WASP::Config.output.print("\r")
|
34
|
+
#WASP::Config.output.flush
|
35
|
+
end
|
36
|
+
|
37
|
+
def err(message, prefix='Error: ')
|
38
|
+
raise WASP::CliExit, "#{prefix}#{message}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def quit(message = nil)
|
42
|
+
raise WASP::GracefulExit, message
|
43
|
+
end
|
44
|
+
|
45
|
+
def blank?
|
46
|
+
self.to_s.blank?
|
47
|
+
end
|
48
|
+
|
49
|
+
def uptime_string(delta)
|
50
|
+
num_seconds = delta.to_i
|
51
|
+
days = num_seconds / (60 * 60 * 24);
|
52
|
+
num_seconds -= days * (60 * 60 * 24);
|
53
|
+
hours = num_seconds / (60 * 60);
|
54
|
+
num_seconds -= hours * (60 * 60);
|
55
|
+
minutes = num_seconds / 60;
|
56
|
+
num_seconds -= minutes * 60;
|
57
|
+
"#{days}d:#{hours}h:#{minutes}m:#{num_seconds}s"
|
58
|
+
end
|
59
|
+
|
60
|
+
def pretty_size(size, prec=1)
|
61
|
+
return 'NA' unless size
|
62
|
+
return "#{size}B" if size < 1024
|
63
|
+
return sprintf("%.#{prec}fK", size/1024.0) if size < (1024*1024)
|
64
|
+
return sprintf("%.#{prec}fM", size/(1024.0*1024.0)) if size < (1024*1024*1024)
|
65
|
+
return sprintf("%.#{prec}fG", size/(1024.0*1024.0*1024.0))
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
module StringExtensions
|
71
|
+
def red
|
72
|
+
colorize("\e[0m\e[31m")
|
73
|
+
end
|
74
|
+
|
75
|
+
def green
|
76
|
+
colorize("\e[0m\e[32m")
|
77
|
+
end
|
78
|
+
|
79
|
+
def yellow
|
80
|
+
colorize("\e[0m\e[33m")
|
81
|
+
end
|
82
|
+
|
83
|
+
def bold
|
84
|
+
colorize("\e[0m\e[1m")
|
85
|
+
end
|
86
|
+
|
87
|
+
def colorize(color_code)
|
88
|
+
"#{color_code}#{self}\e[0m"
|
89
|
+
end
|
90
|
+
|
91
|
+
def blank?
|
92
|
+
self =~ /^\s*$/
|
93
|
+
end
|
94
|
+
|
95
|
+
def truncate(limit = 30)
|
96
|
+
return "" if self.blank?
|
97
|
+
etc = "..."
|
98
|
+
stripped = self.strip[0..limit]
|
99
|
+
if stripped.length > limit
|
100
|
+
stripped.gsub(/\s+?(\S+)?$/, "") + etc
|
101
|
+
else
|
102
|
+
stripped
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class Object
|
108
|
+
include WASPExtensions
|
109
|
+
end
|
110
|
+
|
111
|
+
class String
|
112
|
+
include StringExtensions
|
113
|
+
end
|
data/lib/wasp/ec2.rb
ADDED
@@ -0,0 +1,355 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
|
3
|
+
module WASP
|
4
|
+
class Aws
|
5
|
+
attr_reader :config_path
|
6
|
+
attr_reader :ec2
|
7
|
+
attr_reader :group
|
8
|
+
attr_reader :key
|
9
|
+
attr_reader :instances
|
10
|
+
attr_reader :regions
|
11
|
+
attr_reader :instance_list
|
12
|
+
attr_reader :threads
|
13
|
+
attr_reader :login
|
14
|
+
|
15
|
+
SLEEP_TIME = 1
|
16
|
+
LINE_LENGTH = 100
|
17
|
+
|
18
|
+
def initialize (args)
|
19
|
+
config_path = ENV["HOME"] + "/.waspaws.yml"
|
20
|
+
begin
|
21
|
+
AWS.config(YAML.load(File.read(config_path)))
|
22
|
+
@ec2 = AWS::EC2.new
|
23
|
+
rescue => ex
|
24
|
+
puts "[WARN]".yellow + " #{ex.message}"
|
25
|
+
puts "[WARN]".yellow + " Please set AWS credential file."
|
26
|
+
exit false
|
27
|
+
end
|
28
|
+
|
29
|
+
# evaluate AWS access_key and secret_access_key
|
30
|
+
begin
|
31
|
+
print "EC2".green + " Checking access key validation.."
|
32
|
+
@ec2.availability_zones.each do |av|
|
33
|
+
av.name
|
34
|
+
end
|
35
|
+
puts " OK".green
|
36
|
+
rescue => ex
|
37
|
+
puts "[WARN]".yellow + " #{ex.message}"
|
38
|
+
puts "[WARN]".yellow + " Please copy/paste correct AWS access_key and secret_access_key to config/aws.yml file"
|
39
|
+
exit false
|
40
|
+
end
|
41
|
+
|
42
|
+
@num_wasps = if args[:server].nil? then WASP::Const::DEFAULT_WASPS
|
43
|
+
else
|
44
|
+
args[:server].to_i
|
45
|
+
end
|
46
|
+
@group = if args[:group].nil? then WASP::Const::DEFAULT_GROUP
|
47
|
+
else
|
48
|
+
args[:group]
|
49
|
+
end
|
50
|
+
@zone = if args[:zone].nil? then WASP::Const::DEFAULT_ZONE
|
51
|
+
else
|
52
|
+
args[:zone]
|
53
|
+
end
|
54
|
+
@ami = if args[:ami].nil? then get_default_ami(@zone)
|
55
|
+
else
|
56
|
+
args[:ami]
|
57
|
+
end
|
58
|
+
@login = if args[:login].nil? then WASP::Const::DEFAULT_USER
|
59
|
+
else
|
60
|
+
args[:login]
|
61
|
+
end
|
62
|
+
|
63
|
+
@key = args[:key]
|
64
|
+
|
65
|
+
|
66
|
+
@regions = @ec2.regions
|
67
|
+
@instance_list = []
|
68
|
+
@instances = nil
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_keypair
|
72
|
+
make_key = true
|
73
|
+
key = @regions[@zone].key_pairs.filter('key-name', @key + '-' + @zone).first
|
74
|
+
|
75
|
+
if key.nil? == false then
|
76
|
+
if not File.exists?("#{ENV['HOME']}/.ssh/#{@key}-#{@zone}.pem") then
|
77
|
+
key.delete
|
78
|
+
make_key = true
|
79
|
+
else
|
80
|
+
make_key = false
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if make_key then
|
85
|
+
key = @regions[@zone].key_pairs.create(@key + '-' + @zone)
|
86
|
+
keyfile = "#{ENV['HOME']}/.ssh/#{@key}-#{@zone}.pem"
|
87
|
+
begin
|
88
|
+
File.delete(keyfile) if File.exists?(keyfile)
|
89
|
+
File.open(keyfile, "w") do |f|
|
90
|
+
f.write(key.private_key)
|
91
|
+
end
|
92
|
+
File.chmod(0400, keyfile)
|
93
|
+
rescue => ex
|
94
|
+
print "[WARN]".yellow + " #{ex.message}"
|
95
|
+
exit false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
puts "EC2".green + " Private key is created in " + "~/.ssh/#{@key}-#{@zone}.pem".bold
|
100
|
+
end
|
101
|
+
|
102
|
+
def get_security_group
|
103
|
+
found = false
|
104
|
+
puts "EC2".green + " Look up existed security group [" + "#{@group}".bold + "].."
|
105
|
+
security_groups = @regions[@zone].security_groups
|
106
|
+
|
107
|
+
found = true if security_groups.filter('group-name', @group).first != nil
|
108
|
+
|
109
|
+
if not found then
|
110
|
+
puts "EC2".green + " Creating security group " + "#{@group}".bold + ".."
|
111
|
+
wasps = security_groups.create(@group)
|
112
|
+
puts "EC2".green + " Open inbound tcp port :#{WASP::Const::SSH_PORT}"
|
113
|
+
wasps.authorize_ingress(:tcp, WASP::Const::SSH_PORT)
|
114
|
+
puts "EC2".green + " Open inbound tcp port :#{WASP::Const::NATS_PORT}"
|
115
|
+
wasps.authorize_ingress(:tcp, WASP::Const::NATS_PORT)
|
116
|
+
puts "EC2".green + " Allow ping"
|
117
|
+
wasps.allow_ping
|
118
|
+
end
|
119
|
+
|
120
|
+
puts "EC2".green + " Security group [#{@group}] have set.."
|
121
|
+
end
|
122
|
+
|
123
|
+
def waiting_wasp (i)
|
124
|
+
banner = "EC2".green + " Launching wasps: "
|
125
|
+
|
126
|
+
display banner, false
|
127
|
+
while i.status == :pending do
|
128
|
+
print '.'
|
129
|
+
sleep SLEEP_TIME
|
130
|
+
end
|
131
|
+
|
132
|
+
if i.status == :running then
|
133
|
+
clear(LINE_LENGTH)
|
134
|
+
display "#{banner}#{'OK'.green}"
|
135
|
+
@instance_list.push(i.id)
|
136
|
+
puts "Wasp " + "#{i.id}".yellow + " is ready to attack"
|
137
|
+
i.tags.Name = 'a wasp!'
|
138
|
+
else
|
139
|
+
puts "EC2".green + " #{i.id} is going to wrong place"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def create
|
144
|
+
puts "EC2".green + " #{@num_wasps} wasps will be launched.."
|
145
|
+
|
146
|
+
begin
|
147
|
+
@instances = @ec2.regions[@zone].instances.create(:image_id=>@ami,
|
148
|
+
:security_groups=>[@group],
|
149
|
+
:key_name=>@key + '-' + @zone,
|
150
|
+
:instance_type=>'t1.micro',
|
151
|
+
:count=>@num_wasps)
|
152
|
+
num_wasps = 0
|
153
|
+
rescue => ex
|
154
|
+
puts "[WARN]".yellow + " #{ex.message}"
|
155
|
+
return false
|
156
|
+
end
|
157
|
+
if @instances.class == Array then
|
158
|
+
@instances.each do |i|
|
159
|
+
waiting_wasp(i)
|
160
|
+
end
|
161
|
+
num_wasps = @instances.count
|
162
|
+
else
|
163
|
+
waiting_wasp(@instances)
|
164
|
+
num_wasps = 1
|
165
|
+
end
|
166
|
+
|
167
|
+
_write_to_file
|
168
|
+
|
169
|
+
puts "The swarm has assembled " + "#{num_wasps}".yellow + " wasps.\n"
|
170
|
+
true
|
171
|
+
end
|
172
|
+
|
173
|
+
def _get_instances
|
174
|
+
status_of_wasps = {}
|
175
|
+
if @instance_list.count == 0 then
|
176
|
+
begin
|
177
|
+
File.open("#{ENV["HOME"]}/.nest", "r") do |file|
|
178
|
+
lines = file.readlines
|
179
|
+
lines.each do |line|
|
180
|
+
instance, key, zone, login = line.split(' ')
|
181
|
+
|
182
|
+
if status_of_wasps[zone].nil? then
|
183
|
+
status_of_wasps[zone] = {}
|
184
|
+
status_of_wasps[zone][:instances] = []
|
185
|
+
status_of_wasps[zone][:instances].push(instance)
|
186
|
+
status_of_wasps[zone][:login] = login
|
187
|
+
else
|
188
|
+
status_of_wasps[zone][:instances].push(instance)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
rescue => ex
|
193
|
+
puts "There is no wasps in the air."
|
194
|
+
|
195
|
+
return nil
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
return status_of_wasps
|
200
|
+
end
|
201
|
+
|
202
|
+
def _write_to_file
|
203
|
+
begin
|
204
|
+
File.open("#{ENV["HOME"]}/.nest", "a+") do |file|
|
205
|
+
if @instances.class == Array then
|
206
|
+
@instances.each do |i|
|
207
|
+
file.puts("#{i.id} #{i.key_name} #{i.availability_zone} #{@login}\n")
|
208
|
+
end
|
209
|
+
else
|
210
|
+
file.puts("#{@instances.id} #{@instances.key_name} #{@instances.availability_zone} #{@login}\n")
|
211
|
+
end
|
212
|
+
end
|
213
|
+
rescue => ex
|
214
|
+
puts "[WARN]".yellow + " #{ex.message}"
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def _delete_file
|
219
|
+
begin
|
220
|
+
File.delete("#{ENV["HOME"]}/.nest")
|
221
|
+
rescue => ex
|
222
|
+
puts "[WARN]".yellow + "#{ex.message}"
|
223
|
+
puts "There is no wasps in the air."
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def terminate
|
228
|
+
count = 0
|
229
|
+
|
230
|
+
#if @instances.nil? then
|
231
|
+
ins = _get_instances
|
232
|
+
|
233
|
+
return nil if ins.nil?
|
234
|
+
|
235
|
+
|
236
|
+
ins.each do |region, info|
|
237
|
+
r = get_ec2_zone(region)
|
238
|
+
info[:instances].each do |i|
|
239
|
+
count += 1
|
240
|
+
puts "Wasp" + " #{i}".yellow + " from #{region} is going home"
|
241
|
+
begin
|
242
|
+
@ec2.regions[r].instances[i].terminate
|
243
|
+
rescue => e
|
244
|
+
puts "#{e.message}"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
_delete_file
|
250
|
+
|
251
|
+
puts "EC2".green + " Stood down #{count} wasps.\n"
|
252
|
+
end
|
253
|
+
|
254
|
+
def get_wasps
|
255
|
+
wasps = []
|
256
|
+
ins = _get_instances
|
257
|
+
|
258
|
+
return nil if ins.nil?
|
259
|
+
|
260
|
+
count = ins.count
|
261
|
+
ins.each do |region, info|
|
262
|
+
r = get_ec2_zone(region)
|
263
|
+
login = info[:login]
|
264
|
+
info[:instances].each do |it|
|
265
|
+
i = @ec2.regions[r].instances[it]
|
266
|
+
|
267
|
+
wasps.push({:instance_id => i.id,
|
268
|
+
:instance_name => i.dns_name,
|
269
|
+
:region => region,
|
270
|
+
:login => login,
|
271
|
+
:key_name => i.key_pair.name,
|
272
|
+
:report => nil,
|
273
|
+
:wavereport => nil})
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
wasps
|
278
|
+
end
|
279
|
+
|
280
|
+
def status
|
281
|
+
return ins = _get_instances
|
282
|
+
end
|
283
|
+
|
284
|
+
def get_wasp_status(zone=WASP::Const::DEFAULT_ZONE , id)
|
285
|
+
begin
|
286
|
+
z = get_ec2_zone(zone)
|
287
|
+
@ec2.regions[z].instances[id].status
|
288
|
+
rescue => ex
|
289
|
+
puts "[WARN]".yellow + " #{ex.message}"
|
290
|
+
return nil
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def get_wasp_domain(zone=WASP::Const::DEFAULT_ZONE , id)
|
295
|
+
begin
|
296
|
+
z = get_ec2_zone(zone)
|
297
|
+
@ec2.regions[z].instances[id].dns_name
|
298
|
+
rescue => ex
|
299
|
+
puts "[WARN]".yellow + " #{ex.message}"
|
300
|
+
return nil
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def get_ec2_zone(zone)
|
305
|
+
case
|
306
|
+
when zone.match(/eu-west-1/)
|
307
|
+
"eu-west-1"
|
308
|
+
when zone.match(/sa-east-1/)
|
309
|
+
"sa-east-1"
|
310
|
+
when zone.match(/us-west-1/)
|
311
|
+
"us-west-1"
|
312
|
+
when zone.match(/us-west-2/)
|
313
|
+
"us-west-2"
|
314
|
+
when zone.match(/ap-northeast-1/)
|
315
|
+
"ap-northeast-1"
|
316
|
+
when zone.match(/us-east-1/)
|
317
|
+
"us-east-1"
|
318
|
+
when zone.match(/ap-southeast-1/)
|
319
|
+
"ap-southeast-1"
|
320
|
+
else
|
321
|
+
"us-east-1"
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def get_default_ami(zone)
|
326
|
+
case
|
327
|
+
when zone.match(/eu-west-1/)
|
328
|
+
"ami-895069fd"
|
329
|
+
when zone.match(/sa-east-1/)
|
330
|
+
"ami-b673acab"
|
331
|
+
when zone.match(/us-west-1/)
|
332
|
+
"ami-6da8f128"
|
333
|
+
when zone.match(/us-west-2/)
|
334
|
+
"ami-ae05889e"
|
335
|
+
when zone.match(/ap-northeast-1/)
|
336
|
+
"ami-10299f11"
|
337
|
+
when zone.match(/us-east-1/)
|
338
|
+
"ami-baba68d3"
|
339
|
+
when zone.match(/ap-southeast-1/)
|
340
|
+
"ami-4296d210"
|
341
|
+
else
|
342
|
+
"ami-baba68d3"
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
def get_regions
|
347
|
+
regions = []
|
348
|
+
@ec2.regions.each do |r|
|
349
|
+
regions.push(r.name)
|
350
|
+
end
|
351
|
+
|
352
|
+
regions
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|