gaptool-server 0.6.6 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/gaptool-server +1 -1
- data/bin/gaptool_server_migrate_0.6-0.7 +35 -0
- data/lib/helpers/data.rb +23 -16
- data/lib/helpers/ec2.rb +42 -9
- data/lib/helpers/rehash.rb +4 -2
- data/lib/routes.rb +47 -12
- data/tasks/app.rb +24 -7
- data/tasks/docker.rb +6 -6
- data/tasks/ec2.rb +6 -0
- data/tasks/role.rb +1 -1
- data/test/api_test.rb +113 -6
- data/test/data_test.rb +9 -9
- metadata +22 -8
- data/bin/gaptool_migrate_security_groups +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bdd9381a7a9adcc78aed7919ba4cdc36c718f93
|
4
|
+
data.tar.gz: 9d716274f9ab9c02a9c0c62e27d011d6b381029c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07863c41b56f69c29b9915deb3db26aa03a89965c48a63cf71196a0545646d2ea994e61d03b789011382bdb23da37d157e055e9ac20358a052be250f9aa37531
|
7
|
+
data.tar.gz: 2e3f46dc0f16ff83aab782e97a50b938c83f7b736c7a7fa38e30bb9d74755bbd6662a9b101a17766a28af9b25d5064214d1dd6b67aa516becdffcfdc3a2c6380
|
data/Rakefile
CHANGED
@@ -32,7 +32,7 @@ unless File.exists?('/.dockerenv')
|
|
32
32
|
|
33
33
|
desc "Start the HTTP server"
|
34
34
|
task :server do
|
35
|
-
exec "
|
35
|
+
exec "puma -p 3000 --preload -t 8:32 -w 3 #{Shellwords.join(ARGV[1..-1])}"
|
36
36
|
end
|
37
37
|
|
38
38
|
desc "Bump the version"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.0
|
data/bin/gaptool-server
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Convert all apps for new data format
|
4
|
+
|
5
|
+
libpath = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
6
|
+
$:.unshift(libpath)
|
7
|
+
require "#{libpath}/helpers/redis"
|
8
|
+
require "#{libpath}/helpers/data"
|
9
|
+
DH = Gaptool::Data
|
10
|
+
|
11
|
+
# - $redis.sadd("role:#{role}:apps", name)
|
12
|
+
# - $redis.set("app:#{name}", role)
|
13
|
+
# + $redis.sadd("apps:#{environment}", name)
|
14
|
+
# + $redis.sadd("role:#{role}:#{environment}:apps", name)
|
15
|
+
# + $redis.hset("app:#{name}", environment, role)
|
16
|
+
# - role = $redis.get(key)
|
17
|
+
# + roles = $redis.hgetall(key)
|
18
|
+
# - role = $redis.get("app:#{app}")
|
19
|
+
# + return $redis.hgetall("app:#{app}")
|
20
|
+
# - $redis.smembers("role:#{role}:apps")
|
21
|
+
# + $redis.smembers("apps:#{environment}")
|
22
|
+
# + $redis.smembers("role:#{role}:#{environment}:apps")
|
23
|
+
|
24
|
+
puts 'Removing role:*:apps'
|
25
|
+
$redis.keys("role:*:apps").each {|k| $redis.del(k)}
|
26
|
+
puts "Migrating apps"
|
27
|
+
$redis.keys("app:*").each do |key|
|
28
|
+
app = key.sub(/app:/, "")
|
29
|
+
puts " * app: #{app} (#{key})"
|
30
|
+
role = $redis.get(key)
|
31
|
+
$redis.del("app:#{app}")
|
32
|
+
%w(staging production).each do |env|
|
33
|
+
DH.add_app(app, role, env)
|
34
|
+
end
|
35
|
+
end
|
data/lib/helpers/data.rb
CHANGED
@@ -39,7 +39,7 @@ module Gaptool
|
|
39
39
|
if !key.nil? && !data.nil? && !data.empty?
|
40
40
|
$redis.multi do
|
41
41
|
$redis.del(key)
|
42
|
-
$redis.hmset(key, *data.select{ |k,v| !v.nil? && ((v.is_a?(String) && !v.empty?) || !!v == v)}.flatten)
|
42
|
+
$redis.hmset(key, *data.select{ |k,v| !v.nil? && ((v.is_a?(String) && !v.empty?) || (v.is_a?(Integer)) || !!v == v)}.flatten)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
@@ -152,12 +152,17 @@ module Gaptool
|
|
152
152
|
rs.delete('terminable')
|
153
153
|
end
|
154
154
|
|
155
|
+
if !rs['hidden'].nil? && rs['hidden'] == "true"
|
156
|
+
rs['hidden'] = true
|
157
|
+
end
|
158
|
+
|
155
159
|
if opts[:force_runlist] && rs['chef_runlist'].nil?
|
156
160
|
rs['chef_runlist'] = default_runlist
|
157
161
|
end
|
158
162
|
|
159
163
|
rs.delete_if {|k,v| v.nil? || (!!v != v && v.empty?)}
|
160
|
-
rs['
|
164
|
+
rs['launch_time'] = rs['launch_time'].to_i if rs['launch_time']
|
165
|
+
rs['apps'] = apps_in_role(rs['role'], rs['environment'])
|
161
166
|
rs
|
162
167
|
end
|
163
168
|
|
@@ -172,16 +177,16 @@ module Gaptool
|
|
172
177
|
overwrite_hash("role:#{role}:sg", sgs)
|
173
178
|
end
|
174
179
|
if data['apps']
|
175
|
-
apps = data.delete("apps")
|
176
|
-
apps.each {|
|
180
|
+
apps = data.delete("apps")
|
181
|
+
apps.each {|env, app| add_app(app, role, env)}
|
177
182
|
end
|
178
183
|
overwrite_hash("role:#{role}", data)
|
179
184
|
$redis.sadd("roles", role)
|
180
185
|
end
|
181
186
|
|
182
|
-
def self.get_role_data(role)
|
187
|
+
def self.get_role_data(role, environment=nil)
|
183
188
|
res = $redis.hgetall("role:#{role}")
|
184
|
-
res['apps'] = apps_in_role(role)
|
189
|
+
res['apps'] = environment ? apps_in_role(role, environment) : []
|
185
190
|
res['amis'] = $redis.hgetall("role:#{role}:amis")
|
186
191
|
res['sg'] = $redis.hgetall("role:#{role}:sg")
|
187
192
|
res
|
@@ -231,12 +236,13 @@ module Gaptool
|
|
231
236
|
Hash[$redis.smembers("roles").map {|r| [r, get_role_data(r)] }]
|
232
237
|
end
|
233
238
|
|
234
|
-
def self.add_app(name, role)
|
239
|
+
def self.add_app(name, role, environment)
|
235
240
|
return if name.nil? || role.nil?
|
236
241
|
$redis.multi do
|
237
242
|
$redis.sadd("apps", name)
|
238
|
-
$redis.sadd("
|
239
|
-
$redis.
|
243
|
+
$redis.sadd("apps:#{environment}", name)
|
244
|
+
$redis.sadd("role:#{role}:#{environment}:apps", name)
|
245
|
+
$redis.hset("app:#{name}", environment, role)
|
240
246
|
end
|
241
247
|
end
|
242
248
|
|
@@ -244,12 +250,14 @@ module Gaptool
|
|
244
250
|
return if name.nil?
|
245
251
|
key = "app:#{name}"
|
246
252
|
$redis.watch(key) do
|
247
|
-
|
248
|
-
if !
|
253
|
+
roles = $redis.hgetall(key)
|
254
|
+
if !roles.nil?
|
249
255
|
$redis.multi do |m|
|
250
256
|
m.del(key)
|
251
257
|
m.srem("apps", name)
|
252
|
-
|
258
|
+
roles.each do |env, role|
|
259
|
+
m.srem("role:#{role}:#{env}:apps", name)
|
260
|
+
end
|
253
261
|
end
|
254
262
|
else
|
255
263
|
$redis.unwatch
|
@@ -258,16 +266,15 @@ module Gaptool
|
|
258
266
|
end
|
259
267
|
|
260
268
|
def self.get_app_data(app)
|
261
|
-
|
262
|
-
return {"role" => role } unless role.nil?
|
269
|
+
return $redis.hgetall("app:#{app}")
|
263
270
|
end
|
264
271
|
|
265
272
|
def self.apps
|
266
273
|
$redis.smembers("apps")
|
267
274
|
end
|
268
275
|
|
269
|
-
def self.apps_in_role(role)
|
270
|
-
$redis.smembers("role:#{role}:apps")
|
276
|
+
def self.apps_in_role(role, environment)
|
277
|
+
$redis.smembers("role:#{role}:#{environment}:apps")
|
271
278
|
end
|
272
279
|
|
273
280
|
def self.stringify_apps(rs)
|
data/lib/helpers/ec2.rb
CHANGED
@@ -54,7 +54,7 @@ module Gaptool
|
|
54
54
|
return {id: id,
|
55
55
|
hostname: "test-#{id}.#{data[:zone].chop}.compute.amazonaws.com",
|
56
56
|
instance: nil,
|
57
|
-
launch_time: Time.now.
|
57
|
+
launch_time: Time.now.to_i}
|
58
58
|
end
|
59
59
|
configure_ec2 data[:zone].chop
|
60
60
|
ec2 = AWS::EC2.new
|
@@ -71,13 +71,6 @@ module Gaptool
|
|
71
71
|
retry
|
72
72
|
end
|
73
73
|
|
74
|
-
begin
|
75
|
-
launch_time = instance.launch_time.to_s
|
76
|
-
launch_time = launch_time.empty? ? Time.now.to_s : launch_time
|
77
|
-
rescue
|
78
|
-
launch_time = Time.now.to_s
|
79
|
-
end
|
80
|
-
|
81
74
|
i = 0
|
82
75
|
begin
|
83
76
|
hostname = instance.public_dns_name
|
@@ -89,7 +82,7 @@ module Gaptool
|
|
89
82
|
Airbrake.notify_or_ignore(
|
90
83
|
e,
|
91
84
|
error_class: "EC2 public dns fail",
|
92
|
-
parameters: {instance: instance
|
85
|
+
parameters: {instance: instance.id, role: data['role'], environment: data['environment'], hostname: nil}
|
93
86
|
)
|
94
87
|
else
|
95
88
|
@@logger.error("Error getting hostname for instance: #{e}: sleeping #{sleeptime}s and retrying (#{i}/#{retries})")
|
@@ -97,6 +90,31 @@ module Gaptool
|
|
97
90
|
retry
|
98
91
|
end
|
99
92
|
end
|
93
|
+
|
94
|
+
i = 0
|
95
|
+
begin
|
96
|
+
launch_time = instance.launch_time.to_i
|
97
|
+
raise unless launch_time.is_a? Integer
|
98
|
+
|
99
|
+
rescue => e
|
100
|
+
i += 1
|
101
|
+
if i > retries
|
102
|
+
@@logger.error("Cloud not get launch time for instance #{instance} after #{retries} retries. Setting to now()")
|
103
|
+
launch_time = Time.now.to_i
|
104
|
+
Airbrake.notify_or_ignore(
|
105
|
+
e,
|
106
|
+
error_class: "EC2 get launch_time fail",
|
107
|
+
parameters: {instance: instance.id, role: data['role'], environment: data['environment'], hostname: nil}
|
108
|
+
)
|
109
|
+
else
|
110
|
+
@@logger.error("Error getting launch_time for instance: #{e}: sleeping #{sleeptime}s and retrying (#{i}/#{retries})")
|
111
|
+
sleep sleeptime
|
112
|
+
retry
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
@@logger.info {"Instance #{instance.id} launch_time: #{launch_time} #{instance.launch_time}"}
|
117
|
+
|
100
118
|
{
|
101
119
|
id: instance.id,
|
102
120
|
instance: instance,
|
@@ -142,5 +160,20 @@ module Gaptool
|
|
142
160
|
hostname: instance.dns_name
|
143
161
|
}
|
144
162
|
end
|
163
|
+
|
164
|
+
def self.retag()
|
165
|
+
logger = Logger.new(STDOUT)
|
166
|
+
Gaptool::Data::servers.each do |id|
|
167
|
+
data = Gaptool::Data.get_server_data(id)
|
168
|
+
next if data.nil? || data['zone'].nil? || data['zone'].empty?
|
169
|
+
Gaptool::EC2::configure_ec2 data['zone'].chop
|
170
|
+
ec2 = AWS::EC2.new(region: data['zone'].chop)
|
171
|
+
instance = ec2.instances[id]
|
172
|
+
next if instance.tags.role && instance.tags.environment
|
173
|
+
logger.info("Retagging instance #{id} in zone #{data['zone'].chop}")
|
174
|
+
instance.tags.role = data['role']
|
175
|
+
instance.tags.environment = data['environment']
|
176
|
+
end
|
177
|
+
end
|
145
178
|
end
|
146
179
|
end
|
data/lib/helpers/rehash.rb
CHANGED
@@ -48,7 +48,7 @@ module Gaptool
|
|
48
48
|
%w[hostname itype security_group].each do |property|
|
49
49
|
res[property] = self.rehash_property_for_instance(property, instance_id, false)
|
50
50
|
end
|
51
|
-
Gaptool::set_server_data_attributes(instance_id, res)
|
51
|
+
Gaptool::Data::set_server_data_attributes(instance_id, res)
|
52
52
|
end
|
53
53
|
|
54
54
|
def self.rehash_property_for_instance(property, instance_id, save=true)
|
@@ -67,11 +67,13 @@ module Gaptool
|
|
67
67
|
value = instance.instance_type
|
68
68
|
when "security_group"
|
69
69
|
value = instance.security_groups[0].name
|
70
|
+
when "launch_time"
|
71
|
+
value = instance.launch_time.to_i
|
70
72
|
else
|
71
73
|
return false
|
72
74
|
end
|
75
|
+
logger.info("Setting #{property} to #{value} for #{instance_id}")
|
73
76
|
if save
|
74
|
-
logger.info("Setting #{property} to #{value} for #{instance_id}")
|
75
77
|
Gaptool::Data.set_server_data_attr(instance_id, property, value)
|
76
78
|
else
|
77
79
|
value
|
data/lib/routes.rb
CHANGED
@@ -67,7 +67,7 @@ class GaptoolServer < Sinatra::Application
|
|
67
67
|
end
|
68
68
|
|
69
69
|
# Add host tag
|
70
|
-
data.merge(instance.reject { |k, v| [:id, :instance].include?(k) })
|
70
|
+
data.merge!(Hash[instance.reject { |k, v| [:id, :instance].include?(k) }.map {|k, v| [k.to_s, v]}])
|
71
71
|
Gaptool::Data::addserver(instance[:id], data, secret)
|
72
72
|
json({instance: instance[:id],
|
73
73
|
ami: image_id,
|
@@ -136,24 +136,37 @@ class GaptoolServer < Sinatra::Application
|
|
136
136
|
end
|
137
137
|
|
138
138
|
get '/hosts' do
|
139
|
-
|
139
|
+
filter = !!params['hidden'] ? Proc.new {|s| !s['registered']} : Proc.new { |s| !s['registered'] && !s['hidden'] == true}
|
140
|
+
json(Gaptool::Data::servers.map do |inst|
|
140
141
|
Gaptool::Data::get_server_data inst
|
141
|
-
end.select
|
142
|
-
json servers
|
142
|
+
end.select(&filter))
|
143
143
|
end
|
144
144
|
|
145
145
|
get '/apps' do
|
146
|
-
|
147
|
-
|
148
|
-
|
146
|
+
json(Hash[Gaptool::Data.apps.map {|a| ["app:#{a}", Gaptool::Data::get_app_data(a)]}])
|
147
|
+
end
|
148
|
+
|
149
|
+
get '/app/:app/:environment/hosts' do
|
150
|
+
app_data = Gaptool::Data::get_app_data(params[:app])
|
151
|
+
unless app_data
|
152
|
+
status 404
|
153
|
+
error_response "app '#{params[:apps]}' not found"
|
149
154
|
end
|
150
|
-
|
155
|
+
|
156
|
+
role = app_data[params[:environment]]
|
157
|
+
list = Gaptool::Data::servers_in_role_env role, params[:environment]
|
158
|
+
filter = !!params['hidden'] ? Proc.new {|s| false } : Proc.new { |s| s['hidden']}
|
159
|
+
json(list.map do |inst|
|
160
|
+
data = Gaptool::Data::get_server_data(inst)
|
161
|
+
Gaptool::Data::stringify_apps(data)
|
162
|
+
end.delete_if(&filter))
|
151
163
|
end
|
152
164
|
|
153
165
|
get '/hosts/:role' do
|
166
|
+
filter = !!params['hidden'] ? Proc.new {|s| !s['registered']} : Proc.new { |s| !s['registered'] && !s['hidden'] == true}
|
154
167
|
servers = Gaptool::Data::servers_in_role(params[:role]).map do |inst|
|
155
|
-
Gaptool::Data::get_server_data
|
156
|
-
end.select
|
168
|
+
Gaptool::Data::get_server_data(inst)
|
169
|
+
end.select(&filter)
|
157
170
|
json servers
|
158
171
|
end
|
159
172
|
|
@@ -167,15 +180,37 @@ class GaptoolServer < Sinatra::Application
|
|
167
180
|
end
|
168
181
|
end
|
169
182
|
|
183
|
+
patch '/instance/:id' do
|
184
|
+
rs = Gaptool::Data::get_server_data(params[:id])
|
185
|
+
if rs.nil?
|
186
|
+
status 404
|
187
|
+
error_response "instance with id '#{params[:id]}' not found"
|
188
|
+
else
|
189
|
+
data = JSON.parse(request.body.read)
|
190
|
+
if !data['hidden'].nil?
|
191
|
+
hidden = !!data['hidden']
|
192
|
+
rs["hidden"] = hidden if hidden == true
|
193
|
+
rs.delete("hidden") if hidden == false
|
194
|
+
end
|
195
|
+
if !data['terminable'].nil?
|
196
|
+
rs["terminable"] = !!data['terminable']
|
197
|
+
end
|
198
|
+
Gaptool::Data::save_server_data params[:id], rs
|
199
|
+
json Gaptool::Data::stringify_apps(rs)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
170
203
|
get '/hosts/:role/:environment' do
|
171
204
|
if params[:role] == 'ALL'
|
172
205
|
list = Gaptool::Data::servers_in_env params[:environment]
|
173
206
|
else
|
174
207
|
list = Gaptool::Data::servers_in_role_env params[:role], params[:environment]
|
175
208
|
end
|
209
|
+
filter = !!params['hidden'] ? Proc.new {|s| false } : Proc.new { |s| s['hidden']}
|
176
210
|
servers = list.map do |inst|
|
177
|
-
Gaptool::Data::
|
178
|
-
|
211
|
+
data = Gaptool::Data::get_server_data(inst)
|
212
|
+
Gaptool::Data::stringify_apps(data)
|
213
|
+
end.delete_if(&filter)
|
179
214
|
|
180
215
|
json servers
|
181
216
|
end
|
data/tasks/app.rb
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
namespace :app do
|
2
2
|
desc "Add an application"
|
3
|
-
task :add, [:app, :role] do |t, args|
|
4
|
-
|
3
|
+
task :add, [:app, :role, :environment] do |t, args|
|
4
|
+
[:app, :role, :environment].each do |arg|
|
5
|
+
abort("Missing parameter #{arg}") if args[arg].nil? || args[arg].empty?
|
6
|
+
end
|
5
7
|
ex = DH.get_app_data(args[:app])
|
6
8
|
unless ex.nil?
|
7
|
-
puts "Updating application #{args[:app]}
|
9
|
+
puts "Updating application #{args[:app]} (#{args[:environment]}) to #{args[:role]}"
|
8
10
|
DH.remove_app(args[:app])
|
11
|
+
ex.delete(args[:environment])
|
12
|
+
end
|
13
|
+
DH.add_app(args[:app], args[:role], args[:environment])
|
14
|
+
ex.each do |env, role|
|
15
|
+
DH.add_app(args[:app], role, env)
|
9
16
|
end
|
10
|
-
|
11
|
-
puts "Added app #{args[:app]} in role #{args[:role]}"
|
17
|
+
puts "Added app #{args[:app]}, role #{args[:role]}, environment: #{args[:environment]}"
|
12
18
|
end
|
13
19
|
|
14
20
|
desc "Remove an application"
|
@@ -25,9 +31,20 @@ namespace :app do
|
|
25
31
|
if info.nil? || info.empty?
|
26
32
|
puts "No such app #{args[:app]}"
|
27
33
|
else
|
28
|
-
puts " * #{
|
34
|
+
puts " * #{app} #{info.map {|k,v| "#{k}: #{v}"}.join(", ")}"
|
29
35
|
end
|
36
|
+
end
|
30
37
|
|
38
|
+
desc "Copy all apps for a role to a new env"
|
39
|
+
task :newenv, [:role, :oldenv, :newenv, :newrole] do |t, args|
|
40
|
+
[:role, :oldenv, :newenv].each do |k|
|
41
|
+
abort "Missing parameter #{k}" if args[k].nil?
|
42
|
+
end
|
43
|
+
newrole = args[:newrole] || args[:role]
|
44
|
+
DH.apps_in_role(args[:role], args[:oldenv]).each do |app|
|
45
|
+
puts " * app: #{app} to role #{newrole} (#{args[:newenv]})"
|
46
|
+
DH.add_app(app, newrole, args[:newenv])
|
47
|
+
end
|
31
48
|
end
|
32
49
|
end
|
33
50
|
|
@@ -36,6 +53,6 @@ task :app do
|
|
36
53
|
puts "Apps:"
|
37
54
|
DH.apps.each do |app|
|
38
55
|
info = DH.get_app_data(app)
|
39
|
-
puts " * #{app}
|
56
|
+
puts " * #{app} #{info.map {|k,v| "#{k}: #{v}"}.join(", ")}"
|
40
57
|
end
|
41
58
|
end
|
data/tasks/docker.rb
CHANGED
@@ -23,17 +23,17 @@ unless File.exists?('/.dockerenv')
|
|
23
23
|
|
24
24
|
desc "Run tests w/ docker"
|
25
25
|
task :test => :build do
|
26
|
-
sys(%w(
|
26
|
+
sys(%w(docker-compose run --rm gaptool rake test))
|
27
27
|
end
|
28
28
|
|
29
29
|
desc "Stop docker containers"
|
30
30
|
task :stop do
|
31
|
-
sys(%w(
|
31
|
+
sys(%w(docker-compose stop))
|
32
32
|
end
|
33
33
|
|
34
34
|
desc "Start docker containers"
|
35
35
|
task :start do
|
36
|
-
sys(%w(
|
36
|
+
sys(%w(docker-compose start))
|
37
37
|
end
|
38
38
|
|
39
39
|
desc "Restart docker containers"
|
@@ -41,19 +41,19 @@ unless File.exists?('/.dockerenv')
|
|
41
41
|
|
42
42
|
desc "Stop and remove docker containers (alias 'rm')"
|
43
43
|
task :remove => :stop do
|
44
|
-
sys(%w(
|
44
|
+
sys(%w(docker-compose rm --force))
|
45
45
|
end
|
46
46
|
|
47
47
|
task :rm => :remove
|
48
48
|
|
49
49
|
desc "Recreate docker containers without building"
|
50
50
|
task :recreate do
|
51
|
-
sys(%w(
|
51
|
+
sys(%w(docker-compose up -d))
|
52
52
|
end
|
53
53
|
|
54
54
|
desc "Run a command in the docker container"
|
55
55
|
task :run do
|
56
|
-
exit sys(%W(
|
56
|
+
exit sys(%W(docker-compose run --rm gaptool #{ARGV[1..-1].shelljoin}))
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
data/tasks/ec2.rb
CHANGED
data/tasks/role.rb
CHANGED
@@ -2,7 +2,7 @@ namespace :role do
|
|
2
2
|
desc "Set security group for a role"
|
3
3
|
task :set_sg, [:role, :environment, :security_group] do |t, args|
|
4
4
|
abort("Missing parameters") if args[:role].nil? || args[:environment].nil? || args[:role].empty? || args[:environment].empty? || args[:security_group].nil? || args[:security_group].empty?
|
5
|
-
role = DH.get_role_data(args[:role])
|
5
|
+
role = DH.get_role_data(args[:role], args[:environment])
|
6
6
|
role['sg'].merge!(args[:environment] => args[:security_group])
|
7
7
|
DH.save_role_data(args[:role], role)
|
8
8
|
end
|
data/test/api_test.rb
CHANGED
@@ -16,6 +16,7 @@ describe "Test API" do
|
|
16
16
|
header 'X_GAPTOOL_KEY', 'test'
|
17
17
|
$redis.flushall
|
18
18
|
DH.useradd('test', 'test')
|
19
|
+
$time = Time.now
|
19
20
|
end
|
20
21
|
|
21
22
|
def add_and_register_server data=nil
|
@@ -45,7 +46,8 @@ describe "Test API" do
|
|
45
46
|
'terminable' => true,
|
46
47
|
'zone' => 'my-zone-1a',
|
47
48
|
'itype' => 'm1.type',
|
48
|
-
"hostname" => 'fake.hostname.gild.com'
|
49
|
+
"hostname" => 'fake.hostname.gild.com',
|
50
|
+
"launch_time" => $time.to_i
|
49
51
|
}
|
50
52
|
end
|
51
53
|
|
@@ -67,7 +69,8 @@ describe "Test API" do
|
|
67
69
|
it "should create a instance" do
|
68
70
|
post '/init', host_data.to_json
|
69
71
|
expect(last_response.status).to eq(200)
|
70
|
-
expect(JSON.parse(last_response.body).keys).to eq(["instance", "ami", "role", "hostname", "launch_time",
|
72
|
+
expect(JSON.parse(last_response.body).keys).to eq(["instance", "ami", "role", "hostname", "launch_time",
|
73
|
+
"environment", "secret", "terminable", "security_group"])
|
71
74
|
end
|
72
75
|
|
73
76
|
it "should get the runlist from the role" do
|
@@ -96,6 +99,86 @@ describe "Test API" do
|
|
96
99
|
expect(resp['security_group']).to eq("#{host_data['role']}-#{host_data['environment']}")
|
97
100
|
end
|
98
101
|
|
102
|
+
it "should set instance unterminable" do
|
103
|
+
id = add_and_register_server()['instance']
|
104
|
+
|
105
|
+
get "/instance/#{id}"
|
106
|
+
expect(last_response.status).to eq(200)
|
107
|
+
resp = JSON.parse(last_response.body)
|
108
|
+
expect(resp.keys).not_to include("terminable")
|
109
|
+
|
110
|
+
patch "/instance/#{id}", {terminable: false}.to_json
|
111
|
+
expect(last_response.status).to eq(200)
|
112
|
+
resp = JSON.parse(last_response.body)
|
113
|
+
expect(resp['terminable']).to eq(false)
|
114
|
+
|
115
|
+
get "/instance/#{id}"
|
116
|
+
expect(last_response.status).to eq(200)
|
117
|
+
resp = JSON.parse(last_response.body)
|
118
|
+
expect(resp['terminable']).to eq(false)
|
119
|
+
|
120
|
+
post '/terminate', {'id' => id}.to_json
|
121
|
+
expect(last_response.status).to eq(409)
|
122
|
+
|
123
|
+
patch "/instance/#{id}", {terminable: true}.to_json
|
124
|
+
expect(last_response.status).to eq(200)
|
125
|
+
resp = JSON.parse(last_response.body)
|
126
|
+
expect(resp['terminable']).to eq(true)
|
127
|
+
|
128
|
+
post '/terminate', {'id' => id}.to_json
|
129
|
+
expect(last_response.status).to eq(200)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should set an instance as hidden" do
|
133
|
+
id = add_and_register_server()['instance']
|
134
|
+
|
135
|
+
get "/instance/#{id}"
|
136
|
+
expect(last_response.status).to eq(200)
|
137
|
+
resp = JSON.parse(last_response.body)
|
138
|
+
expect(resp.keys).not_to include("hidden")
|
139
|
+
|
140
|
+
patch "/instance/#{id}", {hidden: false}.to_json
|
141
|
+
expect(last_response.status).to eq(200)
|
142
|
+
resp = JSON.parse(last_response.body)
|
143
|
+
expect(resp.keys).not_to include("hidden")
|
144
|
+
|
145
|
+
get "/instance/#{id}"
|
146
|
+
expect(last_response.status).to eq(200)
|
147
|
+
resp = JSON.parse(last_response.body)
|
148
|
+
expect(resp.keys).not_to include("hidden")
|
149
|
+
|
150
|
+
patch "/instance/#{id}", {hidden: true}.to_json
|
151
|
+
expect(last_response.status).to eq(200)
|
152
|
+
resp = JSON.parse(last_response.body)
|
153
|
+
expect(resp['hidden']).to eq(true)
|
154
|
+
|
155
|
+
get "/instance/#{id}"
|
156
|
+
expect(last_response.status).to eq(200)
|
157
|
+
resp = JSON.parse(last_response.body)
|
158
|
+
expect(resp['hidden']).to eq(true)
|
159
|
+
|
160
|
+
get "/host/#{host_data['role']}/#{host_data['environment']}/#{id}"
|
161
|
+
expect(last_response.status).to eq(200)
|
162
|
+
resp = JSON.parse(last_response.body)
|
163
|
+
expect(resp['hidden']).to eq(true)
|
164
|
+
|
165
|
+
get "/hosts"
|
166
|
+
expect(last_response.status).to eq(200)
|
167
|
+
expect(JSON.parse(last_response.body)).to eq([])
|
168
|
+
|
169
|
+
get "/hosts/#{host_data['role']}"
|
170
|
+
expect(last_response.status).to eq(200)
|
171
|
+
expect(JSON.parse(last_response.body)).to eq([])
|
172
|
+
|
173
|
+
get "/hosts/#{host_data['role']}/#{host_data['environment']}"
|
174
|
+
expect(last_response.status).to eq(200)
|
175
|
+
expect(JSON.parse(last_response.body)).to eq([])
|
176
|
+
|
177
|
+
get "/hosts/ALL/#{host_data['environment']}"
|
178
|
+
expect(last_response.status).to eq(200)
|
179
|
+
expect(JSON.parse(last_response.body)).to eq([])
|
180
|
+
end
|
181
|
+
|
99
182
|
it "should remove default runlist" do
|
100
183
|
id = add_and_register_server(host_data.merge("chef_runlist"=> ['recipe[init]']))['instance']
|
101
184
|
get "/host/testrole/testenv/#{id}"
|
@@ -226,6 +309,30 @@ describe "Test API" do
|
|
226
309
|
expect(JSON.parse(last_response.body).to_set).to eq(exp_data)
|
227
310
|
end
|
228
311
|
|
312
|
+
it "should find one hidden host" do
|
313
|
+
id1 = add_and_register_server()['instance']
|
314
|
+
id2 = add_and_register_server()['instance']
|
315
|
+
patch "/instance/#{id1}", {hidden: true}.to_json
|
316
|
+
%W(/hosts /hosts/#{host_data['role']} /hosts/#{host_data['role']}/#{host_data['environment']} /hosts/ALL/#{host_data['environment']}).each do |url|
|
317
|
+
get url
|
318
|
+
expect(last_response.status).to eq(200)
|
319
|
+
res = JSON.parse(last_response.body).map{|x| x.delete('apps'); x}.to_set
|
320
|
+
exp_data = [host_data.reject{|k,v| k == 'terminable'}.merge({'instance' => id2,
|
321
|
+
'chef_runlist' => expanded_runlist})].to_set
|
322
|
+
expect(res).to eq(exp_data)
|
323
|
+
get url, {hidden: true}
|
324
|
+
expect(last_response.status).to eq(200)
|
325
|
+
exp_data = [
|
326
|
+
host_data.reject{|k,v| k == 'terminable'}.merge({'instance' => id1,
|
327
|
+
'chef_runlist' => expanded_runlist,
|
328
|
+
'hidden' => true}),
|
329
|
+
host_data.reject{|k,v| k == 'terminable'}.merge({'instance' => id2,
|
330
|
+
'chef_runlist' => expanded_runlist})
|
331
|
+
].to_set
|
332
|
+
expect(JSON.parse(last_response.body).map{|x| x.delete('apps'); x}.to_set).to eq(exp_data)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
229
336
|
it "should find an host by role" do
|
230
337
|
other = host_data.merge({'role' => 'otherrole'})
|
231
338
|
id1 = add_and_register_server(other)['instance']
|
@@ -295,10 +402,10 @@ describe "Test API" do
|
|
295
402
|
end
|
296
403
|
|
297
404
|
it "should return the list of apps" do
|
298
|
-
DH.add_app("firstapp", "testrole")
|
299
|
-
DH.add_app("secondapp", "testrole")
|
300
|
-
apps_list = {"app:firstapp" => {"
|
301
|
-
"app:secondapp" =>{"
|
405
|
+
DH.add_app("firstapp", "testrole", "testenv")
|
406
|
+
DH.add_app("secondapp", "testrole", "testenv")
|
407
|
+
apps_list = {"app:firstapp" => {"testenv" => "testrole"},
|
408
|
+
"app:secondapp" => {"testenv" => "testrole"}}
|
302
409
|
get "/apps"
|
303
410
|
expect(last_response.status).to eq(200)
|
304
411
|
expect(JSON.parse(last_response.body)).to eq(apps_list)
|
data/test/data_test.rb
CHANGED
@@ -105,7 +105,7 @@ describe "data helpers" do
|
|
105
105
|
it "should get the runlist for a node from the role" do
|
106
106
|
DH.save_role_data("role", chef_runlist: ["recipe[myrecipe]"].to_json)
|
107
107
|
DH.addserver(instid, data, nil)
|
108
|
-
role = DH.get_role_data("role")
|
108
|
+
role = DH.get_role_data("role", "testenv")
|
109
109
|
expect(role).to eq({"chef_runlist"=> ["recipe[myrecipe]"].to_json,
|
110
110
|
"apps" => [],
|
111
111
|
"amis" => {},
|
@@ -121,19 +121,19 @@ describe "data helpers" do
|
|
121
121
|
it "shoud get the ami for a node from the role" do
|
122
122
|
DH.save_role_data("role", ami: 'ami-1234567')
|
123
123
|
DH.addserver(instid, data, nil)
|
124
|
-
role = DH.get_role_data("role")
|
124
|
+
role = DH.get_role_data("role", "testenv")
|
125
125
|
expect(role).to eq({'ami' => 'ami-1234567',
|
126
126
|
"apps" => [],
|
127
127
|
"amis" => {},
|
128
128
|
"sg" => {}})
|
129
129
|
end
|
130
130
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
131
|
+
it "shoud get the sg for a node from the role" do
|
132
|
+
DH.save_role_data("role", ami: 'ami-1234567', "sg" => {"test" => "my_role"})
|
133
|
+
role = DH.get_role_data("role", "testenv")
|
134
|
+
expect(role).to eq({'ami' => 'ami-1234567',
|
135
|
+
"apps" => [],
|
136
|
+
"amis" => {},
|
137
|
+
"sg" => {"test" => "my_role"}})
|
138
138
|
end
|
139
139
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gaptool-server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Bailey
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-05-31 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: sinatra
|
@@ -41,19 +41,19 @@ dependencies:
|
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '1.4'
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
|
-
name:
|
44
|
+
name: puma
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 2.11.1
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
56
|
+
version: 2.11.1
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: redis
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -180,6 +180,20 @@ dependencies:
|
|
180
180
|
- - "~>"
|
181
181
|
- !ruby/object:Gem::Version
|
182
182
|
version: '1.8'
|
183
|
+
- !ruby/object:Gem::Dependency
|
184
|
+
name: rake
|
185
|
+
requirement: !ruby/object:Gem::Requirement
|
186
|
+
requirements:
|
187
|
+
- - "~>"
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '10'
|
190
|
+
type: :runtime
|
191
|
+
prerelease: false
|
192
|
+
version_requirements: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - "~>"
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '10'
|
183
197
|
- !ruby/object:Gem::Dependency
|
184
198
|
name: rspec
|
185
199
|
requirement: !ruby/object:Gem::Requirement
|
@@ -241,7 +255,7 @@ email: ops@gild.com
|
|
241
255
|
executables:
|
242
256
|
- gaptool-server
|
243
257
|
- gaptool-shell
|
244
|
-
-
|
258
|
+
- gaptool_server_migrate_0.6-0.7
|
245
259
|
extensions: []
|
246
260
|
extra_rdoc_files:
|
247
261
|
- LICENSE.txt
|
@@ -255,7 +269,7 @@ files:
|
|
255
269
|
- VERSION
|
256
270
|
- bin/gaptool-server
|
257
271
|
- bin/gaptool-shell
|
258
|
-
- bin/
|
272
|
+
- bin/gaptool_server_migrate_0.6-0.7
|
259
273
|
- config.ru
|
260
274
|
- lib/app.rb
|
261
275
|
- lib/exceptions.rb
|
@@ -298,7 +312,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
298
312
|
version: '0'
|
299
313
|
requirements: []
|
300
314
|
rubyforge_project:
|
301
|
-
rubygems_version: 2.
|
315
|
+
rubygems_version: 2.2.2
|
302
316
|
signing_key:
|
303
317
|
specification_version: 4
|
304
318
|
summary: gaptool-server for managing cloud resources
|
@@ -1,18 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# convert the old data model for the gaptool server
|
4
|
-
# to the new struct
|
5
|
-
|
6
|
-
libpath = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
7
|
-
$:.unshift(libpath)
|
8
|
-
require "#{libpath}/helpers/redis"
|
9
|
-
require "#{libpath}/helpers/data"
|
10
|
-
DH = Gaptool::Data
|
11
|
-
|
12
|
-
$redis.keys("role:*").each do |k|
|
13
|
-
next if k.end_with?('instances') || k.end_with?('apps') || k.end_with?('amis')
|
14
|
-
puts "Migrating #{k}"
|
15
|
-
sgroup = $redis.hget(k, "security_group")
|
16
|
-
$redis.hset("#{k}:sg", "production", sgroup)
|
17
|
-
$redis.del(k)
|
18
|
-
end
|