gaptool-server 0.6.4 → 0.6.6

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: 3ddb439ba551286b15caaccf7ba3990faec9dcbb
4
- data.tar.gz: 3e4e425e4cb7d018903ed538a367af4f736dd83d
3
+ metadata.gz: 6323ce0f24d59f15f894675c6cf76724f5b8ace1
4
+ data.tar.gz: 4af7e863c6b3527d54ff458fa29cdaebf09583eb
5
5
  SHA512:
6
- metadata.gz: 5fd00e76e360031a00389f6ab31735007e70e31366b230430055825417cbaaf99534c64b5ef3498e39484883cbcf082f41e76cf21777ab957959812a75b50005
7
- data.tar.gz: 5894bb1f4762abbb4fed353324dc8ae5f4c00179c098d9dcd789f370362da914be9df30b06e33909dafc4c330ca95942e0746eb68b4b77179e651cf46cbf099d
6
+ metadata.gz: 8bb6202e2fc26965a53acad59625830ea198cd7c930414d005b4977291a49c1a79823e5a29ad00c8c97ed68f0a979ab047f93d5933203455f199138d29f7a1b0
7
+ data.tar.gz: 97cdc9abf27d57332ef261dac8b7919bd732102362d6b5a79bf70b26df9870ab4e1c8911edfe8c2c59a3cf050036f1a9f77477a355988f6f82a2cc82f25fcc31
data/Rakefile CHANGED
@@ -4,10 +4,12 @@ Dir.chdir(File.dirname(__FILE__))
4
4
  require 'shellwords'
5
5
  require 'rspec/core/rake_task'
6
6
  require_relative 'lib/helpers/redis'
7
+ require_relative 'lib/helpers/ec2'
7
8
  require_relative 'lib/helpers/init'
8
9
  require_relative 'lib/helpers/rehash'
9
10
 
10
11
  DH = Gaptool::Data
12
+ EC2 = Gaptool::EC2
11
13
  $stdout.sync = true
12
14
 
13
15
  def sys(cmd)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.4
1
+ 0.6.6
@@ -0,0 +1,18 @@
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
data/lib/app.rb CHANGED
@@ -9,14 +9,16 @@ require 'openssl'
9
9
  require 'net/ssh'
10
10
  require 'peach'
11
11
  require 'airbrake'
12
+ require 'logger'
12
13
  require_relative 'exceptions'
13
14
 
14
15
  class GaptoolServer < Sinatra::Application
15
16
  helpers Sinatra::JSON
17
+ use Airbrake::Sinatra
16
18
 
17
19
  def error_response msg=''
18
- message = "#{env['sinatra.error'].message}"
19
- message = "#{msg} #{message}" unless msg.empty?
20
+ message = env['sinatra_error'].nil? ? "" : " #{env['sinatra.error'].message}"
21
+ message = "#{msg}#{message}" unless msg.empty?
20
22
  json result: 'error', message: message
21
23
  end
22
24
 
@@ -30,6 +32,10 @@ class GaptoolServer < Sinatra::Application
30
32
  error_response
31
33
  end
32
34
 
35
+ def unauthenticated
36
+ halt(401, error_response("Unauthenticated"))
37
+ end
38
+
33
39
  error do
34
40
  status 500
35
41
  error_response
@@ -39,8 +45,8 @@ class GaptoolServer < Sinatra::Application
39
45
  unless ENV['AIRBRAKE_API_KEY'].nil?
40
46
  Airbrake.configure do |cfg|
41
47
  cfg.api_key = ENV['AIRBRAKE_API_KEY']
48
+ cfg.logger = Logger.new(STDOUT)
42
49
  end
43
- use Airbrake::Sinatra
44
50
  end
45
51
  disable :sessions
46
52
  enable :dump_errors
@@ -50,8 +56,8 @@ class GaptoolServer < Sinatra::Application
50
56
  before do
51
57
  if request.path_info != '/ping' && ENV['GAPTOOL_DISABLE_AUTH'].nil?
52
58
  user = Gaptool::Data.user(env['HTTP_X_GAPTOOL_USER'])
