chamber 2.13.1 → 2.14.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +101 -26
  5. data/lib/chamber.rb +72 -10
  6. data/lib/chamber/adapters/cloud/circle_ci.rb +16 -13
  7. data/lib/chamber/adapters/cloud/heroku.rb +40 -13
  8. data/lib/chamber/binary/circle_ci.rb +25 -12
  9. data/lib/chamber/binary/heroku.rb +31 -12
  10. data/lib/chamber/binary/runner.rb +37 -27
  11. data/lib/chamber/binary/travis.rb +5 -3
  12. data/lib/chamber/commands/base.rb +10 -16
  13. data/lib/chamber/commands/cloud/base.rb +3 -3
  14. data/lib/chamber/commands/cloud/pull.rb +2 -2
  15. data/lib/chamber/commands/cloud/push.rb +7 -7
  16. data/lib/chamber/commands/comparable.rb +2 -2
  17. data/lib/chamber/commands/compare.rb +6 -9
  18. data/lib/chamber/commands/initialize.rb +26 -22
  19. data/lib/chamber/commands/securable.rb +9 -9
  20. data/lib/chamber/commands/secure.rb +2 -2
  21. data/lib/chamber/commands/show.rb +8 -8
  22. data/lib/chamber/commands/sign.rb +2 -2
  23. data/lib/chamber/commands/verify.rb +2 -2
  24. data/lib/chamber/configuration.rb +6 -3
  25. data/lib/chamber/context_resolver.rb +8 -7
  26. data/lib/chamber/encryption_methods/ssl.rb +12 -12
  27. data/lib/chamber/file.rb +16 -14
  28. data/lib/chamber/file_set.rb +18 -8
  29. data/lib/chamber/files/signature.rb +16 -14
  30. data/lib/chamber/filters/decryption_filter.rb +12 -10
  31. data/lib/chamber/filters/encryption_filter.rb +8 -8
  32. data/lib/chamber/filters/environment_filter.rb +12 -14
  33. data/lib/chamber/filters/failed_decryption_filter.rb +6 -6
  34. data/lib/chamber/filters/insecure_filter.rb +3 -3
  35. data/lib/chamber/filters/namespace_filter.rb +5 -5
  36. data/lib/chamber/filters/secure_filter.rb +5 -5
  37. data/lib/chamber/filters/translate_secure_keys_filter.rb +5 -5
  38. data/lib/chamber/instance.rb +37 -21
  39. data/lib/chamber/key_pair.rb +7 -7
  40. data/lib/chamber/keys/base.rb +13 -13
  41. data/lib/chamber/keys/decryption.rb +3 -3
  42. data/lib/chamber/keys/encryption.rb +3 -3
  43. data/lib/chamber/namespace_set.rb +2 -4
  44. data/lib/chamber/settings.rb +45 -43
  45. data/lib/chamber/types/secured.rb +8 -10
  46. data/lib/chamber/version.rb +1 -1
  47. data/templates/settings.yml +2 -0
  48. metadata +24 -26
  49. metadata.gz.sig +0 -0
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'thor'
4
+ require 'chamber/core_ext/hash'
4
5
  require 'chamber/commands/cloud/clear'
5
6
  require 'chamber/commands/cloud/push'
6
7
  require 'chamber/commands/cloud/pull'
@@ -18,8 +19,15 @@ class Heroku < Thor
18
19
  desc: 'The name of the Heroku application whose config values will ' \
19
20
  'be affected'
20
21
 
21
- desc 'clear', 'Removes all Heroku environment variables which match settings that ' \
22
- 'Chamber knows about'
22
+ class_option :api_token,
23
+ type: :string,
24
+ aliases: '-t',
25
+ required: true,
26
+ desc: 'The API token to access your Heroku project.'
27
+
28
+ desc 'clear',
29
+ 'Removes all Heroku environment variables which match settings that ' \
30
+ 'Chamber knows about'
23
31
 
24
32
  method_option :dry_run,
25
33
  type: :boolean,
@@ -28,11 +36,14 @@ class Heroku < Thor
28
36
  'would change if cleared'
29
37
 
30
38
  def clear
31
- Commands::Cloud::Clear.call(options.merge(shell: self, adapter: 'heroku'))
39
+ Commands::Cloud::Clear.call(**options
40
+ .transform_keys(&:to_sym)
41
+ .merge(shell: self, adapter: 'heroku'))
32
42
  end
33
43
 
