chamber 2.12.3 → 2.14.1

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 (57) hide show
  1. checksums.yaml +5 -5
  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 +82 -10
  6. data/lib/chamber/adapters/cloud/circle_ci.rb +85 -0
  7. data/lib/chamber/adapters/cloud/heroku.rb +74 -0
  8. data/lib/chamber/binary/circle_ci.rb +122 -0
  9. data/lib/chamber/binary/heroku.rb +45 -16
  10. data/lib/chamber/binary/runner.rb +42 -26
  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 +35 -0
  14. data/lib/chamber/commands/{heroku → cloud}/clear.rb +6 -8
  15. data/lib/chamber/commands/cloud/compare.rb +26 -0
  16. data/lib/chamber/commands/cloud/pull.rb +29 -0
  17. data/lib/chamber/commands/cloud/push.rb +44 -0
  18. data/lib/chamber/commands/comparable.rb +2 -2
  19. data/lib/chamber/commands/compare.rb +6 -9
  20. data/lib/chamber/commands/initialize.rb +26 -22
  21. data/lib/chamber/commands/securable.rb +10 -10
  22. data/lib/chamber/commands/secure.rb +2 -2
  23. data/lib/chamber/commands/show.rb +8 -8
  24. data/lib/chamber/commands/sign.rb +2 -2
  25. data/lib/chamber/commands/verify.rb +2 -2
  26. data/lib/chamber/configuration.rb +8 -3
  27. data/lib/chamber/context_resolver.rb +16 -7
  28. data/lib/chamber/encryption_methods/ssl.rb +21 -12
  29. data/lib/chamber/file.rb +22 -20
  30. data/lib/chamber/file_set.rb +21 -11
  31. data/lib/chamber/files/signature.rb +31 -23
  32. data/lib/chamber/filters/decryption_filter.rb +13 -11
  33. data/lib/chamber/filters/encryption_filter.rb +17 -8
  34. data/lib/chamber/filters/environment_filter.rb +12 -14
  35. data/lib/chamber/filters/failed_decryption_filter.rb +6 -6
  36. data/lib/chamber/filters/insecure_filter.rb +12 -3
  37. data/lib/chamber/filters/namespace_filter.rb +5 -5
  38. data/lib/chamber/filters/secure_filter.rb +5 -5
  39. data/lib/chamber/filters/translate_secure_keys_filter.rb +5 -5
  40. data/lib/chamber/instance.rb +54 -30
  41. data/lib/chamber/integrations/rails.rb +1 -1
  42. data/lib/chamber/integrations/sinatra.rb +6 -6
  43. data/lib/chamber/key_pair.rb +8 -8
  44. data/lib/chamber/keys/base.rb +35 -41
  45. data/lib/chamber/keys/decryption.rb +8 -14
  46. data/lib/chamber/keys/encryption.rb +8 -14
  47. data/lib/chamber/namespace_set.rb +2 -4
  48. data/lib/chamber/settings.rb +86 -56
  49. data/lib/chamber/types/secured.rb +8 -10
  50. data/lib/chamber/version.rb +1 -1
  51. data/templates/settings.yml +2 -0
  52. metadata +51 -41
  53. metadata.gz.sig +0 -0
  54. data/lib/chamber/commands/heroku.rb +0 -31
  55. data/lib/chamber/commands/heroku/compare.rb +0 -33
  56. data/lib/chamber/commands/heroku/pull.rb +0 -30
  57. data/lib/chamber/commands/heroku/push.rb +0 -27
@@ -1,14 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'thor'
4
- require 'chamber/commands/heroku/clear'
5
- require 'chamber/commands/heroku/push'
6
- require 'chamber/commands/heroku/pull'
7
- require 'chamber/commands/heroku/compare'
4
+ require 'chamber/core_ext/hash'
5
+ require 'chamber/commands/cloud/clear'
6
+ require 'chamber/commands/cloud/push'
7
+ require 'chamber/commands/cloud/pull'
8
+ require 'chamber/commands/cloud/compare'
8
9
 
9
10
  module Chamber
10
11
  module Binary
