chamber 2.12.5 → 2.14.2
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +101 -26
- data/lib/chamber.rb +82 -10
- data/lib/chamber/adapters/cloud/circle_ci.rb +85 -0
- data/lib/chamber/adapters/cloud/heroku.rb +74 -0
- data/lib/chamber/binary/circle_ci.rb +122 -0
- data/lib/chamber/binary/heroku.rb +45 -16
- data/lib/chamber/binary/runner.rb +42 -26
- data/lib/chamber/binary/travis.rb +5 -3
- data/lib/chamber/commands/base.rb +10 -16
- data/lib/chamber/commands/cloud/base.rb +35 -0
- data/lib/chamber/commands/{heroku → cloud}/clear.rb +6 -8
- data/lib/chamber/commands/cloud/compare.rb +26 -0
- data/lib/chamber/commands/cloud/pull.rb +29 -0
- data/lib/chamber/commands/cloud/push.rb +44 -0
- data/lib/chamber/commands/comparable.rb +2 -2
- data/lib/chamber/commands/compare.rb +6 -9
- data/lib/chamber/commands/initialize.rb +26 -22
- data/lib/chamber/commands/securable.rb +9 -9
- data/lib/chamber/commands/secure.rb +2 -2
- data/lib/chamber/commands/show.rb +8 -8
- data/lib/chamber/commands/sign.rb +2 -2
- data/lib/chamber/commands/verify.rb +2 -2
- data/lib/chamber/configuration.rb +8 -3
- data/lib/chamber/context_resolver.rb +8 -7
- data/lib/chamber/encryption_methods/ssl.rb +12 -12
- data/lib/chamber/file.rb +16 -14
- data/lib/chamber/file_set.rb +18 -8
- data/lib/chamber/files/signature.rb +16 -14
- data/lib/chamber/filters/decryption_filter.rb +17 -13
- data/lib/chamber/filters/encryption_filter.rb +8 -8
- data/lib/chamber/filters/environment_filter.rb +12 -14
- data/lib/chamber/filters/failed_decryption_filter.rb +6 -6
- data/lib/chamber/filters/insecure_filter.rb +3 -3
- data/lib/chamber/filters/namespace_filter.rb +5 -5
- data/lib/chamber/filters/secure_filter.rb +5 -5
- data/lib/chamber/filters/translate_secure_keys_filter.rb +5 -5
- data/lib/chamber/instance.rb +45 -21
- data/lib/chamber/key_pair.rb +7 -7
- data/lib/chamber/keys/base.rb +31 -49
- data/lib/chamber/keys/decryption.rb +5 -5
- data/lib/chamber/keys/encryption.rb +5 -5
- data/lib/chamber/namespace_set.rb +2 -4
- data/lib/chamber/settings.rb +73 -45
- data/lib/chamber/types/secured.rb +8 -10
- data/lib/chamber/version.rb +1 -1
- data/templates/settings.yml +2 -0
- metadata +46 -39
- metadata.gz.sig +0 -0
- data/lib/chamber/commands/heroku.rb +0 -31
- data/lib/chamber/commands/heroku/compare.rb +0 -33
- data/lib/chamber/commands/heroku/pull.rb +0 -30
- data/lib/chamber/commands/heroku/push.rb +0 -27
data/lib/chamber/key_pair.rb
CHANGED
@@ -9,10 +9,10 @@ class KeyPair
|
|
9
9
|
:namespace,
|
10
10
|
:passphrase
|
11
11
|
|
12
|
-
def initialize(
|
13
|
-
self.namespace =
|
14
|
-
self.passphrase =
|
15
|
-
self.key_file_path = Pathname.new(
|
12
|
+
def initialize(key_file_path:, namespace: nil, passphrase: ::SecureRandom.uuid)
|
13
|
+
self.namespace = namespace
|
14
|
+
self.passphrase = passphrase
|
15
|
+
self.key_file_path = Pathname.new(key_file_path)
|
16
16
|
end
|
17
17
|
|
18
18
|
def encrypted_private_key_passphrase_filepath
|
@@ -78,9 +78,9 @@ class KeyPair
|
|
78
78
|
@base_key_filename ||= [
|
79
79
|
'.chamber',
|
80
80
|
namespace ? namespace.tr('-.', '') : nil,
|
81
|
-
]
|
82
|
-
compact
|
83
|
-
join('.')
|
81
|
+
]
|
82
|
+
.compact
|
83
|
+
.join('.')
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
data/lib/chamber/keys/base.rb
CHANGED
@@ -3,81 +3,63 @@
|
|
3
3
|
module Chamber
|
4
4
|
module Keys
|
5
5
|
class Base
|
6
|
-
def self.resolve(
|
7
|
-
new(
|
6
|
+
def self.resolve(**args)
|
7
|
+
new(**args).resolve
|
8
8
|
end
|
9
9
|
|
10
10
|
attr_accessor :rootpath
|
11
11
|
attr_reader :filenames,
|
12
12
|
:namespaces
|
13
13
|
|
14
|
-
def initialize(
|
15
|
-
self.rootpath = Pathname.new(
|
16
|
-
self.namespaces =
|
17
|
-
self.filenames =
|
14
|
+
def initialize(rootpath:, namespaces:, filenames: nil)
|
15
|
+
self.rootpath = Pathname.new(rootpath)
|
16
|
+
self.namespaces = namespaces
|
17
|
+
self.filenames = filenames
|
18
18
|
end
|
19
19
|
|
20
20
|
def resolve
|
21
|
-
|
22
|
-
namespace =
|
23
|
-
value =
|
24
|
-
key_from_environment_variable(filename)
|
21
|
+
key_paths.each_with_object({}) do |path, memo|
|
22
|
+
namespace = namespace_from_path(path) || '__default'
|
23
|
+
value = path.readable? ? path.read : ENV[environment_variable_from_path(path)]
|
25
24
|
|
26
25
|
memo[namespace.downcase.to_sym] = value if value
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
map { |o| Pathname.new(o) }.
|
35
|
-
compact
|
36
|
-
|
37
|
-
paths << default_key_file_path if paths.empty?
|
38
|
-
|
39
|
-
(
|
40
|
-
paths +
|
41
|
-
generate_key_filenames
|
42
|
-
).
|
43
|
-
uniq
|
44
|
-
end
|
29
|
+
def as_environment_variables
|
30
|
+
key_paths.select(&:readable?).each_with_object({}) do |path, memo|
|
31
|
+
memo[environment_variable_from_path(path)] = path.read
|
32
|
+
end
|
45
33
|
end
|
46
|
-
# rubocop:enable Performance/ChainArrayAllocation
|
47
34
|
|
48
35
|
private
|
49
36
|
|
50
|
-
def
|
51
|
-
@
|
52
|
-
|
53
|
-
other.keys.map(&:to_s)
|
54
|
-
else
|
55
|
-
other
|
56
|
-
end
|
57
|
-
|
58
|
-
keys + %w{signature}
|
59
|
-
end
|
37
|
+
def key_paths
|
38
|
+
@key_paths = (filenames.any? ? filenames : [default_key_file_path]) +
|
39
|
+
namespaces.map { |n| namespace_to_key_path(n) }
|
60
40
|
end
|
61
41
|
|
62
|
-
|
63
|
-
|
42
|
+
# rubocop:disable Performance/ChainArrayAllocation
|
43
|
+
def filenames=(other)
|
44
|
+
@filenames = Array(other)
|
45
|
+
.map { |o| Pathname.new(o) }
|
46
|
+
.compact
|
64
47
|
end
|
48
|
+
# rubocop:enable Performance/ChainArrayAllocation
|
65
49
|
|
66
|
-
def
|
67
|
-
|
50
|
+
def namespaces=(other)
|
51
|
+
@namespaces = other + %w{signature}
|
68
52
|
end
|
69
53
|
|
70
|
-
def
|
71
|
-
|
72
|
-
basename
|
73
|
-
to_s
|
74
|
-
match(self.class::NAMESPACE_PATTERN) { |m| m[1].upcase }
|
54
|
+
def namespace_from_path(path)
|
55
|
+
path
|
56
|
+
.basename
|
57
|
+
.to_s
|
58
|
+
.match(self.class::NAMESPACE_PATTERN) { |m| m[1].upcase }
|
75
59
|
end
|
76
60
|
|
77
|
-
def
|
78
|
-
|
79
|
-
rootpath + ".chamber.#{namespace.to_s.tr('.-', '')}#{key_filename_extension}"
|
80
|
-
end
|
61
|
+
def namespace_to_key_path(namespace)
|
62
|
+
rootpath + ".chamber.#{namespace.to_s.tr('.-', '')}#{key_filename_extension}"
|
81
63
|
end
|
82
64
|
|
83
65
|
def default_key_file_path
|
@@ -17,14 +17,14 @@ class Decryption < Chamber::Keys::Base
|
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
-
def
|
20
|
+
def environment_variable_from_path(path)
|
21
21
|
[
|
22
22
|
'CHAMBER',
|
23
|
-
|
23
|
+
namespace_from_path(path),
|
24
24
|
'KEY',
|
25
|
-
]
|
26
|
-
compact
|
27
|
-
join('_')
|
25
|
+
]
|
26
|
+
.compact
|
27
|
+
.join('_')
|
28
28
|
end
|
29
29
|
|
30
30
|
def key_filename_extension
|
@@ -17,14 +17,14 @@ class Encryption < Chamber::Keys::Base
|
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
-
def
|
20
|
+
def environment_variable_from_path(path)
|
21
21
|
[
|
22
22
|
'CHAMBER',
|
23
|
-
|
23
|
+
namespace_from_path(path),
|
24
24
|
'PUBLIC_KEY',
|
25
|
-
]
|
26
|
-
compact
|
27
|
-
join('_')
|
25
|
+
]
|
26
|
+
.compact
|
27
|
+
.join('_')
|
28
28
|
end
|
29
29
|
|
30
30
|
def key_filename_extension
|
@@ -71,10 +71,8 @@ class NamespaceSet
|
|
71
71
|
# Internal: Iterates over each namespace value and allows it to be used in
|
72
72
|
# a block.
|
73
73
|
#
|
74
|
-
def each
|
75
|
-
namespaces.each
|
76
|
-
yield namespace
|
77
|
-
end
|
74
|
+
def each(&block)
|
75
|
+
namespaces.each(&block)
|
78
76
|
end
|
79
77
|
|
80
78
|
###
|
data/lib/chamber/settings.rb
CHANGED
@@ -16,29 +16,40 @@ require 'chamber/filters/failed_decryption_filter'
|
|
16
16
|
#
|
17
17
|
module Chamber
|
18
18
|
class Settings
|
19
|
-
attr_accessor :
|
20
|
-
:post_filters,
|
19
|
+
attr_accessor :decryption_keys,
|
21
20
|
:encryption_keys,
|
22
|
-
:
|
21
|
+
:post_filters,
|
22
|
+
:pre_filters,
|
23
|
+
:secure_key_prefix
|
23
24
|
attr_reader :namespaces
|
24
25
|
|
25
|
-
# rubocop:disable Metrics/
|
26
|
-
def initialize(
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
26
|
+
# rubocop:disable Metrics/ParameterLists
|
27
|
+
def initialize(
|
28
|
+
decryption_keys: {},
|
29
|
+
encryption_keys: {},
|
30
|
+
namespaces: [],
|
31
|
+
pre_filters: [
|
32
|
+
Filters::NamespaceFilter,
|
33
|
+
],
|
34
|
+
post_filters: [
|
35
|
+
Filters::DecryptionFilter,
|
36
|
+
Filters::EnvironmentFilter,
|
37
|
+
Filters::FailedDecryptionFilter,
|
38
|
+
Filters::TranslateSecureKeysFilter,
|
39
|
+
],
|
40
|
+
secure_key_prefix: '_secure_',
|
41
|
+
settings: {},
|
42
|
+
**_args
|
43
|
+
)
|
44
|
+
self.decryption_keys = decryption_keys
|
45
|
+
self.encryption_keys = encryption_keys
|
46
|
+
self.namespaces = namespaces
|
47
|
+
self.post_filters = post_filters
|
48
|
+
self.pre_filters = pre_filters
|
49
|
+
self.raw_data = settings
|
50
|
+
self.secure_key_prefix = secure_key_prefix
|
40
51
|
end
|
41
|
-
# rubocop:enable Metrics/
|
52
|
+
# rubocop:enable Metrics/ParameterLists
|
42
53
|
|
43
54
|
###
|
44
55
|
# Internal: Converts a Settings object into a hash that is compatible as an
|
@@ -79,15 +90,11 @@ class Settings
|
|
79
90
|
# } ).to_s
|
80
91
|
# # => 'MY_KEY="my value" MY_OTHER_KEY="my other value"'
|
81
92
|
#
|
82
|
-
def to_s(
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
concatenated_name_hash = to_concatenated_name_hash(hierarchical_separator)
|
89
|
-
|
90
|
-
pairs = concatenated_name_hash.to_a.map do |key, value|
|
93
|
+
def to_s(hierarchical_separator: '_',
|
94
|
+
pair_separator: ' ',
|
95
|
+
value_surrounder: '"',
|
96
|
+
name_value_separator: '=')
|
97
|
+
pairs = to_concatenated_name_hash(hierarchical_separator).to_a.map do |key, value|
|
91
98
|
"#{key.upcase}#{name_value_separator}#{value_surrounder}#{value}#{value_surrounder}"
|
92
99
|
end
|
93
100
|
|
@@ -182,20 +189,21 @@ class Settings
|
|
182
189
|
# Returns a new Settings object
|
183
190
|
#
|
184
191
|
def merge(other)
|
185
|
-
other_settings =
|
192
|
+
other_settings = case other
|
193
|
+
when Settings
|
186
194
|
other
|
187
|
-
|
195
|
+
when Hash
|
188
196
|
Settings.new(settings: other)
|
189
197
|
end
|
190
198
|
|
191
|
-
# rubocop:disable
|
199
|
+
# rubocop:disable Layout/LineLength
|
192
200
|
Settings.new(
|
193
201
|
encryption_keys: encryption_keys.any? ? encryption_keys : other_settings.encryption_keys,
|
194
202
|
decryption_keys: decryption_keys.any? ? decryption_keys : other_settings.decryption_keys,
|
195
203
|
namespaces: (namespaces + other_settings.namespaces),
|
196
204
|
settings: raw_data.merge(other_settings.raw_data),
|
197
205
|
)
|
198
|
-
# rubocop:enable
|
206
|
+
# rubocop:enable Layout/LineLength
|
199
207
|
end
|
200
208
|
|
201
209
|
###
|
@@ -219,15 +227,36 @@ class Settings
|
|
219
227
|
namespaces == other.namespaces
|
220
228
|
end
|
221
229
|
|
230
|
+
def [](key)
|
231
|
+
warn "WARNING: Bracket access will require strings instead of symbols in Chamber 3.0. You attempted to access the '#{key}' setting. See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#removal-of-bracket-indifferent-access for full details." if key.is_a?(::Symbol) # rubocop:disable Layout/LineLength
|
232
|
+
warn "WARNING: Accessing a non-existent key ('#{key}') with brackets will fail in Chamber 3.0. See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#bracket-access-now-fails-on-non-existent-keys for full details." unless data.has_key?(key) # rubocop:disable Layout/LineLength
|
233
|
+
|
234
|
+
data.[](key)
|
235
|
+
end
|
236
|
+
|
237
|
+
def dig!(*args)
|
238
|
+
args.inject(data) do |data_value, bracket_value|
|
239
|
+
key = bracket_value.is_a?(::Symbol) ? bracket_value.to_s : bracket_value
|
240
|
+
|
241
|
+
data_value.fetch(key)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def dig(*args)
|
246
|
+
dig!(*args)
|
247
|
+
rescue ::KeyError, ::IndexError # rubocop:disable Lint/ShadowedException
|
248
|
+
nil
|
249
|
+
end
|
250
|
+
|
222
251
|
def securable
|
223
|
-
Settings.new(metadata.merge(
|
252
|
+
Settings.new(**metadata.merge(
|
224
253
|
settings: raw_data,
|
225
254
|
pre_filters: [Filters::SecureFilter],
|
226
255
|
))
|
227
256
|
end
|
228
257
|
|
229
258
|
def secure
|
230
|
-
Settings.new(metadata.merge(
|
259
|
+
Settings.new(**metadata.merge(
|
231
260
|
settings: raw_data,
|
232
261
|
pre_filters: [Filters::EncryptionFilter],
|
233
262
|
post_filters: [Filters::TranslateSecureKeysFilter],
|
@@ -235,7 +264,7 @@ class Settings
|
|
235
264
|
end
|
236
265
|
|
237
266
|
def insecure
|
238
|
-
Settings.new(metadata.merge(
|
267
|
+
Settings.new(**metadata.merge(
|
239
268
|
settings: raw_data,
|
240
269
|
pre_filters: [Filters::InsecureFilter],
|
241
270
|
post_filters: [Filters::TranslateSecureKeysFilter],
|
@@ -243,9 +272,14 @@ class Settings
|
|
243
272
|
end
|
244
273
|
|
245
274
|
def method_missing(name, *args)
|
246
|
-
|
275
|
+
if data.respond_to?(name)
|
276
|
+
warn "WARNING: Object notation access is deprecated and will be removed in Chamber 3.0. You attempted to access the '#{name}' setting. See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#removal-of-object-notation-access for full details." # rubocop:disable Layout/LineLength
|
277
|
+
warn "WARNING: Predicate methods are deprecated and will be removed in Chamber 3.0. You attempted to access the '#{name}' setting. See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#removal-of-predicate-accessors for full details." if name.to_s.end_with?('?') # rubocop:disable Layout/LineLength
|
247
278
|
|
248
|
-
|
279
|
+
data.public_send(name, *args)
|
280
|
+
else
|
281
|
+
super
|
282
|
+
end
|
249
283
|
end
|
250
284
|
|
251
285
|
def respond_to_missing?(name, include_private = false)
|
@@ -265,23 +299,17 @@ class Settings
|
|
265
299
|
# rubocop:disable Naming/MemoizedInstanceVariableName
|
266
300
|
def raw_data
|
267
301
|
@filtered_raw_data ||= pre_filters.inject(@raw_data) do |filtered_data, filter|
|
268
|
-
filter.execute({ data: filtered_data }.
|
269
|
-
merge(metadata))
|
302
|
+
filter.execute(**{ data: filtered_data }.merge(metadata))
|
270
303
|
end
|
271
304
|
end
|
272
305
|
# rubocop:enable Naming/MemoizedInstanceVariableName
|
273
306
|
|
274
307
|
def data
|
275
308
|
@data ||= post_filters.inject(raw_data) do |filtered_data, filter|
|
276
|
-
filter.execute({ data: filtered_data }.
|
277
|
-
merge(metadata))
|
309
|
+
filter.execute(**{ data: filtered_data }.merge(metadata))
|
278
310
|
end
|
279
311
|
end
|
280
312
|
|
281
|
-
def secure_key_prefix
|
282
|
-
'_secure_'
|
283
|
-
end
|
284
|
-
|
285
313
|
def metadata
|
286
314
|
{
|
287
315
|
decryption_keys: decryption_keys,
|
@@ -3,21 +3,19 @@
|
|
3
3
|
require 'active_support/json'
|
4
4
|
require 'chamber'
|
5
5
|
|
6
|
-
# rubocop:disable Lint/HandleExceptions, Layout/EmptyLinesAroundModuleBody
|
7
6
|
module Chamber
|
8
|
-
|
9
7
|
begin
|
10
8
|
require 'active_record/type/value'
|
11
9
|
|
12
10
|
CHAMBER_TYPE_VALUE_SUPERCLASS = ActiveRecord::Type::Value
|
13
|
-
rescue LoadError
|
11
|
+
rescue LoadError # rubocop:disable Lint/SuppressedException
|
14
12
|
end
|
15
13
|
|
16
14
|
begin
|
17
15
|
require 'active_model/type/value'
|
18
16
|
|
19
17
|
CHAMBER_TYPE_VALUE_SUPERCLASS = ActiveModel::Type::Value
|
20
|
-
rescue LoadError
|
18
|
+
rescue LoadError # rubocop:disable Lint/SuppressedException
|
21
19
|
end
|
22
20
|
|
23
21
|
module Types
|
@@ -25,11 +23,12 @@ class Secured < CHAMBER_TYPE_VALUE_SUPERCLASS
|
|
25
23
|
attr_accessor :decryption_keys,
|
26
24
|
:encryption_keys
|
27
25
|
|
28
|
-
def initialize(
|
29
|
-
|
30
|
-
|
31
|
-
self.
|
32
|
-
|
26
|
+
def initialize(decryption_keys: ::Chamber.configuration.decryption_keys,
|
27
|
+
encryption_keys: ::Chamber.configuration.encryption_keys)
|
28
|
+
self.decryption_keys = decryption_keys
|
29
|
+
self.encryption_keys = encryption_keys
|
30
|
+
|
31
|
+
super()
|
33
32
|
end
|
34
33
|
|
35
34
|
def type
|
@@ -78,4 +77,3 @@ class Secured < CHAMBER_TYPE_VALUE_SUPERCLASS
|
|
78
77
|
end
|
79
78
|
end
|
80
79
|
end
|
81
|
-
# rubocop:enable Lint/HandleExceptions, Layout/EmptyLinesAroundModuleBody
|
data/lib/chamber/version.rb
CHANGED