34
- desc 'push', 'Sends settings to Heroku so that they may be used in the application ' \
35
- 'once it is deployed'
44
+ desc 'push',
45
+ 'Sends settings to Heroku so that they may be used in the application ' \
46
+ 'once it is deployed'
36
47
 
37
48
  method_option :dry_run,
38
49
  type: :boolean,
@@ -57,11 +68,14 @@ class Heroku < Thor
57
68
  'will be pushed'
58
69
 
59
70
  def push
60
- Commands::Cloud::Push.call(options.merge(shell: self, adapter: 'heroku'))
71
+ Commands::Cloud::Push.call(**options
72
+ .transform_keys(&:to_sym)
73
+ .merge(shell: self, adapter: 'heroku'))
61
74
  end
62
75
 
63
- desc 'pull', 'Retrieves the environment variables for the application and stores ' \
64
- 'them in a temporary file'
76
+ desc 'pull',
77
+ 'Retrieves the environment variables for the application and stores ' \
78
+ 'them in a temporary file'
65
79
 
66
80
  method_option :into,
67
81
  type: :string,
@@ -69,11 +83,14 @@ class Heroku < Thor
69
83
  'stored. This file WILL BE OVERRIDDEN.'
70
84
 
71
85
  def pull
72
- Commands::Cloud::Pull.call(options.merge(shell: self, adapter: 'heroku'))
86
+ Commands::Cloud::Pull.call(**options
87
+ .transform_keys(&:to_sym)
88
+ .merge(shell: self, adapter: 'heroku'))
73
89
  end
74
90
 
75
- desc 'compare', 'Displays the difference between what is currently stored in the ' \
76
- 'Heroku application\'s config and what Chamber knows about locally'
91
+ desc 'compare',
92
+ 'Displays the difference between what is currently stored in the ' \
93
+ 'Heroku application\'s config and what Chamber knows about locally'
77
94
 
78
95
  method_option :only_sensitive,
79
96
  type: :boolean,
@@ -84,7 +101,9 @@ class Heroku < Thor
84
101
  'which are marked as "_secure"'
85
102
 
86
103
  def compare
87
- Commands::Cloud::Compare.call(options.merge(shell: self, adapter: 'heroku'))
104
+ Commands::Cloud::Compare.call(**options
105
+ .transform_keys(&:to_sym)
106
+ .merge(shell: self, adapter: 'heroku'))
88
107
  end
89
108
  end
90
109
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'thor'
4
+ require 'chamber/core_ext/hash'
4
5
  require 'chamber/rubinius_fix'
5
6
  require 'chamber/binary/travis'
6
7
  require 'chamber/binary/heroku'
@@ -18,7 +19,7 @@ module Binary
18
19
  class Runner < Thor
19
20
  include Thor::Actions
20
21
 
21
- source_root ::File.expand_path('../../../../templates', __FILE__)
22
+ source_root ::File.expand_path('../../../templates', __dir__)
22
23
 
23
24
  class_option :rootpath,
24
25
  type: :string,
@@ -62,17 +63,17 @@ class Runner < Thor
62
63
 
63
64
  ################################################################################
64
65
 
65
- desc 'travis SUBCOMMAND ...ARGS', 'For manipulating Travis CI environment variables'
66
+ desc 'travis SUBCOMMAND ...ARGS', 'For manipulating Travis CI environment variables'
66
67
  subcommand 'travis', Chamber::Binary::Travis
67
68
 
68
69
  ################################################################################
69
70
 
70
- desc 'heroku SUBCOMMAND ...ARGS', 'For manipulating Heroku environment variables'
71
+ desc 'heroku SUBCOMMAND ...ARGS', 'For manipulating Heroku environment variables'
71
72
  subcommand 'heroku', Chamber::Binary::Heroku
72
73
 
73
74
  ################################################################################
74
75
 
75
- desc 'circleci SUBCOMMAND ...ARGS', 'For manipulating CircleCI environment variables'
76
+ desc 'circleci SUBCOMMAND ...ARGS', 'For manipulating CircleCI environment variables'
76
77
  subcommand 'circleci', Chamber::Binary::CircleCi
77
78
 
78
79
  ################################################################################
@@ -92,7 +93,7 @@ class Runner < Thor
92
93
  'Useful for debugging.'
93
94
 
94
95
  def show
95
- puts Commands::Show.call(options.merge(shell: self))
96
+ puts Commands::Show.call(**options.transform_keys(&:to_sym).merge(shell: self))
96
97
  end
97
98
 
98
99
  ################################################################################
@@ -100,15 +101,16 @@ class Runner < Thor
100
101
  desc 'files', 'Lists the settings files which are parsed with the given options'