11
12
  class Heroku < Thor
13
+ include Thor::Actions
14
+
12
15
  class_option :app,
13
16
  type: :string,
14
17
  aliases: '-a',
@@ -16,8 +19,15 @@ class Heroku < Thor
16
19
  desc: 'The name of the Heroku application whose config values will ' \
17
20
  'be affected'
18
21
 
19
- desc 'clear', 'Removes all Heroku environment variables which match settings that ' \
20
- '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'
21
31
 
22
32
  method_option :dry_run,
23
33
  type: :boolean,
@@ -26,11 +36,14 @@ class Heroku < Thor
26
36
  'would change if cleared'
27
37
 
28
38
  def clear
29
- Commands::Heroku::Clear.call(options)
39
+ Commands::Cloud::Clear.call(**options
40
+ .transform_keys(&:to_sym)
41
+ .merge(shell: self, adapter: 'heroku'))
30
42
  end
31
43
 
32
- desc 'push', 'Sends settings to Heroku so that they may be used in the application ' \
33
- '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'
34
47
 
35
48
  method_option :dry_run,
36
49
  type: :boolean,
@@ -38,6 +51,14 @@ class Heroku < Thor
38
51
  desc: 'Does not actually push anything to Heroku, but instead ' \
39
52
  'displays what would change if pushed'
40
53
 
54
+ method_option :keys,
55
+ type: :boolean,
56
+ aliases: '-k',
57
+ desc: 'Pushes private Chamber keys to Heroku as environment ' \
58
+ 'variables. Chamber will automatically detect it and ' \
59
+ 'transparently decrypt your secure settings without any ' \
60
+ 'further synchronization.'
61
+
41
62
  method_option :only_sensitive,
42
63
  type: :boolean,
43
64
  aliases: '-o',
@@ -47,11 +68,14 @@ class Heroku < Thor
47
68
  'will be pushed'
48
69
 
49
70
  def push
50
- Commands::Heroku::Push.call(options)
71
+ Commands::Cloud::Push.call(**options
72
+ .transform_keys(&:to_sym)
73
+ .merge(shell: self, adapter: 'heroku'))
51
74
  end
52
75
 
53
- desc 'pull', 'Retrieves the environment variables for the application and stores ' \
54
- 'them in a temporary file'
76
+ desc 'pull',
77
+ 'Retrieves the environment variables for the application and stores ' \
78
+ 'them in a temporary file'
55
79
 
56
80
  method_option :into,
57
81
  type: :string,
@@ -59,11 +83,14 @@ class Heroku < Thor
59
83
  'stored. This file WILL BE OVERRIDDEN.'
60
84
 
61
85
  def pull
62
- puts Commands::Heroku::Pull.call(options)
86
+ Commands::Cloud::Pull.call(**options
87
+ .transform_keys(&:to_sym)
88
+ .merge(shell: self, adapter: 'heroku'))
63
89
  end
64
90
 
65
- desc 'compare', 'Displays the difference between what is currently stored in the ' \
66
- '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'
67
94
 
68
95
  method_option :only_sensitive,
69
96
  type: :boolean,
@@ -74,7 +101,9 @@ class Heroku < Thor
74
101
  'which are marked as "_secure"'
75
102
 
76
103
  def compare
77
- Commands::Heroku::Compare.call(options)
104
+ Commands::Cloud::Compare.call(**options
105
+ .transform_keys(&:to_sym)
106
+ .merge(shell: self, adapter: 'heroku'))
78
107
  end
79
108
  end
80
109
  end
@@ -1,9 +1,11 @@
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'
8
+ require 'chamber/binary/circle_ci'
7
9
  require 'chamber/commands/show'
8
10
  require 'chamber/commands/files'
9
11
  require 'chamber/commands/secure'
@@ -17,7 +19,7 @@ module Binary
17
19
  class Runner < Thor
18
20
  include Thor::Actions
19
21
 
20
- source_root ::File.expand_path('../../../../templates', __FILE__)
22
+ source_root ::File.expand_path('../../../templates', __dir__)
21
23
 