53
- raise Unauthenticated if user.nil?
54
- raise Unauthenticated unless user[:key] == env['HTTP_X_GAPTOOL_KEY']
59
+ return unauthenticated if user.nil?
60
+ return unauthenticated unless user[:key] == env['HTTP_X_GAPTOOL_KEY']
55
61
  end
56
62
  end
57
63
 
data/lib/exceptions.rb CHANGED
@@ -18,10 +18,6 @@ class BadRequest < ClientError
18
18
  @code = 400
19
19
  end
20
20
 
21
- class Unauthenticated < ClientError
22
- @code = 401
23
- end
24
-
25
21
  class Forbidden < ClientError
26
22
  @code = 403
27
23
  end
data/lib/helpers/data.rb CHANGED
@@ -49,6 +49,11 @@ module Gaptool
49
49
  $redis.hset("instance:#{instance}", attr, value)
50
50
  end
51
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
+
52
57
  def self.save_server_data(instance, data)
53
58
 
54
59
  unless data['chef_runlist'].nil?
@@ -151,8 +156,9 @@ module Gaptool
151
156
  rs['chef_runlist'] = default_runlist
152
157
  end
153
158
 
154
- rs['apps'] = apps_in_role(rs['role'])
155
159
  rs.delete_if {|k,v| v.nil? || (!!v != v && v.empty?)}
160
+ rs['apps'] = apps_in_role(rs['role'])
161
+ rs
156
162
  end
157
163
 
158
164
  def self.save_role_data(role, data)
@@ -161,6 +167,10 @@ module Gaptool
161
167
  amis = data.delete("amis") || {}
162
168
  overwrite_hash("role:#{role}:amis", amis)
163
169
  end
170
+ if data['sg']
171
+ sgs = data.delete("sg") || {}
172
+ overwrite_hash("role:#{role}:sg", sgs)
173
+ end
164
174
  if data['apps']
165
175
  apps = data.delete("apps") || []
166
176
  apps.each {|a| add_app(a, role)}
@@ -173,14 +183,18 @@ module Gaptool
173
183
  res = $redis.hgetall("role:#{role}")
174
184
  res['apps'] = apps_in_role(role)
175
185
  res['amis'] = $redis.hgetall("role:#{role}:amis")
186
+ res['sg'] = $redis.hgetall("role:#{role}:sg")
176
187
  res
177
188
  end
178
189
 
179
190
  def self.get_ami_for_role(role, region=nil)
180
-
181
191
  $redis.hget("role:#{role}:amis", region) || $redis.hget("amis", region)
182
192
  end
183
193
 
194
+ def self.get_sg_for_role(role, environment)
195
+ $redis.hget("role:#{role}:sg", environment) || "#{role}-#{environment}"
196
+ end
197
+
184
198
  def self.get_runlist_for_role(role)
185
199
  rl = $redis.hget("role:#{role}", "chef_runlist")
186
200
  return nil if rl.nil?
@@ -257,7 +271,7 @@ module Gaptool
257
271
  end
258
272
 
259
273
  def self.stringify_apps(rs)
260
- unless rs['apps'].nil?
274
+ if !rs.nil? && !rs['apps'].nil?
261
275
  rs['apps'] = rs['apps'].to_json
262
276
  end
263
277
  rs
data/lib/helpers/ec2.rb CHANGED
@@ -1,9 +1,12 @@
1
1
  require 'aws-sdk'
2
2
  require 'securerandom'
3
+ require 'logger'
4
+ require 'airbrake'
3
5
 
4
6
  # encoding: utf-8
5
7
  module Gaptool
6
8
  module EC2
9
+ @@logger = Logger.new(STDERR)
7
10
 
8
11
  def self.configure_ec2 zone
9
12
  return if ENV['DRYRUN']
@@ -45,28 +48,79 @@ module Gaptool
45
48
  return sg.id
46
49
  end
47
50
 
48
- def self.create_ec2_instance(ec2opts, data)
51
+ def self.create_ec2_instance(ec2opts, data, retries=3, sleeptime=0.5)
49
52
  if ENV['DRYRUN']