101
102
 
102
103
  def files
103
- puts Commands::Files.call(options.merge(shell: self))
104
+ puts Commands::Files.call(**options.transform_keys(&:to_sym).merge(shell: self))
104
105
  end
105
106
 
106
107
  ################################################################################
107
108
 
108
- desc 'compare', 'Displays the difference between the settings in the first set ' \
109
- 'of namespaces and the settings in the second set. Useful for ' \
110
- 'tracking down why there may be issues in development versus test ' \
111
- 'or differences between staging and production.'
109
+ desc 'compare',
110
+ 'Displays the difference between the settings in the first set ' \
111
+ 'of namespaces and the settings in the second set. Useful for ' \
112
+ 'tracking down why there may be issues in development versus test ' \
113
+ 'or differences between staging and production.'
112
114
 
113
115
  method_option :keys_only,
114
116
  type: :boolean,
@@ -117,23 +119,26 @@ class Runner < Thor
117
119
  'of the two sets of settings'
118
120
 
119
121
  method_option :first,
120
- type: :array,
121
- desc: 'The list of namespaces which will be used as the source of ' \
122
- 'the comparison'
122
+ type: :array,
123
+ required: true,
124
+ desc: 'The list of namespaces which will be used as the source of ' \
125
+ 'the comparison'
123
126
 
124
127
  method_option :second,
125
- type: :array,
126
- desc: 'The list of namespaces which will be used as the destination ' \
127
- 'of the comparison'
128
+ type: :array,
129
+ required: true,
130
+ desc: 'The list of namespaces which will be used as the ' \
131
+ 'destination of the comparison'
128
132
 
129
133
  def compare
130
- Commands::Compare.call(options.merge(shell: self))
134
+ Commands::Compare.call(**options.transform_keys(&:to_sym).merge(shell: self))
131
135
  end
132
136
 
133
137
  ################################################################################
134
138
 
135
- desc 'secure', 'Secures any values which appear to need to be encrypted in any of ' \
136
- 'the settings files which match irrespective of namespaces'
139
+ desc 'secure',
140
+ 'Secures any values which appear to need to be encrypted in any of ' \
141
+ 'the settings files which match irrespective of namespaces'
137
142
 
138
143
  method_option :only_sensitive,
139
144
  type: :boolean,
@@ -146,37 +151,42 @@ class Runner < Thor
146
151
  'what values would be encrypted'
147
152
 
148
153
  def secure
149
- Commands::Secure.call(options.merge(shell: self))
154
+ Commands::Secure.call(**options.transform_keys(&:to_sym).merge(shell: self))
150
155
  end
151
156
 
152
157
  ################################################################################
153
158
 
154
- desc 'sign', 'Creates or verifies signatures for all current settings files using ' \
155
- 'the signature private key.'
159
+ desc 'sign',
160
+ 'Creates or verifies signatures for all current settings files using ' \
161
+ 'the signature private key.'
156
162
 
157
163
  method_option :verify,
158
164
  type: :boolean,
159
165
  default: false
160
166
 
167
+ method_option :signature_name,
168
+ type: :string,
169
+ default: `git config --get 'user.name'`.chomp
170
+
161
171
  def sign
162
172
  if options[:verify]
163
- Commands::Verify.call(options.merge(shell: self))
173
+ Commands::Verify.call(**options.transform_keys(&:to_sym).merge(shell: self))
164
174
  else
165
- Commands::Sign.call(options.merge(shell: self))
175
+ Commands::Sign.call(**options.transform_keys(&:to_sym).merge(shell: self))
166
176
  end
167
177
  end
168
178
 
169
179
  ################################################################################
170
180
 
171
- desc 'init', 'Sets Chamber up using best practices for secure configuration ' \
172
- 'management'
181
+ desc 'init',
182
+ 'Sets Chamber up using best practices for secure configuration management'
173
183
 
174
184
  method_option :signature,
175
185
  type: :boolean,
176
186
  default: false
177
187
 
178
188
  def init
179
- Commands::Initialize.call(options.merge(shell: self))
189
+ Commands::Initialize.call(**options.transform_keys(&:to_sym).merge(shell: self))
180
190
  end
181
191
  end
182
192
  end
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'thor'
4
+ require 'chamber/core_ext/hash'
4
5
  require 'chamber/commands/travis/secure'
5
6
 
6
7
  module Chamber
7
8
  module Binary
8
9
  class Travis < Thor
