gaptool-server 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9bdd9381a7a9adcc78aed7919ba4cdc36c718f93
4
- data.tar.gz: 9d716274f9ab9c02a9c0c62e27d011d6b381029c
3
+ metadata.gz: 91476ed75e704cd7168262de3aee3563632c6571
4
+ data.tar.gz: 6e20d2d9cfd1f1e6d386bf3f8b801ef353cae179
5
5
  SHA512:
6
- metadata.gz: 07863c41b56f69c29b9915deb3db26aa03a89965c48a63cf71196a0545646d2ea994e61d03b789011382bdb23da37d157e055e9ac20358a052be250f9aa37531
7
- data.tar.gz: 2e3f46dc0f16ff83aab782e97a50b938c83f7b736c7a7fa38e30bb9d74755bbd6662a9b101a17766a28af9b25d5064214d1dd6b67aa516becdffcfdc3a2c6380
6
+ metadata.gz: db20d97b206b75e2753165da1eb30047ff8afede719f0e262477773187d19b916ec1fd9d3faae18a3e6fab08524d62fc9233c4affd0e90e9ef77634da105fbf8
7
+ data.tar.gz: c56b3aa929695a7b9948580ad0c65e0fdaf76c2df6d0d35d4c2c122eb0f77ca21898b46ba0a867c7014c20b7c532b73b6a44eb11e063719e2d8b201066247d9d
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.0
1
+ 0.7.1
data/lib/app.rb CHANGED
@@ -10,6 +10,7 @@ require 'net/ssh'
10
10
  require 'peach'
11
11
  require 'airbrake'
12
12
  require 'logger'
13
+ require 'versionomy'
13
14
  require_relative 'exceptions'
14
15
 
15
16
  class GaptoolServer < Sinatra::Application
@@ -36,6 +37,24 @@ class GaptoolServer < Sinatra::Application
36
37
  halt(401, error_response("Unauthenticated"))
37
38
  end
38
39
 
40
+ def check_version(server, client)
41
+ @@client_versions ||= {}
42
+ cl_v = @@client_versions[client]
43
+ if cl_v.nil?
44
+ begin
45
+ @@client_versions[client] = Versionomy.parse(client)
46
+ cl_v = @@client_versions[client]
47
+ rescue
48
+ return false
49
+ end
50
+ end
51
+ cl_v.major == server.major && cl_v.minor == server.minor
52
+ end
53
+
54
+ def invalid_version(server, client)
55
+ halt(400, error_response("Invalid version #{client} (server: #{server})"))
56
+ end
57
+
39
58
  error do
40
59
  status 500
41
60
  error_response
@@ -51,6 +70,11 @@ class GaptoolServer < Sinatra::Application
51
70
  disable :sessions
52
71
  enable :dump_errors
53
72
  disable :show_exceptions
73
+ version = File.read(File.realpath(
74
+ File.join(File.dirname(__FILE__), "..", 'VERSION')
75
+ )).strip
76
+ set(:version, version)
77
+ set(:version_parsed, Versionomy.parse(version))
54
78
  end
55
79
 
56
80
  before do
@@ -58,6 +82,9 @@ class GaptoolServer < Sinatra::Application
58
82
  user = Gaptool::Data.user(env['HTTP_X_GAPTOOL_USER'])
59
83
  return unauthenticated if user.nil?
60
84
  return unauthenticated unless user[:key] == env['HTTP_X_GAPTOOL_KEY']
85
+ if !ENV['GAPTOOL_CHECK_CLIENT_VERSION'].nil? && !check_version(settings.version_parsed, env['HTTP_X_GAPTOOL_VERSION'])
86
+ return invalid_version(settings.version, env['HTTP_X_GAPTOOL_VERSION'])
87
+ end
61
88
  end
62
89
  end
63
90
 
data/lib/routes.rb CHANGED
@@ -227,9 +227,7 @@ class GaptoolServer < Sinatra::Application
227
227
  end
228
228
 
229
229
  get '/version' do
230
- version = File.read(File.realpath(
231
- File.join(File.dirname(__FILE__), "..", 'VERSION')
232
- )).strip
230
+ version = settings.version
233
231
  json server_version: version, api: {v0: "/"}
