chamber 2.12.3 → 2.14.1

Sign up to get free protection for your applications and to get access to all the features.
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