stack_master 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/lib/stack_master/commands/terminal_helper.rb +14 -1
- data/lib/stack_master/parameter_resolvers/secret.rb +7 -2
- data/lib/stack_master/version.rb +1 -1
- metadata +21 -216
- data/.gitignore +0 -18
- data/.rspec +0 -2
- data/.travis.yml +0 -12
- data/CODE_OF_CONDUCT.md +0 -73
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -22
- data/Rakefile +0 -27
- data/apply_demo.gif +0 -0
- data/example/simple/Gemfile +0 -3
- data/example/simple/parameters/myapp_vpc.yml +0 -1
- data/example/simple/parameters/myapp_web.yml +0 -2
- data/example/simple/stack_master.yml +0 -13
- data/example/simple/templates/myapp_vpc.rb +0 -39
- data/example/simple/templates/myapp_web.rb +0 -16
- data/features/apply.feature +0 -392
- data/features/apply_with_compile_time_parameters.feature +0 -93
- data/features/apply_with_env_parameters.feature +0 -49
- data/features/apply_with_parameter_store_parameters.feature +0 -47
- data/features/apply_with_s3.feature +0 -106
- data/features/delete.feature +0 -29
- data/features/diff.feature +0 -179
- data/features/events.feature +0 -33
- data/features/init.feature +0 -6
- data/features/outputs.feature +0 -45
- data/features/region_aliases.feature +0 -62
- data/features/resources.feature +0 -42
- data/features/stack_defaults.feature +0 -82
- data/features/status.feature +0 -118
- data/features/step_definitions/parameter_store_steps.rb +0 -14
- data/features/step_definitions/stack_steps.rb +0 -71
- data/features/support/env.rb +0 -16
- data/features/validate.feature +0 -46
- data/logo.png +0 -0
- data/script/buildkite/bundle.sh +0 -5
- data/script/buildkite/clean.sh +0 -3
- data/script/buildkite_rspec.sh +0 -27
- data/spec/fixtures/parameters/myapp_vpc.yml +0 -1
- data/spec/fixtures/parameters/myapp_vpc_with_secrets.yml +0 -3
- data/spec/fixtures/sparkle_pack_integration/my_sparkle_pack/lib/my_sparkle_pack.rb +0 -1
- data/spec/fixtures/sparkle_pack_integration/my_sparkle_pack/lib/sparkleformation/dynamics/my_dynamic.rb +0 -5
- data/spec/fixtures/sparkle_pack_integration/templates/dynamics/local_dynamic.rb +0 -5
- data/spec/fixtures/sparkle_pack_integration/templates/template_with_dynamic.rb +0 -3
- data/spec/fixtures/sparkle_pack_integration/templates/template_with_dynamic_from_pack.rb +0 -3
- data/spec/fixtures/stack_master.yml +0 -49
- data/spec/fixtures/templates/json/valid_myapp_vpc.json +0 -53
- data/spec/fixtures/templates/myapp_vpc.json +0 -1
- data/spec/fixtures/templates/rb/cfndsl/sample.json +0 -28
- data/spec/fixtures/templates/rb/cfndsl/sample.rb +0 -16
- data/spec/fixtures/templates/yml/valid_myapp_vpc.yml +0 -35
- data/spec/fixtures/test/.gitkeep +0 -0
- data/spec/spec_helper.rb +0 -102
- data/spec/stack_master/aws_driver/s3_spec.rb +0 -130
- data/spec/stack_master/change_set_spec.rb +0 -70
- data/spec/stack_master/command_spec.rb +0 -66
- data/spec/stack_master/commands/apply_spec.rb +0 -259
- data/spec/stack_master/commands/delete_spec.rb +0 -40
- data/spec/stack_master/commands/init_spec.rb +0 -17
- data/spec/stack_master/commands/status_spec.rb +0 -44
- data/spec/stack_master/commands/validate_spec.rb +0 -27
- data/spec/stack_master/config_spec.rb +0 -153
- data/spec/stack_master/paged_response_accumulator_spec.rb +0 -39
- data/spec/stack_master/parameter_loader_spec.rb +0 -110
- data/spec/stack_master/parameter_resolver_spec.rb +0 -148
- data/spec/stack_master/parameter_resolvers/ami_finder_spec.rb +0 -68
- data/spec/stack_master/parameter_resolvers/env_spec.rb +0 -35
- data/spec/stack_master/parameter_resolvers/latest_ami_by_tags_spec.rb +0 -33
- data/spec/stack_master/parameter_resolvers/latest_ami_spec.rb +0 -46
- data/spec/stack_master/parameter_resolvers/parameter_store_spec.rb +0 -50
- data/spec/stack_master/parameter_resolvers/secret_spec.rb +0 -66
- data/spec/stack_master/parameter_resolvers/security_group_spec.rb +0 -19
- data/spec/stack_master/parameter_resolvers/security_groups_spec.rb +0 -32
- data/spec/stack_master/parameter_resolvers/sns_topic_name_spec.rb +0 -43
- data/spec/stack_master/parameter_resolvers/stack_output_spec.rb +0 -127
- data/spec/stack_master/prompter_spec.rb +0 -23
- data/spec/stack_master/resolver_array_spec.rb +0 -42
- data/spec/stack_master/security_group_finder_spec.rb +0 -49
- data/spec/stack_master/sns_topic_finder_spec.rb +0 -25
- data/spec/stack_master/sparkle_formation/compile_time/allowed_pattern_validator_spec.rb +0 -47
- data/spec/stack_master/sparkle_formation/compile_time/allowed_values_validator_spec.rb +0 -47
- data/spec/stack_master/sparkle_formation/compile_time/definitions_validator_spec.rb +0 -36
- data/spec/stack_master/sparkle_formation/compile_time/empty_validator_spec.rb +0 -47
- data/spec/stack_master/sparkle_formation/compile_time/max_length_validator_spec.rb +0 -37
- data/spec/stack_master/sparkle_formation/compile_time/max_size_validator_spec.rb +0 -27
- data/spec/stack_master/sparkle_formation/compile_time/min_length_validator_spec.rb +0 -36
- data/spec/stack_master/sparkle_formation/compile_time/min_size_validator_spec.rb +0 -28
- data/spec/stack_master/sparkle_formation/compile_time/number_validator_spec.rb +0 -41
- data/spec/stack_master/sparkle_formation/compile_time/parameters_validator_spec.rb +0 -65
- data/spec/stack_master/sparkle_formation/compile_time/state_builder_spec.rb +0 -28
- data/spec/stack_master/sparkle_formation/compile_time/string_validator_spec.rb +0 -35
- data/spec/stack_master/sparkle_formation/compile_time/value_build_spec.rb +0 -52
- data/spec/stack_master/sparkle_formation/compile_time/value_validator_factory_spec.rb +0 -40
- data/spec/stack_master/sparkle_formation/template_file_spec.rb +0 -147
- data/spec/stack_master/stack_definition_spec.rb +0 -70
- data/spec/stack_master/stack_differ_spec.rb +0 -46
- data/spec/stack_master/stack_events/fetcher_spec.rb +0 -40
- data/spec/stack_master/stack_events/presenter_spec.rb +0 -18
- data/spec/stack_master/stack_events/streamer_spec.rb +0 -47
- data/spec/stack_master/stack_spec.rb +0 -184
- data/spec/stack_master/template_compiler_spec.rb +0 -39
- data/spec/stack_master/template_compilers/cfndsl_spec.rb +0 -22
- data/spec/stack_master/template_compilers/json_spec.rb +0 -32
- data/spec/stack_master/template_compilers/sparkle_formation_spec.rb +0 -116
- data/spec/stack_master/template_compilers/yaml_spec.rb +0 -20
- data/spec/stack_master/template_utils_spec.rb +0 -21
- data/spec/stack_master/test_driver/cloud_formation_spec.rb +0 -64
- data/spec/stack_master/test_driver/s3_spec.rb +0 -17
- data/spec/stack_master/utils_spec.rb +0 -30
- data/spec/stack_master/validator_spec.rb +0 -56
- data/spec/stack_master_spec.rb +0 -81
- data/spec/support/gemfiles/Gemfile.activesupport-4.0.0 +0 -5
- data/spec/support/validator_spec.rb +0 -23
- data/stack_master.gemspec +0 -46
- data/stacktemplates/parameter_region.yml +0 -3
- data/stacktemplates/parameter_stack_name.yml +0 -3
- data/stacktemplates/stack.json.erb +0 -20
- data/stacktemplates/stack_master.yml.erb +0 -6
@@ -1,68 +0,0 @@
|
|
1
|
-
RSpec.describe StackMaster::ParameterResolvers::AmiFinder do
|
2
|
-
subject(:resolver) { described_class.new('us-east-1') }
|
3
|
-
let(:ec2) { Aws::EC2::Client.new }
|
4
|
-
|
5
|
-
before do
|
6
|
-
allow(Aws::EC2::Client).to receive(:new).and_return(ec2)
|
7
|
-
end
|
8
|
-
|
9
|
-
describe '#build_filters_from_string' do
|
10
|
-
context 'when a single key-value pair is specified' do
|
11
|
-
it 'returns an array with a single hash' do
|
12
|
-
expect(resolver.build_filters_from_string('my-attr=my-value', nil)).to eq [
|
13
|
-
{ name: 'my-attr', values: ['my-value']}
|
14
|
-
]
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'when multiple key-value pairs are specified' do
|
19
|
-
it 'returns an array with multiple hashes' do
|
20
|
-
expect(resolver.build_filters_from_string('my-attr=my-value,foo=bar', nil)).to eq [
|
21
|
-
{ name: 'my-attr', values: ['my-value']},
|
22
|
-
{ name: 'foo', values: ['bar']}
|
23
|
-
]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'when a prefix is supplied' do
|
28
|
-
it 'adds the prefix to the filter' do
|
29
|
-
expect(resolver.build_filters_from_string('my-tag=my-value', 'tag')).to eq [
|
30
|
-
{ name: 'tag:my-tag', values: ['my-value']}
|
31
|
-
]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe '#build_filters_from_hash' do
|
37
|
-
it 'outputs a hash of values in the format expected by the AWS API' do
|
38
|
-
expect(resolver.build_filters_from_hash({'foo' => 'bacon'})).to eq([{name: 'foo', values: ['bacon']}])
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe '#find_latest_ami' do
|
43
|
-
let(:filter) { [{ name: "String", values: ["String"]}] }
|
44
|
-
|
45
|
-
context 'when matches are found' do
|
46
|
-
before do
|
47
|
-
ec2.stub_responses(:describe_images, images: [
|
48
|
-
{ image_id: '1', creation_date: '2015-01-02 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] },
|
49
|
-
{ image_id: '2', creation_date: '2015-01-03 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] }
|
50
|
-
])
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'returns the latest one' do
|
54
|
-
expect(resolver.find_latest_ami(filter).image_id).to eq '2'
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
context 'when no matches are found' do
|
59
|
-
before do
|
60
|
-
ec2.stub_responses(:describe_images, images: [])
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'returns nil' do
|
64
|
-
expect(resolver.find_latest_ami(filter)).to be_nil
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
RSpec.describe StackMaster::ParameterResolvers::Env do
|
2
|
-
|
3
|
-
describe '#resolve' do
|
4
|
-
|
5
|
-
subject(:resolver) { described_class.new(nil, double(region: 'us-east-1')) }
|
6
|
-
let(:environment_variable_name) { 'TEST' }
|
7
|
-
let(:error) { "The environment variable #{environment_variable_name} is not set" }
|
8
|
-
|
9
|
-
before(:each) do
|
10
|
-
ENV.delete(environment_variable_name)
|
11
|
-
end
|
12
|
-
|
13
|
-
context 'the environment variable is defined' do
|
14
|
-
it 'should return the environment variable value' do
|
15
|
-
ENV[environment_variable_name] = 'a'
|
16
|
-
expect(resolver.resolve(environment_variable_name)).to eq 'a'
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
context 'the environment variable is undefined' do
|
21
|
-
it 'should raise and error' do
|
22
|
-
expect { resolver.resolve(environment_variable_name) }
|
23
|
-
.to raise_error(ArgumentError, error)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'the environment variable is defined but empty' do
|
28
|
-
it 'should return the empty string' do
|
29
|
-
ENV[environment_variable_name] = ''
|
30
|
-
expect(resolver.resolve(environment_variable_name)).to eq ''
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
RSpec.describe StackMaster::ParameterResolvers::LatestAmiByTags do
|
2
|
-
let(:config) { double(base_dir: '/base') }
|
3
|
-
let(:stack_definition) { double(stack_name: 'mystack', region: 'us-east-1') }
|
4
|
-
subject(:resolver) { described_class.new(config, stack_definition) }
|
5
|
-
let(:ec2) { Aws::EC2::Client.new }
|
6
|
-
|
7
|
-
before do
|
8
|
-
allow(Aws::EC2::Client).to receive(:new).and_return(ec2)
|
9
|
-
end
|
10
|
-
|
11
|
-
context 'when matches are found' do
|
12
|
-
before do
|
13
|
-
ec2.stub_responses(:describe_images, images: [
|
14
|
-
{ image_id: '1', creation_date: '2015-01-02 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] },
|
15
|
-
{ image_id: '2', creation_date: '2015-01-03 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] }
|
16
|
-
])
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'returns the latest one' do
|
20
|
-
expect(resolver.resolve('my-tag=my-value')).to eq '2'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'when no matches are found' do
|
25
|
-
before do
|
26
|
-
ec2.stub_responses(:describe_images, images: [])
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'returns nil' do
|
30
|
-
expect(resolver.resolve('my-tag=my-value')).to be_nil
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
RSpec.describe StackMaster::ParameterResolvers::LatestAmi do
|
2
|
-
let(:config) { double(base_dir: '/base') }
|
3
|
-
let(:stack_definition) { double(stack_name: 'mystack', region: 'us-east-1') }
|
4
|
-
subject(:resolver) { described_class.new(config, stack_definition) }
|
5
|
-
let(:ec2) { Aws::EC2::Client.new }
|
6
|
-
|
7
|
-
before do
|
8
|
-
allow(Aws::EC2::Client).to receive(:new).and_return(ec2)
|
9
|
-
end
|
10
|
-
|
11
|
-
context 'when matches are found' do
|
12
|
-
before do
|
13
|
-
ec2.stub_responses(:describe_images, images: [
|
14
|
-
{ image_id: '1', creation_date: '2015-01-02 00:00:00', name: 'foo' },
|
15
|
-
{ image_id: '2', creation_date: '2015-01-03 00:00:00', name: 'foo' }
|
16
|
-
])
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'returns the latest one' do
|
20
|
-
expect(resolver.resolve('filters' => {'name' => 'foo'})).to eq '2'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'when no matches are found' do
|
25
|
-
before do
|
26
|
-
ec2.stub_responses(:describe_images, images: [])
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'returns nil' do
|
30
|
-
expect(resolver.resolve('filters' => {'name' => 'foo'})).to be_nil
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context 'when an owner_id is passed' do
|
35
|
-
let(:ami_finder) { StackMaster::ParameterResolvers::AmiFinder.new('us-east-1') }
|
36
|
-
before do
|
37
|
-
expect(StackMaster::ParameterResolvers::AmiFinder).to receive(:new).and_return(ami_finder)
|
38
|
-
allow(ami_finder).to receive(:build_filters_from_hash).and_call_original
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'calls find_latest_ami with the owner and filters' do
|
42
|
-
expect(ami_finder).to receive(:find_latest_ami).with([{name: 'foo', values: ['bacon']}], ['123456'])
|
43
|
-
resolver.resolve({'owners' => 123456, 'filters' => {'foo' => 'bacon'} })
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
RSpec.describe StackMaster::ParameterResolvers::ParameterStore do
|
2
|
-
|
3
|
-
describe '#resolve' do
|
4
|
-
|
5
|
-
let(:config) { double(base_dir: '/base') }
|
6
|
-
let(:stack_definition) { double(stack_name: 'mystack', region: 'us-east-1') }
|
7
|
-
subject(:resolver) { described_class.new(config, stack_definition) }
|
8
|
-
let(:parameter_name) { 'TEST' }
|
9
|
-
let(:parameter_value) { 'TEST' }
|
10
|
-
let(:unknown_parameter_name) { 'NOTEST' }
|
11
|
-
let(:unencryptable_parameter_name) { 'SECRETTEST' }
|
12
|
-
|
13
|
-
|
14
|
-
context 'the parameter is defined' do
|
15
|
-
before do
|
16
|
-
Aws.config[:ssm] = {
|
17
|
-
stub_responses: {
|
18
|
-
get_parameter: {
|
19
|
-
parameter: {
|
20
|
-
name: parameter_name,
|
21
|
-
value: parameter_value,
|
22
|
-
type: "SecureString",
|
23
|
-
version: 1
|
24
|
-
}
|
25
|
-
}
|
26
|
-
}
|
27
|
-
}
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'should return the parameter value' do
|
31
|
-
expect(resolver.resolve(parameter_name)).to eq parameter_value
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'the parameter is undefined' do
|
36
|
-
before do
|
37
|
-
Aws.config[:ssm] = {
|
38
|
-
stub_responses: {
|
39
|
-
get_parameter:
|
40
|
-
Aws::SSM::Errors::ParameterNotFound.new(unknown_parameter_name, "Parameter #{unknown_parameter_name} not found")
|
41
|
-
}
|
42
|
-
}
|
43
|
-
end
|
44
|
-
it 'should raise and error' do
|
45
|
-
expect { resolver.resolve(unknown_parameter_name) }
|
46
|
-
.to raise_error(StackMaster::ParameterResolvers::ParameterStore::ParameterNotFound, "Unable to find #{unknown_parameter_name} in Parameter Store")
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
RSpec.describe StackMaster::ParameterResolvers::Secret do
|
2
|
-
let(:base_dir) { '/base_dir' }
|
3
|
-
let(:config) { double(base_dir: base_dir) }
|
4
|
-
let(:stack_definition) { double(secret_file: secrets_file_name, stack_name: 'mystack', region: 'us-east-1') }
|
5
|
-
subject(:resolve_secret) { StackMaster::ParameterResolvers::Secret.new(config, stack_definition).resolve(value) }
|
6
|
-
let(:value) { 'my_file/my_secret_key' }
|
7
|
-
let(:secrets_file_name) { "my_file.yml.gpg" }
|
8
|
-
let(:file_path) { "#{base_dir}/secrets/#{secrets_file_name}" }
|
9
|
-
|
10
|
-
context 'the secret file does not exist' do
|
11
|
-
before do
|
12
|
-
allow(File).to receive(:exist?).with(file_path).and_return(false)
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'raises an ArgumentError with the location of the expected secret file' do
|
16
|
-
expect {
|
17
|
-
resolve_secret
|
18
|
-
}.to raise_error(ArgumentError, /#{file_path}/)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
context 'no secret file is specified for the stack definition' do
|
23
|
-
before do
|
24
|
-
allow(stack_definition).to receive(:secret_file).and_return(nil)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'raises an ArgumentError with the location of the expected secret file' do
|
28
|
-
expect {
|
29
|
-
resolve_secret
|
30
|
-
}.to raise_error(ArgumentError, /No secret_file defined/)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context 'the secret file exists' do
|
35
|
-
let(:dir) { double(Dotgpg::Dir) }
|
36
|
-
let(:decrypted_file) { <<EOF }
|
37
|
-
secret_key_1: secret_value_1
|
38
|
-
secret_key_2: secret_value_2
|
39
|
-
EOF
|
40
|
-
|
41
|
-
before do
|
42
|
-
allow(File).to receive(:exist?).with(file_path).and_return(true)
|
43
|
-
allow(Dotgpg::Dir).to receive(:closest).with(file_path).and_return(dir)
|
44
|
-
allow(dir).to receive(:decrypt).with("secrets/#{secrets_file_name}", anything)
|
45
|
-
allow(StringIO).to receive(:new).and_return(double(string: decrypted_file))
|
46
|
-
end
|
47
|
-
|
48
|
-
context 'the secret key does not exist' do
|
49
|
-
let(:value) { 'unknown_secret' }
|
50
|
-
|
51
|
-
it 'raises a secret not found error' do
|
52
|
-
expect {
|
53
|
-
resolve_secret
|
54
|
-
}.to raise_error(StackMaster::ParameterResolvers::Secret::SecretNotFound)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
context 'the secret key exists' do
|
59
|
-
let(:value) { 'secret_key_2' }
|
60
|
-
|
61
|
-
it 'returns the secret' do
|
62
|
-
expect(resolve_secret).to eq('secret_value_2')
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
RSpec.describe StackMaster::ParameterResolvers::SecurityGroup do
|
2
|
-
describe "#resolve" do
|
3
|
-
subject(:resolver) { described_class.new(nil, double(region: 'us-east-1')) }
|
4
|
-
let(:finder) { instance_double(StackMaster::SecurityGroupFinder) }
|
5
|
-
let(:sg_id) { 'sg-id' }
|
6
|
-
let(:sg_name) { 'sg-name' }
|
7
|
-
|
8
|
-
before do
|
9
|
-
allow(StackMaster::SecurityGroupFinder).to receive(:new).with('us-east-1').and_return finder
|
10
|
-
expect(finder).to receive(:find).once.with(sg_name).and_return sg_id
|
11
|
-
end
|
12
|
-
|
13
|
-
context 'when given a single SG name' do
|
14
|
-
it "resolves the security group" do
|
15
|
-
expect(resolver.resolve(sg_name)).to eq sg_id
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
RSpec.describe StackMaster::ParameterResolvers::SecurityGroups do
|
2
|
-
describe "#resolve" do
|
3
|
-
subject(:resolver) { described_class.new(nil, double(region: 'us-east-1')) }
|
4
|
-
let(:finder) { instance_double(StackMaster::SecurityGroupFinder) }
|
5
|
-
let(:sg_id) { 'sg-id' }
|
6
|
-
let(:sg_name) { 'sg-name' }
|
7
|
-
|
8
|
-
before do
|
9
|
-
allow(StackMaster::SecurityGroupFinder).to receive(:new).with('us-east-1').and_return finder
|
10
|
-
expect(finder).to receive(:find).once.with(sg_name).and_return sg_id
|
11
|
-
end
|
12
|
-
|
13
|
-
context 'when given a single SG name' do
|
14
|
-
it "resolves the security group" do
|
15
|
-
expect(resolver.resolve(sg_name)).to eq sg_id
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
context 'when given a an array of SG names' do
|
20
|
-
let(:sg_id2) { 'sg-id2' }
|
21
|
-
let(:sg_name2) { 'sg-name2' }
|
22
|
-
|
23
|
-
before do
|
24
|
-
expect(finder).to receive(:find).once.with(sg_name2).and_return sg_id2
|
25
|
-
end
|
26
|
-
|
27
|
-
it "resolves the security groups" do
|
28
|
-
expect(resolver.resolve([sg_name, sg_name2])).to eq "#{sg_id},#{sg_id2}"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
RSpec.describe StackMaster::ParameterResolvers::SnsTopicName do
|
2
|
-
let(:region) { 'us-east-1' }
|
3
|
-
let(:stack_name) { 'my-stack' }
|
4
|
-
let(:config) { double }
|
5
|
-
|
6
|
-
def resolve(value)
|
7
|
-
described_class.new(config, double(region: 'us-east-1')).resolve(value)
|
8
|
-
end
|
9
|
-
|
10
|
-
subject(:resolved_value) { resolve(value) }
|
11
|
-
|
12
|
-
context 'when given a hash' do
|
13
|
-
let(:value) { { not_expected: 1} }
|
14
|
-
|
15
|
-
it 'raises an error' do
|
16
|
-
expect {
|
17
|
-
resolved_value
|
18
|
-
}.to raise_error(ArgumentError)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
context 'when given a string value' do
|
23
|
-
let(:value) { 'my-topic-name' }
|
24
|
-
|
25
|
-
context 'the stack and sns topic name exist' do
|
26
|
-
before do
|
27
|
-
allow_any_instance_of(StackMaster::SnsTopicFinder).to receive(:find).with(value).and_return('myresolvedvalue')
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'resolves the value' do
|
31
|
-
expect(resolved_value).to eq 'myresolvedvalue'
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context "the topic doesn't exist" do
|
36
|
-
it 'raises topic not found' do
|
37
|
-
expect {
|
38
|
-
resolved_value
|
39
|
-
}.to raise_error(StackMaster::ParameterResolvers::SnsTopicName::TopicNotFound)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,127 +0,0 @@
|
|
1
|
-
RSpec.describe StackMaster::ParameterResolvers::StackOutput do
|
2
|
-
let(:region) { 'us-east-1' }
|
3
|
-
let(:stack_name) { 'my-stack' }
|
4
|
-
let(:resolver) { described_class.new(config, double(region: 'us-east-1')) }
|
5
|
-
let(:cf) { Aws::CloudFormation::Client.new }
|
6
|
-
let(:config) { double(:unalias_region => region) }
|
7
|
-
|
8
|
-
def resolve(value)
|
9
|
-
resolver.resolve(value)
|
10
|
-
end
|
11
|
-
|
12
|
-
subject(:resolved_value) { resolve(value) }
|
13
|
-
|
14
|
-
context 'when given an invalid string value' do
|
15
|
-
let(:value) { 'stack-name-without-output' }
|
16
|
-
|
17
|
-
it 'raises an error' do
|
18
|
-
expect {
|
19
|
-
resolved_value
|
20
|
-
}.to raise_error(ArgumentError)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'when given a hash' do
|
25
|
-
let(:value) { { not_expected: 1} }
|
26
|
-
|
27
|
-
it 'raises an error' do
|
28
|
-
expect {
|
29
|
-
resolved_value
|
30
|
-
}.to raise_error(ArgumentError)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context 'when given a valid string value' do
|
35
|
-
let(:value) { 'my-stack/MyOutput' }
|
36
|
-
let(:stacks) { [{ stack_name: 'blah', creation_time: Time.now, stack_status: 'CREATE_COMPLETE', outputs: outputs}] }
|
37
|
-
let(:outputs) { [] }
|
38
|
-
|
39
|
-
before do
|
40
|
-
allow(Aws::CloudFormation::Client).to receive(:new).and_return(cf)
|
41
|
-
cf.stub_responses(:describe_stacks, stacks: stacks)
|
42
|
-
end
|
43
|
-
|
44
|
-
context 'the stack and output exist' do
|
45
|
-
let(:outputs) { [{output_key: 'MyOutput', output_value: 'myresolvedvalue'}] }
|
46
|
-
|
47
|
-
it 'resolves the value' do
|
48
|
-
expect(resolved_value).to eq 'myresolvedvalue'
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'caches stacks for the lifetime of the instance' do
|
52
|
-
resolver.resolve(value)
|
53
|
-
resolver.resolve(value)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
context "the stack doesn't exist" do
|
58
|
-
let(:stacks) { nil }
|
59
|
-
|
60
|
-
it 'resolves the value' do
|
61
|
-
expect {
|
62
|
-
resolved_value
|
63
|
-
}.to raise_error(StackMaster::ParameterResolvers::StackOutput::StackNotFound)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context "the output doesn't exist" do
|
68
|
-
let(:outputs) { [] }
|
69
|
-
|
70
|
-
it 'resolves the value' do
|
71
|
-
expect {
|
72
|
-
resolved_value
|
73
|
-
}.to raise_error(StackMaster::ParameterResolvers::StackOutput::StackOutputNotFound)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context 'when given a valid string value including region' do
|
79
|
-
let(:value) { 'us-east-1:my-stack/MyOutput' }
|
80
|
-
let(:stacks) { [{ stack_name: 'my-stack', creation_time: Time.now, stack_status: 'CREATE_COMPLETE', outputs: outputs}] }
|
81
|
-
let(:outputs) { [] }
|
82
|
-
|
83
|
-
before do
|
84
|
-
allow(Aws::CloudFormation::Client).to receive(:new).and_return(cf)
|
85
|
-
cf.stub_responses(:describe_stacks, stacks: stacks)
|
86
|
-
end
|
87
|
-
|
88
|
-
context 'the stack and output exist' do
|
89
|
-
let(:outputs) { [{output_key: 'MyOutput', output_value: 'myresolvedvalue'}] }
|
90
|
-
|
91
|
-
it 'resolves the value' do
|
92
|
-
expect(resolved_value).to eq 'myresolvedvalue'
|
93
|
-
end
|
94
|
-
|
95
|
-
context 'the stack and output exist in a different region with the same name' do
|
96
|
-
let(:value_in_region_alias) { 'global:my-stack/MyOutput' }
|
97
|
-
let(:value_in_region_2) { 'ap-southeast-2:my-stack/MyOutput' }
|
98
|
-
let(:outputs_in_region_2) { [{output_key: 'MyOutput', output_value: 'myresolvedvalue2'}] }
|
99
|
-
let(:stacks_in_region_2) { [{ stack_name: 'my-stack', creation_time: Time.now, stack_status: 'CREATE_COMPLETE', outputs: outputs_in_region_2}] }
|
100
|
-
|
101
|
-
before do
|
102
|
-
cf.stub_responses(
|
103
|
-
:describe_stacks,
|
104
|
-
{ stacks: stacks },
|
105
|
-
{ stacks: stacks_in_region_2 }
|
106
|
-
)
|
107
|
-
allow(config).to receive(:unalias_region) do |aliased_region|
|
108
|
-
if aliased_region == 'global'
|
109
|
-
'us-east-1'
|
110
|
-
else
|
111
|
-
aliased_region
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
it 'resolves the value to the right region' do
|
117
|
-
resolver.resolve(value)
|
118
|
-
expect(resolver.resolve(value_in_region_2)).to eq 'myresolvedvalue2'
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'resolves to the same region if it is an alias' do
|
122
|
-
expect(resolver.resolve(value_in_region_alias)).to eq 'myresolvedvalue'
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|