50
53
  id = "i-test#{SecureRandom.hex(2)}"
51
54
  return {id: id,
52
55
  hostname: "test-#{id}.#{data[:zone].chop}.compute.amazonaws.com",
56
+ instance: nil,
53
57
  launch_time: Time.now.to_s}
54
58
  end
55
59
  configure_ec2 data[:zone].chop
56
60
  ec2 = AWS::EC2.new
57
61
 
58
- instance = ec2.instances.create(ec2opts)
59
- instance.add_tag('Name', value: "#{data[:role]}-#{data[:env]}-#{instance.id}")
60
- instance.add_tag('gaptool', :value => "yes")
61
- launch_time = instance.launch_time.to_s
62
- launch_time = launch_time.empty? ? Time.now.to_s : launch_time
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
+ 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
+ i = 0
82
+ begin
83
+ hostname = instance.public_dns_name
84
+ rescue => e
85
+ i += 1
86
+ if i > retries
87
+ @@logger.error("Could not get hostname for instance #{instance} after #{retries} retries, setting to nil")
88
+ hostname = nil
89
+ Airbrake.notify_or_ignore(
90
+ e,
91
+ error_class: "EC2 public dns fail",
92
+ parameters: {instance: instance[:id], role: data['role'], environment: data['environment'], hostname: nil}
93
+ )
94
+ else
95
+ @@logger.error("Error getting hostname for instance: #{e}: sleeping #{sleeptime}s and retrying (#{i}/#{retries})")
96
+ sleep sleeptime
97
+ retry
98
+ end
99
+ end
63
100
  {
64
101
  id: instance.id,
65
- hostname: instance.public_dns_name,
102
+ instance: instance,
103
+ hostname: hostname,
66
104
  launch_time: launch_time
67
105
  }
68
106
  end
69
107
 
108
+ def self.tag_ec2_instance(instance, key, value, retries=5, sleeptime=0.5)
109
+ return true if ENV['DRYRUN']
110
+ i = 0
111
+ begin
112
+ instance.add_tag(key, value: value)
113
+ @@logger.debug("Added tag #{key}=#{value} to #{instance.id}")
114
+ true
115
+ rescue => e
116
+ i += 1
117
+ raise if i > retries
118
+ @@logger.error("Error adding tag #{key} to #{instance.id}: #{e}: sleeping #{sleeptime}s and retrying (#{i}/#{retries})")
119
+ sleep sleeptime
120
+ retry
121
+ end
122
+ end
123
+
70
124
  def self.terminate_ec2_instance(zone, id)
71
125
  return if ENV['DRYRUN']
72
126
  configure_ec2 zone
@@ -1,5 +1,6 @@
1
1
  require_relative "ec2"
2
2
  require_relative "data"
3
+ require "logger"
3
4
 
4
5
  module Gaptool
5
6
  module EC2
@@ -27,12 +28,54 @@ module Gaptool
27
28
  "hostname" => instance.public_dns_name,
28
29
  "launch_time" => instance.launch_time.to_s,
29
30
  "apps" => roles[role].to_s,
30
- "instance"=> instance.instance_id
31
+ "instance"=> instance.instance_id,
32
+ "security_group" => instance.security_groups[0].name
31
33
  }
32
34
  Gaptool::Data::addserver(iid, data, nil)
33
35
  end
34
36
  end
35
37
  return {"action" => "complete"}
36
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::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
+ else
71
+ return false
72
+ end
73
+ if save
74
+ logger.info("Setting #{property} to #{value} for #{instance_id}")
75
+ Gaptool::Data.set_server_data_attr(instance_id, property, value)
76
+ else
77
+ value
78
+ end
79
+ end
37
80
  end
38
81
  end
data/lib/routes.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  require 'securerandom'
3
3
  require 'set'
4
4
  require_relative 'exceptions'
5
+
5
6
  class GaptoolServer < Sinatra::Application
6
7
 
7
8
  def require_parameters(required_keys, data)
@@ -27,8 +28,8 @@ class GaptoolServer < Sinatra::Application
27
28
  JSON.parse(request.body.read))
