vault-tools 0.3.11 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/vault-tools.rb +13 -1
- data/lib/vault-tools/config.rb +130 -24
- data/lib/vault-tools/core_db_tasks.rb +4 -4
- data/lib/vault-tools/log.rb +4 -4
- data/lib/vault-tools/payments_db_tasks.rb +2 -2
- data/lib/vault-tools/version.rb +1 -1
- data/lib/vault-tools/web.rb +2 -1
- data/test/config_test.rb +120 -47
- data/test/defaults_test.rb +47 -0
- data/test/helper.rb +32 -4
- data/test/log_test.rb +8 -0
- data/test/text_processor_test.rb +2 -0
- data/test/web_test.rb +31 -8
- data/vault-tools.gemspec +1 -0
- metadata +69 -17
- data/lib/vault-tools/shushu_db_tasks.rb +0 -31
data/lib/vault-tools.rb
CHANGED
@@ -4,6 +4,11 @@ require 'sinatra/base'
|
|
4
4
|
require 'scrolls'
|
5
5
|
require 'rack/ssl-enforcer'
|
6
6
|
require 'heroku-api'
|
7
|
+
require 'honeybadger'
|
8
|
+
|
9
|
+
Honeybadger.configure do |config|
|
10
|
+
config.api_key = ENV['HONEYBADGER_API_KEY']
|
11
|
+
end
|
7
12
|
|
8
13
|
module Vault
|
9
14
|
#require bundler and the proper gems for the ENV
|
@@ -27,19 +32,26 @@ module Vault
|
|
27
32
|
end
|
28
33
|
|
29
34
|
def self.hack_time_class
|
30
|
-
$stderr.puts "Modifying Time#to_s to use #iso8601"
|
35
|
+
$stderr.puts "Modifying Time#to_s to use #iso8601..."
|
31
36
|
# use send to call private method
|
32
37
|
Time.send(:define_method, :to_s) do
|
33
38
|
self.iso8601
|
34
39
|
end
|
35
40
|
end
|
36
41
|
|
42
|
+
def self.override_global_config
|
43
|
+
$stderr.puts "Set Config to Vault::Config..."
|
44
|
+
Object.send(:remove_const, :Config)
|
45
|
+
Object.const_set(:Config, Vault::Config)
|
46
|
+
end
|
47
|
+
|
37
48
|
# all in one go
|
38
49
|
def self.setup
|
39
50
|
self.require
|
40
51
|
self.load_path
|
41
52
|
self.set_timezones
|
42
53
|
self.hack_time_class
|
54
|
+
self.override_global_config
|
43
55
|
end
|
44
56
|
end
|
45
57
|
|
data/lib/vault-tools/config.rb
CHANGED
@@ -1,62 +1,168 @@
|
|
1
1
|
module Vault
|
2
2
|
module Config
|
3
|
-
|
3
|
+
@@defaults = {}
|
4
4
|
|
5
|
-
|
5
|
+
# An environment variable from another app.
|
6
|
+
#
|
7
|
+
# @param app [String] The name of the app to get the value from.
|
8
|
+
# @param name [String] The name of the environment variable to fetch a
|
9
|
+
# value for.
|
10
|
+
# @return [String] The value of an environment variable from another
|
11
|
+
# Heroku app or nil if no match is available.
|
12
|
+
def self.remote_env(app, name)
|
6
13
|
heroku = Heroku::API.new
|
7
|
-
heroku.get_config_vars(app).body[
|
14
|
+
heroku.get_config_vars(app).body[name]
|
8
15
|
end
|
9
16
|
|
10
|
-
|
11
|
-
|
17
|
+
# An environment variable.
|
18
|
+
#
|
19
|
+
# @param name [String] The name of the environment variable to fetch a
|
20
|
+
# value for.
|
21
|
+
# @return [String] The value of the environment variable or nil if no
|
22
|
+
# match is available.
|
23
|
+
def self.env(name)
|
24
|
+
self[name]
|
12
25
|
end
|
13
26
|
|
14
|
-
|
15
|
-
|
27
|
+
# Set a default
|
28
|
+
# Defaults are supplied when accessing via Config[:varname]
|
29
|
+
#
|
30
|
+
# @param key [Symbol/String] The lower-case name of the default
|
31
|
+
# @return [String] The value of the default
|
32
|
+
def self.default(key, value)
|
33
|
+
@@defaults[key.to_sym] = value
|
16
34
|
end
|
17
35
|
|
18
|
-
|
19
|
-
|
36
|
+
# Get all the defaults
|
37
|
+
# @return [Hash] The current set of defaults
|
38
|
+
def self.defaults
|
39
|
+
@@defaults
|
20
40
|
end
|
21
41
|
|
22
|
-
|
23
|
-
|
42
|
+
# Get a Config value
|
43
|
+
# Uses defaults if available. Converts upper-case ENV var names
|
44
|
+
# to lower-case default names.
|
45
|
+
#
|
46
|
+
# Config[:foo] == nil
|
47
|
+
#
|
48
|
+
# Config.default(:foo, 'bar')
|
49
|
+
# Config[:foo] == 'bar'
|
50
|
+
#
|
51
|
+
# ENV['FOO'] = 'baz'
|
52
|
+
# Config[:foo] == 'baz'
|
53
|
+
#
|
54
|
+
# @param key [Symbol] The lower-case name of the ENV value
|
55
|
+
# @return [String] The value of the ENV value or default.
|
56
|
+
def self.[](name)
|
57
|
+
var_name = name.to_s.upcase
|
58
|
+
ENV[var_name] || @@defaults[name]
|
24
59
|
end
|
25
60
|
|
26
|
-
|
27
|
-
|
61
|
+
# An environment variable.
|
62
|
+
#
|
63
|
+
# @param name [String] The name of the environment variable to fetch a
|
64
|
+
# value for.
|
65
|
+
# @raise [RuntimeError] Raised if the environment variable is not defined.
|
66
|
+
# @return [String] The value of the environment variable.
|
67
|
+
def self.env!(name)
|
68
|
+
self[name] || raise("missing #{name}")
|
28
69
|
end
|
29
70
|
|
30
|
-
|
71
|
+
# The `RACK_ENV` environment variable is used to determine whether the
|
72
|
+
# service is in production mode or not.
|
73
|
+
#
|
74
|
+
# @return [Bool] True if the service is in production mode.
|
75
|
+
def self.production?
|
76
|
+
self['RACK_ENV'] == 'production'
|
77
|
+
end
|
78
|
+
|
79
|
+
# The `RACK_ENV` environment variable is used to determine whether the
|
80
|
+
# service is in test mode or not.
|
81
|
+
#
|
82
|
+
# @return [Bool] True if the service is in test mode.
|
83
|
+
def self.test?
|
84
|
+
self['RACK_ENV'] == 'test'
|
85
|
+
end
|
86
|
+
|
87
|
+
# The `APP_NAME` env var is used to identify which codebase is
|
88
|
+
# running in librato. This usually matches the name of the repository.
|
89
|
+
#
|
90
|
+
# @return [String] The name of the app
|
91
|
+
def self.app_name
|
31
92
|
env!("APP_NAME")
|
32
93
|
end
|
33
94
|
|
34
|
-
|
95
|
+
# The `APP_DEPLOY` env var is used to identify which deploy of the codebase is
|
96
|
+
# running in librato. This usually matches the name of the environment such
|
97
|
+
# as local, production, staging, etc.
|
98
|
+
#
|
99
|
+
# @return [String] The deploy/environment of the app
|
100
|
+
def self.app_deploy
|
35
101
|
env!("APP_DEPLOY")
|
36
102
|
end
|
37
103
|
|
38
|
-
|
104
|
+
# The port to listen on for web requests.
|
105
|
+
#
|
106
|
+
# @return [Fixnum] The port to listen on for web requests.
|
107
|
+
def self.port
|
39
108
|
env!("PORT").to_i
|
40
109
|
end
|
41
110
|
|
42
|
-
|
111
|
+
# The database URL from the environment.
|
112
|
+
#
|
113
|
+
# @param kind [String] Optionally, the leading name of `*_DATABASE_URL`
|
114
|
+
# environment variable. Defaults to `DATABASE_URL`.
|
115
|
+
# @raise [RuntimeError] Raised if the environment variable is not defined.
|
116
|
+
def self.database_url(kind = '')
|
43
117
|
kind = "#{kind}_".upcase unless kind.empty?
|
44
118
|
env!("#{kind}DATABASE_URL")
|
45
119
|
end
|
46
120
|
|
47
|
-
|
48
|
-
|
121
|
+
# Enforce HTTPS connections in the web API?
|
122
|
+
#
|
123
|
+
# @return [Bool] True if SSL is enforced, otherwise false.
|
124
|
+
def self.enable_ssl?
|
125
|
+
!bool?('VAULT_TOOLS_DISABLE_SSL')
|
126
|
+
end
|
127
|
+
|
128
|
+
# An environment variable converted to a Fixnum.
|
129
|
+
#
|
130
|
+
# @param name [String] The name of the environment variable to fetch a
|
131
|
+
# Fixnum for.
|
132
|
+
# @return [Fixnum] The number or nil if the value couldn't be coerced to a
|
133
|
+
# Fixnum.
|
134
|
+
def self.int(name)
|
135
|
+
self[name] ? self[name].to_i : nil
|
136
|
+
end
|
137
|
+
|
138
|
+
# Comma-separated words converted to an array.
|
139
|
+
#
|
140
|
+
# @param name [String] The name of the environment variable to fetch an
|
141
|
+
# array for.
|
142
|
+
# @raise [RuntimeError] Raised if the environment variable is not defined.
|
143
|
+
# @return [Array] An array of values.
|
144
|
+
def self.array(name)
|
145
|
+
env!(name).split(',')
|
49
146
|
end
|
50
147
|
|
51
|
-
|
52
|
-
|
148
|
+
# An environment variable converted to a bool.
|
149
|
+
#
|
150
|
+
# @param name [String] The name of the environment variable to fetch a
|
151
|
+
# boolean for.
|
152
|
+
# @return [bool] True if the value is `true`, otherwise false.
|
153
|
+
def self.bool?(name)
|
154
|
+
self[name] == 'true'
|
53
155
|
end
|
54
156
|
|
55
|
-
def
|
56
|
-
|
157
|
+
def self.time(name)
|
158
|
+
Time.parse(self[name])
|
57
159
|
end
|
58
160
|
|
59
|
-
|
161
|
+
# The number of threads to use in Sidekiq workers.
|
162
|
+
#
|
163
|
+
# @return [Fixnum] The number of threads from the `SIDEKIQ_CONCURRENCY`
|
164
|
+
# environment variable or 25 if no variable is defined.
|
165
|
+
def self.sidekiq_concurrency
|
60
166
|
int('SIDEKIQ_CONCURRENCY') || 25
|
61
167
|
end
|
62
168
|
end
|
@@ -4,14 +4,14 @@
|
|
4
4
|
#
|
5
5
|
# require 'vault-tools/core_db_tasks'
|
6
6
|
|
7
|
-
desc "Pull db/structure.sql from
|
7
|
+
desc "Pull db/structure.sql from api HEAD"
|
8
8
|
task :pull_core do
|
9
9
|
steps = []
|
10
10
|
steps << 'cd contrib/'
|
11
11
|
if File.exists?('contrib/core')
|
12
12
|
steps << 'rm -rf core'
|
13
13
|
end
|
14
|
-
steps << 'git clone -n git@github.com:heroku/
|
14
|
+
steps << 'git clone -n git@github.com:heroku/api --depth 1'
|
15
15
|
steps << 'cd core'
|
16
16
|
steps << 'git checkout HEAD db/structure.sql'
|
17
17
|
# make sure we don't submodule it
|
@@ -19,13 +19,13 @@ task :pull_core do
|
|
19
19
|
sh steps.join(' && ')
|
20
20
|
end
|
21
21
|
|
22
|
-
desc "Drop and
|
22
|
+
desc "Drop and recreate the core-test database"
|
23
23
|
task :create_core_db => [:drop_core_db, :pull_core] do
|
24
24
|
sh 'createdb core-test'
|
25
25
|
sh 'psql core-test -f contrib/core/db/structure.sql'
|
26
26
|
end
|
27
27
|
|
28
|
-
desc "Drop the
|
28
|
+
desc "Drop the core-test database"
|
29
29
|
task :drop_core_db do
|
30
30
|
sh 'dropdb core-test || true'
|
31
31
|
end
|
data/lib/vault-tools/log.rb
CHANGED
@@ -42,10 +42,10 @@ module Vault
|
|
42
42
|
# @param duration [Fixnum] The duration to record, in milliseconds.
|
43
43
|
def self.time(name, duration)
|
44
44
|
if name
|
45
|
-
name.gsub(/\/:\w+/, '').
|
46
|
-
gsub(
|
47
|
-
gsub(/[^A-Za-z0-9\-\_]/, '').
|
48
|
-
sub(
|
45
|
+
name.gsub(/\/:\w+/, ''). # Remove param names from path.
|
46
|
+
gsub(/[\/_]+/, "-"). # Replace slash with dash.
|
47
|
+
gsub(/[^A-Za-z0-9\-\_]/, ''). # Only keep subset of chars.
|
48
|
+
sub(/^-+/, ""). # Strip the leading dashes.
|
49
49
|
tap { |name| measure(name, "#{duration}ms") }
|
50
50
|
end
|
51
51
|
end
|
@@ -13,13 +13,13 @@ task :pull_payments do
|
|
13
13
|
sh steps.join(' && ')
|
14
14
|
end
|
15
15
|
|
16
|
-
desc "Drop and
|
16
|
+
desc "Drop and recreate payments-test database"
|
17
17
|
task :create_payments_db => [:drop_payments_db, :pull_payments] do
|
18
18
|
sh 'createdb payments-test'
|
19
19
|
sh 'psql payments-test -f contrib/payments/db/structure.sql'
|
20
20
|
end
|
21
21
|
|
22
|
-
desc "Drop the
|
22
|
+
desc "Drop the payments-test database"
|
23
23
|
task :drop_payments_db do
|
24
24
|
sh 'dropdb payments-test || true'
|
25
25
|
end
|
data/lib/vault-tools/version.rb
CHANGED
data/lib/vault-tools/web.rb
CHANGED
@@ -23,7 +23,7 @@ module Vault
|
|
23
23
|
# Check request for HTTP Basic creds and
|
24
24
|
# password matches settings.basic_password
|
25
25
|
def authorized?
|
26
|
-
@auth ||=
|
26
|
+
@auth ||= Rack::Auth::Basic::Request.new(request.env)
|
27
27
|
@auth.provided? && @auth.basic? && @auth.credentials &&
|
28
28
|
@auth.credentials[1] == settings.basic_password
|
29
29
|
end
|
@@ -51,6 +51,7 @@ module Vault
|
|
51
51
|
# body for easy debugging of errors.
|
52
52
|
error do
|
53
53
|
e = env['sinatra.error']
|
54
|
+
Honeybadger.notify(e, rack_env: env)
|
54
55
|
content = "#{e.class}: #{e.message}\n\n"
|
55
56
|
content << e.backtrace.join("\n")
|
56
57
|
[500, content]
|
data/test/config_test.rb
CHANGED
@@ -2,107 +2,180 @@ require 'helper'
|
|
2
2
|
require 'minitest/mock'
|
3
3
|
|
4
4
|
class ConfigTest < Vault::TestCase
|
5
|
-
|
5
|
+
include Vault::Test::EnvironmentHelpers
|
6
|
+
|
7
|
+
# Config.remote_env uses the Heroku API to read config vars from
|
8
|
+
# other apps.
|
9
|
+
def test_remote_env
|
10
|
+
api_mock = MiniTest::Mock.new
|
11
|
+
api_response = OpenStruct.new(body: {'DATABASE_URL' => 'postgres:///foo'})
|
12
|
+
Heroku::API.stub(:new, api_mock) do
|
13
|
+
api_mock.expect(:get_config_vars, api_response, ['app'])
|
14
|
+
assert_equal('postgres:///foo',
|
15
|
+
Config.remote_env('app', 'DATABASE_URL'))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Config.env returns the value matching the specified environment
|
20
|
+
# variable name.
|
21
|
+
def test_env
|
22
|
+
set_env('VALUE', 'value')
|
23
|
+
assert_equal(Config.env('VALUE'), 'value')
|
24
|
+
end
|
25
|
+
|
26
|
+
# Config[] returns the value matching the specified environment
|
27
|
+
# variable name.
|
28
|
+
def test_brackets
|
29
|
+
set_env('VALUE', 'value')
|
30
|
+
assert_equal(Config[:value], 'value')
|
31
|
+
end
|
32
|
+
|
33
|
+
# Config.env return nil if an unknown environment variable is
|
34
|
+
# requested.
|
35
|
+
def test_env_with_unknown_name
|
36
|
+
assert_equal(Config.env('UNKNOWN'), nil)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Config.env! returns the value matching the specified environment
|
40
|
+
# variable name.
|
41
|
+
def test_env!
|
42
|
+
set_env('VALUE', 'value')
|
43
|
+
assert_equal(Config.env!('VALUE'), 'value')
|
44
|
+
end
|
45
|
+
|
46
|
+
# Config.env! raises a RuntimeError if an unknown environment
|
47
|
+
# variable is requested.
|
48
|
+
def test_env_with_unknown_name!
|
49
|
+
error = assert_raises RuntimeError do
|
50
|
+
Config.env!('UNKNOWN')
|
51
|
+
end
|
52
|
+
assert_equal(error.message, 'missing UNKNOWN')
|
53
|
+
end
|
54
|
+
|
55
|
+
# Config.production? is true when RACK_ENV=production.
|
6
56
|
def test_production_mode
|
7
57
|
set_env 'RACK_ENV', nil
|
8
|
-
refute
|
58
|
+
refute Config.production?
|
9
59
|
set_env 'RACK_ENV', 'production'
|
10
|
-
assert
|
60
|
+
assert Config.production?
|
11
61
|
end
|
12
62
|
|
13
|
-
# Config.test? is true when RACK_ENV=test
|
63
|
+
# Config.test? is true when RACK_ENV=test.
|
14
64
|
def test_test_mode
|
15
65
|
set_env 'RACK_ENV', nil
|
16
|
-
refute
|
66
|
+
refute Config.test?
|
17
67
|
set_env 'RACK_ENV', 'test'
|
18
|
-
assert
|
68
|
+
assert Config.test?
|
19
69
|
end
|
20
70
|
|
21
|
-
# Returns DATABASE_URL with no params
|
71
|
+
# Returns DATABASE_URL with no params.
|
22
72
|
def test_database_url
|
23
73
|
set_env 'DATABASE_URL', "postgres:///foo"
|
24
|
-
|
74
|
+
assert_equal(Config.database_url, 'postgres:///foo')
|
25
75
|
end
|
26
76
|
|
27
77
|
# Returns #{kind}_DATABASE_URL with one param
|
28
78
|
def test_database_url_takes_and_capitalizes_params
|
29
79
|
set_env 'FOO_DATABASE_URL', "postgres:///foo"
|
30
|
-
|
80
|
+
assert_equal(Config.database_url('foo'), 'postgres:///foo')
|
31
81
|
end
|
32
82
|
|
83
|
+
# Config.database_url raises a RuntimeError if no DATABASE_URL
|
84
|
+
# environment variables is defined.
|
33
85
|
def test_database_url_raises_when_not_found
|
34
86
|
assert_raises RuntimeError do
|
35
|
-
|
87
|
+
Config.database_url('foo')
|
36
88
|
end
|
37
89
|
end
|
38
90
|
|
39
|
-
#
|
91
|
+
# Config.app_name returns the value of the APP_NAME environment
|
40
92
|
# variable.
|
41
93
|
def test_app_name
|
42
94
|
set_env 'APP_NAME', "my-app"
|
43
|
-
|
95
|
+
Config.app_name.must_equal 'my-app'
|
44
96
|
end
|
45
97
|
|
98
|
+
# Config.app_deploy returns the value of the APP_DEPLOY environment
|
99
|
+
# variable.
|
46
100
|
def test_app_deploy
|
47
101
|
set_env 'APP_DEPLOY', "test"
|
48
|
-
|
102
|
+
Config.app_deploy.must_equal 'test'
|
49
103
|
end
|
50
104
|
|
105
|
+
# Config.port raises a RuntimeError if no `PORT` environment variable
|
106
|
+
# is defined.
|
51
107
|
def test_port_raises
|
52
108
|
assert_raises RuntimeError do
|
53
|
-
|
109
|
+
Config.port
|
54
110
|
end
|
55
111
|
end
|
56
112
|
|
113
|
+
# Config.port converts the value from the environment to a Fixnum
|
57
114
|
def test_port_convert_to_int
|
58
115
|
set_env 'PORT', "3000"
|
59
|
-
|
116
|
+
assert_equal(3000, Config.port)
|
60
117
|
end
|
61
118
|
|
62
|
-
# Config.
|
119
|
+
# Config.enable_ssl? is true unless VAULT_TOOLS_DISABLE_SSL is set.
|
120
|
+
def test_enable_ssl
|
121
|
+
set_env 'VAULT_TOOLS_DISABLE_SSL', nil
|
122
|
+
assert Config.enable_ssl?
|
123
|
+
set_env 'VAULT_TOOLS_DISABLE_SSL', 'true'
|
124
|
+
refute Config.enable_ssl?
|
125
|
+
set_env 'VAULT_TOOLS_DISABLE_SSL', 'false'
|
126
|
+
assert Config.enable_ssl?
|
127
|
+
end
|
128
|
+
|
129
|
+
# Config.int(VAR) returns nil or VAR as integer.
|
63
130
|
def test_int
|
64
|
-
assert_equal(nil,
|
131
|
+
assert_equal(nil, Config.int('FOO'))
|
65
132
|
set_env 'FOO', "3000"
|
66
|
-
assert_equal(3000,
|
133
|
+
assert_equal(3000, Config.int('FOO'))
|
67
134
|
end
|
68
135
|
|
69
|
-
# Config.
|
70
|
-
#
|
71
|
-
def
|
72
|
-
set_env '
|
73
|
-
|
74
|
-
set_env '
|
75
|
-
|
76
|
-
set_env '
|
77
|
-
|
136
|
+
# Config.array loads a comma-separated list of words into an array of
|
137
|
+
# strings.
|
138
|
+
def test_array
|
139
|
+
set_env 'ARRAY', ''
|
140
|
+
assert_equal([], Config.array('ARRAY'))
|
141
|
+
set_env 'ARRAY', 'apple'
|
142
|
+
assert_equal(['apple'], Config.array('ARRAY'))
|
143
|
+
set_env 'ARRAY', 'apple,orange,cherry'
|
144
|
+
assert_equal(['apple', 'orange', 'cherry'], Config.array('ARRAY'))
|
78
145
|
end
|
79
146
|
|
80
|
-
# Config.
|
81
|
-
#
|
82
|
-
def
|
83
|
-
|
84
|
-
|
85
|
-
Heroku::API.stub(:new, api_mock) do
|
86
|
-
api_mock.expect(:get_config_vars, api_response, ['app'])
|
87
|
-
assert_equal('postgres:///foo', Vault::Config.remote_env('app', 'DATABASE_URL'))
|
147
|
+
# Config.array raises a RuntimeError if the environment variable
|
148
|
+
# doesn't exist.
|
149
|
+
def test_array_with_unknown_environment_variable
|
150
|
+
assert_raises RuntimeError do
|
151
|
+
Config.array('UNKNOWN')
|
88
152
|
end
|
89
153
|
end
|
90
154
|
|
91
|
-
|
92
|
-
|
93
|
-
set_env 'SIDEKIQ_CONCURRENCY', '10'
|
94
|
-
assert_equal(10, Vault::Config.sidekiq_concurrency)
|
95
|
-
end
|
96
|
-
|
97
|
-
# Config.bool?(var) is only true if the value of var is the string 'true'.
|
98
|
-
# If the var is absent or any other value, it evaluates to false.
|
155
|
+
# Config.bool?(var) is only true if the value of var is the string
|
156
|
+
# 'true'. If the var is absent or any other value, it evaluates to false.
|
99
157
|
def test_bool_returns_true
|
100
|
-
assert_equal(false,
|
158
|
+
assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
|
101
159
|
set_env 'VAULT_BOOLEAN_VAR', 'true'
|
102
|
-
assert_equal(true,
|
160
|
+
assert_equal(true, Config.bool?('VAULT_BOOLEAN_VAR'))
|
161
|
+
end
|
162
|
+
|
163
|
+
# Config.bool?(var) is false if the value of var is anything other
|
164
|
+
# than the string 'true'.
|
165
|
+
def test_bool_returns_false
|
103
166
|
set_env 'VAULT_BOOLEAN_VAR', 'false'
|
104
|
-
assert_equal(false,
|
167
|
+
assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
|
105
168
|
set_env 'VAULT_BOOLEAN_VAR', 'foo'
|
106
|
-
assert_equal(false,
|
169
|
+
assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
|
170
|
+
set_env 'VAULT_BOOLEAN_VAR', '1'
|
171
|
+
assert_equal(false, Config.bool?('VAULT_BOOLEAN_VAR'))
|
172
|
+
end
|
173
|
+
|
174
|
+
# Config.sidekiq_concurrency returns the value of the
|
175
|
+
# `SIDEKIQ_CONCURRENCY` environment variable or 25 if one isn't defined.
|
176
|
+
def test_sidekiq_concurrency
|
177
|
+
assert_equal(25, Config.sidekiq_concurrency)
|
178
|
+
set_env 'SIDEKIQ_CONCURRENCY', '10'
|
179
|
+
assert_equal(10, Config.sidekiq_concurrency)
|
107
180
|
end
|
108
181
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class DefaultsTest < Vault::TestCase
|
4
|
+
include Vault::Test::EnvironmentHelpers
|
5
|
+
|
6
|
+
def setup
|
7
|
+
Config.defaults.clear
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_default_when_no_value
|
11
|
+
assert_equal(Config[:max_connections], nil)
|
12
|
+
Config.default(:max_connections, 10)
|
13
|
+
assert_equal(Config[:max_connections], 10)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_default_with_int
|
17
|
+
assert_equal(Config[:max_connections], nil)
|
18
|
+
Config.default(:max_connections, '10')
|
19
|
+
assert_equal('10', Config[:max_connections])
|
20
|
+
assert_equal(10, Config.int(:max_connections))
|
21
|
+
set_env 'MAX_CONNECTIONS', '100'
|
22
|
+
assert_equal(100, Config.int(:max_connections))
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_default_with_time
|
26
|
+
assert_equal(Config[:date], nil)
|
27
|
+
Config.default(:date, '2013-01-01')
|
28
|
+
assert_equal('2013-01-01', Config[:date])
|
29
|
+
assert_equal(Time.utc(2013), Config.time(:date))
|
30
|
+
set_env 'DATE', '2014-01-01'
|
31
|
+
assert_equal('2014-01-01', Config[:date])
|
32
|
+
assert_equal(Time.utc(2014), Config.time(:date))
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_default_with_array
|
36
|
+
assert_equal(Config[:array], nil)
|
37
|
+
Config.default(:array, '10')
|
38
|
+
assert_equal('10', Config[:array])
|
39
|
+
assert_equal(['10'], Config.array(:array))
|
40
|
+
Config.default(:array, '1,0')
|
41
|
+
assert_equal('1,0', Config[:array])
|
42
|
+
assert_equal(['1','0'], Config.array(:array))
|
43
|
+
set_env 'ARRAY', '1,2'
|
44
|
+
assert_equal('1,2', Config[:array])
|
45
|
+
assert_equal(['1','2'], Config.array(:array))
|
46
|
+
end
|
47
|
+
end
|
data/test/helper.rb
CHANGED
@@ -1,12 +1,40 @@
|
|
1
1
|
require 'vault-test-tools'
|
2
2
|
require 'vault-tools'
|
3
|
-
ENV['RACK_ENV'] = 'test'
|
4
|
-
Vault.setup
|
5
3
|
|
6
|
-
|
7
|
-
include Vault::Test::EnvironmentHelpers
|
4
|
+
ENV['RACK_ENV'] = 'test'
|
8
5
|
|
6
|
+
module LoggedDataHelper
|
9
7
|
def logged_data
|
10
8
|
Hash[Scrolls.stream.string.split(/\s+/).map {|p| p.split('=') }]
|
11
9
|
end
|
12
10
|
end
|
11
|
+
|
12
|
+
# Overwrite the Honeybadger module
|
13
|
+
module Honeybadger
|
14
|
+
# A place to store the exceptions
|
15
|
+
def self.exceptions
|
16
|
+
@exceptions ||= []
|
17
|
+
end
|
18
|
+
|
19
|
+
# Store calls to notify in an array instead
|
20
|
+
# of calling out to the Honeybadger service
|
21
|
+
def self.notify(exception, opts = {})
|
22
|
+
self.exceptions << [exception, opts]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Clear the stored exceptions in Honeybadger
|
27
|
+
# so each test starts w. a clean slate
|
28
|
+
module HoneybadgerHelper
|
29
|
+
def setup
|
30
|
+
super
|
31
|
+
Honeybadger.exceptions.clear
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Vault::TestCase
|
36
|
+
include Vault::Test::EnvironmentHelpers
|
37
|
+
include HoneybadgerHelper
|
38
|
+
end
|
39
|
+
|
40
|
+
Vault.setup
|
data/test/log_test.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
class LogTest < Vault::TestCase
|
4
|
+
include Vault::Test::EnvironmentHelpers
|
5
|
+
include LoggedDataHelper
|
6
|
+
|
4
7
|
def setup
|
5
8
|
super
|
6
9
|
set_env('APP_NAME', 'test-app')
|
@@ -64,6 +67,11 @@ class LogTest < Vault::TestCase
|
|
64
67
|
assert_equal '123.4ms', logged_data['measure#test-app.some-web-path']
|
65
68
|
end
|
66
69
|
|
70
|
+
def test_time_replaces_underscore_with_dash
|
71
|
+
Vault::Log.time('/some/web_path', 123.4)
|
72
|
+
assert_equal '123.4ms', logged_data['measure#test-app.some-web-path']
|
73
|
+
end
|
74
|
+
|
67
75
|
# Vault::Log.time removes parameters.
|
68
76
|
def test_time_removes_parameters
|
69
77
|
Vault::Log.time('/some/:web/path', 123.4)
|
data/test/text_processor_test.rb
CHANGED
data/test/web_test.rb
CHANGED
@@ -2,6 +2,8 @@ require 'helper'
|
|
2
2
|
|
3
3
|
class WebTest < Vault::TestCase
|
4
4
|
include Rack::Test::Methods
|
5
|
+
include Vault::Test::EnvironmentHelpers
|
6
|
+
include LoggedDataHelper
|
5
7
|
|
6
8
|
# Anonymous Web Frontend
|
7
9
|
def app
|
@@ -20,7 +22,7 @@ class WebTest < Vault::TestCase
|
|
20
22
|
app.set :basic_password, 'password'
|
21
23
|
app.get '/protected' do
|
22
24
|
protected!
|
23
|
-
'
|
25
|
+
'You may pass'
|
24
26
|
end
|
25
27
|
|
26
28
|
get '/protected'
|
@@ -28,7 +30,7 @@ class WebTest < Vault::TestCase
|
|
28
30
|
authorize('','password')
|
29
31
|
get '/protected'
|
30
32
|
assert_equal 200, last_response.status
|
31
|
-
assert_equal '
|
33
|
+
assert_equal 'You may pass', last_response.body
|
32
34
|
end
|
33
35
|
|
34
36
|
# Middleware is attached at load time, so we have to delete the Vault::Web
|
@@ -68,8 +70,9 @@ class WebTest < Vault::TestCase
|
|
68
70
|
assert_equal(404, last_response.status)
|
69
71
|
end
|
70
72
|
|
71
|
-
# An
|
72
|
-
# traceback is
|
73
|
+
# An `http_500` and an `http_5xx` log metric is written when an internal
|
74
|
+
# server error occurs. A traceback is written to the response body to ease
|
75
|
+
# debugging.
|
73
76
|
def test_error_logs_500
|
74
77
|
get '/boom'
|
75
78
|
assert_equal '1', logged_data['count#test-app.http.500']
|
@@ -79,6 +82,15 @@ class WebTest < Vault::TestCase
|
|
79
82
|
assert_equal(500, last_response.status)
|
80
83
|
end
|
81
84
|
|
85
|
+
# Test we register errors with Honeybadger when they happen
|
86
|
+
def test_error_with_honeybadger
|
87
|
+
assert_equal(0, Honeybadger.exceptions.size)
|
88
|
+
get '/boom'
|
89
|
+
assert_equal(1, Honeybadger.exceptions.size)
|
90
|
+
error, opts = Honeybadger.exceptions.first
|
91
|
+
assert_equal(RuntimeError, error.class)
|
92
|
+
end
|
93
|
+
|
82
94
|
# SSL is enforced when we are in production mode
|
83
95
|
def test_ssl_enforced_in_production_mode
|
84
96
|
set_env 'RACK_ENV', 'production'
|
@@ -89,11 +101,22 @@ class WebTest < Vault::TestCase
|
|
89
101
|
assert_match(/^https/, last_response.headers['Location'])
|
90
102
|
end
|
91
103
|
|
92
|
-
# SSL
|
93
|
-
#
|
94
|
-
def
|
104
|
+
# SSL is explicitly enforced when we're in production mode and the
|
105
|
+
# `VAULT_TOOLS_DISABLE_SSL` environment variable is set to `false`.
|
106
|
+
def test_ssl_explicitly_enforced_in_production_mode
|
107
|
+
set_env 'RACK_ENV', 'production'
|
108
|
+
set_env 'VAULT_TOOLS_DISABLE_SSL', 'false'
|
109
|
+
reload_web!
|
110
|
+
get '/health'
|
111
|
+
assert_equal(301, last_response.status)
|
112
|
+
assert_match(/^https/, last_response.headers['Location'])
|
113
|
+
end
|
114
|
+
|
115
|
+
# SSL isn't enforced when the `VAULT_TOOLS_DISABLE_SSL` environment variable
|
116
|
+
# is set to `true`.
|
117
|
+
def test_ssl_can_be_disabled_in_production_mode
|
95
118
|
set_env 'RACK_ENV', 'production'
|
96
|
-
set_env 'VAULT_TOOLS_DISABLE_SSL', '
|
119
|
+
set_env 'VAULT_TOOLS_DISABLE_SSL', 'true'
|
97
120
|
reload_web!
|
98
121
|
get '/health'
|
99
122
|
assert_equal(200, last_response.status)
|
data/vault-tools.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vault-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-11-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: scrolls
|
17
|
-
requirement:
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,15 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements:
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
26
31
|
- !ruby/object:Gem::Dependency
|
27
32
|
name: sinatra
|
28
|
-
requirement:
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
29
34
|
none: false
|
30
35
|
requirements:
|
31
36
|
- - ! '>='
|
@@ -33,10 +38,15 @@ dependencies:
|
|
33
38
|
version: '0'
|
34
39
|
type: :runtime
|
35
40
|
prerelease: false
|
36
|
-
version_requirements:
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
37
47
|
- !ruby/object:Gem::Dependency
|
38
48
|
name: uuidtools
|
39
|
-
requirement:
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
40
50
|
none: false
|
41
51
|
requirements:
|
42
52
|
- - ! '>='
|
@@ -44,10 +54,15 @@ dependencies:
|
|
44
54
|
version: '0'
|
45
55
|
type: :runtime
|
46
56
|
prerelease: false
|
47
|
-
version_requirements:
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
48
63
|
- !ruby/object:Gem::Dependency
|
49
64
|
name: rack-ssl-enforcer
|
50
|
-
requirement:
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
51
66
|
none: false
|
52
67
|
requirements:
|
53
68
|
- - ! '>='
|
@@ -55,10 +70,15 @@ dependencies:
|
|
55
70
|
version: '0'
|
56
71
|
type: :runtime
|
57
72
|
prerelease: false
|
58
|
-
version_requirements:
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
59
79
|
- !ruby/object:Gem::Dependency
|
60
80
|
name: heroku-api
|
61
|
-
requirement:
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
62
82
|
none: false
|
63
83
|
requirements:
|
64
84
|
- - ! '>='
|
@@ -66,18 +86,44 @@ dependencies:
|
|
66
86
|
version: '0'
|
67
87
|
type: :runtime
|
68
88
|
prerelease: false
|
69
|
-
version_requirements:
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
70
95
|
- !ruby/object:Gem::Dependency
|
71
96
|
name: fernet
|
72
|
-
requirement:
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
73
98
|
none: false
|
74
99
|
requirements:
|
75
|
-
- - =
|
100
|
+
- - '='
|
76
101
|
- !ruby/object:Gem::Version
|
77
102
|
version: 2.0.rc2
|
78
103
|
type: :runtime
|
79
104
|
prerelease: false
|
80
|
-
version_requirements:
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 2.0.rc2
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: honeybadger
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :runtime
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ! '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
81
127
|
description: Basic tools for Heroku Vault's Ruby projects
|
82
128
|
email:
|
83
129
|
- christopher.continanza@gmail.com
|
@@ -104,7 +150,6 @@ files:
|
|
104
150
|
- lib/vault-tools/payments_db_tasks.rb
|
105
151
|
- lib/vault-tools/pipeline.rb
|
106
152
|
- lib/vault-tools/product.rb
|
107
|
-
- lib/vault-tools/shushu_db_tasks.rb
|
108
153
|
- lib/vault-tools/sinatra_helpers/html_serializer.rb
|
109
154
|
- lib/vault-tools/text_processor.rb
|
110
155
|
- lib/vault-tools/user.rb
|
@@ -112,6 +157,7 @@ files:
|
|
112
157
|
- lib/vault-tools/web.rb
|
113
158
|
- test/app_test.rb
|
114
159
|
- test/config_test.rb
|
160
|
+
- test/defaults_test.rb
|
115
161
|
- test/helper.rb
|
116
162
|
- test/hid_test.rb
|
117
163
|
- test/log_test.rb
|
@@ -134,15 +180,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
134
180
|
- - ! '>='
|
135
181
|
- !ruby/object:Gem::Version
|
136
182
|
version: '0'
|
183
|
+
segments:
|
184
|
+
- 0
|
185
|
+
hash: 24233614407525305
|
137
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
187
|
none: false
|
139
188
|
requirements:
|
140
189
|
- - ! '>='
|
141
190
|
- !ruby/object:Gem::Version
|
142
191
|
version: '0'
|
192
|
+
segments:
|
193
|
+
- 0
|
194
|
+
hash: 24233614407525305
|
143
195
|
requirements: []
|
144
196
|
rubyforge_project:
|
145
|
-
rubygems_version: 1.8.
|
197
|
+
rubygems_version: 1.8.23
|
146
198
|
signing_key:
|
147
199
|
specification_version: 3
|
148
200
|
summary: Test classes, base web classes, and helpers - oh my!
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# Rake tasks for Shushu DB
|
2
|
-
#
|
3
|
-
# include in Rakefile via:
|
4
|
-
#
|
5
|
-
# require 'vault-tools/shushu_db_tasks'
|
6
|
-
|
7
|
-
desc "Pull db/structure.sql from shushu HEAD"
|
8
|
-
task :pull_shushu do
|
9
|
-
steps = []
|
10
|
-
steps << 'cd contrib/'
|
11
|
-
if File.exists?('contrib/shushu')
|
12
|
-
steps << 'rm -rf shushu'
|
13
|
-
end
|
14
|
-
steps << 'git clone -n git@github.com:heroku/shushud shushu --depth 1'
|
15
|
-
steps << 'cd shushu'
|
16
|
-
steps << 'git checkout HEAD db/*'
|
17
|
-
# make sure we don't submodule it
|
18
|
-
steps << 'rm -rf .git'
|
19
|
-
sh steps.join(' && ')
|
20
|
-
end
|
21
|
-
|
22
|
-
desc "Drop and create shushu-test database"
|
23
|
-
task :create_shushu_db => [:drop_shushu_db, :pull_shushu] do
|
24
|
-
sh 'createdb shushu-test'
|
25
|
-
sh 'cd contrib/shushu && ../../vendor/bin/sequel postgres:///shushu-test -m db/migrations'
|
26
|
-
end
|
27
|
-
|
28
|
-
desc "Drop the vault-usage-test, core-test and shushu-test databases"
|
29
|
-
task :drop_shushu_db do
|
30
|
-
sh 'dropdb shushu-test || true'
|
31
|
-
end
|