gaptool-server 0.7.0 → 0.7.1

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.
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)