22
24
  class_option :rootpath,
23
25
  type: :string,
@@ -61,16 +63,21 @@ class Runner < Thor
61
63
 
62
64
  ################################################################################
63
65
 
64
- desc 'travis SUBCOMMAND ...ARGS', 'For manipulating Travis CI environment variables'
66
+ desc 'travis SUBCOMMAND ...ARGS', 'For manipulating Travis CI environment variables'
65
67
  subcommand 'travis', Chamber::Binary::Travis
66
68
 
67
69
  ################################################################################
68
70
 
69
- desc 'heroku SUBCOMMAND ...ARGS', 'For manipulating Heroku environment variables'
71
+ desc 'heroku SUBCOMMAND ...ARGS', 'For manipulating Heroku environment variables'
70
72
  subcommand 'heroku', Chamber::Binary::Heroku
71
73
 
72
74
  ################################################################################
73
75
 
76
+ desc 'circleci SUBCOMMAND ...ARGS', 'For manipulating CircleCI environment variables'
77
+ subcommand 'circleci', Chamber::Binary::CircleCi
78
+
79
+ ################################################################################
80
+
74
81
  desc 'show', 'Displays the list of settings and their values'
75
82
 
76
83
  method_option :as_env,
@@ -86,7 +93,7 @@ class Runner < Thor
86
93
  'Useful for debugging.'
87
94
 
88
95
  def show
89
- puts Commands::Show.call(options.merge(shell: self))
96
+ puts Commands::Show.call(**options.transform_keys(&:to_sym).merge(shell: self))
90
97
  end
91
98
 
92
99
  ################################################################################
@@ -94,15 +101,16 @@ class Runner < Thor
94
101
  desc 'files', 'Lists the settings files which are parsed with the given options'
95
102
 
96
103
  def files
97
- puts Commands::Files.call(options.merge(shell: self))
104
+ puts Commands::Files.call(**options.transform_keys(&:to_sym).merge(shell: self))
98
105
  end
99
106
 
100
107
  ################################################################################
101
108
 
102
- desc 'compare', 'Displays the difference between the settings in the first set ' \
103
- 'of namespaces and the settings in the second set. Useful for ' \
104
- 'tracking down why there may be issues in development versus test ' \
105
- '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.'
106
114
 
107
115
  method_option :keys_only,
108
116
  type: :boolean,
@@ -111,23 +119,26 @@ class Runner < Thor
111
119
  'of the two sets of settings'
112
120
 
113
121
  method_option :first,
114
- type: :array,
115
- desc: 'The list of namespaces which will be used as the source of ' \
116
- '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'
117
126
 
118
127
  method_option :second,
119
- type: :array,
120
- desc: 'The list of namespaces which will be used as the destination ' \
121
- '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'
122
132
 
123
133
  def compare
124
- Commands::Compare.call(options.merge(shell: self))
134
+ Commands::Compare.call(**options.transform_keys(&:to_sym).merge(shell: self))
125
135
  end
126
136
 
127
137
  ################################################################################
128
138
 
129
- desc 'secure', 'Secures any values which appear to need to be encrypted in any of ' \
130
- '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'
131
142
 
132
143
  method_option :only_sensitive,
133
144
  type: :boolean,
@@ -140,37 +151,42 @@ class Runner < Thor
140
151
  'what values would be encrypted'
141
152
 
142
153
  def secure
143
- Commands::Secure.call(options.merge(shell: self))
154
+ Commands::Secure.call(**options.transform_keys(&:to_sym).merge(shell: self))
144
155
  end
145
156
 
146
157
  ################################################################################
147
158
 
148
- desc 'sign', 'Creates or verifies signatures for all current settings files using ' \
149
- 'the signature private key.'
159
+ desc 'sign',
160
+ 'Creates or verifies signatures for all current settings files using ' \
161
+ 'the signature private key.'
150
162
 
151
163
  method_option :verify,
152
164
  type: :boolean,
153
165
  default: false
154
166
 
167
+ method_option :signature_name,
168
+ type: :string,
169
+ default: `git config --get 'user.name'`.chomp
170
+
155
171
  def sign
