roo_on_rails 1.10.0 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +672 -0
- data/.circleci/config.yml.erb +86 -0
- data/.gitignore +2 -1
- data/.rspec +2 -0
- data/CHANGELOG.md +27 -0
- data/README.md +75 -26
- data/README.routemaster_client.md +2 -0
- data/exe/roo_on_rails +96 -7
- data/lib/roo_on_rails/checks/base.rb +34 -17
- data/lib/roo_on_rails/checks/documentation/playbook.rb +2 -6
- data/lib/roo_on_rails/checks/environment.rb +2 -4
- data/lib/roo_on_rails/checks/environment_independent.rb +22 -0
- data/lib/roo_on_rails/checks/heroku/app_exists.rb +9 -2
- data/lib/roo_on_rails/checks/heroku/drains_metrics.rb +2 -2
- data/lib/roo_on_rails/checks/heroku/metrics_bridge_configured.rb +6 -2
- data/lib/roo_on_rails/checks/heroku/preboot_enabled.rb +3 -3
- data/lib/roo_on_rails/checks/papertrail/drain_exists.rb +4 -4
- data/lib/roo_on_rails/checks/papertrail/system_exists.rb +2 -2
- data/lib/roo_on_rails/checks/papertrail/system_named.rb +1 -1
- data/lib/roo_on_rails/checks/sidekiq/settings.rb +1 -1
- data/lib/roo_on_rails/checks/sidekiq/sidekiq.rb +1 -0
- data/lib/roo_on_rails/context_logging.rb +1 -0
- data/lib/roo_on_rails/harness.rb +8 -14
- data/lib/roo_on_rails/logfmt.rb +3 -15
- data/lib/roo_on_rails/logger.rb +104 -0
- data/lib/roo_on_rails/railties/database.rb +8 -6
- data/lib/roo_on_rails/railties/env.rb +11 -0
- data/lib/roo_on_rails/railties/google_oauth.rb +3 -7
- data/lib/roo_on_rails/railties/http.rb +31 -27
- data/lib/roo_on_rails/railties/logging.rb +16 -0
- data/lib/roo_on_rails/railties/new_relic.rb +15 -14
- data/lib/roo_on_rails/railties/rake_tasks.rb +0 -2
- data/lib/roo_on_rails/railties/routemaster.rb +9 -8
- data/lib/roo_on_rails/railties/sidekiq.rb +12 -8
- data/lib/roo_on_rails/routemaster/publisher.rb +14 -1
- data/lib/roo_on_rails/routemaster/publishers.rb +3 -3
- data/lib/roo_on_rails/sidekiq/process_scaling.rb +1 -1
- data/lib/roo_on_rails/tasks/db.rake +3 -2
- data/lib/roo_on_rails/version.rb +1 -1
- data/lib/roo_on_rails.rb +2 -1
- metadata +8 -7
- data/gemfiles/rails_3.gemfile.lock +0 -278
- data/gemfiles/rails_4.gemfile.lock +0 -293
- data/gemfiles/rails_5.gemfile.lock +0 -299
- data/gemfiles/rails_5_1.gemfile.lock +0 -300
- data/lib/roo_on_rails/railtie.rb +0 -16
@@ -0,0 +1,86 @@
|
|
1
|
+
# To update the build configuration, edit the "builds" array below and run:
|
2
|
+
# erb .circleci/config.yml.erb > .circleci/config.yml
|
3
|
+
<%
|
4
|
+
builds = [
|
5
|
+
['2.2.6', 'rails_3'],
|
6
|
+
['2.3.3', 'rails_3'],
|
7
|
+
['2.2.6', 'rails_4'],
|
8
|
+
['2.3.3', 'rails_4'],
|
9
|
+
['2.4.0', 'rails_4'],
|
10
|
+
['2.2.6', 'rails_5'],
|
11
|
+
['2.3.3', 'rails_5'],
|
12
|
+
['2.4.0', 'rails_5'],
|
13
|
+
['2.2.6', 'rails_5_1'],
|
14
|
+
['2.3.3', 'rails_5_1'],
|
15
|
+
['2.4.0', 'rails_5_1'],
|
16
|
+
]
|
17
|
+
%>
|
18
|
+
version: 2
|
19
|
+
jobs:
|
20
|
+
<% builds.each do |ruby,variant| %>
|
21
|
+
build_<%= ruby %>_<%= variant %>:
|
22
|
+
docker:
|
23
|
+
- image: deliveroo/multiruby
|
24
|
+
- image: postgres:9.6-alpine
|
25
|
+
environment:
|
26
|
+
PGDATA: /dev/shm/pgdata
|
27
|
+
- image: redis:3-alpine
|
28
|
+
steps:
|
29
|
+
- checkout
|
30
|
+
|
31
|
+
- run:
|
32
|
+
name: Setup RAM disk
|
33
|
+
command: |
|
34
|
+
rm -rf ~/project/tmp ;
|
35
|
+
mkdir /dev/shm/tmp ;
|
36
|
+
ln -s /dev/shm/tmp ~/project/tmp
|
37
|
+
|
38
|
+
- run:
|
39
|
+
name: Select build variant (Ruby <%= ruby %>, <%= variant %>)
|
40
|
+
command: |
|
41
|
+
rbenv local <%= ruby %> ;
|
42
|
+
gem install bundler ;
|
43
|
+
bundle config --local gemfile $PWD/gemfiles/<%= variant %>.gemfile
|
44
|
+
|
45
|
+
- restore_cache:
|
46
|
+
keys:
|
47
|
+
- v2-bundle-<%= ruby %>-<%= variant %>-{{ .Branch }}
|
48
|
+
- v2-bundle-<%= ruby %>-<%= variant %>
|
49
|
+
- v2-bundle-<%= ruby %>
|
50
|
+
|
51
|
+
- run:
|
52
|
+
name: Install dependencies
|
53
|
+
command: |
|
54
|
+
bundle install --jobs=3 --retry=3 --path=$PWD/vendor/bundle
|
55
|
+
|
56
|
+
- run:
|
57
|
+
name: Run test suite
|
58
|
+
command: |
|
59
|
+
unset RACK_ENV &&
|
60
|
+
unset RAILS_ENV &&
|
61
|
+
bundle exec rspec
|
62
|
+
|
63
|
+
- save_cache:
|
64
|
+
key: v2-bundle-<%= ruby %>-<%= variant %>-{{ .Branch }}
|
65
|
+
paths:
|
66
|
+
- ~/project/vendor/bundle
|
67
|
+
- ~/project/vendor/bundle-scaffold
|
68
|
+
- save_cache:
|
69
|
+
key: v2-bundle-<%= ruby %>-<%= variant %>
|
70
|
+
paths:
|
71
|
+
- ~/project/vendor/bundle
|
72
|
+
- ~/project/vendor/bundle-scaffold
|
73
|
+
- save_cache:
|
74
|
+
key: v2-bundle-<%= ruby %>
|
75
|
+
paths:
|
76
|
+
- ~/project/vendor/bundle
|
77
|
+
- ~/project/vendor/bundle-scaffold
|
78
|
+
<% end %>
|
79
|
+
|
80
|
+
workflows:
|
81
|
+
version: 2
|
82
|
+
test:
|
83
|
+
jobs:
|
84
|
+
<% builds.each do |ruby,variant| %>
|
85
|
+
- build_<%= ruby %>_<%= variant %>
|
86
|
+
<% end %>
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
# v1.11.0 (2017-08-11)
|
2
|
+
|
3
|
+
Features (library):
|
4
|
+
|
5
|
+
- Replaces the Rails logger with a structured logger (#60)
|
6
|
+
- Auto-fills the Routemaster `t` timestamp field, where appropriate, from the
|
7
|
+
model's `created_at` and `updated_at` fields if available (#64)
|
8
|
+
|
9
|
+
Features (app harness):
|
10
|
+
|
11
|
+
- The `roo_on_rails` test harness now defaults to not fixing issues, and has extra
|
12
|
+
`--env` and `--fix` flags (#57)
|
13
|
+
- All checks will now run regardless of previous failure to avoid
|
14
|
+
back-and-forthing (#57)
|
15
|
+
- Tolerates apps with abbreviated environment names (#55)
|
16
|
+
|
17
|
+
Bug fixes:
|
18
|
+
|
19
|
+
- Bugfix for supporting non-default publishers after a `reload!` in the rails console (#62)
|
20
|
+
- Friendlier error message when facing Heroku permission errors (#58)
|
21
|
+
- Support apps without ActiveRecord (#40)
|
22
|
+
|
23
|
+
Misc:
|
24
|
+
|
25
|
+
- Now using CircleCI for builds (#61, #63)
|
26
|
+
- Document Datadog integration (#59)
|
27
|
+
|
1
28
|
# v1.10.0 (2017-08-11)
|
2
29
|
|
3
30
|
Features:
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
## `roo_on_rails` [![Gem Version](https://badge.fury.io/rb/roo_on_rails.svg)](https://badge.fury.io/rb/roo_on_rails) [![Build Status](https://
|
1
|
+
## `roo_on_rails` [![Gem Version](https://badge.fury.io/rb/roo_on_rails.svg)](https://badge.fury.io/rb/roo_on_rails) [![Build Status](https://circleci.com/gh/deliveroo/roo_on_rails.svg?style=shield&circle-token=f8ad2021dfc72fd86850fd0b7224759f34a91281)](https://circleci.com/gh/deliveroo/roo_on_rails) [![Code Climate](https://codeclimate.com/repos/58809e664ab8420081007382/badges/3489b7689ab2e0cf5d61/gpa.svg)](https://codeclimate.com/repos/58809e664ab8420081007382/feed)
|
2
2
|
|
3
3
|
|
4
4
|
`roo_on_rails` is:
|
@@ -24,6 +24,7 @@
|
|
24
24
|
- [HireFire (for Sidekiq workers)](#hirefire-for-sidekiq-workers)
|
25
25
|
- [Logging](#logging)
|
26
26
|
- [Google OAuth authentication](#google-oauth-authentication)
|
27
|
+
- [Datadog Integration](#datadog-integration)
|
27
28
|
- [Routemaster Client](#routemaster-client)
|
28
29
|
- [Command features](#command-features)
|
29
30
|
- [Usage](#usage)
|
@@ -149,38 +150,47 @@ be used:
|
|
149
150
|
|
150
151
|
### Logging
|
151
152
|
|
152
|
-
For clearer and machine-parseable log output,
|
153
|
-
to add context to your logs which is output as
|
154
|
-
[logfmt](https://brandur.org/logfmt) key/value pairs
|
153
|
+
For clearer and machine-parseable log output, the Rails logger is replaced by an
|
154
|
+
extended logger to add context to your logs, which is output as
|
155
|
+
[logfmt](https://brandur.org/logfmt) key/value pairs along with the log message.
|
156
|
+
|
157
|
+
You can use the logger as usual:
|
155
158
|
|
156
159
|
```ruby
|
157
|
-
|
160
|
+
Rails.logger.info { 'hello world' }
|
161
|
+
```
|
158
162
|
|
159
|
-
|
163
|
+
From your console, the output will include the timestamp, severity, and message:
|
160
164
|
|
161
|
-
|
165
|
+
```
|
166
|
+
[2017-08-25 14:34:54.899] INFO | hello world
|
167
|
+
```
|
162
168
|
|
163
|
-
|
164
|
-
|
165
|
-
if logger.nil?
|
166
|
-
logger = ActiveSupport::Logger.new($stdout)
|
167
|
-
logger.formatter = config.log_formatter
|
168
|
-
end
|
169
|
-
logger = ActiveSupport::TaggedLogging.new(logger) unless logger.respond_to?(:tagged)
|
170
|
-
config.logger = RooOnRails::ContextLogging.new(logger)
|
169
|
+
In production (or whenever the output isn't a TTY), the timestamp is stripped
|
170
|
+
(as it's provided by the logging pipes) and the output is fully valid `logfmt`:
|
171
171
|
|
172
|
-
|
172
|
+
```
|
173
|
+
at=INFO msg="hello world"
|
173
174
|
```
|
174
175
|
|
175
|
-
|
176
|
+
One can also add context using the `with` method:
|
176
177
|
|
177
178
|
```ruby
|
178
179
|
logger.with(a: 1, b: 2) { logger.info 'Stuff' }
|
180
|
+
# => at=INFO msg=Stuff a=1 b=2
|
181
|
+
```
|
182
|
+
|
183
|
+
```ruby
|
179
184
|
logger.with(a: 1) { logger.with(b: 2) { logger.info('Stuff') } }
|
185
|
+
# => at=INFO msg=Stuff a=1 b=2
|
186
|
+
```
|
187
|
+
|
188
|
+
```ruby
|
180
189
|
logger.with(a: 1, b: 2).info('Stuff')
|
190
|
+
# => at=INFO msg=Stuff a=1 b=2
|
181
191
|
```
|
182
192
|
|
183
|
-
See the [class documentation](lib/roo_on_rails/
|
193
|
+
See the [class documentation](lib/roo_on_rails/logger.rb) for further
|
184
194
|
details.
|
185
195
|
|
186
196
|
### Google OAuth authentication
|
@@ -199,6 +209,44 @@ application.
|
|
199
209
|
|
200
210
|
A simple but secure example is detailed in `README.google_oauth2.md`.
|
201
211
|
|
212
|
+
### Datadog Integration
|
213
|
+
|
214
|
+
#### Heroku metrics
|
215
|
+
|
216
|
+
To send system metrics to Datadog (CPU, memory usage, HTTP throughput per
|
217
|
+
status, latency, etc), your application need to send their logs to
|
218
|
+
[the metrics bridge](https://github.com/deliveroo/heroku-datadog-drain-golang).
|
219
|
+
|
220
|
+
This is automatically configured when running `roo_on_rails harness`.
|
221
|
+
|
222
|
+
#### Custom application metrics
|
223
|
+
|
224
|
+
Sending custom metrics to Datadog through Statsd requires an agent running in
|
225
|
+
each dyno.
|
226
|
+
You need to add the buildpack
|
227
|
+
[`heroku-buildpack-datadog`](https://github.com/deliveroo/heroku-buildpack-datadog).
|
228
|
+
|
229
|
+
Once this is done, you can send metrics with e.g.:
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
RooOnRails.statsd.increment('my.metric', tags: 'tag:value')
|
233
|
+
```
|
234
|
+
|
235
|
+
Tags `env:{name}`, `source:{dyno}`, and `app:{name}` will automatically be added
|
236
|
+
to all your metrics.
|
237
|
+
|
238
|
+
The following environment variables are being used. The default values are fine
|
239
|
+
except for `STATSD_ENV` which should be set.
|
240
|
+
|
241
|
+
- `STATSD_ENV`
|
242
|
+
- `STATSD_HOST`
|
243
|
+
- `STATSD_PORT`
|
244
|
+
|
245
|
+
These extra required variables are automatically set by Heroku:
|
246
|
+
|
247
|
+
- `DYNO`
|
248
|
+
- `HEROKU_APP_NAME`
|
249
|
+
|
202
250
|
### Routemaster Client
|
203
251
|
|
204
252
|
When `ROUTEMASTER_ENABLED` is set to `true` we attempt to configure [`routemaster-client`](https://github.com/deliveroo/routemaster-client) on your application. In order for this to happen you need to set the following environment variables:
|
@@ -215,7 +263,7 @@ If you then want to enable the publishing of events onto the event bus, you need
|
|
215
263
|
Run the following from your app's top-level directory:
|
216
264
|
|
217
265
|
```
|
218
|
-
|
266
|
+
roo_on_rails harness
|
219
267
|
```
|
220
268
|
|
221
269
|
That command will sequentially run a number of checks. For it to run successfully, you will need:
|
@@ -223,17 +271,18 @@ That command will sequentially run a number of checks. For it to run successfull
|
|
223
271
|
- a GitHub API token that can read your GitHub repository's settings placed in `~/.roo_on_rails/github-token`
|
224
272
|
- the Heroku toolbelt installed and logged in
|
225
273
|
- admin privileges on the `roo-dd-bridge-production` (this will be addressed eventually)
|
226
|
-
- checks are run sequentially for staging and then for production. The process halts at any non-fixable failing check. To process only specific environments, you can set a config variable while running the command, like so:
|
227
274
|
|
275
|
+
The command can automatically fix most of the failing checks automatically;
|
276
|
+
simply run it with the `--fix` flag:
|
277
|
+
|
278
|
+
```
|
279
|
+
roo_on_rails harness --fix
|
228
280
|
```
|
229
|
-
# the default behaviour:
|
230
|
-
ROO_ON_RAILS_ENVIRONMENTS=staging,production bundle exec roo_on_rails
|
231
281
|
|
232
|
-
|
233
|
-
ROO_ON_RAILS_ENVIRONMENTS=staging bundle exec roo_on_rails
|
282
|
+
To run checks for only one environment, use the `--env` flag:
|
234
283
|
|
235
|
-
|
236
|
-
|
284
|
+
```
|
285
|
+
roo_on_rails harness --env staging
|
237
286
|
```
|
238
287
|
|
239
288
|
|
@@ -78,6 +78,8 @@ class RiderPublisher < ApplicationPublisher
|
|
78
78
|
end
|
79
79
|
```
|
80
80
|
|
81
|
+
`#publish?`, `#topics`, `#async?`, `#data` and `#timestamp` can be overriden; see [the `Publisher` class](lib/roo_on_rails_routemaster/publisher.rb) for the default implementations.
|
82
|
+
|
81
83
|
### Register the publishers with Routemaster
|
82
84
|
|
83
85
|
The final step is to tell Routemaster that these publishers exist, so that it can listen to their events. We're going to do this in an initialiser:
|
data/exe/roo_on_rails
CHANGED
@@ -3,12 +3,101 @@
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'roo_on_rails/config'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
module RooOnRails
|
7
|
+
module CLI
|
8
|
+
class Base
|
9
|
+
attr_reader :argv
|
10
|
+
|
11
|
+
def initialize(argv)
|
12
|
+
@argv = argv
|
13
|
+
end
|
14
|
+
|
15
|
+
def usage
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def _log(message)
|
22
|
+
$stderr.puts message
|
23
|
+
end
|
24
|
+
|
25
|
+
def _assert_argv_length(range)
|
26
|
+
return if range.include?(argv.length)
|
27
|
+
_log 'Wrong number of arguments.'
|
28
|
+
_log "Usage: #{usage}"
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Sidekiq < Base
|
34
|
+
def usage
|
35
|
+
'roo_on_rails sidekiq'
|
36
|
+
end
|
37
|
+
|
38
|
+
def run
|
39
|
+
_assert_argv_length(0..0)
|
40
|
+
require 'roo_on_rails/sidekiq/loader'
|
41
|
+
RooOnRails::Sidekiq::Loader.run
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Harness < Base
|
46
|
+
def usage
|
47
|
+
'roo_on_rails harness [-f|--fix]'
|
48
|
+
end
|
49
|
+
|
50
|
+
def run
|
51
|
+
_parser.parse!(argv)
|
52
|
+
_assert_argv_length(0..0)
|
53
|
+
require 'roo_on_rails/harness'
|
54
|
+
RooOnRails::Harness.new(try_fix: _options[:fix], context: Config.load).run
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def _options
|
60
|
+
@options ||= { fix: false, env: nil }
|
61
|
+
end
|
62
|
+
|
63
|
+
def _parser
|
64
|
+
require 'optionparser'
|
65
|
+
|
66
|
+
OptionParser.new do |o|
|
67
|
+
o.banner = usage
|
68
|
+
|
69
|
+
o.on('-f', '--fix', 'Attempt to fix failed checks') do
|
70
|
+
_options[:fix] = true
|
71
|
+
end
|
72
|
+
|
73
|
+
o.on('-e', '--env', 'Application environments to check (comma-separated)') do |v|
|
74
|
+
_options[:env] = v
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class Toplevel < Base
|
81
|
+
def usage
|
82
|
+
'roo_on_rails [sidekiq|harness] [options]'
|
83
|
+
end
|
84
|
+
|
85
|
+
def run
|
86
|
+
case argv.first
|
87
|
+
when 'sidekiq' then
|
88
|
+
argv.shift
|
89
|
+
Sidekiq.new(argv).run
|
90
|
+
when 'harness', nil then
|
91
|
+
argv.shift
|
92
|
+
Harness.new(argv).run
|
93
|
+
else
|
94
|
+
_log 'Incorrect arguments.'
|
95
|
+
_log "Usage: #{usage}"
|
96
|
+
exit 1
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
13
100
|
end
|
14
101
|
end
|
102
|
+
|
103
|
+
RooOnRails::CLI::Toplevel.new(ARGV).run
|
@@ -24,18 +24,30 @@ module RooOnRails
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def run
|
27
|
-
resolve dependencies
|
28
|
-
|
27
|
+
dependency_status = resolve dependencies
|
28
|
+
|
29
29
|
say intro
|
30
|
-
|
30
|
+
unless dependency_status
|
31
|
+
final_fail! 'Unmet dependencies.'
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
35
|
+
return true if @dry_run
|
36
|
+
|
37
|
+
begin
|
38
|
+
call
|
39
|
+
rescue Failure
|
40
|
+
return false unless @fix
|
41
|
+
say "\t· attempting to fix", %i[yellow]
|
42
|
+
fix
|
43
|
+
@fix = false
|
44
|
+
say "\t· re-checking", %i[yellow]
|
45
|
+
retry
|
46
|
+
end
|
47
|
+
|
31
48
|
true
|
32
|
-
rescue
|
33
|
-
|
34
|
-
raise unless @fix
|
35
|
-
say "\t· attempting to fix", %i[yellow]
|
36
|
-
fix
|
37
|
-
say "\t· re-checking", %i[yellow]
|
38
|
-
call
|
49
|
+
rescue FinalFailure
|
50
|
+
false
|
39
51
|
end
|
40
52
|
|
41
53
|
protected
|
@@ -44,7 +56,7 @@ module RooOnRails
|
|
44
56
|
|
45
57
|
# Returns prerequisite checks. Can be overriden.
|
46
58
|
def dependencies
|
47
|
-
self.class.requires.map { |k|
|
59
|
+
@dependencies ||= self.class.requires.map { |k|
|
48
60
|
k.new(fix: @fix, context: @context, shell: @shell, **@options)
|
49
61
|
}
|
50
62
|
end
|
@@ -54,11 +66,11 @@ module RooOnRails
|
|
54
66
|
end
|
55
67
|
|
56
68
|
def call
|
57
|
-
|
69
|
+
final_fail! "this check wasn't implemented"
|
58
70
|
end
|
59
71
|
|
60
72
|
def fix
|
61
|
-
|
73
|
+
final_fail! "can't fix this on my own"
|
62
74
|
end
|
63
75
|
|
64
76
|
def pass(msg)
|
@@ -84,10 +96,15 @@ module RooOnRails
|
|
84
96
|
|
85
97
|
# Run each dependency, then mark them as run.
|
86
98
|
def resolve(deps)
|
87
|
-
deps
|
88
|
-
|
89
|
-
|
90
|
-
|
99
|
+
context.deps ||= {}
|
100
|
+
deps.map { |dep|
|
101
|
+
sig = dep.signature.join('/')
|
102
|
+
if context.deps.key?(sig)
|
103
|
+
context.deps[sig]
|
104
|
+
else
|
105
|
+
context.deps[sig] = dep.run
|
106
|
+
end
|
107
|
+
}.to_a.all?
|
91
108
|
end
|
92
109
|
end
|
93
110
|
end
|
@@ -13,15 +13,11 @@ module RooOnRails
|
|
13
13
|
|
14
14
|
def call
|
15
15
|
fail! "no playbook at #{LOCATION}." if playbook_missing?
|
16
|
-
|
17
|
-
pass
|
16
|
+
final_fail! 'playbook still contains FIXME template sections' if playbook_unfinished?
|
17
|
+
pass 'playbook found, legion on-call engineers thank you.'
|
18
18
|
end
|
19
19
|
|
20
20
|
def fix
|
21
|
-
if !playbook_missing? && playbook_unfinished?
|
22
|
-
fail! 'please add detail to your playbook, removing FIXME sections'
|
23
|
-
end
|
24
|
-
|
25
21
|
FileUtils.cp(
|
26
22
|
File.join(__dir__, 'playbook_template.md'),
|
27
23
|
LOCATION
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'roo_on_rails/checks/env_specific'
|
2
|
-
require 'roo_on_rails/checks/github/branch_protection'
|
3
2
|
require 'roo_on_rails/checks/heroku/app_exists'
|
4
3
|
require 'roo_on_rails/checks/heroku/preboot_enabled'
|
5
4
|
require 'roo_on_rails/checks/heroku/app_exists'
|
@@ -9,19 +8,18 @@ require 'roo_on_rails/checks/papertrail/all'
|
|
9
8
|
module RooOnRails
|
10
9
|
module Checks
|
11
10
|
class Environment < EnvSpecific
|
12
|
-
requires GitHub::BranchProtection
|
13
11
|
requires Heroku::DrainsMetrics
|
14
12
|
requires Heroku::PrebootEnabled
|
15
13
|
requires Papertrail::All
|
16
14
|
|
17
15
|
def call
|
18
|
-
|
16
|
+
pass 'all good'
|
19
17
|
end
|
20
18
|
|
21
19
|
protected
|
22
20
|
|
23
21
|
def intro
|
24
|
-
"
|
22
|
+
"Validating #{bold @env} environment"
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'roo_on_rails/checks/base'
|
2
|
+
require 'roo_on_rails/checks/github/branch_protection'
|
3
|
+
require 'roo_on_rails/checks/sidekiq/settings'
|
4
|
+
require 'roo_on_rails/checks/documentation/playbook'
|
5
|
+
|
6
|
+
module RooOnRails
|
7
|
+
module Checks
|
8
|
+
class EnvironmentIndependent < Base
|
9
|
+
requires GitHub::BranchProtection
|
10
|
+
requires Documentation::Playbook
|
11
|
+
requires Sidekiq::Settings
|
12
|
+
|
13
|
+
def intro
|
14
|
+
'Validating environment-independent setup'
|
15
|
+
end
|
16
|
+
|
17
|
+
def call
|
18
|
+
say 'All good', :green
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -16,6 +16,10 @@ module RooOnRails
|
|
16
16
|
# Output context:
|
17
17
|
# - heroku.app.{env}: an app name.
|
18
18
|
class AppExists < EnvSpecific
|
19
|
+
ACCEPTABLE_ENV_NAMES = {
|
20
|
+
'production' => %w(prd production),
|
21
|
+
'staging' => %w(stg staging)
|
22
|
+
}.freeze
|
19
23
|
requires Git::Origin, Heroku::Token
|
20
24
|
|
21
25
|
def intro
|
@@ -25,7 +29,6 @@ module RooOnRails
|
|
25
29
|
def call
|
26
30
|
all_apps = client.app.list.map { |a| a['name'] }
|
27
31
|
matches = all_apps.select { |a| candidates.include?(a) }
|
28
|
-
|
29
32
|
if matches.empty?
|
30
33
|
fail! "no apps with matching names detected"
|
31
34
|
end
|
@@ -45,11 +48,15 @@ module RooOnRails
|
|
45
48
|
context.app_name_stem || context.git_repo.delete('.')
|
46
49
|
end
|
47
50
|
|
51
|
+
def env_suffixes
|
52
|
+
ACCEPTABLE_ENV_NAMES.fetch(env, [env])
|
53
|
+
end
|
54
|
+
|
48
55
|
def candidates
|
49
56
|
[
|
50
57
|
['deliveroo', 'roo', nil],
|
51
58
|
[name_stem],
|
52
|
-
|
59
|
+
env_suffixes,
|
53
60
|
].tap { |a|
|
54
61
|
a.replace a.first.product(*a[1..-1])
|
55
62
|
}.map { |c|
|
@@ -18,7 +18,7 @@ module RooOnRails
|
|
18
18
|
requires Heroku::AppExists, MetricsBridgeConfigured
|
19
19
|
|
20
20
|
def intro
|
21
|
-
|
21
|
+
'Checking for metrics drain...'
|
22
22
|
end
|
23
23
|
|
24
24
|
def call
|
@@ -28,7 +28,7 @@ module RooOnRails
|
|
28
28
|
|
29
29
|
fail! 'No matching drain found' if url.nil?
|
30
30
|
final_fail! 'Misconfigured drain found' if url != drain_uri
|
31
|
-
pass
|
31
|
+
pass "Drain is connected to #{bold app_name}"
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
@@ -22,7 +22,7 @@ module RooOnRails
|
|
22
22
|
BRIDGE_APP = 'roo-dd-bridge-production'.freeze
|
23
23
|
|
24
24
|
def intro
|
25
|
-
|
25
|
+
'Checking whether metrics bridge is configured...'
|
26
26
|
end
|
27
27
|
|
28
28
|
def call
|
@@ -33,7 +33,7 @@ module RooOnRails
|
|
33
33
|
fail! 'Bridge lacks credentials for this app' unless config[token_var]
|
34
34
|
fail! 'Bridge lacks tags for this app' unless config[tags_var]
|
35
35
|
|
36
|
-
pass
|
36
|
+
pass "Bridge is configured for #{bold app_name}"
|
37
37
|
context.heroku.metric_bridge_token![env] = config[token_var]
|
38
38
|
end
|
39
39
|
|
@@ -48,10 +48,14 @@ module RooOnRails
|
|
48
48
|
token_var => SecureRandom.hex(16),
|
49
49
|
app_list_var => app_list.to_a.join(',')
|
50
50
|
)
|
51
|
+
rescue Excon::Error::Forbidden
|
52
|
+
fail! "You are missing 'operate' permissions for #{bold BRIDGE_APP}"
|
51
53
|
end
|
52
54
|
|
53
55
|
def current_config
|
54
56
|
client.config_var.info_for_app(BRIDGE_APP)
|
57
|
+
rescue Excon::Error::Forbidden
|
58
|
+
fail! "You are missing 'deploy' permissions for #{bold BRIDGE_APP}"
|
55
59
|
end
|
56
60
|
|
57
61
|
def app_list_var
|
@@ -12,15 +12,15 @@ module RooOnRails
|
|
12
12
|
requires Git::Origin, Heroku::AppExists
|
13
13
|
|
14
14
|
def intro
|
15
|
-
|
15
|
+
'Checking preboot status...'
|
16
16
|
end
|
17
17
|
|
18
18
|
def call
|
19
19
|
status = client.app_feature.info(app_name, 'preboot')
|
20
20
|
if status['enabled']
|
21
|
-
pass
|
21
|
+
pass "preboot enabled on #{bold app_name}"
|
22
22
|
else
|
23
|
-
fail!
|
23
|
+
fail! "preboot disabled on #{bold app_name}"
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|