kumo_keisei 4.0.7 → 5.0.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.
- checksums.yaml +4 -4
- data/README.md +3 -14
- data/VERSION +1 -1
- data/kumo_keisei.gemspec +1 -1
- data/lib/kumo_keisei.rb +0 -1
- data/lib/kumo_keisei/stack.rb +19 -3
- data/spec/lib/kumo_keisei/stack_spec.rb +8 -8
- metadata +3 -9
- data/lib/kumo_keisei/environment_config.rb +0 -136
- data/lib/kumo_keisei/file_loader.rb +0 -38
- data/spec/lib/kumo_keisei/environment_config_spec.rb +0 -282
- data/spec/lib/kumo_keisei/file_loader_spec.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98d31fb2d5e7dea5e297475a4580f02038ec74ce
|
4
|
+
data.tar.gz: f5d7e8d9ab455adab43ae717ebbd4343056b4db6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 288aedeb13b80df6a1728c5729ca9cefc02524b8507ece03669fd6e2115eb113e3d1ab3c168e775cd35164aae03e0240ec75f0efb5112a1807f0f2ecc311f03c
|
7
|
+
data.tar.gz: 89848dab939d87145bce5f9cae4997752edc57ff954338cba24faa2922b6f90a876745c2da50da1b3399eca29319f04a577f511d9c7a078fbf41d7e1ea9eecbb
|
data/README.md
CHANGED
@@ -118,9 +118,9 @@ end
|
|
118
118
|
|
119
119
|
## Upgrading from `KumoKeisei::CloudFormationStack` to `KumoKeisei::Stack`
|
120
120
|
|
121
|
-
`KumoKeisei::CloudFormationStack` is deprecated and should be replaced with a `KumoKeisei::Stack` which encompasses an environment object (`
|
121
|
+
`KumoKeisei::CloudFormationStack` is deprecated and should be replaced with a `KumoKeisei::Stack` which encompasses an environment object (`KumoConfig::EnvironmentConfig`).
|
122
122
|
|
123
|
-
Previously you would have to construct your own `EnvironmentConfig` which would marshal
|
123
|
+
Previously you would have to construct your own `EnvironmentConfig` which would marshal its configuration, then instantiate a `CloudFormationStack` and conduct operations on it.
|
124
124
|
|
125
125
|
E.g. `apply-env`:
|
126
126
|
```ruby
|
@@ -131,7 +131,7 @@ environment_name = ARGV.fetch(0) rescue raise("Error! No environment name given!
|
|
131
131
|
stack = CloudFormationStack.new(environment_name)
|
132
132
|
stack.apply
|
133
133
|
```
|
134
|
-
and `
|
134
|
+
and `cloudformation_stack.rb`:
|
135
135
|
```ruby
|
136
136
|
require 'kumo_keisei'
|
137
137
|
|
@@ -216,14 +216,3 @@ You can test the Cloudformation responsibilities of this gem by extending the in
|
|
216
216
|
To run these tests you need a properly configured AWS environment (with AWS_DEFAULT_REGION, AWS_ACCESS_KEY and AWS_SECRET_ACCESS_KEY set) and then run `./script/integration_test.sh`.
|
217
217
|
|
218
218
|
If you run this within a Buildkite job then you will have a stack named "kumokeisei-test-$buildnumber" created and torn down for each integration test context. If you run this outside of a Buildkite job then the stack will be named "kumokeisei-test-$username".
|
219
|
-
|
220
|
-
### Manual testing with Kumo Tools container
|
221
|
-
|
222
|
-
Changes to the gem can be manually tested end to end in a project that uses the gem (i.e. http-wala).
|
223
|
-
|
224
|
-
1. First start the dev-tools container: `kumo tools debug non-production`
|
225
|
-
1. gem install specific_install
|
226
|
-
1. Re-install the gem: `gem specific_install https://github.com/redbubble/kumo_keisei_gem.git -b <your_branch>`
|
227
|
-
1. Fire up a console: `irb`
|
228
|
-
1. Require the gem: `require "kumo_keisei"`
|
229
|
-
1. Interact with the gem's classes. `KumoKeisei::Stack.new(...).apply!`
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
5.0.0
|
data/kumo_keisei.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
20
|
spec.add_runtime_dependency 'aws-sdk', "~> 2.2"
|
21
|
-
spec.add_runtime_dependency '
|
21
|
+
spec.add_runtime_dependency 'kumo_config'
|
22
22
|
spec.add_development_dependency "bundler", "~> 1.6"
|
23
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
24
|
spec.add_development_dependency "rspec", "~> 3.4"
|
data/lib/kumo_keisei.rb
CHANGED
data/lib/kumo_keisei/stack.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'aws-sdk'
|
2
|
+
require 'kumo_config'
|
2
3
|
|
3
4
|
module KumoKeisei
|
4
5
|
class Stack
|
@@ -93,6 +94,21 @@ module KumoKeisei
|
|
93
94
|
|
94
95
|
private
|
95
96
|
|
97
|
+
def cf_params(stack_config, environment_config)
|
98
|
+
erb = params_template_erb(stack_config)
|
99
|
+
return [] unless erb
|
100
|
+
|
101
|
+
stack_params = YAML.load(erb.result(environment_config.get_binding))
|
102
|
+
KumoKeisei::ParameterBuilder.new(stack_params).params
|
103
|
+
end
|
104
|
+
|
105
|
+
def params_template_erb(stack_config)
|
106
|
+
template_path = params_template_path(stack_config)
|
107
|
+
|
108
|
+
return nil unless template_path && File.exist?(template_path)
|
109
|
+
ERB.new(File.read(template_path))
|
110
|
+
end
|
111
|
+
|
96
112
|
def transform_logical_resource_id(id)
|
97
113
|
id.to_s.split('_').map {|w| w.capitalize }.join
|
98
114
|
end
|
@@ -141,7 +157,7 @@ module KumoKeisei
|
|
141
157
|
cloudformation.create_stack(
|
142
158
|
stack_name: @stack_name,
|
143
159
|
template_body: File.read(stack_config[:template_path]),
|
144
|
-
parameters: environment_config(stack_config)
|
160
|
+
parameters: cf_params(stack_config, environment_config(stack_config)),
|
145
161
|
capabilities: ["CAPABILITY_IAM"],
|
146
162
|
on_failure: "DELETE"
|
147
163
|
)
|
@@ -159,7 +175,7 @@ module KumoKeisei
|
|
159
175
|
cloudformation.update_stack(
|
160
176
|
stack_name: @stack_name,
|
161
177
|
template_body: File.read(stack_config[:template_path]),
|
162
|
-
parameters: environment_config(stack_config)
|
178
|
+
parameters: cf_params(stack_config, environment_config(stack_config)),
|
163
179
|
capabilities: ["CAPABILITY_IAM"]
|
164
180
|
)
|
165
181
|
|
@@ -174,7 +190,7 @@ module KumoKeisei
|
|
174
190
|
end
|
175
191
|
|
176
192
|
def environment_config(stack_config)
|
177
|
-
EnvironmentConfig.new(stack_config
|
193
|
+
KumoConfig::EnvironmentConfig.new(stack_config)
|
178
194
|
end
|
179
195
|
|
180
196
|
def stack_events_url
|
@@ -23,7 +23,7 @@ describe KumoKeisei::Stack do
|
|
23
23
|
{
|
24
24
|
stack_name: stack_name,
|
25
25
|
template_body: stack_template_body,
|
26
|
-
parameters:
|
26
|
+
parameters: [],
|
27
27
|
capabilities: ["CAPABILITY_IAM"]
|
28
28
|
}
|
29
29
|
end
|
@@ -48,7 +48,7 @@ describe KumoKeisei::Stack do
|
|
48
48
|
allow(cloudformation).to receive(:describe_stacks).with({stack_name: stack_name}).and_return(cf_stack)
|
49
49
|
allow(KumoKeisei::ParameterBuilder).to receive(:new).and_return(parameter_builder)
|
50
50
|
allow(File).to receive(:read).with(stack_cfntemplate_filename).and_return(stack_template_body)
|
51
|
-
allow(
|
51
|
+
allow(KumoConfig::EnvironmentConfig).to receive(:new).with(stack_config).and_return(double(:environment_config))
|
52
52
|
Dir.chdir('/')
|
53
53
|
end
|
54
54
|
|
@@ -278,8 +278,8 @@ describe KumoKeisei::Stack do
|
|
278
278
|
|
279
279
|
describe "#config" do
|
280
280
|
context "when passed a config_path and params_template_file_path" do
|
281
|
-
it "will return the results of the nested
|
282
|
-
expect(
|
281
|
+
it "will return the results of the nested KumoConfig::EnvironmentConfig.config" do
|
282
|
+
expect(KumoConfig::EnvironmentConfig).to receive(:new).with(stack_config).and_return(double(:environment_config, cf_params: {}, config: { :foo=> 'bar', :baz=> 'qux' }))
|
283
283
|
expect(subject.config(stack_config)).to eq({:foo=> 'bar', :baz=>'qux'})
|
284
284
|
end
|
285
285
|
end
|
@@ -292,8 +292,8 @@ describe KumoKeisei::Stack do
|
|
292
292
|
}
|
293
293
|
}
|
294
294
|
|
295
|
-
it "will return the results of the nested
|
296
|
-
expect(
|
295
|
+
it "will return the results of the nested KumoConfig::EnvironmentConfig.config" do
|
296
|
+
expect(KumoConfig::EnvironmentConfig).to receive(:new).with(stack_config).and_return(double(:environment_config, cf_params: {}, config: { :foo=> 'bar', :baz=> 'qux' }))
|
297
297
|
expect(subject.config(stack_config)).to eq({:foo=> 'bar', :baz=>'qux'})
|
298
298
|
end
|
299
299
|
end
|
@@ -344,8 +344,8 @@ describe KumoKeisei::Stack do
|
|
344
344
|
|
345
345
|
describe "#plain_text_secrets" do
|
346
346
|
context "when passed a config_path and params_template_file_path" do
|
347
|
-
it "will return the results of the nested
|
348
|
-
expect(
|
347
|
+
it "will return the results of the nested KumoConfig::EnvironmentConfig.plain_text_secrets" do
|
348
|
+
expect(KumoConfig::EnvironmentConfig).to receive(:new).with(stack_config).and_return(double(:environment_config, cf_params: {}, plain_text_secrets: { :foo=> 'bar', :baz=> 'qux' }))
|
349
349
|
expect(subject.plain_text_secrets(stack_config)).to eq({:foo=> 'bar', :baz=>'qux'})
|
350
350
|
end
|
351
351
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kumo_keisei
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Redbubble
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: kumo_config
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -115,9 +115,7 @@ files:
|
|
115
115
|
- lib/kumo_keisei.rb
|
116
116
|
- lib/kumo_keisei/cloud_formation_stack.rb
|
117
117
|
- lib/kumo_keisei/console_jockey.rb
|
118
|
-
- lib/kumo_keisei/environment_config.rb
|
119
118
|
- lib/kumo_keisei/errors.rb
|
120
|
-
- lib/kumo_keisei/file_loader.rb
|
121
119
|
- lib/kumo_keisei/get_stack_output.rb
|
122
120
|
- lib/kumo_keisei/parameter_builder.rb
|
123
121
|
- lib/kumo_keisei/stack.rb
|
@@ -133,8 +131,6 @@ files:
|
|
133
131
|
- spec/integration/stack_spec.rb
|
134
132
|
- spec/lib/kumo_keisei/cloud_formation_stack_spec.rb
|
135
133
|
- spec/lib/kumo_keisei/console_jockey_spec.rb
|
136
|
-
- spec/lib/kumo_keisei/environment_config_spec.rb
|
137
|
-
- spec/lib/kumo_keisei/file_loader_spec.rb
|
138
134
|
- spec/lib/kumo_keisei/get_stack_output_spec.rb
|
139
135
|
- spec/lib/kumo_keisei/parameter_builder_spec.rb
|
140
136
|
- spec/lib/kumo_keisei/stack_spec.rb
|
@@ -172,8 +168,6 @@ test_files:
|
|
172
168
|
- spec/integration/stack_spec.rb
|
173
169
|
- spec/lib/kumo_keisei/cloud_formation_stack_spec.rb
|
174
170
|
- spec/lib/kumo_keisei/console_jockey_spec.rb
|
175
|
-
- spec/lib/kumo_keisei/environment_config_spec.rb
|
176
|
-
- spec/lib/kumo_keisei/file_loader_spec.rb
|
177
171
|
- spec/lib/kumo_keisei/get_stack_output_spec.rb
|
178
172
|
- spec/lib/kumo_keisei/parameter_builder_spec.rb
|
179
173
|
- spec/lib/kumo_keisei/stack_spec.rb
|
@@ -1,136 +0,0 @@
|
|
1
|
-
require 'kumo_ki'
|
2
|
-
require 'logger'
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
require_relative 'file_loader'
|
6
|
-
require_relative 'parameter_builder'
|
7
|
-
|
8
|
-
module KumoKeisei
|
9
|
-
# Environment Configuration for a cloud formation stack
|
10
|
-
class EnvironmentConfig
|
11
|
-
class ConfigurationError < StandardError; end
|
12
|
-
|
13
|
-
LOGGER = Logger.new(STDOUT)
|
14
|
-
|
15
|
-
attr_reader :app_name, :env_name
|
16
|
-
|
17
|
-
def initialize(options, logger = LOGGER)
|
18
|
-
@env_name = options[:env_name]
|
19
|
-
@params_template_file_path = options[:params_template_file_path]
|
20
|
-
@injected_config = options[:injected_config] || {}
|
21
|
-
@log = logger
|
22
|
-
|
23
|
-
if options[:config_path]
|
24
|
-
@config_file_loader = KumoKeisei::FileLoader.new(config_dir_path: options[:config_path])
|
25
|
-
elsif options[:config_dir_path]
|
26
|
-
@log.warn "[DEPRECATION] `:config_dir_path` is deprecated, please pass in `:config_path` instead"
|
27
|
-
@config_file_loader = KumoKeisei::FileLoader.new(config_dir_path: options[:config_dir_path])
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
def production?
|
33
|
-
env_name == 'production'
|
34
|
-
end
|
35
|
-
|
36
|
-
def development?
|
37
|
-
!%w(production staging).include? env_name
|
38
|
-
end
|
39
|
-
|
40
|
-
def plain_text_secrets
|
41
|
-
@plain_text_secrets ||= decrypt_secrets(encrypted_secrets)
|
42
|
-
end
|
43
|
-
|
44
|
-
def config
|
45
|
-
# a hash of all settings that apply to this environment
|
46
|
-
@config ||= common_config.merge(env_config).merge(@injected_config)
|
47
|
-
end
|
48
|
-
|
49
|
-
def cf_params
|
50
|
-
# returns a list of Cfn friendly paramater_value, paramater_key pairs for
|
51
|
-
# consumption by cloudformation.
|
52
|
-
return [] unless params_template_erb
|
53
|
-
config
|
54
|
-
|
55
|
-
stack_params = YAML.load(params_template_erb.result(binding))
|
56
|
-
KumoKeisei::ParameterBuilder.new(stack_params).params
|
57
|
-
end
|
58
|
-
|
59
|
-
def get_binding
|
60
|
-
binding
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
64
|
-
|
65
|
-
def kms
|
66
|
-
@kms ||= KumoKi::KMS.new
|
67
|
-
end
|
68
|
-
|
69
|
-
def params_template_erb
|
70
|
-
return nil unless @params_template_file_path && File.exist?(@params_template_file_path)
|
71
|
-
template_file_loader = KumoKeisei::FileLoader.new(config_dir_path: File.dirname(@params_template_file_path))
|
72
|
-
template_file_loader.load_erb(File.basename(@params_template_file_path))
|
73
|
-
end
|
74
|
-
|
75
|
-
def decrypt_secrets(secrets)
|
76
|
-
Hash[
|
77
|
-
secrets.map do |name, cipher_text|
|
78
|
-
@log.debug "Decrypting '#{name}'"
|
79
|
-
decrypt_cipher name, cipher_text
|
80
|
-
end
|
81
|
-
]
|
82
|
-
end
|
83
|
-
|
84
|
-
def decrypt_cipher(name, cipher_text)
|
85
|
-
if cipher_text.start_with? '[ENC,'
|
86
|
-
begin
|
87
|
-
[name, kms.decrypt(cipher_text[5, cipher_text.size]).to_s]
|
88
|
-
rescue
|
89
|
-
@log.error "Error decrypting secret '#{name}'"
|
90
|
-
raise
|
91
|
-
end
|
92
|
-
else
|
93
|
-
[name, cipher_text]
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def env_config_file_name
|
98
|
-
"#{env_name}.yml"
|
99
|
-
end
|
100
|
-
|
101
|
-
def env_secrets_file_name
|
102
|
-
"#{env_name}_secrets.yml"
|
103
|
-
end
|
104
|
-
|
105
|
-
def encrypted_secrets
|
106
|
-
encrypted_common_secrets.merge(encrypted_env_secrets)
|
107
|
-
end
|
108
|
-
|
109
|
-
def encrypted_common_secrets
|
110
|
-
@config_file_loader.load_hash('common_secrets.yml')
|
111
|
-
end
|
112
|
-
|
113
|
-
def encrypted_env_secrets
|
114
|
-
secrets = @config_file_loader.load_hash(env_secrets_file_name)
|
115
|
-
|
116
|
-
if !secrets.empty?
|
117
|
-
secrets
|
118
|
-
else
|
119
|
-
@config_file_loader.load_hash('development_secrets.yml')
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def common_config
|
124
|
-
@config_file_loader.load_hash('common.yml')
|
125
|
-
end
|
126
|
-
|
127
|
-
def env_config
|
128
|
-
config = @config_file_loader.load_hash(env_config_file_name)
|
129
|
-
if !config.empty?
|
130
|
-
config
|
131
|
-
else
|
132
|
-
@config_file_loader.load_hash('development.yml')
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'erb'
|
2
|
-
|
3
|
-
module KumoKeisei
|
4
|
-
class FileLoader
|
5
|
-
def initialize(options)
|
6
|
-
@config_dir_path = options[:config_dir_path]
|
7
|
-
end
|
8
|
-
|
9
|
-
def load_hash(file_name, optional = true)
|
10
|
-
# reads a file presuming it's a yml in form of key: value, returning it as a hash
|
11
|
-
path = file_path(file_name)
|
12
|
-
|
13
|
-
begin
|
14
|
-
YAML::load(File.read(path))
|
15
|
-
rescue Errno::ENOENT => ex
|
16
|
-
# file not found, return empty dictionary if that is ok
|
17
|
-
return {} if optional
|
18
|
-
raise ex
|
19
|
-
rescue StandardError => ex
|
20
|
-
# this is an error we weren't expecting
|
21
|
-
raise ex
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def load_erb(file_name)
|
26
|
-
# loads a file, constructs an ERB object from it and returns the ERB object
|
27
|
-
# DOES NOT RENDER A RESULT!!
|
28
|
-
path = file_path(file_name)
|
29
|
-
ERB.new(File.read(path))
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def file_path(file_name)
|
35
|
-
File.join(@config_dir_path, file_name)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,282 +0,0 @@
|
|
1
|
-
describe KumoKeisei::EnvironmentConfig do
|
2
|
-
let(:env_name) { 'the_jungle' }
|
3
|
-
let(:config_dir_path) { '/var/config' }
|
4
|
-
let(:options) do
|
5
|
-
{
|
6
|
-
env_name: env_name,
|
7
|
-
config_path: config_dir_path,
|
8
|
-
params_template_file_path: params_template_file_path
|
9
|
-
}
|
10
|
-
end
|
11
|
-
let(:file_loader) { instance_double(KumoKeisei::FileLoader) }
|
12
|
-
let(:file_loader_cloudformation) { instance_double(KumoKeisei::FileLoader) }
|
13
|
-
let(:parameters_erb) { ERB.new("") }
|
14
|
-
let(:params_template_file_path) { 'junk.txt' }
|
15
|
-
let(:environment_config_file_name) { "#{env_name}.yml" }
|
16
|
-
let(:kms) { instance_double(KumoKi::KMS) }
|
17
|
-
let(:logger) { double(:test_logger, debug: nil) }
|
18
|
-
let(:environment_config) { described_class.new(options, logger) }
|
19
|
-
|
20
|
-
before do
|
21
|
-
allow(KumoKeisei::FileLoader).to receive(:new).and_return(file_loader)
|
22
|
-
allow(KumoKi::KMS).to receive(:new).and_return(kms)
|
23
|
-
allow(file_loader).to receive(:load_erb).with(params_template_file_path).and_return(parameters_erb)
|
24
|
-
allow(File).to receive(:dirname).and_return('/tmp')
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'backward compatibility' do
|
28
|
-
context 'config_path' do
|
29
|
-
let(:options) do
|
30
|
-
{
|
31
|
-
env_name: env_name,
|
32
|
-
config_path: config_dir_path
|
33
|
-
}
|
34
|
-
end
|
35
|
-
it 'will be used without complaint' do
|
36
|
-
expect(KumoKeisei::FileLoader).to receive(:new).with(config_dir_path: config_dir_path).and_return(nil)
|
37
|
-
expect(logger).to receive(:warn).at_most(0).times
|
38
|
-
expect(logger).to receive(:fatal).at_most(0).times
|
39
|
-
described_class.new(options, logger)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
context 'config_dir_path' do
|
44
|
-
let(:options) do
|
45
|
-
{
|
46
|
-
env_name: env_name,
|
47
|
-
config_dir_path: config_dir_path
|
48
|
-
}
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'will be used if given and raise a deprecation warning' do
|
52
|
-
expect(KumoKeisei::FileLoader).to receive(:new).with(config_dir_path: config_dir_path).and_return(nil)
|
53
|
-
expect(logger).to receive(:warn).with("[DEPRECATION] `:config_dir_path` is deprecated, please pass in `:config_path` instead")
|
54
|
-
described_class.new(options, logger)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
context 'unit tests' do
|
60
|
-
describe '#get_binding' do
|
61
|
-
subject { environment_config.get_binding }
|
62
|
-
|
63
|
-
it 'returns a binding' do
|
64
|
-
expect(subject).to be_a(Binding)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe '#cf_params' do
|
69
|
-
subject { environment_config.cf_params }
|
70
|
-
|
71
|
-
context 'params template file path is not provided' do
|
72
|
-
let(:options) do
|
73
|
-
{
|
74
|
-
env_name: env_name,
|
75
|
-
config_path: config_dir_path
|
76
|
-
}
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'creates an empty array' do
|
80
|
-
expect(subject).to eq([])
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
context 'params is empty' do
|
85
|
-
let(:parameters_erb) { nil }
|
86
|
-
|
87
|
-
it 'creates an empty array' do
|
88
|
-
expect(subject).to eq([])
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'no config_path' do
|
93
|
-
let(:options) { { params_template_file_path: "not-a-real-file.yml.erb" } }
|
94
|
-
|
95
|
-
it { is_expected.to eq([]) }
|
96
|
-
end
|
97
|
-
|
98
|
-
context 'a hard-coded param' do
|
99
|
-
let(:parameters_erb) { ERB.new("foo: \"bar\"") }
|
100
|
-
|
101
|
-
before do
|
102
|
-
allow(File).to receive(:exist?).with(params_template_file_path).and_return(true)
|
103
|
-
allow(file_loader).to receive(:load_hash).with('common.yml').and_return({})
|
104
|
-
allow(file_loader).to receive(:load_hash).with('the_jungle.yml').and_return({})
|
105
|
-
allow(file_loader).to receive(:load_hash).with('development.yml').and_return({})
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'creates a array containing an aws formatted parameter hash' do
|
109
|
-
expect(subject).to eq([{parameter_key: "foo", parameter_value: "bar"}])
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
describe "#config" do
|
114
|
-
subject { described_class.new(options, logger).config }
|
115
|
-
|
116
|
-
context 'injected config' do
|
117
|
-
|
118
|
-
let(:options) do
|
119
|
-
{
|
120
|
-
env_name: env_name,
|
121
|
-
config_path: config_dir_path,
|
122
|
-
params_template_file_path: params_template_file_path,
|
123
|
-
injected_config: { "injected" => "yes" }
|
124
|
-
}
|
125
|
-
end
|
126
|
-
|
127
|
-
let(:common_parameters) { { "stack_name" => "okonomiyaki" } }
|
128
|
-
it 'adds injected config to the config hash' do
|
129
|
-
expect(file_loader).to receive(:load_hash).with('common.yml').and_return(common_parameters)
|
130
|
-
expect(file_loader).to receive(:load_hash).with(environment_config_file_name).and_return({})
|
131
|
-
expect(file_loader).to receive(:load_hash).with("development.yml").and_return({})
|
132
|
-
|
133
|
-
expect(subject).to eq({ "stack_name" => "okonomiyaki", "injected" => "yes" })
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context 'common config' do
|
138
|
-
let(:common_parameters) { { "stack_name" => "okonomiyaki" } }
|
139
|
-
|
140
|
-
it 'creates a array containing an aws formatted parameter hash' do
|
141
|
-
expect(file_loader).to receive(:load_hash).with('common.yml').and_return(common_parameters)
|
142
|
-
expect(file_loader).to receive(:load_hash).with(environment_config_file_name).and_return({})
|
143
|
-
expect(file_loader).to receive(:load_hash).with("development.yml").and_return({})
|
144
|
-
|
145
|
-
expect(subject).to eq('stack_name' => 'okonomiyaki')
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
context 'merging common and environment specific configurations' do
|
150
|
-
let(:environment_config) { {'image' => 'ami-5678'} }
|
151
|
-
let(:development_config) { {'image' => 'ami-9999'} }
|
152
|
-
|
153
|
-
context 'with environmental overrides' do
|
154
|
-
let(:parameter_template) { "image: <%= config['image'] %>" }
|
155
|
-
let(:common_config) { {'image' => 'ami-1234'} }
|
156
|
-
let(:env_name) { 'development' }
|
157
|
-
|
158
|
-
it 'replaces the common value with the env value' do
|
159
|
-
expect(file_loader).to receive(:load_hash).with('common.yml').and_return(common_config)
|
160
|
-
expect(file_loader).to receive(:load_hash).with(environment_config_file_name).and_return(environment_config)
|
161
|
-
expect(subject).to eq('image' => 'ami-5678')
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
it 'falls back to a default environment if the requested one does not exist' do
|
166
|
-
expect(file_loader).to receive(:load_hash).with('common.yml').and_return({})
|
167
|
-
expect(file_loader).to receive(:load_hash).with("#{env_name}.yml").and_return({})
|
168
|
-
expect(file_loader).to receive(:load_hash).with("development.yml").and_return(development_config)
|
169
|
-
|
170
|
-
expect(subject).to eq('image' => 'ami-9999')
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
describe "#plain_text_secrets" do
|
176
|
-
subject { described_class.new(options, logger).plain_text_secrets }
|
177
|
-
|
178
|
-
let(:crypted_password) { 'lookatmyencryptedpasswords' }
|
179
|
-
let(:plain_text_password) { 'plain_text_password' }
|
180
|
-
let(:secrets) { { 'secret_password' => "[ENC,#{crypted_password}" } }
|
181
|
-
|
182
|
-
let(:crypted_env_password) { 'cryptedenvpassword' }
|
183
|
-
let(:plain_text_env_password) { 'plain_text_env_password' }
|
184
|
-
let(:env_secrets) { { 'secret_password' => "[ENC,#{crypted_env_password}"}}
|
185
|
-
|
186
|
-
before do
|
187
|
-
allow(kms).to receive(:decrypt).with(crypted_password).and_return(plain_text_password)
|
188
|
-
end
|
189
|
-
|
190
|
-
it 'decrypts common secrets' do
|
191
|
-
allow(file_loader).to receive(:load_hash).with('common_secrets.yml').and_return(secrets)
|
192
|
-
allow(file_loader).to receive(:load_hash).with("#{env_name}_secrets.yml").and_return({})
|
193
|
-
allow(file_loader).to receive(:load_hash).with("development_secrets.yml").and_return({})
|
194
|
-
|
195
|
-
expect(subject).to eq('secret_password' => plain_text_password)
|
196
|
-
end
|
197
|
-
|
198
|
-
it 'decrypts environment secrets' do
|
199
|
-
allow(file_loader).to receive(:load_hash).with('common_secrets.yml').and_return({})
|
200
|
-
allow(file_loader).to receive(:load_hash).with("#{env_name}_secrets.yml").and_return(secrets)
|
201
|
-
|
202
|
-
expect(subject).to eq('secret_password' => plain_text_password)
|
203
|
-
end
|
204
|
-
|
205
|
-
it 'gives preference to environment secrets' do
|
206
|
-
allow(file_loader).to receive(:load_hash).with('common_secrets.yml').and_return(secrets)
|
207
|
-
allow(file_loader).to receive(:load_hash).with("#{env_name}_secrets.yml").and_return(env_secrets)
|
208
|
-
allow(kms).to receive(:decrypt).with(crypted_env_password).and_return(plain_text_env_password)
|
209
|
-
|
210
|
-
expect(subject).to eq('secret_password' => plain_text_env_password)
|
211
|
-
end
|
212
|
-
|
213
|
-
it 'falls back to a default environment if the requested one does not exist' do
|
214
|
-
allow(file_loader).to receive(:load_hash).with('common_secrets.yml').and_return({})
|
215
|
-
allow(file_loader).to receive(:load_hash).with("#{env_name}_secrets.yml").and_return({})
|
216
|
-
expect(file_loader).to receive(:load_hash).with("development_secrets.yml").and_return(secrets)
|
217
|
-
|
218
|
-
expect(subject).to eq('secret_password' => plain_text_password)
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
describe '#development?' do
|
223
|
-
%w(production staging).each do |environment|
|
224
|
-
it "returns false for #{environment}" do
|
225
|
-
expect(
|
226
|
-
described_class.new({
|
227
|
-
env_name: environment,
|
228
|
-
config_path: '',
|
229
|
-
params_template_file_path: ''}
|
230
|
-
).development?).to eq false
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
it 'returns true for anything other than production or staging' do
|
235
|
-
expect(
|
236
|
-
described_class.new({
|
237
|
-
env_name: 'fred',
|
238
|
-
config_path: '',
|
239
|
-
params_template_file_path: ''}
|
240
|
-
).development?).to eq true
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
context 'integration tests' do
|
246
|
-
describe '#cf_params' do
|
247
|
-
subject { environment_config.cf_params }
|
248
|
-
|
249
|
-
context 'templated params' do
|
250
|
-
before { allow(File).to receive(:exist?).with(params_template_file_path).and_return(true) }
|
251
|
-
|
252
|
-
let(:parameters_erb) { ERB.new("stack_name: \"<%= config['stack_name'] %>\"" ) }
|
253
|
-
let(:common_config) { { "stack_name" => "common"} }
|
254
|
-
let(:staging_config) { { "stack_name" => "staging" } }
|
255
|
-
let(:development_config) { { "stack_name" => "development" } }
|
256
|
-
|
257
|
-
context 'hiearchy of parameters' do
|
258
|
-
it 'will load values from the common paramater file' do
|
259
|
-
expect(file_loader).to receive(:load_hash).with('common.yml').and_return(common_config)
|
260
|
-
expect(file_loader).to receive(:load_hash).with("development.yml").and_return({})
|
261
|
-
expect(file_loader).to receive(:load_hash).with(environment_config_file_name).and_return({})
|
262
|
-
expect(subject).to eq([{parameter_key: "stack_name", parameter_value: "common"}])
|
263
|
-
end
|
264
|
-
|
265
|
-
it 'will load values from the environment specific file' do
|
266
|
-
expect(file_loader).to receive(:load_hash).with('common.yml').and_return({})
|
267
|
-
expect(file_loader).to receive(:load_hash).with(environment_config_file_name).and_return(staging_config)
|
268
|
-
expect(subject).to eq([{parameter_key: "stack_name", parameter_value: "staging"}])
|
269
|
-
end
|
270
|
-
|
271
|
-
it 'will load values from the shared development file if an environment specific file has no values' do
|
272
|
-
expect(file_loader).to receive(:load_hash).with('common.yml').and_return({})
|
273
|
-
expect(file_loader).to receive(:load_hash).with(environment_config_file_name).and_return({})
|
274
|
-
expect(file_loader).to receive(:load_hash).with("development.yml").and_return(development_config)
|
275
|
-
expect(subject).to eq([{parameter_key: "stack_name", parameter_value: "development"}])
|
276
|
-
end
|
277
|
-
end
|
278
|
-
end
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
282
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
describe KumoKeisei::FileLoader do
|
2
|
-
let(:config_dir_path) { '/the/garden/path' }
|
3
|
-
let(:options) { { config_dir_path: config_dir_path } }
|
4
|
-
let(:file_name) { 'environment.yml' }
|
5
|
-
let(:full_file_path) { config_dir_path + '/' + file_name }
|
6
|
-
|
7
|
-
describe "#load_erb" do
|
8
|
-
subject { KumoKeisei::FileLoader.new(options).load_erb(file_name) }
|
9
|
-
|
10
|
-
context "when the requested erb file exits" do
|
11
|
-
let(:fake_erb_object) { double() }
|
12
|
-
let(:fake_file_handle) { double() }
|
13
|
-
|
14
|
-
it "loads the file and returns an ERB object" do
|
15
|
-
expect(File).to receive(:read).with("#{config_dir_path}/#{file_name}").and_return(fake_file_handle)
|
16
|
-
expect(ERB).to receive(:new).with(fake_file_handle).and_return(fake_erb_object)
|
17
|
-
expect(subject).to eq(fake_erb_object)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe "#load_hash" do
|
23
|
-
subject { KumoKeisei::FileLoader.new(options).load_hash(file_name) }
|
24
|
-
|
25
|
-
context "when the file does not exist" do
|
26
|
-
it "returns an empty hash" do
|
27
|
-
expect(subject).to eq({})
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context "when the file does exist" do
|
32
|
-
let(:file_contents) { 'key: value' }
|
33
|
-
|
34
|
-
it "populates a hash" do
|
35
|
-
expect(File).to receive(:read).with(full_file_path).and_return(file_contents)
|
36
|
-
expect(subject).to eq({ 'key' => 'value' })
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "#load_hash when you set optional flag to false" do
|
42
|
-
let(:config_dir_path) { '/the/garden/path' }
|
43
|
-
let(:options) { { config_dir_path: config_dir_path } }
|
44
|
-
let(:file_name) { 'environment.yml' }
|
45
|
-
let(:full_file_path) { config_dir_path + '/' + file_name }
|
46
|
-
|
47
|
-
subject { KumoKeisei::FileLoader.new(options).load_hash(file_name, false) }
|
48
|
-
|
49
|
-
context 'when the file does not exist' do
|
50
|
-
it 'raises an error' do
|
51
|
-
expect { subject }.to raise_error(Errno::ENOENT)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
context 'when the file exists' do
|
56
|
-
let(:file_contents) { 'key: value' }
|
57
|
-
|
58
|
-
it 'populates a hash' do
|
59
|
-
expect(File).to receive(:read).with(full_file_path).and_return(file_contents)
|
60
|
-
expect(subject).to eq({ 'key' => 'value' })
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|