28
29
 
29
30
  secret = SecureRandom.hex(12)
30
- security_group = data['security_group'] || Gaptool::Data::get_role_data(data['role'])["security_group"]
31
- sgid = Gaptool::EC2::get_or_create_securitygroup(data['role'], data['environment'], data['zone'], security_group)
31
+ data['security_group'] = data['security_group'] || Gaptool::Data::get_sg_for_role(data['role'], data['environment'])
32
+ sgid = Gaptool::EC2::get_or_create_securitygroup(data['role'], data['environment'], data['zone'], data['security_group'])
32
33
  image_id = data['ami'] || Gaptool::Data::get_ami_for_role(data['role'], data['zone'].chop)
33
34
  data['terminable'] = data['terminable'].nil? ? true : !!data['terminable']
34
35
  data['secret'] = secret
@@ -47,8 +48,26 @@ class GaptoolServer < Sinatra::Application
47
48
  zone: data['zone']
48
49
  }
49
50
  )
51
+
52
+ # Tag instance
53
+ role = data['role']
54
+ env = data['environment']
55
+ name = "#{role}-#{env}-#{instance[:id]}"
56
+ {'Name' => name, 'gaptool' => 'yes', 'role' => role, 'environment' => env}.each do |tag, value|
57
+ begin
58
+ Gaptool::EC2::tag_ec2_instance(instance[:instance], tag, value)
59
+ rescue => e
60
+ logger.error("Error while tagging: #{e}. Skipping tag")
61
+ Airbrake.notify_or_ignore(
62
+ e,
63
+ error_class: "EC2 Tag failed",
64
+ parameters: {instance: instance[:id], name: name, role: role, environment: env}
65
+ )
66
+ end
67
+ end
68
+
50
69
  # Add host tag
51
- data.merge(instance.reject { |k, v| k == :id })
70
+ data.merge(instance.reject { |k, v| [:id, :instance].include?(k) })
52
71
  Gaptool::Data::addserver(instance[:id], data, secret)
53
72
  json({instance: instance[:id],
54
73
  ami: image_id,
@@ -139,7 +158,13 @@ class GaptoolServer < Sinatra::Application
139
158
  end
140
159
 
141
160
  get '/instance/:id' do
142
- json Gaptool::Data::stringify_apps(Gaptool::Data::get_server_data(params[:id]))
161
+ rs = Gaptool::Data::get_server_data(params[:id])
162
+ if rs.nil?
163
+ status 404
164
+ error_response "instance with id '#{params[:id]}' not found"
165
+ else
166
+ json Gaptool::Data::stringify_apps(rs)
167
+ end
143
168
  end
144
169
 
145
170
  get '/hosts/:role/:environment' do
data/tasks/ec2.rb ADDED
@@ -0,0 +1,44 @@
1
+ namespace :ec2 do
2
+ desc "Rehash instances"
3
+ task :rehash do |t|
4
+ EC2.rehash
5
+ end
6
+
7
+ desc "Rehash single attribute of all instances"
8
+ task :rehash_attr_all, [:property] do |t, args|
9
+ if args[:property].nil?
10
+ puts "Missing property"
11
+ return 1
12
+ end
13
+ EC2.rehash_property(args[:property])
14
+ end
15
+
16
+ desc "Rehash ec2 attributes for a single instance"
17
+ task :rehash_attrs_for, [:instance] do |t, args|
18
+ if args[:instance].nil?
19
+ puts "Missing instance"
20
+ return 1
21
+ end
22
+ res = EC2.rehash_properties_for_instance(args[:instance])
23
+ return 1 unless res
24
+ end
25
+
26
+ desc "Rehash a single property for an instance"
27
+ task :rehash_attr_for, [:instance, :property] do |t, args|
28
+ if args[:instance].nil?
29
+ puts "Missing instance"
30
+ return 1
31
+ end
32
+ if args[:property].nil?
33
+ puts "Missing property"
34
+ return 1
35
+ end
36
+ res = EC2.rehash_property_for_instance(args[:property], args[:instance])
37
+ if res
38
+ puts "#{property} for instance #{instance} set to '#{res}'"
39
+ else
40
+ return 1
41
+ end
42
+ end
43
+
44
+ end
data/tasks/role.rb ADDED
@@ -0,0 +1,9 @@
1
+ namespace :role do
2
+ desc "Set security group for a role"
3
+ task :set_sg, [:role, :environment, :security_group] do |t, args|
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])
6
+ role['sg'].merge!(args[:environment] => args[:security_group])
7
+ DH.save_role_data(args[:role], role)
8
+ end
9
+ end
data/tasks/server.rb CHANGED
@@ -8,4 +8,13 @@ namespace :server do
8
8
  DH.set_server_data_attr args[:instance], 'terminable', (args[:value] == "true" ? "true" : "false")