234
232
  end
235
233
 
data/tasks/docker.rb CHANGED
@@ -23,7 +23,7 @@ unless File.exists?('/.dockerenv')
23
23
 
24
24
  desc "Run tests w/ docker"
25
25
  task :test => :build do
26
- sys(%w(docker-compose run --rm gaptool rake test))
26
+ sys(%w(docker-compose run --rm gaptool bundle exec rake test))
27
27
  end
28
28
 
29
29
  desc "Stop docker containers"
data/test/api_test.rb CHANGED
@@ -5,15 +5,21 @@ require 'set'
5
5
  describe "Test API" do
6
6
  before(:all) do
7
7
  ENV['DRYRUN'] = 'true'
8
+ ENV['GAPTOOL_CHECK_CLIENT_VERSION'] = 'true'
9
+ @version = File.read(File.realpath(
10
+ File.join(File.dirname(__FILE__), "..", 'VERSION')
11
+ )).strip.split(".")[0..1].join(".")
8
12
  end
9
13
 
10
14
  after(:all) do
11
15
  ENV['DRYRUN'] = nil
16
+ ENV['GAPTOOL_CHECK_CLIENT_VERSION'] = nil
12
17
  end
13
18
 
14
19
  before(:each) do
15
- header 'X_GAPTOOL_USER', 'test'
16
- header 'X_GAPTOOL_KEY', 'test'
20
+ header 'X-GAPTOOL-USER', 'test'
21
+ header 'X-GAPTOOL-KEY', 'test'
22
+ header 'X-GAPTOOL-VERSION', @version
17
23
  $redis.flushall
18
24
  DH.useradd('test', 'test')
19
25
  $time = Time.now
@@ -410,4 +416,20 @@ describe "Test API" do
410
416
  expect(last_response.status).to eq(200)
411
417
  expect(JSON.parse(last_response.body)).to eq(apps_list)
412
418
  end
419
+
420
+ it "should fail as client did not send version" do
421
+ header 'X-GAPTOOL-VERSION', nil
422
+ get "/version"
423
+ expect(last_response.status).to eq(400)
424
+ resp = JSON.parse(last_response.body)
425
+ expect(resp['result']).to eq('error')
426
+ expect(resp['message']).to match(/^Invalid version/)
427
+ end
428
+
429
+ it "should not check version for clients" do
430
+ ENV['GAPTOOL_CHECK_CLIENT_VERSION'] = nil
431
+ header 'X_GAPTOOL_VERSION', nil
432
+ get "/version"
433
+ expect(last_response.status).to eq(200)
434
+ end
413
435
  end
data/test/test_helper.rb CHANGED
@@ -1,6 +1,15 @@
1
1
  ENV['RACK_ENV'] = 'test'
2
2
  if ENV['COVERAGE']
3
3
  require 'simplecov'
4
+ require 'simplecov-rcov'
5
+
6
+ class SimpleCov::Formatter::MergedFormatter
7
+ def format(result)
8
+ SimpleCov::Formatter::HTMLFormatter.new.format(result)
9
+ SimpleCov::Formatter::RcovFormatter.new.format(result)
10
+ end
11
+ end
12
+ SimpleCov.formatter = SimpleCov::Formatter::MergedFormatter
4
13
  SimpleCov.start do
5
14
  add_filter '/test/'
6
15
  add_group 'helpers', 'lib/helpers'
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.7.0
4
+ version: 0.7.1
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-05-31 00:00:00.000000000 Z
13
+ date: 2015-06-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sinatra
@@ -45,6 +45,9 @@ dependencies:
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '2.11'
50
+ - - ">="
48
51
  - !ruby/object:Gem::Version
49
52
  version: 2.11.1
50
53
  type: :runtime
@@ -52,6 +55,9 @@ dependencies:
52
55
  version_requirements: !ruby/object:Gem::Requirement
53
56
  requirements:
54
57
  - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2.11'
60
+ - - ">="
55
61
  - !ruby/object:Gem::Version
56
62
  version: 2.11.1
57
63
  - !ruby/object:Gem::Dependency
@@ -116,14 +122,14 @@ dependencies:
116
122
  requirements:
