convection 0.2.32 → 0.2.33

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -1
  3. data/.rubocop_todo.yml +1 -2
  4. data/Gemfile +2 -1
  5. data/Rakefile +3 -7
  6. data/lib/convection.rb +2 -2
  7. data/lib/convection/control/stack.rb +49 -10
  8. data/lib/convection/model/event.rb +3 -2
  9. data/lib/convection/model/template.rb +13 -1
  10. data/lib/convection/model/template/metadata.rb +22 -0
  11. data/lib/convection/model/template/resource/aws_ec2_subnet.rb +1 -0
  12. data/lib/convection/model/template/resource/aws_events_rule.rb +4 -0
  13. data/spec/cf_client_context.rb +10 -0
  14. data/spec/collect_availability_zones_task_context.rb +17 -0
  15. data/spec/convection/control/stack/after_create_tasks_spec.rb +51 -0
  16. data/spec/convection/control/stack/after_delete_tasks_spec.rb +51 -0
  17. data/spec/convection/control/stack/after_update_tasks_spec.rb +54 -0
  18. data/spec/convection/control/stack/before_create_tasks_spec.rb +52 -0
  19. data/spec/convection/control/stack/before_delete_tasks_spec.rb +51 -0
  20. data/spec/convection/control/stack/before_update_tasks_spec.rb +55 -0
  21. data/spec/convection/dsl/intrinsic_functions_spec.rb +88 -0
  22. data/spec/convection/model/template/condition_spec.rb +38 -0
  23. data/spec/convection/model/template/resource/directoryservice_simple_ad_spec.rb +39 -0
  24. data/spec/convection/model/template/resource/ec2_security_group_spec.rb +39 -0
  25. data/spec/convection/model/template/resource/ec2_subnet_spec.rb +48 -0
  26. data/spec/convection/model/template/resource/elasticache_cache_cluster_spec.rb +52 -0
  27. data/spec/convection/model/template/resource/elasticache_parameter_group_spec.rb +38 -0
  28. data/spec/convection/model/template/resource/elasticache_security_group_ingress_spec.rb +40 -0
  29. data/spec/convection/model/template/resource/elasticache_security_group_spec.rb +32 -0
  30. data/spec/convection/model/template/resource/events_rule_spec.rb +44 -0
  31. data/spec/convection/model/template/resource/iam_role_spec.rb +37 -0
  32. data/spec/convection/model/template/resource/lambdas_spec.rb +70 -0
  33. data/spec/convection/model/template/resource/loggroups_spec.rb +34 -0
  34. data/spec/convection/model/template/resource/permission_spec.rb +43 -0
  35. data/spec/convection/model/template/resource/rds_security_groups_spec.rb +50 -0
  36. data/spec/convection/model/template/resource/vpc_endpoints_spec.rb +65 -0
  37. data/spec/convection/model/template/resource_attribute/update_policies_spec.rb +66 -0
  38. data/spec/convection/model/template/template_spec.rb +60 -0
  39. data/spec/convection/model/template/validate_bytesize_spec.rb +49 -0
  40. data/spec/convection/model/template/validate_description_spec.rb +31 -0
  41. data/spec/convection/model/template/validate_mappings_spec.rb +88 -0
  42. data/spec/convection/model/template/validate_outputs_spec.rb +62 -0
  43. data/spec/convection/model/template/validate_parameters_spec.rb +84 -0
  44. data/spec/convection/model/template/validate_resources_spec.rb +50 -0
  45. data/spec/ec2_client_context.rb +18 -0
  46. data/spec/spec_helper.rb +11 -0
  47. metadata +72 -40
  48. data/test/convection/model/test_conditions.rb +0 -121
  49. data/test/convection/model/test_directory_service.rb +0 -40
  50. data/test/convection/model/test_elasticache.rb +0 -97
  51. data/test/convection/model/test_lambdas.rb +0 -53
  52. data/test/convection/model/test_loggroups.rb +0 -25
  53. data/test/convection/model/test_permission.rb +0 -31
  54. data/test/convection/model/test_rds.rb +0 -76
  55. data/test/convection/model/test_template.rb +0 -64
  56. data/test/convection/model/test_trust.rb +0 -28
  57. data/test/convection/model/test_update_policies.rb +0 -54
  58. data/test/convection/model/test_validation.rb +0 -216
  59. data/test/convection/model/test_vpc_endpoint.rb +0 -51
  60. data/test/convection/tasks/test_after_create_tasks.rb +0 -66
  61. data/test/convection/tasks/test_after_delete_tasks.rb +0 -66
  62. data/test/convection/tasks/test_after_update_tasks.rb +0 -71
  63. data/test/convection/tasks/test_before_create_tasks.rb +0 -66
  64. data/test/convection/tasks/test_before_delete_tasks.rb +0 -66
  65. data/test/convection/tasks/test_before_update_tasks.rb +0 -71
  66. data/test/test_helper.rb +0 -72
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ module Convection::Control
4
+ describe Stack do
5
+ let(:template) do
6
+ Convection.template do
7
+ description 'EC2 VPC Test Template'
8
+
9
+ ec2_vpc 'TargetVPC' do
10
+ network '10.0.0.0'
11
+ subnet_length 24
12
+ enable_dns
13
+ end
14
+ end
15
+ end
16
+
17
+ # TODO: Test that before_create tasks are not run on a new Stack.
18
+ describe 'before create tasks' do
19
+ include_context 'with a CollectAvailabilityZonesTask defined'
20
+ include_context 'with a mock CloudFormation client'
21
+ include_context 'with a mock EC2 client'
22
+
23
+ before do
24
+ allow(Aws::CloudFormation::Client).to receive(:new).and_return(cf_client)
25
+ allow(Aws::EC2::Client).to receive(:new).and_return(ec2_client)
26
+ end
27
+ let(:task) { CollectAvailabilityZonesTask.new }
28
+ subject do
29
+ scope = self
30
+ Convection::Control::Stack.new('EC2 VPC Test Stack', template) do
31
+ before_create_task scope.task
32
+ end
33
+ end
34
+
35
+ it 'is registered before Stack#apply is called' do
36
+ expect(subject.tasks[:before_create]).to_not be_empty
37
+ end
38
+
39
+ it 'is executed on Stack#apply' do
40
+ subject.apply
41
+
42
+ expect(task.availability_zones).to include('eu-central-1')
43
+ end
44
+
45
+ it 'is deregistered after Stack#apply is called' do
46
+ subject.apply
47
+
48
+ expect(subject.tasks[:before_create]).to be_empty
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ module Convection::Control
4
+ describe Stack do
5
+ let(:template) do
6
+ Convection.template do
7
+ description 'EC2 VPC Test Template'
8
+
9
+ ec2_vpc 'TargetVPC' do
10
+ network '10.0.0.0'
11
+ subnet_length 24
12
+ enable_dns
13
+ end
14
+ end
15
+ end
16
+
17
+ describe 'before delete tasks' do
18
+ include_context 'with a CollectAvailabilityZonesTask defined'
19
+ include_context 'with a mock CloudFormation client'
20
+ include_context 'with a mock EC2 client'
21
+
22
+ before do
23
+ allow(Aws::CloudFormation::Client).to receive(:new).and_return(cf_client)
24
+ allow(Aws::EC2::Client).to receive(:new).and_return(ec2_client)
25
+ end
26
+ let(:task) { CollectAvailabilityZonesTask.new }
27
+ subject do
28
+ scope = self
29
+ Convection::Control::Stack.new('EC2 VPC Test Stack', template) do
30
+ before_delete_task scope.task
31
+ end
32
+ end
33
+
34
+ it 'is registered before Stack#delete is called' do
35
+ expect(subject.tasks[:before_delete]).to_not be_empty
36
+ end
37
+
38
+ it 'is executed on Stack#delete' do
39
+ subject.delete
40
+
41
+ expect(task.availability_zones).to include('eu-central-1')
42
+ end
43
+
44
+ it 'is deregistered after Stack#delete is called' do
45
+ subject.delete
46
+
47
+ expect(subject.tasks[:before_delete]).to be_empty
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ module Convection::Control
4
+ describe Stack do
5
+ let(:template) do
6
+ Convection.template do
7
+ description 'EC2 VPC Test Template'
8
+
9
+ ec2_vpc 'TargetVPC' do
10
+ network '10.0.0.0'
11
+ subnet_length 24
12
+ enable_dns
13
+ end
14
+ end
15
+ end
16
+
17
+ # TODO: Test that before_update tasks are not run on a new Stack.
18
+ describe 'before update tasks' do
19
+ include_context 'with a CollectAvailabilityZonesTask defined'
20
+ include_context 'with a mock CloudFormation client'
21
+ include_context 'with a mock EC2 client'
22
+
23
+ before do
24
+ allow(Aws::CloudFormation::Client).to receive(:new).and_return(cf_client)
25
+ allow(Aws::EC2::Client).to receive(:new).and_return(ec2_client)
26
+ end
27
+ let(:task) { CollectAvailabilityZonesTask.new }
28
+ subject do
29
+ scope = self
30
+ stack = Convection::Control::Stack.new('EC2 VPC Test Stack', template) do
31
+ before_update_task scope.task
32
+ end
33
+ allow(stack).to receive(:exist).and_return(true)
34
+ allow(stack).to receive(:exist?).and_return(true)
35
+ stack
36
+ end
37
+
38
+ it 'is registered before Stack#apply is called' do
39
+ expect(subject.tasks[:before_update]).to_not be_empty
40
+ end
41
+
42
+ it 'is executed on Stack#apply' do
43
+ subject.apply
44
+
45
+ expect(task.availability_zones).to include('eu-central-1')
46
+ end
47
+
48
+ it 'is deregistered after Stack#apply is called' do
49
+ subject.apply
50
+
51
+ expect(subject.tasks[:before_update]).to be_empty
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+
3
+ module Convection::DSL
4
+ describe IntrinsicFunctions do
5
+ include described_class
6
+
7
+ let(:apples_to_oranges) do
8
+ { 'Fn::Equals' => %w(apples oranges) }
9
+ end
10
+
11
+ let(:apples_to_apples) do
12
+ { 'Fn::Equals' => %w(apples apples) }
13
+ end
14
+
15
+ let(:value_if_true) do
16
+ { 'Ref' => 'ValueOne' }
17
+ end
18
+
19
+ let(:value_if_false) do
20
+ { 'Ref' => 'ValueTwo' }
21
+ end
22
+
23
+ it 'defines #base64' do
24
+ actual = base64('message to encode')
25
+ expect(actual).to eq('Fn::Base64' => 'message to encode')
26
+ end
27
+
28
+ it 'defines #fn_and' do
29
+ actual = fn_and(apples_to_oranges, apples_to_apples)
30
+
31
+ expect(actual).to eq('Fn::And' => [apples_to_oranges, apples_to_apples])
32
+ end
33
+
34
+ it 'defines #fn_equals' do
35
+ actual = fn_equals('apples', 'oranges')
36
+ expect(actual).to eq(apples_to_oranges)
37
+ end
38
+
39
+ it 'defines #fn_if' do
40
+ actual = fn_if('UseDBSnapshot', value_if_true, value_if_false)
41
+ expect(actual).to eq(
42
+ 'Fn::If' => ['UseDBSnapshot', value_if_true, value_if_false]
43
+ )
44
+ end
45
+
46
+ it 'defines #fn_not' do
47
+ actual = fn_not(apples_to_oranges)
48
+ expect(actual).to eq('Fn::Not' => [apples_to_oranges])
49
+ end
50
+
51
+ it 'defines #fn_or' do
52
+ actual = fn_or(apples_to_oranges, apples_to_apples)
53
+ expect(actual).to eq('Fn::Or' => [apples_to_oranges, apples_to_apples])
54
+ end
55
+
56
+ it 'defines #find_in_map' do
57
+ actual = find_in_map('RegionMap', 'us-east-1', '32')
58
+ expect(actual).to eq(
59
+ 'Fn::FindInMap' => ['RegionMap', 'us-east-1', '32']
60
+ )
61
+ end
62
+
63
+ it 'defines #get_att' do
64
+ actual = get_att('MyLB', 'DNSName')
65
+ expect(actual).to eq('Fn::GetAtt' => %w(MyLB DNSName))
66
+ end
67
+
68
+ it 'defines #get_azs' do
69
+ actual = get_azs('us-east-1')
70
+ expect(actual).to eq('Fn::GetAZs' => 'us-east-1')
71
+ end
72
+
73
+ it 'defines #join' do
74
+ actual = join(' ', 'Hello', 'World')
75
+ expect(actual).to eq('Fn::Join' => [' ', %w(Hello World)])
76
+ end
77
+
78
+ it 'defines #select' do
79
+ actual = select('2', 'duck', 'duck', 'goose')
80
+ expect(actual).to eq('Fn::Select' => ['2', %w(duck duck goose)])
81
+ end
82
+
83
+ it 'defines #fn_ref' do
84
+ actual = fn_ref('SomeLogicalName')
85
+ expect(actual).to eq('Ref' => 'SomeLogicalName')
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ class Convection::Model::Template
4
+ describe Condition do
5
+ let(:template) do
6
+ Convection.template do
7
+ description 'Condition Test Template'
8
+
9
+ condition 'InProd' do
10
+ fn_equals 'prod', 'prod'
11
+ end
12
+
13
+ resource 'SecurityGroup' do
14
+ type 'AWS::EC2::SecurityGroup'
15
+ condition 'InProd'
16
+ end
17
+ end
18
+ end
19
+
20
+ it 'can be referenced by resources' do
21
+ resource = rendered_template
22
+ .fetch('Resources').fetch('SecurityGroup')
23
+ expect(resource).to include('Condition' => 'InProd')
24
+ end
25
+
26
+ it 'can be referenced by resources' do
27
+ resource = rendered_template
28
+ .fetch('Resources').fetch('SecurityGroup')
29
+ expect(resource).to include('Condition' => 'InProd')
30
+ end
31
+
32
+ private
33
+
34
+ def rendered_template
35
+ JSON.parse(template.to_json)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ class Convection::Model::Template::Resource
4
+ describe DirectoryServiceSimpleAD do
5
+ let(:simple_ad_template) do
6
+ Convection.template do
7
+ directoryservice_simple_ad 'SimpleActiveDirectory' do
8
+ description 'Example simple AD'
9
+ enable_sso false
10
+ name 'ExampleSimpleAD'
11
+ password 'directory.password'
12
+ short_name 'directory.name'
13
+ size 'Small'
14
+
15
+ vpc_settings 'SubnetIds', ['subnet-deadb33f']
16
+ vpc_settings 'VpcId', 'vpc-deadb33f'
17
+ end
18
+ end
19
+ end
20
+
21
+ it 'sets VpcSettings.SubnetIds' do
22
+ vpc_settings = simple_ad_json.fetch('Properties').fetch('VpcSettings')
23
+ expect(vpc_settings.fetch('SubnetIds')).to eq(['subnet-deadb33f'])
24
+ end
25
+
26
+ it 'sets VpcSettings.VpcId' do
27
+ vpc_settings = simple_ad_json.fetch('Properties').fetch('VpcSettings')
28
+ expect(vpc_settings.fetch('VpcId')).to eq('vpc-deadb33f')
29
+ end
30
+
31
+ private
32
+
33
+ def simple_ad_json
34
+ JSON.parse(simple_ad_template.to_json)
35
+ .fetch('Resources')
36
+ .fetch('SimpleActiveDirectory')
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ class Convection::Model::Template::Resource
4
+ describe EC2SecurityGroup do
5
+ let(:template) do
6
+ Convection.template do
7
+ description 'Elasticache Test Template'
8
+
9
+ ec2_security_group 'MyEC2SecGroup' do
10
+ description 'EC2 security group'
11
+
12
+ vpc 'vpc-deadb33f'
13
+ end
14
+ end
15
+ end
16
+
17
+ subject do
18
+ template_json
19
+ .fetch('Resources')
20
+ .fetch('MyEC2SecGroup')
21
+ .fetch('Properties')
22
+ end
23
+
24
+ # TODO: Write more meaningful specs for EC2SecurityGroup around things like ingress/egress or the taggable mixin
25
+ it 'has a description' do
26
+ expect(subject['GroupDescription']).to eq('EC2 security group')
27
+ end
28
+
29
+ it 'has a description' do
30
+ expect(subject['VpcId']).to eq('vpc-deadb33f')
31
+ end
32
+
33
+ private
34
+
35
+ def template_json
36
+ JSON.parse(template.to_json)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ class Convection::Model::Template::Resource
4
+ describe EC2Subnet do
5
+ let(:template) do
6
+ Convection.template do
7
+ description 'Ec2 Subnet'
8
+
9
+ ec2_subnet 'PublicSubnet' do
10
+ network '10.10.11.0/24'
11
+ availability_zone 'us-east-1a'
12
+ tag 'Name', 'subnet'
13
+ vpc fn_ref('DemoVPC')
14
+ public_ips true
15
+ end
16
+ end
17
+ end
18
+
19
+ subject do
20
+ template_json
21
+ .fetch('Resources')
22
+ .fetch('PublicSubnet')
23
+ .fetch('Properties')
24
+ end
25
+
26
+ it 'sets the cidr block' do
27
+ expect(subject['CidrBlock']).to eq('10.10.11.0/24')
28
+ end
29
+
30
+ it 'sets the availability zone' do
31
+ expect(subject['AvailabilityZone']).to eq('us-east-1a')
32
+ end
33
+
34
+ it 'sets a subnet as public' do
35
+ expect(subject['MapPublicIpOnLaunch']).to be(true)
36
+ end
37
+
38
+ it 'sets tags' do
39
+ expect(subject['Tags']).to include(hash_including('Key' => 'Name', 'Value' => 'subnet'))
40
+ end
41
+
42
+ private
43
+
44
+ def template_json
45
+ JSON.parse(template.to_json)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ class Convection::Model::Template::Resource
4
+ describe ElastiCacheCluster do
5
+ let(:template) do
6
+ Convection.template do
7
+ description 'Elasticache Test Template'
8
+
9
+ elasticache_cache_cluster 'MyRedisCluster' do
10
+ cluster_name 'RedisCluster007'
11
+
12
+ auto_minor_version_upgrade true
13
+ cache_node_type 'cache.m3.medium'
14
+
15
+ # NOTE: We do not have to actually be able to resolve these
16
+ # function references for unit testing.
17
+ cache_parameter_group_name fn_ref('MyRedisParmGroup')
18
+ cache_security_group_names [fn_ref('MyRedisSecGroup')]
19
+
20
+ engine 'redis'
21
+ engine_version '2.8.6'
22
+ num_cache_nodes 1
23
+ end
24
+ end
25
+ end
26
+
27
+ subject do
28
+ template_json
29
+ .fetch('Resources')
30
+ .fetch('MyRedisCluster')
31
+ .fetch('Properties')
32
+ end
33
+
34
+ it 'references the specified security group names' do
35
+ expect(subject['CacheSecurityGroupNames']).to include('Ref' => 'MyRedisSecGroup')
36
+ end
37
+
38
+ it 'specifies the cluster name RedisCluster007' do
39
+ expect(subject['ClusterName']).to eq('RedisCluster007')
40
+ end
41
+
42
+ it 'specifies the engine redis' do
43
+ expect(subject['Engine']).to eq('redis')
44
+ end
45
+
46
+ private
47
+
48
+ def template_json
49
+ JSON.parse(template.to_json)
50
+ end
51
+ end
52
+ end