roo_on_rails 1.6.0 → 1.7.0

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