117
123
  - - "~>"
118
124
  - !ruby/object:Gem::Version
119
- version: '4.1'
125
+ version: '4.2'
120
126
  type: :runtime
121
127
  prerelease: false
122
128
  version_requirements: !ruby/object:Gem::Requirement
123
129
  requirements:
124
130
  - - "~>"
125
131
  - !ruby/object:Gem::Version
126
- version: '4.1'
132
+ version: '4.2'
127
133
  - !ruby/object:Gem::Dependency
128
134
  name: racksh
129
135
  requirement: !ruby/object:Gem::Requirement
@@ -194,6 +200,20 @@ dependencies:
194
200
  - - "~>"
195
201
  - !ruby/object:Gem::Version
196
202
  version: '10'
203
+ - !ruby/object:Gem::Dependency
204
+ name: versionomy
205
+ requirement: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - "~>"
208
+ - !ruby/object:Gem::Version
209
+ version: '0.4'
210
+ type: :runtime
211
+ prerelease: false
212
+ version_requirements: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - "~>"
215
+ - !ruby/object:Gem::Version
216
+ version: '0.4'
197
217
  - !ruby/object:Gem::Dependency
198
218
  name: rspec
199
219
  requirement: !ruby/object:Gem::Requirement
@@ -242,20 +262,33 @@ dependencies:
242
262
  requirements:
243
263
  - - "~>"
244
264
  - !ruby/object:Gem::Version
245
- version: '0.9'
265
+ version: '0'
266
+ type: :development
267
+ prerelease: false
268
+ version_requirements: !ruby/object:Gem::Requirement
269
+ requirements:
270
+ - - "~>"
271
+ - !ruby/object:Gem::Version
272
+ version: '0'
273
+ - !ruby/object:Gem::Dependency
274
+ name: simplecov-rcov
275
+ requirement: !ruby/object:Gem::Requirement
276
+ requirements:
277
+ - - "~>"
278
+ - !ruby/object:Gem::Version
279
+ version: '0'
246
280
  type: :development
247
281
  prerelease: false
248
282
  version_requirements: !ruby/object:Gem::Requirement
249
283
  requirements:
250
284
  - - "~>"
251
285
  - !ruby/object:Gem::Version
252
- version: '0.9'
286
+ version: '0'
253
287
  description: gaptool-server for managing cloud resources
254
288
  email: ops@gild.com
255
289
  executables:
256
290
  - gaptool-server
257
291
  - gaptool-shell
258
- - gaptool_server_migrate_0.6-0.7
259
292
  extensions: []
260
293
  extra_rdoc_files:
261
294
  - LICENSE.txt
@@ -269,17 +302,10 @@ files:
269
302
  - VERSION
270
303
  - bin/gaptool-server
271
304
  - bin/gaptool-shell
272
- - bin/gaptool_server_migrate_0.6-0.7
273
305
  - config.ru
274
306
  - lib/app.rb
275
307
  - lib/exceptions.rb
276
- - lib/helpers/data.rb
277
- - lib/helpers/ec2.rb
278
- - lib/helpers/init.rb
279
- - lib/helpers/redis.rb
280
- - lib/helpers/rehash.rb
281
308
  - lib/routes.rb
282
- - lib/views/init.erb
283
309
  - tasks/app.rb
284
310
  - tasks/config.rb
285
311
  - tasks/docker.rb