156
172
  if options[:verify]
157
- Commands::Verify.call(options.merge(shell: self))
173
+ Commands::Verify.call(**options.transform_keys(&:to_sym).merge(shell: self))
158
174
  else
159
- Commands::Sign.call(options.merge(shell: self))
175
+ Commands::Sign.call(**options.transform_keys(&:to_sym).merge(shell: self))
160
176
  end
161
177
  end
162
178
 
163
179
  ################################################################################
164
180
 
165
- desc 'init', 'Sets Chamber up using best practices for secure configuration ' \
166
- 'management'
181
+ desc 'init',
182
+ 'Sets Chamber up using best practices for secure configuration management'
167
183
 
168
184
  method_option :signature,
169
185
  type: :boolean,
170
186
  default: false
171
187
 
172
188
  def init
173
- Commands::Initialize.call(options.merge(shell: self))
189
+ Commands::Initialize.call(**options.transform_keys(&:to_sym).merge(shell: self))
174
190
  end
175
191
  end
176
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)
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
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'chamber/commands/base'
4
+
5
+ module Chamber
6
+ module Commands
7
+ module Cloud
8
+ class Base < Chamber::Commands::Base
9
+ attr_accessor :adapter
10
+
11
+ def initialize(adapter:, **args)
12
+ super(**args)
13
+
14
+ self.adapter = adapter_class(adapter).new(**args)
15
+ end
16
+
17
+ private
18
+
19
+ def adapter_class(adapter_name)
20
+ require "chamber/adapters/cloud/#{adapter_name}"
21
+
22
+ @adapter_class ||= case adapter_name
23
+ when 'circle_ci'
24
+ Chamber::Adapters::Cloud::CircleCi
25
+ when 'heroku'
26
+ Chamber::Adapters::Cloud::Heroku
27
+ else
28
+ fail ArgumentError,
29
+ "Invalid Chamber cloud adapter name: #{adapter_name}"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,23 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'chamber/commands/base'
4
- require 'chamber/commands/heroku'
3
+ require 'chamber/commands/cloud/base'
5
4
 
6
5
  module Chamber
7
6
  module Commands
8
- module Heroku
9
- class Clear < Chamber::Commands::Base
10
- include Chamber::Commands::Heroku
11
-
7
+ module Cloud
8
+ class Clear < Chamber::Commands::Cloud::Base
12
9
  def call
13
10
  chamber.to_environment.each_key do |key|
14
- next unless configuration.match(key)
11
+ next unless adapter.environment_variables.has_key?(key)
15
12
 
16
13
  if dry_run
17
14
  shell.say_status 'remove', key, :blue
18
15
  else
19
16
  shell.say_status 'remove', key, :green
20
- shell.say heroku("config:unset #{key}")
17
+
18
+ adapter.remove_environment_variable(key)
21
19
  end
22
20
  end
23
21
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'chamber/commands/cloud/base'
4
+ require 'chamber/commands/comparable'
5
+ require 'chamber/commands/securable'
6
+
7
+ module Chamber
8
+ module Commands
9
+ module Cloud
10
+ class Compare < Chamber::Commands::Cloud::Base
11
+ include Chamber::Commands::Securable
12
+ include Chamber::Commands::Comparable
13
+
14
+ protected
15
+
16
+ def first_settings_data
17
+ ::JSON.pretty_generate(securable_environment_variables)
18
+ end
19
+
20
+ def second_settings_data
21
+ ::JSON.pretty_generate(adapter.environment_variables)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'chamber/commands/cloud/base'
5
+
6
+ module Chamber
7
+ module Commands
8
+ module Cloud
9
+ class Pull < Chamber::Commands::Cloud::Base
10
+ attr_accessor :target_file
11
+
12
+ def initialize(into:, **args)
13
+ super
14
+
15
+ self.target_file = into
16
+ end
17
+
18
+ def call
19
+ if target_file
20
+ shell.create_file(target_file,
21
+ ::JSON.pretty_generate(adapter.environment_variables))
22
+ else
23
+ adapter.environment_variables
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end