9
- desc 'secure', 'Uses your Travis CI public key to encrypt the settings you have ' \
10
- 'chosen not to commit to the repo'
10
+ desc 'secure',
11
+ 'Uses your Travis CI public key to encrypt the settings you have ' \
12
+ 'chosen not to commit to the repo'
11
13
 
12
14
  method_option :dry_run,
13
15
  type: :boolean,
@@ -24,7 +26,7 @@ class Travis < Thor
24
26
  'which are marked as "_secure"'
25
27
 
26
28
  def secure
27
- Commands::Travis::Secure.call(options.merge(shell: self))
29
+ Commands::Travis::Secure.call(**options.transform_keys(&:to_sym).merge(shell: self))
28
30
  end
29
31
  end
30
32
  end
@@ -6,26 +6,20 @@ require 'chamber/instance'
6
6
  module Chamber
7
7
  module Commands
8
8
  class Base
9
- def self.call(options = {})
10
- new(options).call
9
+ def self.call(**args)
10
+ new(**args).call
11
11
  end
12
12
 
13
13
  attr_accessor :chamber,
14
- :shell,
15
- :dry_run
16
- attr_reader :rootpath
14
+ :dry_run,
15
+ :rootpath,
16
+ :shell
17
17
 
18
- def initialize(options = {})
19
- self.chamber = Chamber::Instance.new options
20
- self.shell = options[:shell]
21
- self.rootpath = options[:rootpath]
22
- self.dry_run = options[:dry_run]
23
- end
24
-
25
- protected
26
-
27
- def rootpath=(other)
28
- @rootpath = Pathname.new(other)
18
+ def initialize(shell: nil, rootpath: nil, dry_run: nil, **args)
19
+ self.chamber = Chamber::Instance.new(rootpath: rootpath, **args)
20
+ self.shell = shell
21
+ self.rootpath = chamber.configuration.rootpath
22
+ self.dry_run = dry_run
29
23
  end
30
24
  end
31
25
  end
@@ -8,10 +8,10 @@ module Cloud
8
8
  class Base < Chamber::Commands::Base
9
9
  attr_accessor :adapter
10
10
 
11
- def initialize(options = {})
12
- super
11
+ def initialize(adapter:, **args)
12
+ super(**args)
13
13
 
14
- self.adapter = adapter_class(options[:adapter]).new(options)
14
+ self.adapter = adapter_class(adapter).new(**args)
15
15
  end
16
16
 
17
17
  private
@@ -9,10 +9,10 @@ module Cloud
9
9
  class Pull < Chamber::Commands::Cloud::Base
10
10
  attr_accessor :target_file
11
11
 
12
- def initialize(options = {})
12
+ def initialize(into:, **args)
13
13
  super
14
14
 
15
- self.target_file = options[:into]
15
+ self.target_file = into
16
16
  end
17
17
 
18
18
  def call
@@ -12,18 +12,18 @@ class Push < Chamber::Commands::Cloud::Base
12
12
 
13
13
  attr_accessor :keys
14
14
 
15
- def initialize(options = {})
16
- super
15
+ def initialize(keys:, **args)
16
+ super(**args)
17
17
 
18
- self.keys = options[:keys]
18
+ self.keys = keys
19
19
  end
20
20
 
21
21
  def call
22
22
  environment_variables = if keys
23
- Keys::Decryption.
24
- new(rootpath: chamber.configuration.rootpath,
25
- namespaces: chamber.configuration.namespaces).
26
- as_environment_variables
23
+ Keys::Decryption
24
+ .new(rootpath: chamber.configuration.rootpath,
25
+ namespaces: chamber.configuration.namespaces)
26
+ .as_environment_variables
27
27
  else
28
28
  securable_environment_variables
29
29
  end
@@ -5,10 +5,10 @@ require 'tempfile'
5
5
  module Chamber
6
6
  module Commands
7
7
  module Comparable
8
- def initialize(options = {})
8
+ def initialize(keys_only:, **args)
9
9
  super
10
10
 
11
- self.keys_only = options[:keys_only]
11
+ self.keys_only = keys_only
12
12
  end
13
13
 
14
14
  def call
@@ -12,18 +12,15 @@ class Compare < Chamber::Commands::Base
12
12
  attr_accessor :first_settings_instance,
13
13
  :second_settings_instance
14
14
 
15
- def self.call(options = {})
16
- new(options).call
15
+ def self.call(**args)
16
+ new(**args).call
17
17
  end
18
18
 
19
- def initialize(options = {})
20
- super
19
+ def initialize(first:, second:, **args)
20
+ super(**args)
21
21
 
