roo_on_rails 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,39 @@
1
+ require 'roo_on_rails/checks/env_specific'
2
+ require 'roo_on_rails/checks/papertrail/token'
3
+
4
+ module RooOnRails
5
+ module Checks
6
+ module Papertrail
7
+ # Check for a configured log destination in Papertrail.
8
+ #
9
+ # Input context
10
+ # - papertrail.client: a connected Papertrail client
11
+ #
12
+ # Output context:
13
+ # - papertrail.dest.host, .port: the destination logging host
14
+ class LogDestinationExists < Base
15
+ requires Token
16
+
17
+ # The shared log destination
18
+ NAME = 'default'.freeze
19
+
20
+ def intro
21
+ "Checking for log destination #{bold NAME}..."
22
+ end
23
+
24
+ def call
25
+ data = context.papertrail.client.list_destinations.find { |h|
26
+ h['syslog']['description'] == NAME
27
+ }
28
+
29
+ fail! "Log destination #{bold NAME} not found" if data.nil?
30
+
31
+ context.papertrail!.dest!.host = data['syslog']['hostname']
32
+ context.papertrail!.dest!.port = data['syslog']['port']
33
+
34
+ pass "logging to #{context.papertrail.dest.host}:#{context.papertrail.dest.port}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,78 @@
1
+ require 'roo_on_rails/checks/env_specific'
2
+ require 'roo_on_rails/checks/heroku/app_exists'
3
+ require 'roo_on_rails/checks/heroku/token'
4
+ require 'roo_on_rails/checks/papertrail/token'
5
+ require 'roo_on_rails/checks/papertrail/drain_exists'
6
+
7
+ module RooOnRails
8
+ module Checks
9
+ module Papertrail
10
+ # Checks that the app is declared in Papertrail
11
+ #
12
+ # Input context
13
+ # - heroku.api_client: a connected PlatformAPI client
14
+ # - heroku.app.{env}: an existing app name.
15
+ # - papertrail.system_name.{env}: a Papertrail system name / token
16
+ # - papertrail.client
17
+ # - papertrail.dest.host, .port
18
+ #
19
+ # Output context:
20
+ # - papertrail.system_id.{env}
21
+ class SystemExists < EnvSpecific
22
+ requires Heroku::AppExists
23
+ requires Heroku::Token
24
+ requires Token
25
+ requires DrainExists
26
+ requires LogDestinationExists
27
+
28
+ def intro
29
+ "Checking that #{bold app_name} is logging to Papertrail"
30
+ end
31
+
32
+ def call
33
+ data = context.papertrail.client.list_systems.find { |h|
34
+ h['hostname'] == system_token
35
+ }
36
+ fail! "no system with token '#{system_token}' found" if data.nil?
37
+
38
+ if data.syslog.hostname != context.papertrail.dest.host ||
39
+ data.syslog.port != context.papertrail.dest.port
40
+ final_fail! "system found, but is listening to #{data.syslog.hostname}:#{data.syslog.port} instead of #{context.papertrail.dest.host}:#{context.papertrail.dest.port}"
41
+ end
42
+
43
+ context.papertrail.system_id![env] = data.id
44
+ pass "found system #{data.id} for token #{system_token}"
45
+ end
46
+
47
+ def fix
48
+ # cause the app to log something
49
+ dyno = heroku.dyno.create(app_name, command: 'date')
50
+
51
+ # wait a bit
52
+ 10.times do
53
+ begin
54
+ heroku.dyno.info(app_name, dyno['id'])
55
+ sleep 0.5
56
+ rescue Excon::Error::NotFound
57
+ break
58
+ end
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def system_token
65
+ context.papertrail.system_name[env]
66
+ end
67
+
68
+ def app_name
69
+ context.heroku.app[env]
70
+ end
71
+
72
+ def heroku
73
+ context.heroku.api_client
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,55 @@
1
+ require 'roo_on_rails/checks/env_specific'
2
+ require 'roo_on_rails/checks/heroku/app_exists'
3
+ require 'roo_on_rails/checks/papertrail/token'
4
+ require 'roo_on_rails/checks/papertrail/system_exists'
5
+
6
+ module RooOnRails
7
+ module Checks
8
+ module Papertrail
9
+ # Checks that the Papertrail system for an app in named like the app
10
+ #
11
+ # Input context
12
+ # - heroku.app.{env}
13
+ # - papertrail.system_id.{env}: a Papertrail system ID
14
+ # - papertrail.client
15
+ #
16
+ # Output context:
17
+ # - None
18
+ class SystemNamed < EnvSpecific
19
+ requires Heroku::AppExists
20
+ requires Token
21
+ requires SystemExists
22
+
23
+ def intro
24
+ "Checking that #{bold app_name} is named in Papertrail"
25
+ end
26
+
27
+ def call
28
+ data = context.papertrail.client.get_system(system_id)
29
+
30
+ fail! "wrong name for Papertrail system '#{system_id}' found" if data.name != app_name
31
+
32
+ pass "system #{system_id} named #{app_name}"
33
+ end
34
+
35
+ def fix
36
+ context.papertrail.client.update_system(name: app_name)
37
+ end
38
+
39
+ private
40
+
41
+ def system_id
42
+ context.papertrail.system_id[env]
43
+ end
44
+
45
+ def app_name
46
+ context.heroku.app[env]
47
+ end
48
+
49
+ def heroku
50
+ context.heroku.api_client
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,50 @@
1
+ require 'roo_on_rails/checks/base'
2
+ require 'roo_on_rails/checks/git/origin'
3
+ require 'roo_on_rails/papertrail_client'
4
+ require 'io/console'
5
+ require 'shellwords'
6
+
7
+ module RooOnRails
8
+ module Checks
9
+ module Papertrail
10
+ # Output context:
11
+ # - papertrail.client: a connected Papertrail client
12
+ class Token < Base
13
+ requires Git::Origin
14
+
15
+ def initialize(papertrail_client: nil, **options)
16
+ @papertrail_client = papertrail_client || PapertrailClient
17
+ super(**options)
18
+ end
19
+
20
+ def intro
21
+ 'Obtaining Papertrail auth token...'
22
+ end
23
+
24
+ def call
25
+ status, token = shell.run 'git config papertrail.token'
26
+ fail! 'no Papertrail API token configured' if token.strip.empty? || !status
27
+ token.strip!
28
+
29
+ client = @papertrail_client.new(token: token)
30
+ begin
31
+ client.list_destinations
32
+ rescue Faraday::ClientError => e
33
+ fail! "connecting to Papertrail failed (#{e.message})"
34
+ end
35
+
36
+ pass "connected to Papertrail's API"
37
+ context.papertrail!.client = client
38
+ end
39
+
40
+ def fix
41
+ say 'Enter your Papertrail API token:'
42
+ say 'This can be found at https://papertrailapp.com/account/profile'
43
+ say '(the token will not be echoed on the terminal; paste and press enter)'
44
+ token = IO.console.getpass.strip
45
+ system "git config papertrail.token #{Shellwords.shellescape token}"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -8,6 +8,22 @@ module RooOnRails
8
8
  path = Pathname '.roo_on_rails.yml'
