chamber 0.0.4 → 1.0.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.
- checksums.yaml +4 -4
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +718 -127
- data/bin/chamber +277 -0
- data/lib/chamber.rb +63 -65
- data/lib/chamber/file.rb +84 -0
- data/lib/chamber/file_set.rb +265 -0
- data/lib/chamber/namespace_set.rb +141 -0
- data/lib/chamber/rails.rb +3 -0
- data/lib/chamber/rails/railtie.rb +11 -0
- data/lib/chamber/settings.rb +152 -0
- data/lib/chamber/system_environment.rb +145 -0
- data/lib/chamber/version.rb +2 -2
- data/spec/lib/chamber/file_set_spec.rb +212 -0
- data/spec/lib/chamber/file_spec.rb +94 -0
- data/spec/lib/chamber/namespace_set_spec.rb +81 -0
- data/spec/lib/chamber/settings_spec.rb +135 -0
- data/spec/lib/chamber/system_environment_spec.rb +121 -0
- data/spec/lib/chamber_spec.rb +279 -243
- metadata +58 -59
- data/.gitignore +0 -17
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/.travis.yml +0 -5
- data/Gemfile +0 -4
- data/Rakefile +0 -6
- data/chamber.gemspec +0 -36
- data/spec/spec_helper.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c054c5c22c6b6273bd39adecb26c84209e21930
|
4
|
+
data.tar.gz: dee881699926bd8f73055cdfb87c23bb9a439bb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abf527a63562fcc4a0b048a6de5a33ed1b240eb3c0bf2e140289c35ef0cee4264de48ce4199260ca1dbf56e1049b7202f5435bfbb888d0290c37475bad3bbace
|
7
|
+
data.tar.gz: f92834cf8cb8b504ca6d38c10558560851ed2dd36f09480ec64c41e8f97a685cf6851e4ae3f17dd8f9a716e32495f224c7a7cfb7a84ed104bc7f7549e36ce121
|
data/{LICENSE.txt → LICENSE}
RENAMED
File without changes
|
data/README.md
CHANGED
@@ -1,223 +1,814 @@
|
|
1
|
-
# Chamber [](https://travis-ci.org/m5rk/chamber) [](https://codeclimate.com/github/m5rk/chamber)
|
2
2
|
|
3
|
-
Chamber lets you source your
|
4
|
-
|
5
|
-
|
3
|
+
Chamber lets you source your settings from an arbitrary number of YAML files that
|
4
|
+
values convention over configuration and has an automatic mechanism for working
|
5
|
+
with Heroku's (or anyone else's) ENV variables.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
9
9
|
Add this line to your application's Gemfile:
|
10
10
|
|
11
|
-
|
11
|
+
```ruby
|
12
|
+
gem 'chamber'
|
13
|
+
```
|
12
14
|
|
13
15
|
And then execute:
|
14
16
|
|
15
|
-
|
17
|
+
```sh
|
18
|
+
$ bundle
|
19
|
+
```
|
16
20
|
|
17
21
|
Or install it yourself as:
|
18
22
|
|
19
|
-
|
23
|
+
```sh
|
24
|
+
$ gem install chamber
|
25
|
+
```
|
26
|
+
|
27
|
+
## Basic Usage
|
20
28
|
|
21
|
-
|
29
|
+
### Convention Over Configuration
|
22
30
|
|
23
|
-
|
24
|
-
|
31
|
+
By default Chamber only needs a base path to look for settings files. From
|
32
|
+
that path it will search for:
|
25
33
|
|
26
|
-
|
34
|
+
* The file `<basepath>/credentials.yml`
|
35
|
+
* The file `<basepath>/settings.yml`
|
36
|
+
* A set of files ending in `.yml` in the `<basepath>/settings` directory
|
37
|
+
|
38
|
+
### In Plain Old Ruby
|
27
39
|
|
28
40
|
```ruby
|
29
|
-
|
30
|
-
extend Chamber
|
31
|
-
end
|
41
|
+
Chamber.load basepath: '/path/to/my/application'
|
32
42
|
```
|
33
43
|
|
34
|
-
|
44
|
+
### In Rails
|
35
45
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
46
|
+
If you're running a Rails app, by default Chamber will set the basepath to your
|
47
|
+
Rails app's `config` directory, which is the equivalent of:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
Chamber.load basepath: Rails.root.join('config')
|
51
|
+
```
|
52
|
+
|
53
|
+
### Accessing Settings
|
54
|
+
|
55
|
+
The YAML data will be loaded and you will have access to the settings
|
56
|
+
through the `Chamber` class.
|
57
|
+
|
58
|
+
**Example:**
|
59
|
+
|
60
|
+
Given a `settings.yml` file containing:
|
61
|
+
|
62
|
+
```yaml
|
63
|
+
smtp:
|
64
|
+
server: "example.com"
|
65
|
+
username: "my_user"
|
66
|
+
password: "my_pass"
|
53
67
|
```
|
54
68
|
|
55
|
-
|
69
|
+
can be accessed as follows:
|
56
70
|
|
57
71
|
```ruby
|
58
|
-
|
59
|
-
|
72
|
+
Chamber[:smtp][:server]
|
73
|
+
# => example.com
|
74
|
+
```
|
60
75
|
|
61
|
-
|
62
|
-
|
76
|
+
or via object notation syntax:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
Chamber.env.smtp.server
|
80
|
+
# => example.com
|
63
81
|
```
|
64
82
|
|
65
|
-
|
66
|
-
|
83
|
+
### Keeping Your Settings Files Secure
|
84
|
+
|
85
|
+
Check out [Keeping Private Settings Private](#keeping-private-settings-private)
|
86
|
+
below.
|
87
|
+
|
88
|
+
### Existing Environment Variables (aka Heroku)
|
89
|
+
|
90
|
+
If deploying to a system which has all of your environment variables already
|
91
|
+
set, you're not going to use all of the values stored in the YAML files.
|
92
|
+
Instead, you're going to want to pull certain values from environment variables.
|
67
93
|
|
68
|
-
|
94
|
+
**Example:**
|
95
|
+
|
96
|
+
Given a `settings.yml` file containing:
|
97
|
+
|
98
|
+
```yaml
|
99
|
+
smtp:
|
100
|
+
server: "example.com"
|
101
|
+
username: "my_user"
|
102
|
+
password: "my_pass"
|
103
|
+
```
|
104
|
+
|
105
|
+
If an environment variable is already set like so:
|
106
|
+
|
107
|
+
```sh
|
108
|
+
export SMTP_SERVER="myotherserverisapentium.com"
|
109
|
+
```
|
110
|
+
|
111
|
+
Then when you ask Chamber to give you the SMTP server:
|
69
112
|
|
70
113
|
```ruby
|
71
|
-
|
72
|
-
|
114
|
+
Chamber[:smtp][:server]
|
115
|
+
# => "myotherserverisapentium.com"
|
116
|
+
```
|
73
117
|
|
74
|
-
|
75
|
-
|
118
|
+
It will return not what is in the YAML file, but what is in the environment
|
119
|
+
variable.
|
76
120
|
|
77
|
-
|
78
|
-
|
121
|
+
## Deploying to Heroku
|
122
|
+
|
123
|
+
If you're deploying to Heroku, they won't let you upload custom config files. If
|
124
|
+
you do not have your config files all stored in your repo (which you shouldn't
|
125
|
+
if some of the information is sensitive), it becomes more difficult to gain
|
126
|
+
access to that information on Heroku.
|
127
|
+
|
128
|
+
To solve this problem, Heroku allows you to set environment variables in your
|
129
|
+
application. Unfortunately this has the nasty side effect of being a pain to
|
130
|
+
deal with. For one, you have to deal with environment variables with unweildy
|
131
|
+
names. For another, it makes the organization of those variables difficult.
|
132
|
+
|
133
|
+
Fortunately, Chamber allows you to organize your environment variables in
|
134
|
+
separate files and access them easily using hash or object notation, however at
|
135
|
+
the same time, it provides a convenient way to push all of those sensitive
|
136
|
+
configuration settings up to Heroku as environment variables.
|
137
|
+
|
138
|
+
When Chamber accesses those same hash/object notated config values, it will
|
139
|
+
first look to see if an associated environment variable exists. If it does, it
|
140
|
+
will use that in place of any values inside of the config files.
|
141
|
+
|
142
|
+
Simply run:
|
143
|
+
|
144
|
+
```sh
|
145
|
+
# In the root folder of your Rails app:
|
146
|
+
|
147
|
+
chamber heroku push --preset=rails
|
148
|
+
|
149
|
+
# In the root folder of another type of application:
|
150
|
+
|
151
|
+
chamber heroku push --basepath=./
|
152
|
+
```
|
153
|
+
|
154
|
+
And all of your settings will be converted to environment variable versions
|
155
|
+
and set on your Heroku app.
|
156
|
+
|
157
|
+
_**Note:** For the full set of options, see [The chamber Command Line
|
158
|
+
App](#the-chamber-command-line-app) below._
|
159
|
+
|
160
|
+
## Deploying to Travis CI
|
161
|
+
|
162
|
+
When deploying to Travis CI, it has similar environment variable requirements as
|
163
|
+
Heroku, however Travis allows the encryption of environment variables before
|
164
|
+
they are stored in the .travis.yml file. This allows for that file to be
|
165
|
+
checked into git without worrying about prying eyes figuring out your secret
|
166
|
+
information.
|
167
|
+
|
168
|
+
To execute this, simply run:
|
169
|
+
|
170
|
+
```sh
|
171
|
+
chamber travis secure --basepath=./
|
79
172
|
```
|
80
173
|
|
81
|
-
|
174
|
+
This will add `secure` entries into your `.travis.yml` file. Each one will
|
175
|
+
contain one environment variable.
|
176
|
+
|
177
|
+
_**Warning:** Each time you execute this command it will delete all secure
|
178
|
+
entries under 'env.global' in your `.travis.yml` file._
|
179
|
+
|
180
|
+
_**Note:** For the full set of options, see [The chamber Command Line
|
181
|
+
App](#the-chamber-command-line-app) below._
|
182
|
+
|
183
|
+
## Advanced Usage
|
184
|
+
|
185
|
+
### Explicitly Specifying Settings Files
|
186
|
+
|
187
|
+
Using convention over configuration, Chamber handles the 90% case by default,
|
188
|
+
however there may be times at which you would like to explicitly specify which
|
189
|
+
settings files are loaded. In these cases, Chamber has you covered:
|
82
190
|
|
83
191
|
```ruby
|
84
|
-
|
85
|
-
|
192
|
+
Chamber.load files: [
|
193
|
+
'/path/to/my/application/chamber/credentials.yml',
|
194
|
+
'/path/to/my/application/application*.yml',
|
195
|
+
'/path/to/my/application/chamber/*.yml',
|
196
|
+
]
|
197
|
+
```
|
86
198
|
|
87
|
-
|
88
|
-
|
199
|
+
In this case, Chamber will load *only* the `credentials.yml` file *without ever*
|
200
|
+
looking for a namespaced file. Then it will load `application.yml` *and* any
|
201
|
+
associated namespaced files. Finally it will load all \*.yml files in the
|
202
|
+
`chamber` directory *except* `credentials.yml` because it has previously been
|
203
|
+
loaded.
|
89
204
|
|
90
|
-
|
91
|
-
|
205
|
+
### Object-Based Environment Variable Access
|
206
|
+
|
207
|
+
If you aren't a fan of the hash-based access, you can also access them
|
208
|
+
using methods:
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
Chamber.env.smtp.server
|
92
212
|
```
|
93
213
|
|
94
|
-
|
95
|
-
|
214
|
+
### Predicate Methods
|
215
|
+
|
216
|
+
When using object notation, all settings have `?` and `_` predicate methods
|
217
|
+
defined on them. They work like so:
|
218
|
+
|
219
|
+
#### '?' Predicates Check For Falsity
|
96
220
|
|
97
|
-
|
98
|
-
|
221
|
+
```ruby
|
222
|
+
Chamber.env.my_setting # => nil
|
223
|
+
Chamber.env.my_setting? # => false
|
99
224
|
|
100
|
-
|
225
|
+
Chamber.env.my_other_setting # => false
|
226
|
+
Chamber.env.my_other_setting? # => false
|
101
227
|
|
102
|
-
|
103
|
-
|
104
|
-
access_key_id: value
|
105
|
-
secret_access_key: value
|
106
|
-
bucket: value
|
228
|
+
Chamber.env.another_setting # => 'my value'
|
229
|
+
Chamber.env.another_setting? # => true
|
107
230
|
```
|
108
231
|
|
109
|
-
|
232
|
+
#### '\_' Predicates Allow for Multi-Level Testing
|
110
233
|
|
111
234
|
```ruby
|
112
|
-
|
113
|
-
|
114
|
-
s3_credentials: {
|
115
|
-
access_key_id: Settings.s3.access_key_id,
|
116
|
-
secret_access_key: Settings.s3.secret_access_key
|
117
|
-
},
|
118
|
-
bucket: Settings.s3.bucket,
|
119
|
-
...
|
235
|
+
Chamber.env.empty? # => true
|
236
|
+
Chamber.env.my_setting_group_.my_setting? # => false
|
120
237
|
```
|
121
238
|
|
122
|
-
|
239
|
+
#### 'key?' Checks For Existence
|
123
240
|
|
124
|
-
|
241
|
+
The `?` method will return false if a key has been set to `false` or `nil`. In
|
242
|
+
order to check if a key has been set at all, use the `key?('some_key')` method
|
243
|
+
instead.
|
125
244
|
|
126
|
-
|
127
|
-
sensitive information in git." A better way to say it is that you should store
|
128
|
-
sensitive information separate from non-sensitive information. There's nothing
|
129
|
-
inherently wrong with storing sensitive information in git. You just wouldn't
|
130
|
-
want to store it in a public repository.
|
245
|
+
Notice the difference:
|
131
246
|
|
132
|
-
|
133
|
-
|
134
|
-
|
247
|
+
```ruby
|
248
|
+
Chamber.env.my_setting # => false
|
249
|
+
Chamber.env.my_setting? # => false
|
250
|
+
|
251
|
+
Chamber.env.key?('my_setting') # => true
|
252
|
+
Chamber.env.key?('my_non_existent_key') # => false
|
253
|
+
```
|
254
|
+
|
255
|
+
### ERB Preprocessing
|
256
|
+
|
257
|
+
One of the nice things about Chamber is that it runs each settings file through
|
258
|
+
ERB before it tries to parse it as YAML. The main benefit of this is that you
|
259
|
+
can use settings from previous files in ERB for later files. This is mainly
|
260
|
+
used if you follow our convention of putting all of your sensitive information
|
261
|
+
in your `credentials.yml` file.
|
135
262
|
|
136
|
-
|
263
|
+
**Example:**
|
137
264
|
|
265
|
+
```yaml
|
266
|
+
# credentials.yml
|
267
|
+
|
268
|
+
production:
|
269
|
+
my_secret_key: 123456789
|
138
270
|
```
|
139
|
-
# Ignore the environment-specific files that contain the real credentials:
|
140
|
-
/config/credentials-*.yml
|
141
271
|
|
142
|
-
|
143
|
-
|
272
|
+
```erb
|
273
|
+
<%# settings.yml %>
|
274
|
+
|
275
|
+
production:
|
276
|
+
my_url: http://my_username:<%= Chamber[:my_secret_key] %>@my-url.com
|
277
|
+
```
|
278
|
+
|
279
|
+
Because by default Chamber processes `credentials` settings files before
|
280
|
+
anything else, this works.
|
281
|
+
|
282
|
+
But it's all ERB so you can do as much crazy ERB stuff in your settings files as
|
283
|
+
you'd like:
|
284
|
+
|
285
|
+
```erb
|
286
|
+
<%# settings.yml %>
|
287
|
+
|
288
|
+
<% %w{development test production}.each do |environment| %>
|
289
|
+
<%= environment %>:
|
290
|
+
hostname_with_subdomain: <%= environment %>.example.com:3000
|
291
|
+
|
292
|
+
<% end %>
|
144
293
|
```
|
145
294
|
|
146
|
-
|
295
|
+
Would result in the following settings being set:
|
296
|
+
|
297
|
+
```yaml
|
298
|
+
development:
|
299
|
+
hostname_with_subdomain: development.example.com:3000
|
300
|
+
|
301
|
+
test:
|
302
|
+
hostname_with_subdomain: test.example.com:3000
|
303
|
+
|
304
|
+
production:
|
305
|
+
hostname_with_subdomain: production.example.com:3000
|
306
|
+
```
|
307
|
+
|
308
|
+
### Namespacing
|
309
|
+
|
310
|
+
If, when running your app, you would like to have certain files loaded only
|
311
|
+
under specific circumstances, you can use Chamber's namespaces.
|
312
|
+
|
313
|
+
**Example:**
|
147
314
|
|
148
315
|
```ruby
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
end
|
316
|
+
Chamber.load( :basepath => '/tmp',
|
317
|
+
:namespaces => {
|
318
|
+
:environment => -> { ::Rails.env } } )
|
153
319
|
```
|
154
320
|
|
155
|
-
|
321
|
+
For this class, it will not only try and load the file `config/settings.yml`,
|
322
|
+
it will _also_ try and load the file `config/settings-<environment>.yml`
|
323
|
+
where `<environment>` is whatever Rails environment you happen to be running.
|
156
324
|
|
157
|
-
|
158
|
-
one big jumbo settings.yml? You can do that with Chamber. You want a distinct
|
159
|
-
settings file for each specific concern? You can do that too.
|
325
|
+
#### Inline Namespaces
|
160
326
|
|
161
|
-
|
327
|
+
If having a file per namespace value isn't your thing, you can inline your
|
328
|
+
namespaces. Taking the example from above, rather than having `settings.yml`,
|
329
|
+
`settings-development.yml`, `settings-test.yml`, `settings-staging.yml` and
|
330
|
+
`settings-production.yml`, you could do something like this:
|
162
331
|
|
163
|
-
|
332
|
+
```yaml
|
333
|
+
# settings.yml
|
334
|
+
|
335
|
+
development:
|
336
|
+
smtp:
|
337
|
+
username: my_development_username
|
338
|
+
password: my_development_password`
|
339
|
+
|
340
|
+
test:
|
341
|
+
smtp:
|
342
|
+
username: my_test_username
|
343
|
+
password: my_test_password`
|
344
|
+
|
345
|
+
staging:
|
346
|
+
smtp:
|
347
|
+
username: my_staging_username
|
348
|
+
password: my_staging_password`
|
349
|
+
|
350
|
+
production:
|
351
|
+
smtp:
|
352
|
+
username: my_production_username
|
353
|
+
password: my_production_password`
|
354
|
+
```
|
355
|
+
|
356
|
+
You can even mix and match.
|
357
|
+
|
358
|
+
```yaml
|
359
|
+
# settings.yml
|
360
|
+
|
361
|
+
development:
|
362
|
+
smtp:
|
363
|
+
username: my_development_username
|
364
|
+
password: my_development_password`
|
365
|
+
|
366
|
+
test:
|
367
|
+
smtp:
|
368
|
+
username: my_test_username
|
369
|
+
password: my_test_password`
|
370
|
+
|
371
|
+
staging:
|
372
|
+
smtp:
|
373
|
+
username: my_staging_username
|
374
|
+
password: my_staging_password`
|
375
|
+
```
|
376
|
+
|
377
|
+
```yaml
|
378
|
+
# settings-production.yml
|
379
|
+
|
380
|
+
smtp:
|
381
|
+
username: my_production_username
|
382
|
+
password: my_production_password`
|
383
|
+
````
|
384
|
+
|
385
|
+
The above will yield the same results, but allows you to keep the production
|
386
|
+
values in a separate file which can be secured separately.
|
387
|
+
|
388
|
+
#### Multiple Namespaces
|
389
|
+
|
390
|
+
Multiple namespaces can be defined by passing multiple items to the loader:
|
164
391
|
|
165
392
|
```ruby
|
166
|
-
|
167
|
-
|
393
|
+
Chamber.load( :basepath => '/tmp',
|
394
|
+
:namespaces => {
|
395
|
+
:environment => -> { ::Rails.env },
|
396
|
+
:hostname => -> { ENV['HOST'] } } )
|
397
|
+
```
|
168
398
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
399
|
+
When accessed within the `test` environment on a system named `tumbleweed`, it
|
400
|
+
will load the following files in the following order:
|
401
|
+
|
402
|
+
* `settings.yml`
|
403
|
+
* `settings-test.yml`
|
404
|
+
* `settings-tumbleweed.yml`
|
405
|
+
|
406
|
+
If a file does not exist, it is skipped.
|
407
|
+
|
408
|
+
#### What Happens With Duplicate Entries?
|
409
|
+
|
410
|
+
Similarly named settings in later files can override settings defined in earlier
|
411
|
+
files.
|
412
|
+
|
413
|
+
If `settings.yml` contains a value:
|
414
|
+
|
415
|
+
```yaml
|
416
|
+
smtp:
|
417
|
+
server: "generalserver.com"
|
418
|
+
```
|
419
|
+
|
420
|
+
And then `settings-test.yml` contains this:
|
421
|
+
|
422
|
+
```yaml
|
423
|
+
smtp:
|
424
|
+
server: "testserver.com"
|
174
425
|
```
|
175
426
|
|
176
|
-
|
427
|
+
The when you access the value with `Chamber[:smtp][:server]` you will receive
|
428
|
+
`testserver.com`.
|
429
|
+
|
430
|
+
### Outputting Your Settings
|
177
431
|
|
178
|
-
|
432
|
+
Chamber makes it dead simple to output your environment settings in a variety of
|
433
|
+
formats.
|
434
|
+
|
435
|
+
The simplest is:
|
179
436
|
|
180
437
|
```ruby
|
181
|
-
|
182
|
-
|
438
|
+
Chamber.to_s
|
439
|
+
# => MY_SETTING="my value" MY_OTHER_SETTING="my other value"
|
440
|
+
```
|
183
441
|
|
184
|
-
|
442
|
+
But you can pass other options to customize the string:
|
443
|
+
|
444
|
+
* `pair_separator`
|
445
|
+
* `value_surrounder`
|
446
|
+
* `name_value_separator`
|
447
|
+
|
448
|
+
```ruby
|
449
|
+
Chamber.to_s pair_separator: "\n",
|
450
|
+
value_surrounder: "'",
|
451
|
+
name_value_separator: ': '
|
452
|
+
|
453
|
+
# => MY_SETTING: 'my value'
|
454
|
+
# => MY_OTHER_SETTING: 'my other value'
|
455
|
+
```
|
456
|
+
|
457
|
+
### The chamber Command Line App
|
458
|
+
|
459
|
+
Chamber provides a flexible binary that you can use to make working with your
|
460
|
+
configurations easier. Let's take a look:
|
461
|
+
|
462
|
+
#### Common Options
|
463
|
+
|
464
|
+
Each of the commands described below takes a few common options.
|
465
|
+
|
466
|
+
* `--preset` (or `-p`): Allows you to quickly set the basepath, files and/or
|
467
|
+
namespaces for a given situation (eg working with a Rails app).
|
468
|
+
|
469
|
+
**Example:** `--preset=rails`
|
470
|
+
|
471
|
+
* `--files` (or `-f`): Allows you to specifically set the file patterns that
|
472
|
+
Chamber should look at in determining where to load settings information from.
|
473
|
+
|
474
|
+
**Example:** `--files=/path/to/my/application/secret.yml /path/to/my/application/settings/*.yml`
|
475
|
+
|
476
|
+
* `--basepath` (or `-b`): Sets the base path that Chamber will use to look for
|
477
|
+
its [common settings files](#convention-over-configuration).
|
478
|
+
|
479
|
+
**Example:** `--basepath=/path/to/my/application`
|
480
|
+
|
481
|
+
* `--namespaces` (or `-n`): The namespace values which will be considered for
|
482
|
+
loading settings files.
|
483
|
+
|
484
|
+
**Example:** `--namespaces=development`
|
485
|
+
|
486
|
+
_**Note:** `--basepath`, `--preset` and `--files` are mutually exclusive._
|
487
|
+
|
488
|
+
#### Settings
|
489
|
+
|
490
|
+
##### Settings Commands
|
491
|
+
|
492
|
+
###### Show
|
493
|
+
|
494
|
+
Gives users an easy way of looking at all of the settings that Chamber knows
|
495
|
+
about for a given context. It will be output as a hash of hashes by default.
|
496
|
+
|
497
|
+
* `--as-env`: Instead of outputting the settings as a hash of hashes, convert
|
498
|
+
the settings into environment variable-compatible versions.
|
499
|
+
|
500
|
+
**Example:** `--as-env`
|
501
|
+
|
502
|
+
**Example:** `chamber settings show -p=rails`
|
503
|
+
|
504
|
+
###### Files
|
505
|
+
|
506
|
+
Very useful for troubleshooting, this will output all of the files that
|
507
|
+
Chamber considers relevant based on the given options passed.
|
508
|
+
|
509
|
+
Additionally, the order is significant. Chamber will load settings from the
|
510
|
+
top down so any duplicate items in subsequent entries will override items from
|
511
|
+
previous ones.
|
512
|
+
|
513
|
+
**Example:** `chamber settings files -p=rails`
|
514
|
+
|
515
|
+
###### Compare
|
516
|
+
|
517
|
+
Will display a diff of the settings for one set of namespaces vs the settings
|
518
|
+
for a second set of namespaces.
|
519
|
+
|
520
|
+
This is extremely handy if, for example, you would like to see whether the
|
521
|
+
settings you're using for development match up with the settings you're using
|
522
|
+
for production, or if you're setting all of the same settings for any two
|
523
|
+
environments.
|
524
|
+
|
525
|
+
* `--keys-only`: This is the default. When performing a comparison, only the
|
526
|
+
keys will be considered since values between namespaces will often (and
|
527
|
+
should often) be different.
|
528
|
+
|
529
|
+
**Example:** `--keys-only`, `--no-keys-only`
|
530
|
+
|
531
|
+
* `--first`: This is an array of the first set of namespace settings that you
|
532
|
+
would like to compare from. You can list one or more.
|
533
|
+
|
534
|
+
**Example:** `--first=development`, `--first=development my_host_name`
|
535
|
+
|
536
|
+
* `--second`: This is an array of the second set of namespace settings that
|
537
|
+
you would like to compare against that specified by `--first`. You can list
|
538
|
+
one or more.
|
539
|
+
|
540
|
+
**Example:** `--second=staging`, `--second=staging my_host_name`
|
541
|
+
|
542
|
+
**Example:** `chamber settings compare --first=development --second=staging -p=rails`
|
543
|
+
|
544
|
+
#### Heroku
|
545
|
+
|
546
|
+
As we described above, working with Heroku environment variables is tedious at
|
547
|
+
best. Chamber gives you a few ways to help with that.
|
548
|
+
|
549
|
+
_**Note:** I'll be using the `--preset` shorthand `-p` for brevity below but the
|
550
|
+
examples will work with any of the other options described
|
551
|
+
[above](#common-options)._
|
552
|
+
|
553
|
+
##### Heroku Common Options
|
554
|
+
|
555
|
+
* `--app` (or `-a`): Heroku application name for which you would like to affect
|
556
|
+
its environment variables.
|
557
|
+
|
558
|
+
**Example:** `--app=my-heroku-app-name`
|
559
|
+
|
560
|
+
* `--dry-run` (or `-d`): The command will not actually execute, but will show
|
561
|
+
you a summary of what *would* have happened.
|
562
|
+
|
563
|
+
**Example:** `--dry-run`
|
564
|
+
|
565
|
+
* `--only-ignored` (or `-o`): This is the default. Because Heroku has no issues
|
566
|
+
reading from the config files you have stored in your repo, there is no need
|
567
|
+
to set *all* of your settings as environment variables. So by default,
|
568
|
+
Chamber will only convert and push those settings which have been gitignored.
|
569
|
+
|
570
|
+
To push everything, use the `--no-only-ignored` flag.
|
571
|
+
|
572
|
+
**Example:** `--only-ignored`, `--no-only-ignored`
|
573
|
+
|
574
|
+
##### Heroku Commands
|
575
|
+
|
576
|
+
###### Push
|
577
|
+
|
578
|
+
As we described above, this command will take your current settings and push
|
579
|
+
them to Heroku as environment variables that Chamber will be able to
|
580
|
+
understand.
|
581
|
+
|
582
|
+
**Example:** `chamber heroku push -a=my-heroku-app -p=rails -n=staging`
|
583
|
+
|
584
|
+
_**Note:** To see exactly how Chamber sees your settings as environment variables, see
|
585
|
+
the [chamber settings show](#general-settings-commands) command above._
|
586
|
+
|
587
|
+
###### Pull
|
588
|
+
|
589
|
+
Will display the list of environment variables that you have set on your
|
590
|
+
Heroku instance.
|
591
|
+
|
592
|
+
This is similar to just executing `heroku config --shell` except that you can
|
593
|
+
specify the following option:
|
594
|
+
|
595
|
+
* `--into`: The file which the pulled settings will be copied into. This file
|
596
|
+
*will* be overridden.
|
597
|
+
|
598
|
+
_**Note:** Eventually this will be parsed into YAML that Chamber can load
|
599
|
+
straight away, but for now, it's basically just redirecting the output._
|
600
|
+
|
601
|
+
**Example:** `--into=/path/to/my/app/settings/heroku.yml`
|
602
|
+
|
603
|
+
**Example:** `chamber heroku pull -a=my-heroku-app --into=/path/to/my/app/heroku.yml`
|
604
|
+
|
605
|
+
###### Diff
|
606
|
+
|
607
|
+
Will use git's diff function to display the difference between what Chamber
|
608
|
+
knows about locally and what Heroku currently has set. This is very handy for
|
609
|
+
knowing what changes may be made if `chamber heroku push` is executed.
|
610
|
+
|
611
|
+
**Example:** `chamber heroku diff -a=my-heroku-app -p=rails -n=staging`
|
612
|
+
|
613
|
+
###### Clear
|
614
|
+
|
615
|
+
Will remove any environment variables from Heroku that Chamber knows about.
|
616
|
+
This is useful for clearing out Chamber-related settings without touching
|
617
|
+
Heroku addon-specific items.
|
618
|
+
|
619
|
+
**Example:** `chamber heroku clear -a=my-heroku-app -p=rails -n=staging`
|
620
|
+
|
621
|
+
#### Travis CI
|
622
|
+
|
623
|
+
##### Travis Common Options
|
624
|
+
|
625
|
+
* `--dry-run` (or `-d`): The command will not actually execute, but will show
|
626
|
+
you a summary of what *would* have happened.
|
627
|
+
|
628
|
+
**Example:** `--dry-run`
|
629
|
+
|
630
|
+
* `--only-ignored` (or `-o`): This is the default. Because Travis has no issues
|
631
|
+
reading from the config files you have stored in your repo, there is no need
|
632
|
+
to set *all* of your settings as environment variables. So by default,
|
633
|
+
Chamber will only convert and push those settings which have been gitignored.
|
634
|
+
|
635
|
+
To push everything, use the `--no-only-ignored` flag.
|
636
|
+
|
637
|
+
**Example:** `--only-ignored`, `--no-only-ignored`
|
638
|
+
|
639
|
+
##### Travis Commands
|
640
|
+
|
641
|
+
###### Secure
|
642
|
+
|
643
|
+
Travis CI allows you to use the public key on your Travis repo to encrypt
|
644
|
+
items such as environment variables which you would like for Travis to be able
|
645
|
+
to have access to, but which you wouldn't necessarily want to be in plain text
|
646
|
+
inside of your repo.
|
647
|
+
|
648
|
+
This command takes the settings that Chamber knows about, encrypts them, and
|
649
|
+
puts them inside of your .travis.yml at which point they can be safely
|
650
|
+
committed.
|
651
|
+
|
652
|
+
_**Warning:** This will delete *all* of your previous 'secure' entries under
|
653
|
+
'env.global' in your .travis.yml file._
|
654
|
+
|
655
|
+
**Example:** `chamber travis secure -p=rails -n=continuous_integration`
|
656
|
+
|
657
|
+
### Basic Boolean Conversion
|
658
|
+
|
659
|
+
One of the things that is a huge pain when dealing with environment variables is
|
660
|
+
that they can only be strings. Unfortunately this is kind of a problem for
|
661
|
+
settings which you would like to use to set whether a specific item is enabled
|
662
|
+
or disabled. Because this:
|
663
|
+
|
664
|
+
```yaml
|
665
|
+
# settings.yml
|
666
|
+
|
667
|
+
my_feature:
|
668
|
+
enabled: false
|
669
|
+
```
|
670
|
+
|
671
|
+
```ruby
|
672
|
+
if Chamber.env.my_feature.enabled?
|
673
|
+
# Do stuff with my feature
|
185
674
|
end
|
186
675
|
```
|
187
676
|
|
188
|
-
|
677
|
+
Will always return true because `false` becomes `'false'` on Heroku which, as
|
678
|
+
far as Ruby is concerned, is `true`. Now, you could completely omit the
|
679
|
+
`enabled` key, however this causes issues if you would like to audit your
|
680
|
+
settings (say for each environment) to make sure they are all the same. Some
|
681
|
+
will have the `enabled` setting and some will not, which will give you false
|
682
|
+
positives.
|
189
683
|
|
190
|
-
|
191
|
-
Chamber's `source` method provides an `override_from_environment` option; e.g.,
|
684
|
+
You could work around it by doing this:
|
192
685
|
|
193
686
|
```ruby
|
194
|
-
|
195
|
-
|
687
|
+
if Chamber.env.my_feature.enabled == 'true'
|
688
|
+
# Do stuff with my feature
|
689
|
+
end
|
690
|
+
```
|
691
|
+
|
692
|
+
but that looks awful.
|
693
|
+
|
694
|
+
To solve this problem, Chamber reviews all of your settings values and, if they
|
695
|
+
are any of the following exact strings (case insensitive):
|
196
696
|
|
197
|
-
|
697
|
+
* 'false'
|
698
|
+
* 'f'
|
699
|
+
* 'no'
|
700
|
+
* 'true'
|
701
|
+
* 't'
|
702
|
+
* 'yes'
|
703
|
+
|
704
|
+
The value will be converted to the proper Boolean value. In which case the
|
705
|
+
above `Chamber.env.my_feature.enabled?` will work as expected and your
|
706
|
+
environment audit will pass.
|
707
|
+
|
708
|
+
### In Order to Add Advanced Functionality
|
709
|
+
|
710
|
+
In any case that you need to set configuration options or do advanced post
|
711
|
+
processing on your YAML data, you'll want to create your own object for
|
712
|
+
accessing it. Don't worry, Chamber will take you 98% of the way there.
|
713
|
+
|
714
|
+
Just include it like so:
|
715
|
+
|
716
|
+
```ruby
|
717
|
+
class Settings < Chamber
|
198
718
|
end
|
199
719
|
```
|
200
720
|
|
201
|
-
|
721
|
+
Now, rather than using `Chamber[:application_host]` to access your
|
722
|
+
environment, you can simply use `Settings[:application_host]`.
|
202
723
|
|
203
|
-
|
204
|
-
settings?)
|
724
|
+
## Best Practices
|
205
725
|
|
206
|
-
|
726
|
+
### Why Do We Need Chamber?
|
207
727
|
|
208
|
-
|
728
|
+
> Don't store sensitive information in git.
|
729
|
+
|
730
|
+
A better way to say it is that you should store sensitive information separate
|
731
|
+
from non-sensitive information. There's nothing inherently wrong with storing
|
732
|
+
sensitive information in git. You just wouldn't want to store it in a public
|
733
|
+
repository.
|
209
734
|
|
210
|
-
|
735
|
+
If it weren't for this concern, managing settings would be trivial, easily
|
736
|
+
solved use any number of approaches; e.g., [like using YAML and ERB in an
|
737
|
+
initializer](http://urgetopunt.com/rails/2009/09/12/yaml-config-with-erb.html).
|
738
|
+
|
739
|
+
### Organizing Your Settings
|
740
|
+
|
741
|
+
We recommend starting with a single `config/settings.yml` file. Once this file
|
742
|
+
begins to become too unwieldy, you can begin to extract common options (let's
|
743
|
+
say SMTP settings) into another file (perhaps `config/settings/smtp.yml`).
|
211
744
|
|
212
|
-
|
745
|
+
### Keeping Private Settings Private
|
213
746
|
|
214
|
-
|
747
|
+
Obviously the greater the number of files which need to be kept private the more
|
748
|
+
difficult it is to manage the settings. Therefore we suggest beginning with one
|
749
|
+
private file that stores all of your credentials.
|
215
750
|
|
216
|
-
|
751
|
+
### Ignoring Settings Files
|
217
752
|
|
218
|
-
|
753
|
+
We recommend adding the following to your `.gitignore` file:
|
754
|
+
|
755
|
+
```
|
756
|
+
# Ignore the environment-specific files that contain the real credentials:
|
757
|
+
/config/credentials.yml
|
758
|
+
/config/credentials-*.yml
|
759
|
+
|
760
|
+
# But don't ignore the example file that shows the structure:
|
761
|
+
!/config/credentials-example.yml
|
762
|
+
```
|
763
|
+
|
764
|
+
Along with any namespace-specific exclusions. For example, if you're using
|
765
|
+
Rails, you may want to exclude some of your environment-specific files:
|
766
|
+
|
767
|
+
```
|
768
|
+
*-staging.yml
|
769
|
+
*-production.yml
|
770
|
+
```
|
771
|
+
|
772
|
+
### Full Example
|
773
|
+
|
774
|
+
Let's walk through how you might use Chamber to configure your SMTP settings:
|
775
|
+
|
776
|
+
```yaml
|
777
|
+
# config/settings.yml
|
778
|
+
|
779
|
+
stuff:
|
780
|
+
not: "Not Related to SMTP"
|
781
|
+
|
782
|
+
# config/settings/smtp.yml
|
783
|
+
|
784
|
+
smtp:
|
785
|
+
headers:
|
786
|
+
X-MYAPP-NAME: My Application Name
|
787
|
+
X-MYAPP-STUFF: Other Stuff
|
788
|
+
|
789
|
+
# config/settings/smtp-staging.yml
|
790
|
+
|
791
|
+
smtp:
|
792
|
+
username: my_test_user
|
793
|
+
password: my_test_password
|
794
|
+
```
|
795
|
+
|
796
|
+
Now you can access both `username` and `headers` off of `smtp` like so:
|
797
|
+
|
798
|
+
```ruby
|
799
|
+
Chamber[:smtp][:headers]
|
800
|
+
# => { X-MYAPP-NAME: 'My Application Name', X-MYAPP-STUFF: 'Other Stuff' }
|
801
|
+
|
802
|
+
Chamber[:smtp][:password]
|
803
|
+
# => my_test_password
|
804
|
+
```
|
805
|
+
|
806
|
+
## Alternatives
|
219
807
|
|
220
|
-
[
|
808
|
+
* [dotenv](https://github.com/bkeepers/dotenv)
|
809
|
+
* [figaro](https://github.com/laserlemon/figaro)
|
810
|
+
* [idkfa](https://github.com/bendyworks/idkfa)
|
811
|
+
* [settingslogic](https://github.com/binarylogic/settingslogic)
|
221
812
|
|
222
813
|
### Others?
|
223
814
|
|