9
9
  puts DH.get_server_data args[:instance]
10
10
  end
11
+
12
+ desc "Remove a server from the gaptool database (no actions on AWS)"
13
+ task :rm, [:instance] do |t, args|
14
+ if args[:instance].nil?
15
+ puts "You must select an instance"
16
+ return 1
17
+ end
18
+ DH.rmserver(args[:instance])
19
+ end
11
20
  end
data/test/api_test.rb CHANGED
@@ -79,6 +79,23 @@ describe "Test API" do
79
79
  expect(resp['chef_runlist']).to eq(['recipe[other]'])
80
80
  end
81
81
 
82
+ it "should get the security group from the role" do
83
+ DH.save_role_data(host_data['role'], "sg" => {host_data['environment'] => "mysg-in-role"})
84
+ id = add_and_register_server(host_data.reject{|k,v| k == 'security_group'})['instance']
85
+ get "/host/testrole/testenv/#{id}"
86
+ resp = JSON.parse(last_response.body)
87
+ expect(resp.keys).to include("security_group")
88
+ expect(resp['security_group']).to eq("mysg-in-role")
89
+ end
90
+
91
+ it "should get the default security group" do
92
+ id = add_and_register_server(host_data.reject{|k,v| k == 'security_group'})['instance']
93
+ get "/host/testrole/testenv/#{id}"
94
+ resp = JSON.parse(last_response.body)
95
+ expect(resp.keys).to include("security_group")
96
+ expect(resp['security_group']).to eq("#{host_data['role']}-#{host_data['environment']}")
97
+ end
98
+
82
99
  it "should remove default runlist" do
83
100
  id = add_and_register_server(host_data.merge("chef_runlist"=> ['recipe[init]']))['instance']
84
101
  get "/host/testrole/testenv/#{id}"
@@ -93,7 +110,6 @@ describe "Test API" do
93
110
  resp = JSON.parse(last_response.body)
94
111
  expect(resp.keys).not_to include("chef_runlist")
95
112
  expect(resp['chef_runlist']).to be(nil)
96
-
97
113
  end
98
114
 
99
115
  it "should get the ami from the role" do
@@ -188,7 +204,8 @@ describe "Test API" do
188
204
  id = add_and_register_server()['instance']
189
205
  get '/hosts'
190
206
  expect(last_response.status).to eq(200)
191
- exp_data = host_data.reject{|k,v| k == 'terminable'}.merge('chef_runlist' => expanded_runlist)
207
+ exp_data = host_data.reject{|k,v| k == 'terminable'}.merge('chef_runlist' => expanded_runlist,
208
+ 'apps'=> [])
192
209
  exp_data['instance'] = id
193
210
  expect(JSON.parse(last_response.body)).to eq([exp_data])
194
211
  end
@@ -200,9 +217,11 @@ describe "Test API" do
200
217
  expect(last_response.status).to eq(200)
201
218
  exp_data = [
202
219
  host_data.reject{|k,v| k == 'terminable'}.merge({'instance' => id1,
203
- 'chef_runlist' => expanded_runlist}),
220
+ 'chef_runlist' => expanded_runlist,
221
+ 'apps' => []}),
204
222
  host_data.reject{|k,v| k == 'terminable'}.merge({'instance' => id2,
205
- 'chef_runlist' => expanded_runlist})
223
+ 'chef_runlist' => expanded_runlist,
224
+ 'apps' => []})
206
225
  ].to_set