9
9
  path.exist? ? super(path) : new
10
10
  end
11
+
12
+ def sidekiq_enabled?
13
+ enabled? 'SIDEKIQ_ENABLED'
14
+ end
15
+
16
+ def google_auth_enabled?
17
+ enabled? 'GOOGLE_AUTH_ENABLED', default: false
18
+ end
19
+
20
+ private
21
+
22
+ ENABLED_PATTERN = /\A(YES|TRUE|ON|1)\Z/i
23
+
24
+ def enabled?(var, default: 'true')
25
+ ENABLED_PATTERN === ENV.fetch(var, default).to_s
26
+ end
11
27
  end
12
28
  end
13
29
  end
@@ -1,3 +1,7 @@
1
+ GOOGLE_AUTH_ENABLED=true
2
+ GOOGLE_AUTH_CLIENT_ID=''
3
+ GOOGLE_AUTH_CLIENT_SECRET=''
4
+ GOOGLE_AUTH_ALLOWED_DOMAINS=''
1
5
  NEW_RELIC_LOG=stdout
2
6
  NEW_RELIC_AGENT_ENABLED=true
3
7
  NEW_RELIC_MONITOR_MODE=true
@@ -0,0 +1,45 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+ require 'json'
4
+
5
+ module RooOnRails
6
+ class PapertrailClient
7
+ def initialize(token:)
8
+ @token = token
9
+ end
10
+
11
+ def list_destinations
12
+ _conn.get('destinations.json').body
13
+ end
14
+
15
+ def list_systems
16
+ _conn.get('systems.json').body
17
+ end
18
+
19
+ def get_system(id)
20
+ _conn.get('systems/%s.json' % id).body
21
+ end
22
+
23
+ def update_system(id, data)
24
+ _conn.put('systems/%s.json' % id, system: data).body
25
+ end
26
+
27
+ # private
28
+
29
+ def _conn
30
+ @_conn ||= Faraday.new(_api_url, headers: { 'X-Papertrail-Token' => @token }) do |conf|
31
+ conf.response :mashify
32
+ conf.response :json
33
+ conf.response :raise_error
34
+ # conf.response :logger
35
+ conf.request :json
36
+
37
+ conf.adapter Faraday.default_adapter
38
+ end
39
+ end
40
+
41
+ def _api_url
42
+ @_api_url = URI.parse('https://papertrailapp.com/api/v1')
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ require 'rack'
2
+
3
+ module RooOnRails
4
+ module Rack
5
+ class GoogleOauth
6
+ OAUTH_CALLBACK = '/auth/google_oauth2/callback'.freeze
7
+
8
+ def initialize(app, *args, &block)
9
+ @app = app
10
+ @args = args
11
+ @strategy = block
12
+ end
13
+
14
+ def call(env)
15
+ if is_oauth_callback?(env)
16
+ @strategy.call(env)
17
+ else
18
+ send_to_upstream(env)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def send_to_upstream(env)
25
+ @app.call(env)
26
+ end
27
+
28
+ def is_oauth_callback?(env)
29
+ request = ::Rack::Request.new(env)
30
+ request.fullpath.start_with?(OAUTH_CALLBACK)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ require 'roo_on_rails/config'
2
+ require 'omniauth'
3
+ require 'omniauth-google-oauth2'
4
+ require 'active_support/core_ext/object/blank'
5
+
6
+ module RooOnRails
7
+ module Railties
8
+ class GoogleAuth < Rails::Railtie
9
+ initializer 'roo_on_rails.google_auth' do |app|
10
+ if RooOnRails::Config.google_auth_enabled?
11
+ $stderr.puts 'initializer roo_on_rails.google_auth'
12
+
13
+ google_oauth2_client_id = ENV.fetch('GOOGLE_AUTH_CLIENT_ID')
14
+ google_oauth2_client_secret = ENV.fetch('GOOGLE_AUTH_CLIENT_SECRET')
15
+
16
+ options = {
17
+ path_prefix: '/auth',
18
+ prompt: 'consent',
19
+ }
20
+
21
+ domain_list = ENV.fetch('GOOGLE_AUTH_ALLOWED_DOMAINS', '').split(',').reject(&:blank?)
22
+ options[:hd] = domain_list if domain_list.any?
23
+
24
+ app.config.middleware.use ::OmniAuth::Builder do
25
+ provider :google_oauth2,
26
+ google_oauth2_client_id,
27
+ google_oauth2_client_secret,
28
+ options
29
+ end
30
+ else
31
+ $stderr.puts 'skipping initializer roo_on_rails.google_auth'
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,4 +1,5 @@
1
1
  require 'sidekiq'
