chamber 0.0.4 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/
|
1
|
+
# Chamber [![Build Status](https://travis-ci.org/m5rk/chamber.png)](https://travis-ci.org/m5rk/chamber) [![Code Climate](https://codeclimate.com/github/m5rk/chamber.png)](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
|
|