207
226
  expect(JSON.parse(last_response.body).to_set).to eq(exp_data)
208
227
  end
@@ -215,7 +234,8 @@ describe "Test API" do
215
234
  get '/hosts/otherrole'
216
235
  expect(last_response.status).to eq(200)
217
236
  exp_data = [other.reject{|k,v| k == 'terminable'}.merge({'instance'=> id1,
218
- 'chef_runlist' => expanded_runlist})]
237
+ 'chef_runlist' => expanded_runlist,
238
+ 'apps' => []})]
219
239
  expect(JSON.parse(last_response.body)).to eq(exp_data)
220
240
  end
221
241
 
@@ -226,11 +246,21 @@ describe "Test API" do
226
246
  expect(last_response.status).to eq(200)
227
247
  exp_data = host_data.reject{|k,v| k == 'terminable'}.merge({
228
248
  'instance'=> id,
229
- 'chef_runlist' => expanded_runlist})
249
+ 'chef_runlist' => expanded_runlist,
250
+ 'apps' => "[]"})
230
251
  expect(JSON.parse(last_response.body)).to eq(exp_data)
231
252
  end
232
253
  end
233
254
 
255
+ it "should not find an host by id" do
256
+ add_and_register_server()['instance']
257
+ get '/instance/other'
258
+ expect(last_response.status).to eq(404)
259
+ expect(JSON.parse(last_response.body)).to eq(
260
+ {"result" => "error",
261
+ "message" => "instance with id 'other' not found"})
262
+ end
263
+
234
264
  it "should find all hosts by environment and role" do
235
265
  id1 = add_and_register_server()['instance']
236
266
  id2 = add_and_register_server()['instance']
@@ -238,7 +268,7 @@ describe "Test API" do
238
268
  id4 = add_and_register_server(host_data.merge({'role' => 'otherrole'}))['instance']
239
269
  get '/hosts/testrole/testenv'
240
270
  expect(last_response.status).to eq(200)
241
- d = host_data.reject{|k,v| k == 'terminable'}.merge('chef_runlist' => expanded_runlist)
271
+ d = host_data.reject{|k,v| k == 'terminable'}.merge('chef_runlist' => expanded_runlist, 'apps'=> '[]')
242
272
  exp_data = [
243
273
  d.merge({'instance' => id1}),
244
274
  d.merge({'instance' => id2})
data/test/data_test.rb CHANGED
@@ -36,7 +36,8 @@ describe "data helpers" do
36
36
  'chef_repo' => 'myrepo',
37
37
  'chef_branch' => 'master',
38
38
  'registered' => 'false',
39
- 'secret' => 'secret'
39
+ 'secret' => 'secret',
40
+ 'apps' => []
40
41
  }))
41
42
  end
42
43
 
@@ -46,7 +47,8 @@ describe "data helpers" do
46
47
  expect(server).to eq(data.merge({
47
48
  'instance' => instid,
48
49
  'chef_repo' => 'myrepo',
49
- 'chef_branch' => 'master'
50
+ 'chef_branch' => 'master',
51
+ 'apps' => []
50
52
  }))
51
53
  end
52
54
 
@@ -61,7 +63,8 @@ describe "data helpers" do
61
63
  expect(server).to eq(data.merge({
62
64
  'instance' => instid,
63
65
  'chef_repo' => 'myrepo',
64
- 'chef_branch' => 'master'
66
+ 'chef_branch' => 'master',
67
+ 'apps' => []
65
68
  }))
66
69
  end
67
70
 
@@ -94,7 +97,8 @@ describe "data helpers" do
94
97
  'instance' => instid,
95
98
  'chef_repo' => 'myrepo',
96
99
  'chef_branch' => 'master',
97
- 'initkey' => 'FAKEKEY'
100
+ 'initkey' => 'FAKEKEY',
101
+ 'apps' => []
98
102
  }))
99
103
  end
100
104
 
@@ -104,12 +108,14 @@ describe "data helpers" do
104
108
  role = DH.get_role_data("role")