2
+ require 'roo_on_rails/config'
2
3
  require 'roo_on_rails/statsd'
3
4
  require 'roo_on_rails/sidekiq/settings'
4
5
  require 'roo_on_rails/sidekiq/sla_metric'
@@ -8,11 +9,14 @@ module RooOnRails
8
9
  class Sidekiq < Rails::Railtie
9
10
  initializer 'roo_on_rails.sidekiq' do |app|
10
11
  require 'hirefire-resource'
11
- $stderr.puts 'initializer roo_on_rails.sidekiq'
12
- if ENV.fetch('SIDEKIQ_ENABLED', 'true').to_s =~ /\A(YES|TRUE|ON|1)\Z/i
12
+
13
+ if RooOnRails::Config.sidekiq_enabled?
14
+ $stderr.puts 'initializer roo_on_rails.sidekiq'
13
15
  config_sidekiq
14
16
  config_sidekiq_metrics
15
17
  config_hirefire(app)
18
+ else
19
+ $stderr.puts 'skipping initializer roo_on_rails.sidekiq'
16
20
  end
17
21
  end
18
22
 
@@ -1,3 +1,3 @@
1
1
  module RooOnRails
2
- VERSION = '1.6.0'.freeze
2
+ VERSION = '1.7.0'.freeze
3
3
  end
@@ -32,6 +32,10 @@ Gem::Specification.new do |spec|
32
32
  spec.add_runtime_dependency 'hirefire-resource'
33
33
  spec.add_runtime_dependency 'sidekiq'
34
34
  spec.add_runtime_dependency 'dogstatsd-ruby'
35
+ spec.add_runtime_dependency 'omniauth-google-oauth2'
36
+ spec.add_runtime_dependency 'faraday'
37
+ spec.add_runtime_dependency 'faraday_middleware'
38
+
35
39
  spec.add_development_dependency 'bundler', '~> 1.13'
36
40
  spec.add_development_dependency 'rake', '~> 10.0'
37
41
  spec.add_development_dependency 'rspec', '~> 3.0'