22
- first_settings_options = options.merge(namespaces: options[:first])
23
- self.first_settings_instance = Chamber::Instance.new(first_settings_options)
24
-
25
- second_settings_options = options.merge(namespaces: options[:second])
26
- self.second_settings_instance = Chamber::Instance.new(second_settings_options)
22
+ self.first_settings_instance = Chamber::Instance.new(args.merge(namespaces: first))
23
+ self.second_settings_instance = Chamber::Instance.new(args.merge(namespaces: second))
27
24
  end
28
25
 
29
26
  protected
@@ -11,23 +11,23 @@ require 'chamber/commands/base'
11
11
  module Chamber
12
12
  module Commands
13
13
  class Initialize < Chamber::Commands::Base
14
- def self.call(options = {})
15
- new(options).call
14
+ def self.call(**args)
15
+ new(**args).call
16
16
  end
17
17
 
18
18
  attr_accessor :basepath,
19
19
  :namespaces,
20
20
  :signature
21
21
 
22
- def initialize(options = {})
23
- super
22
+ def initialize(signature:, namespaces: [], **args)
23
+ super(**args)
24
24
 
25
25
  self.basepath = Chamber.configuration.basepath
26
- self.namespaces = options.fetch(:namespaces, [])
27
- self.signature = options.fetch(:signature)
26
+ self.namespaces = namespaces
27
+ self.signature = signature
28
28
  end
29
29
 
30
- # rubocop:disable Metrics/LineLength, Metrics/MethodLength, Metrics/AbcSize
30
+ # rubocop:disable Layout/LineLength, Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
31
31
  def call
32
32
  key_pairs = namespaces.map do |namespace|
33
33
  Chamber::KeyPair.new(namespace: namespace,
@@ -78,21 +78,25 @@ class Initialize < Chamber::Commands::Base
78
78
  shell.say 'Your signature keys, which will be used for verification, are located at:'
79
79
  shell.say ''
80
80
  shell.say ' * Public Key: '
81
- shell.say signature_key_pair.
82
- public_key_filepath.
83
- relative_path_from(Pathname.pwd), :yellow
81
+ shell.say signature_key_pair
82
+ .public_key_filepath
83
+ .relative_path_from(Pathname.pwd),
84
+ :yellow
84
85
  shell.say ' * Private Key: '
85
- shell.say signature_key_pair.
86
- unencrypted_private_key_filepath.
87
- relative_path_from(Pathname.pwd), :yellow
86
+ shell.say signature_key_pair
87
+ .unencrypted_private_key_filepath
88
+ .relative_path_from(Pathname.pwd),
89
+ :yellow
88
90
  shell.say ' * Encrypted Private Key: '
89
- shell.say signature_key_pair.
90
- encrypted_private_key_filepath.
91
- relative_path_from(Pathname.pwd), :yellow
91
+ shell.say signature_key_pair
92
+ .encrypted_private_key_filepath
93
+ .relative_path_from(Pathname.pwd),
94
+ :yellow
92
95
  shell.say ' * Encrypted Passphrase: '
93
- shell.say signature_key_pair.
94
- encrypted_private_key_passphrase_filepath.
95
- relative_path_from(Pathname.pwd), :yellow
96
+ shell.say signature_key_pair
97
+ .encrypted_private_key_passphrase_filepath
98
+ .relative_path_from(Pathname.pwd),
99
+ :yellow
96
100
 
97
101
  shell.say ''
98
102
  shell.say 'The signature private keys should be thought of separately from the other'
@@ -153,7 +157,7 @@ class Initialize < Chamber::Commands::Base
153
157
  shell.say '--------------------------------------------------------------------------------'
154
158
  shell.say ''
155
159
  end
156
- # rubocop:enable Metrics/LineLength, Metrics/MethodLength, Metrics/AbcSize
160
+ # rubocop:enable Layout/LineLength, Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
157
161
 
158
162
  protected
159
163
 
@@ -178,7 +182,7 @@ class Initialize < Chamber::Commands::Base
178
182
  end
179
183
 
180
184
  def append_to_gitignore
181
- ::FileUtils.touch gitignore_filepath
185
+ ::FileUtils.touch(gitignore_filepath)
182
186
 
183
187
  gitignore_contents = ::File.read(gitignore_filepath)
184
188
 
@@ -206,7 +210,7 @@ class Initialize < Chamber::Commands::Base
206
210
 
207
211
  def gem_path
208
212
  @gem_path ||= Pathname.new(
209
- ::File.expand_path('../../../..', __FILE__),
213
+ ::File.expand_path('../../..', __dir__),
210
214
  )
211
215
  end
212
216