105
109
  expect(role).to eq({"chef_runlist"=> ["recipe[myrecipe]"].to_json,
106
110
  "apps" => [],
107
- "amis" => {}})
111
+ "amis" => {},
112
+ "sg" => {}})
108
113
  server = DH.get_server_data(instid)
109
114
  expect(server).to eq(data.merge("instance" => instid,
110
115
  "chef_runlist" => ["recipe[myrecipe]"],
111
116
  "chef_repo" => "myrepo",
112
- "chef_branch" => "master" ))
117
+ "chef_branch" => "master",
118
+ "apps" => [] ))
113
119
  end
114
120
 
115
121
  it "shoud get the ami for a node from the role" do
@@ -118,6 +124,16 @@ describe "data helpers" do
118
124
  role = DH.get_role_data("role")
119
125
  expect(role).to eq({'ami' => 'ami-1234567',
120
126
  "apps" => [],
121
- "amis" => {}})
127
+ "amis" => {},
128
+ "sg" => {}})
129
+ end
130
+
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")
134
+ expect(role).to eq({'ami' => 'ami-1234567',
135
+ "apps" => [],
136
+ "amis" => {},
137
+ "sg" => {"test" => "my_role"}})
122
138
  end
123
139
  end
data/test/test_helper.rb CHANGED
@@ -6,7 +6,8 @@ if ENV['COVERAGE']
6
6
  add_group 'helpers', 'lib/helpers'
7
7
  end
8
8
  end
9
-
9
+ # Clear airbrake env if set
10
+ ENV['AIRBRAKE_API_KEY'] = nil
10
11
  libpath = File.realpath(File.join(File.dirname(__FILE__), "..", "lib"))
11
12
  require 'rspec'
12
13
  require 'rack/test'
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.6.4
4
+ version: 0.6.6
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: 2014-12-12 00:00:00.000000000 Z
13
+ date: 2015-01-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sinatra
@@ -166,6 +166,20 @@ dependencies:
166
166
  - - "~>"
167
167
  - !ruby/object:Gem::Version
168
168
  version: '1.5'
169
+ - !ruby/object:Gem::Dependency
170
+ name: json
171
+ requirement: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - "~>"
174
+ - !ruby/object:Gem::Version
175
+ version: '1.8'
176
+ type: :runtime
177
+ prerelease: false
178
+ version_requirements: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - "~>"
181
+ - !ruby/object:Gem::Version
182
+ version: '1.8'
169
183
  - !ruby/object:Gem::Dependency
170
184
  name: rspec
171
185
  requirement: !ruby/object:Gem::Requirement
@@ -227,7 +241,7 @@ email: ops@gild.com
227
241
  executables:
228
242
  - gaptool-server
229
243
  - gaptool-shell
230
- - gaptool_server_migrate_0.5-0.6
244
+ - gaptool_migrate_security_groups
231
245
  extensions: []
232
246
  extra_rdoc_files:
233
247
  - LICENSE.txt
@@ -241,7 +255,7 @@ files:
241
255
  - VERSION
242
256
  - bin/gaptool-server
243
257
  - bin/gaptool-shell
244
- - bin/gaptool_server_migrate_0.5-0.6
258
+ - bin/gaptool_migrate_security_groups
245
259
  - config.ru
246
260
  - lib/app.rb
247
261
  - lib/exceptions.rb
@@ -255,7 +269,9 @@ files:
255
269
  - tasks/app.rb
256
270
  - tasks/config.rb
257
271
  - tasks/docker.rb
272
+ - tasks/ec2.rb
258
273
  - tasks/gem.rb
274
+ - tasks/role.rb
259
275
  - tasks/server.rb
260
276
  - tasks/user.rb
261
277
  - test/api_test.rb