@@ -40,4 +44,5 @@ Gem::Specification.new do |spec|
40
44
  spec.add_development_dependency 'memfs'
41
45
  spec.add_development_dependency 'simplecov'
42
46
  spec.add_development_dependency 'codecov'
47
+ spec.add_development_dependency 'rack-test'
43
48
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roo_on_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julien Letessier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-07-11 00:00:00.000000000 Z
11
+ date: 2017-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv-rails
@@ -170,6 +170,48 @@ dependencies:
170
170
  - - ">="
171
171
  - !ruby/object:Gem::Version
172
172
  version: '0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: omniauth-google-oauth2
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :runtime
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ - !ruby/object:Gem::Dependency
188
+ name: faraday
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ type: :runtime
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ - !ruby/object:Gem::Dependency
202
+ name: faraday_middleware
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ type: :runtime
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
173
215
  - !ruby/object:Gem::Dependency
174
216
  name: bundler
175
217
  requirement: !ruby/object:Gem::Requirement
@@ -282,6 +324,20 @@ dependencies:
282
324
  - - ">="
283
325
  - !ruby/object:Gem::Version
284
326
  version: '0'
327
+ - !ruby/object:Gem::Dependency
328
+ name: rack-test
329
+ requirement: !ruby/object:Gem::Requirement
330
+ requirements:
331
+ - - ">="
332
+ - !ruby/object:Gem::Version
333
+ version: '0'
334
+ type: :development
335
+ prerelease: false
336
+ version_requirements: !ruby/object:Gem::Requirement
337
+ requirements:
338
+ - - ">="
339
+ - !ruby/object:Gem::Version
340
+ version: '0'
285
341
  description: Scaffolding for building services
286
342
  email:
287
343
  - julien.letessier@gmail.com
@@ -308,6 +364,7 @@ files:
308
364
  - bin/console
309
365
  - bin/setup
310
366
  - exe/roo_on_rails
367
+ - gemfiles/.bundle/config
311
368
  - gemfiles/rails_3.gemfile
312
369
  - gemfiles/rails_3.gemfile.lock
313
370
  - gemfiles/rails_4.gemfile
@@ -325,6 +382,8 @@ files:
325
382
  - lib/roo_on_rails/checks/git/origin.rb
326
383
  - lib/roo_on_rails/checks/github/branch_protection.rb
327
384
  - lib/roo_on_rails/checks/github/token.rb
385
+ - lib/roo_on_rails/checks/google_oauth/_template.rb
386
+ - lib/roo_on_rails/checks/google_oauth/initializer.rb
328
387
  - lib/roo_on_rails/checks/helpers.rb
329
388
  - lib/roo_on_rails/checks/heroku/app_exists.rb
330
389
  - lib/roo_on_rails/checks/heroku/drains_metrics.rb
@@ -334,6 +393,12 @@ files:
334
393
  - lib/roo_on_rails/checks/heroku/token.rb
335
394
  - lib/roo_on_rails/checks/heroku/toolbelt_installed.rb
336
395
  - lib/roo_on_rails/checks/heroku/toolbelt_working.rb
396
+ - lib/roo_on_rails/checks/papertrail/all.rb
397
+ - lib/roo_on_rails/checks/papertrail/drain_exists.rb
398
+ - lib/roo_on_rails/checks/papertrail/log_destination_exists.rb
399
+ - lib/roo_on_rails/checks/papertrail/system_exists.rb
400
+ - lib/roo_on_rails/checks/papertrail/system_named.rb
401
+ - lib/roo_on_rails/checks/papertrail/token.rb
337
402
  - lib/roo_on_rails/checks/sidekiq/settings.rb
338
403
  - lib/roo_on_rails/checks/sidekiq/sidekiq.rb
339
404
  - lib/roo_on_rails/config.rb
@@ -342,9 +407,12 @@ files:
342
407
  - lib/roo_on_rails/environment.rb
343
408
  - lib/roo_on_rails/harness.rb
344
409
  - lib/roo_on_rails/logfmt.rb
410
+ - lib/roo_on_rails/papertrail_client.rb
411
+ - lib/roo_on_rails/rack/google_oauth.rb
345
412
  - lib/roo_on_rails/rack/safe_timeouts.rb
346
413
  - lib/roo_on_rails/railtie.rb
347
414
  - lib/roo_on_rails/railties/database.rb
415
+ - lib/roo_on_rails/railties/google_auth.rb
348
416
  - lib/roo_on_rails/railties/http.rb
349
417
  - lib/roo_on_rails/railties/new_relic.rb
350
418
  - lib/roo_on_rails/railties/rake_tasks.rb