@@ -1,35 +0,0 @@
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 DELETED
@@ -1,306 +0,0 @@
1
- require 'json'
2
- require 'securerandom'
3
-
4
- module Gaptool
5
- module Data
6
-
7
- def self.init_recipe
8
- 'recipe[init]'
9
- end
10
-
11
- def self.default_runlist
12
- [init_recipe]
13
- end
14
-
15
- def self.addserver(instance, data, secret)
16
- role = data['role']
17
- environment = data['environment']
18
- if role.nil? || environment.nil?
19
- raise ArgumentError, "Missing role or environment"
20
- end
21
-
22
- if instance.nil? || instance.empty?
23
- raise ArgumentError, "Missing instance"
24
- end
25
-
26
- $redis.sadd("instances", instance)
27
- $redis.sadd("role:#{role}:instances", instance)
28
- $redis.sadd("environment:#{environment}:instances", instance)
29
- unless secret.nil?
30
- data['registered'] = false
31
- $redis.sadd('instances:unregistered', instance)
32
- $redis.set("instances:secrets:#{data['role']}:#{data['environment']}:#{secret}", instance)
33
- data['secret'] = secret
34
- end
35
- save_server_data instance, data
36
- end
37
-
38
- def self.overwrite_hash(key, data)
39
- if !key.nil? && !data.nil? && !data.empty?
40
- $redis.multi do
41
- $redis.del(key)
42
- $redis.hmset(key, *data.select{ |k,v| !v.nil? && ((v.is_a?(String) && !v.empty?) || (v.is_a?(Integer)) || !!v == v)}.flatten)
43
- end
44
- end
45
- end
46
-
47
- def self.set_server_data_attr(instance, attr, value)
48
- return if value.nil? || (value.is_a?(String) && value.empty?) || !!value == value
49
- $redis.hset("instance:#{instance}", attr, value)
50
- end
51
-
52
- def self.set_server_data_attributes(instance, attrs)
53
- return if attrs.values.any? {|v| v.nil? || (v.is_a?(String) && v.empty?) || !!v == v}
54
- $redis.hmset("instance:#{instance}", *attrs.flatten)
55
- end
56
-
57
- def self.save_server_data(instance, data)
58
-
59
- unless data['chef_runlist'].nil?
60
- data['chef_runlist'] = [*data['chef_runlist']]
61
- unless data['chef_runlist'].include? init_recipe
62
- data['chef_runlist'].unshift(init_recipe)
63
- end
64
-
65
- if data['chef_runlist'] == default_runlist
66
- data.delete('chef_runlist')
67
- else
68
- data['chef_runlist'] = data['chef_runlist'].to_json
69
- end
70
- end
71
- overwrite_hash("instance:#{instance}", data)
72
- end
73
-
74
- def self.register_server(role, environment, secret)
75
- key = "instances:secrets:#{role}:#{environment}:#{secret}"
76
- instance = nil
77
- $redis.watch(key) do
78
- instance = $redis.get(key)
79
- if !instance.nil? && !instance.empty?
80
- $redis.multi do |m|
81
- m.hdel("instance:#{instance}", "secret")
82
- m.hdel("instance:#{instance}", "registered")
83
- m.srem('instances:unregistered', instance)
84
- m.del(key)
85
- end
86
- else
87
- $redis.unwatch
88
- instance = nil
89
- end
90
- end
91
- instance
92
- end
93
-
94
- def self.rmserver(instance)
95
- data = get_server_data instance
96
- return if data.nil?
97
- $redis.multi do |m|
98
- m.srem("instances", instance)
99
- m.srem("role:#{data['role']}:instances", instance)
100
- m.srem("environment:#{data['environment']}:instances", instance)
101
- m.del("instance:#{instance}")
102
- end
103
- instance
104
- end
105
-
106
- def self.get_config(key)
107
- $redis.hget('config', key)
108
- end
109
-
110
- def self.ensure_config(key, default)
111
- cur = get_config(key)
112
- cur = set_config(key, default) if cur.nil? || cur.empty?
113
- cur
114
- end
115
-
116
- def self.set_config(key, value)
117
- $redis.hset('config', key, value)
118
- value
119
- end
120
-
121
- def self.del_config(key)
122
- $redis.hdel('config', key)
123
- end
124
-
125
- def self.get_all_configs
126
- $redis.hgetall('config')
127
- end
128
-
129
- def self.get_server_data(instance, opts={})
130
- rs = $redis.hgetall("instance:#{instance}")
131
- return nil if rs.nil? || rs.empty?
132
- rs['instance'] = instance
133
- if !rs['chef_runlist'].nil? && !rs['chef_runlist'].empty?
134
- rs['chef_runlist'] = JSON.parse rs['chef_runlist']
135
- else
136
- rs['chef_runlist'] = get_runlist_for_role rs['role']
137
- end
138
-
139
- %w(chef_repo chef_branch).each do |v|
140
- if rs[v].nil? || rs[v].empty?
141
- rs[v] = get_config(v)
142
- end
143
- end
144
-
145
- if opts[:initkey]
146
- rs['initkey'] = get_config('initkey')
147
- end
148
-
149
- if !rs['terminable'].nil? && rs['terminable'] == "false"
150
- rs['terminable'] = false
151
- else
152
- rs.delete('terminable')
153
- end
154
-
155
- if !rs['hidden'].nil? && rs['hidden'] == "true"
156
- rs['hidden'] = true
157
- end
158
-
159
- if opts[:force_runlist] && rs['chef_runlist'].nil?
160
- rs['chef_runlist'] = default_runlist
161
- end
162
-
163
- rs.delete_if {|k,v| v.nil? || (!!v != v && v.empty?)}
164
- rs['launch_time'] = rs['launch_time'].to_i if rs['launch_time']
165
- rs['apps'] = apps_in_role(rs['role'], rs['environment'])
166
- rs
167
- end
168
-
169
- def self.save_role_data(role, data)
170
- return if role.nil? || data.nil?
171
- if data['amis']
172
- amis = data.delete("amis") || {}
173
- overwrite_hash("role:#{role}:amis", amis)
174
- end
175
- if data['sg']
176
- sgs = data.delete("sg") || {}
177
- overwrite_hash("role:#{role}:sg", sgs)
178
- end
179
- if data['apps']
180
- apps = data.delete("apps")
181
- apps.each {|env, app| add_app(app, role, env)}
182
- end
183
- overwrite_hash("role:#{role}", data)
184
- $redis.sadd("roles", role)
185
- end
186
-
187
- def self.get_role_data(role, environment=nil)
188
- res = $redis.hgetall("role:#{role}")
189
- res['apps'] = environment ? apps_in_role(role, environment) : []
190
- res['amis'] = $redis.hgetall("role:#{role}:amis")
191
- res['sg'] = $redis.hgetall("role:#{role}:sg")
192
- res
193
- end
194
-
195
- def self.get_ami_for_role(role, region=nil)
196
- $redis.hget("role:#{role}:amis", region) || $redis.hget("amis", region)
197
- end
198
-
199
- def self.get_sg_for_role(role, environment)
200
- $redis.hget("role:#{role}:sg", environment) || "#{role}-#{environment}"
201
- end
202
-
203
- def self.get_runlist_for_role(role)
204
- rl = $redis.hget("role:#{role}", "chef_runlist")
205
- return nil if rl.nil?
206
- rl = JSON.parse rl
207
- return nil if rl == default_runlist
208
- rl
209
- end
210
-
211
- def self.set_amis(amis)
212
- overwrite_hash("amis", amis)
213
- end
214
-
215
- def self.zones
216
- $redis.hgetall('amis').keys
217
- end
218
-
219
- def self.servers_in_role(role)
220
- $redis.smembers("role:#{role}:instances")
221
- end
222
-
223
- def self.servers_in_env(env)
224
- $redis.smembers("environment:#{env}:instances")
225
- end
226
-
227
- def self.servers_in_role_env(role, env)
228
- $redis.sinter("role:#{role}:instances", "environment:#{env}:instances")
229
- end
230
-
231
- def self.servers
232
- $redis.smembers("instances")
233
- end
234
-
235
- def self.roles
236
- Hash[$redis.smembers("roles").map {|r| [r, get_role_data(r)] }]
237
- end
238
-
239
- def self.add_app(name, role, environment)
240
- return if name.nil? || role.nil?
241
- $redis.multi do
242
- $redis.sadd("apps", name)
243
- $redis.sadd("apps:#{environment}", name)
244
- $redis.sadd("role:#{role}:#{environment}:apps", name)
245
- $redis.hset("app:#{name}", environment, role)
246
- end
247
- end
248
-
249
- def self.remove_app(name)
250
- return if name.nil?
251
- key = "app:#{name}"
252
- $redis.watch(key) do
253
- roles = $redis.hgetall(key)
254
- if !roles.nil?
255
- $redis.multi do |m|
256
- m.del(key)
257
- m.srem("apps", name)
258
- roles.each do |env, role|
259
- m.srem("role:#{role}:#{env}:apps", name)
260
- end
261
- end
262
- else
263
- $redis.unwatch
264
- end
265
- end
266
- end
267
-
268
- def self.get_app_data(app)
269
- return $redis.hgetall("app:#{app}")
270
- end
271
-
272
- def self.apps
273
- $redis.smembers("apps")
274
- end
275
-
276
- def self.apps_in_role(role, environment)
277
- $redis.smembers("role:#{role}:#{environment}:apps")
278
- end
279
-
280
- def self.stringify_apps(rs)
281
- if !rs.nil? && !rs['apps'].nil?
282
- rs['apps'] = rs['apps'].to_json
283
- end
284
- rs
285
- end
286
-
287
- def self.useradd(user, key=nil)
288
- key = SecureRandom.hex(64) unless key
289
- $redis.hset('users', user, key)
290
- {username: user, key: key}
291
- end
292
-
293
- def self.userdel(user)
294
- $redis.hdel('users', user)
295
- end
296
-
297
- def self.users
298
- $redis.hgetall('users')
299
- end
300
-
301
- def self.user(user)
302
- userdesc = {username: user, key: $redis.hget('users', user)}
303
- return userdesc[:key].nil? ? nil : userdesc
304
- end
305
- end
306
- end
data/lib/helpers/ec2.rb DELETED
@@ -1,179 +0,0 @@
1
- require 'aws-sdk'
2
- require 'securerandom'
3
- require 'logger'
4
- require 'airbrake'
5
-
6
- # encoding: utf-8
7
- module Gaptool
8
- module EC2
9
- @@logger = Logger.new(STDERR)
10
-
11
- def self.configure_ec2 zone
12
- return if ENV['DRYRUN']
13
- id = ENV['AWS_ACCESS_KEY_ID']
14
- secret = ENV['AWS_SECRET_ACCESS_KEY']
15
- AWS.config(access_key_id: id, secret_access_key: secret,
16
- ec2_endpoint: "ec2.#{zone}.amazonaws.com")
17
- end
18
-
19
- def self.putkey(host)
20
- return "FAKEKEY", "FAKEPUB" if ENV['DRYRUN']
21
- key = OpenSSL::PKey::RSA.new 2048
22
- pubkey = "#{key.ssh_type} #{[key.to_blob].pack('m0')} GAPTOOL_GENERATED_KEY"
23
- ENV['SSH_AUTH_SOCK'] = ''
24
- Net::SSH.start(host, 'admin',
25
- :key_data => [$redis.hget('config', 'gaptoolkey')],
26
- :config => false, :keys_only => true,
27
- :paranoid => false) do |ssh|
28
- ssh.exec! "grep -v GAPTOOL_GENERATED_KEY ~/.ssh/authorized_keys > /tmp/pubkeys"
29
- ssh.exec! "echo #{pubkey} >> /tmp/pubkeys"
30
- ssh.exec! "mv /tmp/pubkeys ~/.ssh/authorized_keys"
31
- end
32
- return key.to_pem, pubkey
33
- end
34
-
35
- def self.get_or_create_securitygroup(role, environment, zone, groupname=nil)
36
- return "sg-test#{SecureRandom.hex(2)}" if ENV['DRYRUN']
37
- configure_ec2 zone.chop
38
- ec2 = AWS::EC2.new
39
- groupname = groupname || "#{role}-#{environment}"
40
- ec2.security_groups.each do |group|
41
- if group.name == groupname
42
- return group.id
43
- end
44
- end
45
- internet = ['0.0.0.0/0']
46
- sg = ec2.security_groups.create(groupname)
47
- sg.authorize_ingress :tcp, 22, *internet
48
- return sg.id
49
- end
50
-
51
- def self.create_ec2_instance(ec2opts, data, retries=3, sleeptime=0.5)
52
- if ENV['DRYRUN']
53
- id = "i-test#{SecureRandom.hex(2)}"
54
- return {id: id,
55
- hostname: "test-#{id}.#{data[:zone].chop}.compute.amazonaws.com",
56
- instance: nil,
57
- launch_time: Time.now.to_i}
58
- end
59
- configure_ec2 data[:zone].chop
60
- ec2 = AWS::EC2.new
61
-
62
- i = 0
63
- begin
64
- instance = ec2.instances.create(ec2opts)
65
- @@logger.debug("Spawned instance #{instance.id}")
66
- rescue => e
67
- i += 1
68
- raise if i > retries
69
- @@logger.error("Error while creating instance: #{e}: sleeping #{sleeptime}s and retrying (#{i}/#{retries})")
70
- sleep sleeptime
71
- retry
72
- end
73
-
74
- i = 0
75
- begin
76
- hostname = instance.public_dns_name
77
- rescue => e
78
- i += 1
79
- if i > retries
80
- @@logger.error("Could not get hostname for instance #{instance} after #{retries} retries, setting to nil")
81
- hostname = nil
82
- Airbrake.notify_or_ignore(
83
- e,
84
- error_class: "EC2 public dns fail",
85
- parameters: {instance: instance.id, role: data['role'], environment: data['environment'], hostname: nil}
86
- )
87
- else
88
- @@logger.error("Error getting hostname for instance: #{e}: sleeping #{sleeptime}s and retrying (#{i}/#{retries})")
89
- sleep sleeptime
90
- retry
91
- end
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
-
118
- {
119
- id: instance.id,
120
- instance: instance,
121
- hostname: hostname,
122
- launch_time: launch_time
123
- }
124
- end
125
-
126
- def self.tag_ec2_instance(instance, key, value, retries=5, sleeptime=0.5)
127
- return true if ENV['DRYRUN']
128
- i = 0
129
- begin
130
- instance.add_tag(key, value: value)
131
- @@logger.debug("Added tag #{key}=#{value} to #{instance.id}")
132
- true
133
- rescue => e
134
- i += 1
135
- raise if i > retries
136
- @@logger.error("Error adding tag #{key} to #{instance.id}: #{e}: sleeping #{sleeptime}s and retrying (#{i}/#{retries})")
137
- sleep sleeptime
138
- retry
139
- end
140
- end
141
-
142
- def self.terminate_ec2_instance(zone, id)
143
- return if ENV['DRYRUN']
144
- configure_ec2 zone
145
- ec2 = AWS::EC2.new
146
- instance = ec2.instances[id]
147
- instance.terminate
148
- end
149
-
150
- def self.get_ec2_instance_data(zone, id)
151
- if ENV['DRYRUN']
152
- return {
153
- hostname: 'fake.hostname.gild.com'
154
- }
155
- end
156
- configure_ec2 zone
157
- ec2 = AWS::EC2.new
158
- instance = ec2.instances[id]
159
- return {
160
- hostname: instance.dns_name
161
- }
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
178
- end
179
- end
data/lib/helpers/init.rb DELETED
@@ -1,4 +0,0 @@
1
- # encoding: utf-8
2
- require_relative 'ec2'
3
- require_relative 'rehash'
4
- require_relative 'data'
data/lib/helpers/redis.rb DELETED
@@ -1,23 +0,0 @@
1
- require 'redis'
2
- require 'redis-namespace'
3
-
4
- # docker links support
5
- unless ENV['REDIS_PORT_6379_TCP_ADDR'].nil?
6
- ENV['REDIS_HOST'] = ENV['REDIS_PORT_6379_TCP_ADDR']
7
- ENV['REDIS_PORT'] = ENV['REDIS_PORT_6379_TCP_PORT']
8
- ENV.delete('REDIS_PASS')
9
- end
10
-
11
- ENV['REDIS_HOST'] = 'localhost' unless ENV['REDIS_HOST']
12
- ENV['REDIS_PORT'] = '6379' unless ENV['REDIS_PORT']
13
- ENV['REDIS_PASS'] = nil unless ENV['REDIS_PASS']
14
- ENV['REDIS_DB'] = '0' unless ENV['REDIS_DB']
15
-
16
- prefix = ENV.fetch('REDIS_PREFIX', 'gt')
17
-
18
- conn = Redis.new(:host => ENV['REDIS_HOST'],
19
- :port => ENV['REDIS_PORT'].to_i,
20
- :password => ENV['REDIS_PASS'],
21
- :db => ENV['REDIS_DB'].to_i)
22
-
23
- $redis = Redis::Namespace.new(prefix, redis: conn)
@@ -1,83 +0,0 @@
1
- require_relative "ec2"
2
- require_relative "data"
3
- require "logger"
4
-
5
- module Gaptool
6
- module EC2
7
- def self.rehash()
8
- Gaptool::Data::servers.each do |inst|
9
- Gaptool::Data::rmserver inst
10
- end
11
- roles = Gaptool::Data::roles
12
- Gaptool::Data::zones.each do |zone|
13
- Gaptool::EC2::configure_ec2 zone
14
- @ec2 = AWS::EC2.new
15
- ilist = []
16
- @ec2.instances.each do |instance|
17
- if instance.tags['gaptool'] == 'yes' && instance.status == :running
18
- ilist << instance
19
- end
20
- end
21
- ilist.each do |instance|
22
- puts " - #{instance.tags['Name']}"
23
- role, environment, iid = instance.tags['Name'].split('-', 3)
24
- data = {
25
- "zone"=> instance.availability_zone,
26
- "role"=> role,
27
- "environment"=> environment,
28
- "hostname" => instance.public_dns_name,
29
- "launch_time" => instance.launch_time.to_s,
30
- "apps" => roles[role].to_s,
31
- "instance"=> instance.instance_id,
32
- "security_group" => instance.security_groups[0].name
33
- }
34
- Gaptool::Data::addserver(iid, data, nil)
35
- end
36
- end
37
- return {"action" => "complete"}
38
- end
39
-
40
- def self.rehash_property(property)
41
- Gaptool::Data::servers.each do |id|
42
- rehash_property_for_instance(property, id)
43
- end
44
- end
45
-
46
- def self.rehash_properties_for_instance(instance_id)
47
- res = {}
48
- %w[hostname itype security_group].each do |property|
49
- res[property] = self.rehash_property_for_instance(property, instance_id, false)
50
- end
51
- Gaptool::Data::set_server_data_attributes(instance_id, res)
52
- end
53
-
54
- def self.rehash_property_for_instance(property, instance_id, save=true)
55
- logger = Logger.new(STDOUT)
56
- data = Gaptool::Data.get_server_data(instance_id)
57
- return false if data.nil? || data['zone'].nil? || data['zone'].empty?
58
- Gaptool::EC2::configure_ec2 data['zone'].chop
59
- ec2 = AWS::EC2.new(region: data['zone'].chop)
60
- logger.info("Updating #{property} for #{instance_id} in zone #{data['zone'].chop}")
61
- instance = ec2.instances[instance_id]
62
- return false if instance.nil?
63
- case property
64
- when "hostname"
65
- value = instance.public_dns_name
66
- when "itype"
67
- value = instance.instance_type
68
- when "security_group"
69
- value = instance.security_groups[0].name
70
- when "launch_time"
71
- value = instance.launch_time.to_i
72
- else
73
- return false
74
- end
75
- logger.info("Setting #{property} to #{value} for #{instance_id}")
76
- if save
77
- Gaptool::Data.set_server_data_attr(instance_id, property, value)
78
- else
79
- value
80
- end
81
- end
82
- end
83
- end
data/lib/views/init.erb DELETED
@@ -1,18 +0,0 @@
1
- #!/bin/bash
2
- set -e
3
- cd /root
4
- apt-get update
5
- apt-get install -ymq zsh git libssl-dev ruby1.9.1-full build-essential
6
- curl -LO https://www.getchef.com/chef/install.sh
7
- bash install.sh -v <%= chef_version %>
8
-
9
- cat << 'EOFKEY' > /root/.ssh/id_rsa
10
- <%= initkey %>
11
- EOFKEY
12
- chmod 600 /root/.ssh/id_rsa
13
- echo 'StrictHostKeyChecking no' > /root/.ssh/config
14
-
15
- git clone -b <%= chef_branch %> <%= chef_repo %> /root/ops
16
- echo '<%= json %>' > /root/init.json
17
- chef-solo -c /root/ops/cookbooks/init.rb -j /root/init.json -E <%= chef_environment %> && \
18
- (rm /root/.ssh/id_rsa; userdel -r ubuntu; rm -rf /root/.ssh; rm -rf /root/ops)