@@ -1,113 +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
- puts "Removing cruft"
13
- # First, remove cruft. Like all servers created but never registered, etc
14
- ['instance:*', '_*', 'apikey:*', 'service:*', 'running', 'ec2*',
15
- 'failover', 'capacity', 'sg:*'].each do |pattern|
16
- $redis.redis.keys(pattern).each do |key|
17
- $redis.redis.del key
18
- end
19
- end
20
-
21
- puts "Migrating roles..."
22
- $redis.redis.keys('role:*').each do |key|
23
- puts " - #{key}"
24
- data = $redis.redis.hgetall(key)
25
- role = key.sub('role:', '')
26
- unless data['ami'].nil?
27
- # We didn't have per-regin ami in roles, so
28
- # default to us-west-2
29
- data['amis'] = {'us-west-2' => data['ami']}
30
- role.delete('ami')
31
- end
32
- DH.save_role_data(role, data)
33
- end
34
-
35
- puts "Migrating ami info to role..."
36
- $redis.redis.keys('amis:*').each do |key|
37
- role = key.sub("amis:", '')
38
- puts " - #{key}"
39
- amis = $redis.redis.hgetall(key)
40
- roledata = DH.get_role_data(role)
41
- roledata['amis'] = amis.merge(roledata['amis'] || {})
42
- DH.save_role_data(role, roledata)
43
- $redis.redis.del(key)
44
- end
45
-
46
- puts "Migrating apps..."
47
- $redis.redis.keys('app:*').each do |key|
48
- puts " - #{key}"
49
- appname = key.sub('app:', '')
50
- role = $redis.redis.hget(key, "role")
51
- if role.nil? || appname.nil?
52
- puts "Missing info for app: #{appname} role: #{role}"
53
- end
54
- $redis.redis.del(key)
55
- DH.add_app(appname, role) unless role.nil?
56
- end
57
-
58
- puts "Migrating instances..."
59
- $redis.redis.keys('host:*').each do |key|
60
- puts " - #{key}"
61
- pfx, role, env, iid = key.split(':')
62
- data = $redis.redis.hgetall(key)
63
- data['role'] = role
64
- data['environment'] = env
65
- unless data['chef_runlist'].nil?
66
- data['chef_runlist'] = JSON.parse data['chef_runlist']
67
- end
68
- DH.addserver(iid, data, nil)
69
- $redis.redis.del(key)
70
- # remove stale keys from hsh
71
- $redis.hdel "instance:#{iid}", ["capacity", "mirror", "secret", 'instance']
72
- end
73
-
74
- puts "Removing unneeded info from instance data..."
75
- $redis.smembers('instances').each do |inst|
76
- $redis.hdel "instance:#{inst}", ["capacity", "mirror", "secret", "instance"]
77
- if $redis.hget("instance:#{inst}", 'chef_runlist') == "recipe[init]"
78
- $redis.hdel "instance:#{inst}", "chef_runlist"
79
- end
80
- term = $redis.hget("instance:#{inst}", "terminate")
81
- unless term.nil?
82
- unless term == 'true'
83
- $redis.hset("instance:#{inst}", "terminable", term)
84
- end
85
- $redis.hdel("instance:#{inst}", "terminate")
86
- end
87
- end
88
-
89
- puts "Rename old config keys"
90
- $redis.redis.rename('config', 'gt:config')
91
- $redis.hset('config', 'chef_repo', $redis.hget('config', 'chefrepo'))
92
- $redis.hset('config', 'chef_branch', $redis.hget('config', 'chefbranch'))
93
-
94
- puts "Removing old config keys"
95
- ['remoteredis:host', 'remoteredis:port', 'aws_id', 'aws_secret',
96
- 'chefrepo', 'chefbranch'].each do |key|
97
- $redis.hdel 'config', key
98
- end
99
-
100
- unless ARGV[0].nil?
101
- puts "Updating GT_URL to #{ARGV[0]}"
102
- $redis.hset('config', 'url', ARGV[0])
103
- end
104
-
105
- puts "Namespace remaining keys"
106
- ['users', 'amis'].each { |k| $redis.redis.rename(k, "gt:#{k}")}
107
-
108
- puts "Removing out-of-namespace keys"
109
- $redis.redis.keys('*').select { |k| !k.start_with? ('gt:')}.each do |k|
110
- $redis.redis.del(k)
111
- end
112
-
113
- $redis.save