cfndsl 0.17.5 → 1.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +4 -4
  4. data/.travis.yml +6 -1
  5. data/CHANGELOG.md +32 -34
  6. data/README.md +68 -21
  7. data/Rakefile +25 -3
  8. data/TODO.md +18 -0
  9. data/UPGRADING.md +22 -0
  10. data/cfndsl.gemspec +3 -3
  11. data/exe/cfndsl +5 -0
  12. data/lib/cfndsl.rb +2 -116
  13. data/lib/cfndsl/aws/cloud_formation_template.rb +8 -1
  14. data/lib/cfndsl/aws/patches/000_sam.spec.json +574 -0
  15. data/lib/cfndsl/aws/patches/100_sam.spec_DeploymentPreference_patch.json +64 -0
  16. data/lib/cfndsl/aws/patches/500_Cognito_IdentityPoolRoleAttachment_patches.json +25 -0
  17. data/lib/cfndsl/aws/patches/500_IoT1Click_patch_PlacementTemplate_DeviceTemplates.json +20 -0
  18. data/lib/cfndsl/aws/patches/500_SAM_Serverless_Function_S3Event_Events_patch.json +16 -0
  19. data/lib/cfndsl/aws/patches/500_SAM_Serverless_Function_S3Location_Version_patch.json +16 -0
  20. data/lib/cfndsl/aws/patches/500_SSM_AssociationName_patch.json +16 -0
  21. data/lib/cfndsl/aws/patches/500_VPCEndpoint_patch.json +17 -0
  22. data/lib/cfndsl/aws/patches/510_ElasticSearch_Domain_patches.json +15 -0
  23. data/lib/cfndsl/aws/patches/600_RefKinds_patch.json +3654 -0
  24. data/lib/cfndsl/aws/patches/700_SAM_Serverless_Function_InlineCode_patch.json +20 -0
  25. data/lib/cfndsl/aws/patches/800_List_types_patch.json +115 -0
  26. data/lib/cfndsl/aws/resource_specification.json +35809 -11627
  27. data/lib/cfndsl/aws/types.rb +3 -3
  28. data/lib/cfndsl/cfnlego.rb +34 -0
  29. data/lib/{cfnlego → cfndsl/cfnlego}/cloudformation.erb +0 -0
  30. data/lib/{cfnlego → cfndsl/cfnlego}/cloudformation.rb +0 -0
  31. data/lib/{cfnlego → cfndsl/cfnlego}/resource.rb +3 -8
  32. data/lib/cfndsl/cloudformation.rb +107 -0
  33. data/lib/cfndsl/conditions.rb +11 -1
  34. data/lib/cfndsl/creation_policy.rb +1 -1
  35. data/lib/cfndsl/deep_merge.rb +4 -0
  36. data/lib/cfndsl/external_parameters.rb +4 -13
  37. data/lib/cfndsl/globals.rb +48 -9
  38. data/lib/cfndsl/jsonable.rb +22 -60
  39. data/lib/cfndsl/mappings.rb +1 -1
  40. data/lib/cfndsl/module.rb +16 -5
  41. data/lib/cfndsl/orchestration_template.rb +185 -83
  42. data/lib/cfndsl/outputs.rb +5 -1
  43. data/lib/cfndsl/parameters.rb +1 -1
  44. data/lib/cfndsl/plurals.rb +12 -1
  45. data/lib/cfndsl/properties.rb +1 -1
  46. data/lib/cfndsl/rake_task.rb +206 -12
  47. data/lib/cfndsl/ref_check.rb +19 -11
  48. data/lib/cfndsl/resources.rb +6 -19
  49. data/lib/cfndsl/rules.rb +1 -1
  50. data/lib/cfndsl/runner.rb +143 -0
  51. data/lib/cfndsl/specification.rb +80 -95
  52. data/lib/cfndsl/types.rb +205 -91
  53. data/lib/cfndsl/update_policy.rb +1 -1
  54. data/lib/cfndsl/version.rb +1 -1
  55. data/sample/autoscale.rb +0 -1
  56. data/sample/autoscale2.rb +0 -1
  57. data/sample/config_service.rb +2 -2
  58. data/sample/t1.rb +1 -1
  59. data/sample/vpc_example.rb +1 -1
  60. data/sample/vpc_with_vpn_example.rb +1 -1
  61. data/spec/aws/list_type_patches_spec.rb +35 -0
  62. data/spec/aws/nested_arrays_spec.rb +155 -3
  63. data/spec/aws/serverless_spec.rb +0 -2
  64. data/spec/cfndsl_spec.rb +94 -78
  65. data/spec/cli_spec.rb +16 -54
  66. data/spec/cloud_formation_template_spec.rb +233 -0
  67. data/spec/condition_spec.rb +24 -0
  68. data/spec/direct_ruby_spec.rb +19 -0
  69. data/spec/external_parameters_spec.rb +2 -15
  70. data/spec/fixtures/condition-assertion.json +1 -0
  71. data/spec/fixtures/test.rb +2 -1
  72. data/spec/generate_spec.rb +4 -2
  73. data/spec/resources_spec.rb +0 -7
  74. data/spec/spec_helper.rb +2 -7
  75. data/spec/support/shared_examples/orchestration_template.rb +15 -2
  76. data/spec/types_definition_spec.rb +3 -6
  77. metadata +52 -23
  78. data/bin/cfndsl +0 -160
  79. data/lib/cfndsl/errors.rb +0 -31
  80. data/lib/cfndsl/os/heat_template.rb +0 -18
  81. data/lib/cfndsl/os/types.rb +0 -14
  82. data/lib/cfndsl/os/types.yaml +0 -2423
  83. data/lib/cfndsl/patches.rb +0 -226
  84. data/lib/cfnlego.rb +0 -44
  85. data/spec/fixtures/heattest.rb +0 -24
  86. data/spec/heat_template_spec.rb +0 -7
data/spec/cli_spec.rb CHANGED
@@ -2,21 +2,17 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- WORKING_SPEC_VERSION = '2.19.0'
6
-
7
5
  describe 'cfndsl', type: :aruba do
8
6
  let(:usage) do
9
7
  <<-USAGE.gsub(/^ {6}/, '').chomp
10
8
  Usage: cfndsl [options] FILE
11
9
  -o, --output FILE Write output to file
12
10
  -y, --yaml FILE Import yaml file as local variables
13
- -r, --ruby FILE Evaluate ruby file before template
14
11
  -j, --json FILE Import json file as local variables
15
12
  -p, --pretty Pretty-format output JSON
16
13
  -f, --format FORMAT Specify the output format (JSON default)
17
14
  -D, --define "VARIABLE=VALUE" Directly set local VARIABLE as VALUE
18
15
  -v, --verbose Turn on verbose ouptut
19
- -b, --disable-binding Disable binding configuration
20
16
  -m, --disable-deep-merge Disable deep merging of yaml
21
17
  -s, --specification-file FILE Location of Cloudformation Resource Specification file
22
18
  -u [VERSION], Update the Resource Specification file to latest, or specific version
@@ -39,12 +35,15 @@ describe 'cfndsl', type: :aruba do
39
35
 
40
36
  before(:each) { write_file('template.rb', template_content) }
41
37
 
38
+ # The known working version is the embedded version
39
+ WORKING_SPEC_VERSION = JSON.parse(File.read(CfnDsl::LOCAL_SPEC_FILE))['ResourceSpecificationVersion']
40
+
42
41
  context "cfndsl -u #{WORKING_SPEC_VERSION}" do
43
42
  it 'updates the specification file' do
44
43
  run_command "cfndsl -u #{WORKING_SPEC_VERSION}"
45
44
  expect(last_command_started).to have_output_on_stderr(<<-OUTPUT.gsub(/^ {8}/, '').chomp)
46
45
  Updating specification file
47
- Specification successfully written to #{ENV['HOME']}/.cfndsl/resource_specification.json
46
+ Specification #{WORKING_SPEC_VERSION} successfully written to #{ENV['HOME']}/.cfndsl/resource_specification.json
48
47
  OUTPUT
49
48
  expect(last_command_started).to have_exit_status(0)
50
49
  end
@@ -53,10 +52,11 @@ describe 'cfndsl', type: :aruba do
53
52
  context 'cfndsl -u' do
54
53
  it 'updates the specification file' do
55
54
  run_command 'cfndsl -u'
56
- expect(last_command_started).to have_output_on_stderr(<<-OUTPUT.gsub(/^ {8}/, '').chomp)
57
- Updating specification file
58
- Specification successfully written to #{ENV['HOME']}/.cfndsl/resource_specification.json
59
- OUTPUT
55
+
56
+ expected = %r{Updating specification file
57
+ Specification ([0-9]+\.){2}[0-9]+ successfully written to #{ENV['HOME']}/.cfndsl/resource_specification.json}
58
+
59
+ expect(last_command_started).to have_output_on_stderr(expected)
60
60
  expect(last_command_started).to have_exit_status(0)
61
61
  end
62
62
  end
@@ -71,7 +71,7 @@ describe 'cfndsl', type: :aruba do
71
71
 
72
72
  context 'cfndsl' do
73
73
  it 'displays the usage' do
74
- run_command 'cfndsl'
74
+ run_command'cfndsl'
75
75
  expect(last_command_started).to have_output(usage)
76
76
  expect(last_command_started).to have_exit_status(1)
77
77
  end
@@ -85,16 +85,6 @@ describe 'cfndsl', type: :aruba do
85
85
  end
86
86
 
87
87
  context 'cfndsl FILE' do
88
- it 'gives a deprecation warning about bindings' do
89
- run_command_and_stop 'cfndsl template.rb'
90
- expect(last_command_started).to have_output_on_stderr(<<-WARN.gsub(/^ {8}/, '').chomp)
91
- The creation of constants as config is deprecated!
92
- Please switch to the #external_parameters method within your templates to access variables
93
- See https://github.com/cfndsl/cfndsl/issues/170
94
- Use the --disable-binding flag to suppress this message
95
- WARN
96
- end
97
-
98
88
  it 'generates a JSON CloudFormation template' do
99
89
  run_command_and_stop 'cfndsl template.rb'
100
90
  expect(last_command_started).to have_output_on_stdout('{"AWSTemplateFormatVersion":"2010-09-09","Description":"default"}')
@@ -138,31 +128,6 @@ describe 'cfndsl', type: :aruba do
138
128
  end
139
129
  end
140
130
 
141
- context 'cfndsl FILE --ruby FILE' do
142
- let(:template_content) do
143
- <<-TEMPLATE.gsub(/^ {8}/, '')
144
- CloudFormation do
145
- DESC = 'default' unless defined? DESC
146
- Description DESC
147
- end
148
- TEMPLATE
149
- end
150
-
151
- before(:each) { write_file('params.rb', 'DESC = "ruby"') }
152
-
153
- it 'interpolates the Ruby file in the CloudFormation template' do
154
- run_command_and_stop 'cfndsl template.rb --ruby params.rb'
155
- expect(last_command_started).to have_output_on_stdout('{"AWSTemplateFormatVersion":"2010-09-09","Description":"ruby"}')
156
- end
157
-
158
- it 'gives a deprecation warning and does not interpolate if bindings are disabled' do
159
- run_command_and_stop 'cfndsl template.rb --ruby params.rb --disable-binding --verbose'
160
- deprecation_warning = /Interpreting Ruby files was disabled\. .*params.rb will not be read/
161
- expect(last_command_started).to have_output_on_stderr(deprecation_warning)
162
- expect(last_command_started).to have_output_on_stdout('{"AWSTemplateFormatVersion":"2010-09-09","Description":"default"}')
163
- end
164
- end
165
-
166
131
  context 'cfndsl FILE --define VARIABLE=VALUE' do
167
132
  it 'interpolates the command line variables in the CloudFormation template' do
168
133
  run_command "cfndsl template.rb --define \"DESC='cli'\""
@@ -175,15 +140,12 @@ describe 'cfndsl', type: :aruba do
175
140
 
176
141
  it 'displays the variables as they are interpolated in the CloudFormation template' do
177
142
  run_command_and_stop 'cfndsl template.rb --yaml params.yaml --verbose'
178
- verbose = %r{The creation of constants as config is deprecated!
179
- Please switch to the #external_parameters method within your templates to access variables
180
- See https://github.com/cfndsl/cfndsl/issues/170
181
- Use the --disable-binding flag to suppress this message
182
- Using specification file .*\.json
183
- Loading YAML file .*params\.yaml
184
- Setting local variable DESC to yaml
185
- Loading template file .*template\.rb
186
- Writing to STDOUT}
143
+ verbose = /
144
+ Using \s specification \s file .* \.json \n
145
+ Loading \s YAML \s file \s .* params\.yaml \n
146
+ Loading \s template \s file \s .* template.rb \n
147
+ Writing \s to \s STDOUT
148
+ /x
187
149
  template = '{"AWSTemplateFormatVersion":"2010-09-09","Description":"yaml"}'
188
150
  expect(last_command_started).to have_output_on_stderr(verbose)
189
151
  expect(last_command_started).to have_output_on_stdout(template)
@@ -4,4 +4,237 @@ require 'spec_helper'
4
4
 
5
5
  describe CfnDsl::CloudFormationTemplate do
6
6
  it_behaves_like 'an orchestration template'
7
+
8
+ context '#validate' do
9
+ it 'returns self if the template is empty' do
10
+ # TODO: Strictly Cloudformation requires at least one resource, but this is not validated yet.
11
+ expect(subject.validate).to equal(subject)
12
+ end
13
+
14
+ context 'resources' do
15
+ it 'returns self if there are valid Refs to parameters' do
16
+ subject.Parameter('TestParameter').Type('String')
17
+ r = subject.Resource(:TestResource)
18
+ r.Type('Custom-TestType')
19
+ r.Property(:AProperty, r.Ref(:TestParameter))
20
+ expect(subject.validate).to equal(subject)
21
+ end
22
+
23
+ it 'returns self if there are valid Refs to other resources' do
24
+ tr = subject.Resource(:TestResource)
25
+ tr.Type('Custom-TestType')
26
+ tr.Property(:AProperty, tr.Ref(:TestResource2))
27
+
28
+ t2 = subject.Resource('TestResource2')
29
+ t2.Type('Custom-TestType')
30
+ expect(subject.validate).to equal(subject)
31
+ end
32
+
33
+ it 'returns self if there are valid Fn::GetAtt references to other resources' do
34
+ tr = subject.Resource(:TestResource)
35
+ tr.Type('Custom-TestType')
36
+ tr.Property(:AProperty, tr.FnGetAtt(:TestResource2, :AnAttribute))
37
+
38
+ t2 = subject.Resource('TestResource2')
39
+ t2.Type('Custom-TestType')
40
+ expect(subject.validate).to equal(subject)
41
+ end
42
+
43
+ it 'returns self if there are valid DependsOn to other resources' do
44
+ tr = subject.Resource(:TestResource)
45
+ tr.Type('Custom-TestType')
46
+ tr.DependsOn(:TestResource2)
47
+
48
+ t2 = subject.Resource('TestResource2')
49
+ t2.Type('Custom-TestType')
50
+ expect(subject.validate).to equal(subject)
51
+ end
52
+
53
+ it 'raises CfnDsl::Error if references a non existent condition' do
54
+ tr = subject.Resource(:TestResource)
55
+ tr.Condition('NoCondition')
56
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /TestResource.*NoCondition/)
57
+ end
58
+
59
+ it 'raises CfnDsl::Error if there are invalid Refs' do
60
+ tr = subject.Resource(:TestResource)
61
+ tr.Type('Custom-TestType')
62
+ tr.Property(:AProperty, tr.Ref(:TestResource2))
63
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /^Invalid Reference:.*TestResource.*TestResource2/)
64
+ end
65
+
66
+ it 'raises CfnDsl::Error if there are invalid Fn::GetAtt references' do
67
+ tr = subject.Resource(:TestResource)
68
+ tr.Type('Custom-TestType')
69
+ tr.Property(:AProperty, tr.FnGetAtt(:TestResource2, :AnAttribute))
70
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /^Invalid Reference:.*TestResource.*TestResource2/)
71
+ end
72
+
73
+ it 'raises CfnDsl::Error if there are invalid Fn::Sub attribute references' do
74
+ tr = subject.Resource(:TestResource)
75
+ tr.Type('Custom-TestType')
76
+ tr.Property(:AProperty, tr.FnBase64(tr.FnSub('${TestResource2.AnAttribute}')))
77
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /^Invalid Reference:.*TestResource.*TestResource2/)
78
+ end
79
+
80
+ it 'raises CfnDsl::Error if there are invalid Fn::Sub references' do
81
+ tr = subject.Resource(:TestResource)
82
+ tr.Type('Custom-TestType')
83
+ tr.Property(:AProperty, tr.FnBase64(tr.FnSub('${TestResource2}')))
84
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /^Invalid Reference:.*TestResource.*TestResource2/)
85
+ end
86
+
87
+ it 'raises CfnDsl::Error if there are invalid DependsOn' do
88
+ tr = subject.Resource(:TestResource)
89
+ tr.Type('Custom-TestType')
90
+ tr.DependsOn(['TestResource2'])
91
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /^Invalid Reference:.*TestResource.*TestResource2/)
92
+ end
93
+
94
+ it 'raises CfnDsl::Error if a resource explicitly DependsOn itself' do
95
+ tr = subject.Resource(:TestResource)
96
+ tr.Type('Custom-TestType')
97
+ tr.DependsOn(['TestResource'])
98
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /TestResource.*references itself/)
99
+ end
100
+
101
+ it 'raises CfnDsl::Error if a resource Refs itself' do
102
+ tr = subject.Resource(:TestResource)
103
+ tr.Type('Custom-TestType')
104
+ tr.Property(:AProperty, tr.Ref(:TestResource))
105
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /TestResource.*itself/i)
106
+ end
107
+
108
+ it 'raises CfnDsl::Error if a resource references itself in Fn::GetAtt' do
109
+ tr = subject.Resource(:TestResource)
110
+ tr.Type('Custom-TestType')
111
+ tr.Property(:AProperty, tr.FnGetAtt(:TestResource, :AnAttr))
112
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /TestResource.*itself/i)
113
+ end
114
+
115
+ it 'raises CfnDsl::Error if a resourcs references itself in Fn::Sub expression' do
116
+ tr = subject.Resource(:TestResource)
117
+ tr.Type('Custom-TestType')
118
+ tr.Property(:AProperty, tr.FnSub('${TestResource}'))
119
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /TestResource.*itself/i)
120
+ end
121
+
122
+ it 'raises CfnDsl::Error if there are cyclic DependsOn references' do
123
+ tr = subject.Resource(:ResourceOne)
124
+ tr.Type('Custom-TestType')
125
+ tr.DependsOn(:ResourceTwo)
126
+
127
+ t2 = subject.Resource('ResourceTwo')
128
+ t2.Type('Custom-TestType')
129
+ t2.DependsOn(:ResourceOne)
130
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /cyclic.*ResourceTwo.*ResourceOne/i)
131
+ end
132
+
133
+ it 'raises CfnDsl::Error if there are cyclic Refs' do
134
+ tr = subject.Resource(:TestResourceOne)
135
+ tr.Type('Custom-TestType')
136
+ tr.Property(:AProperty, tr.Ref(:TestResourceTwo))
137
+
138
+ t2 = subject.Resource('TestResourceTwo')
139
+ t2.Type('Custom-TestType')
140
+ t2.DependsOn('TestResourceOne')
141
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /cyclic.*Two.*One/i)
142
+ end
143
+
144
+ it 'raises CfnDsl::Error if there are cyclic Fn::GetAtt references' do
145
+ tr = subject.Resource(:TestResource1)
146
+ tr.Property(:AProperty, tr.Ref(:TestResource2))
147
+
148
+ t2 = subject.Resource('TestResource2')
149
+ t2.DependsOn('TestResource3')
150
+
151
+ t3 = subject.Resource('TestResource3')
152
+ t3.Property(:OtherProperty, subject.FnGetAtt('TestResource1', :OtherAttribute))
153
+
154
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /cyclic.*3.*2.*1/i)
155
+ end
156
+
157
+ it 'raises CfnDsl::Error if there are cyclic Fn::Sub references' do
158
+ subject.Resource(:TestResource1)
159
+
160
+ t2 = subject.Resource('TestResource2')
161
+ t2.DependsOn(%w[TestResource3 TestResource1])
162
+
163
+ t3 = subject.Resource('TestResource3')
164
+ t3.Property(:OtherProperty, subject.FnSub('SomeValue ${TestResource2}'))
165
+
166
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /cyclic*.3?.*2/i)
167
+ end
168
+ end
169
+
170
+ context 'conditions' do
171
+ it 'returns self if there are valid condition references' do
172
+ subject.Parameter('TestParameter').Type('String')
173
+ subject.Condition(:TestCondition, subject.FnEquals(subject.Ref(:TestParameter), 'testvalue'))
174
+ expect(subject.validate).to equal(subject)
175
+ end
176
+
177
+ it 'raises CfnDsl::Error if invalid ref in condition' do
178
+ subject.Condition(:TestCondition, subject.FnEquals(subject.Ref(:NoParam), 'testvalue'))
179
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /^Invalid Reference:.*TestCondition.*NoParam/)
180
+ end
181
+
182
+ it 'raises CfnDsl::Error if null value in Condition' do
183
+ subject.Condition(:TestCondition, subject.FnEquals(nil, 'testvalue'))
184
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /Condition.*TestCondition.*null/)
185
+ end
186
+
187
+ it 'raises CfnDsl::Error if null value deep in Condition' do
188
+ subject.Condition(:TestCondition, subject.FnEquals({ Condition: nil }, 'testvalue'))
189
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /Condition.*TestCondition.*null/)
190
+ end
191
+
192
+ # Note cycles in conditions tested in cfndsl_spec.rb
193
+ end
194
+
195
+ context 'outputs' do
196
+ it 'returns self if there are valid Refs to parameters' do
197
+ subject.Parameter('TestParameter').Type('String')
198
+ subject.Output('TestOutput').Value(subject.Ref(:TestParameter))
199
+ expect(subject.validate).to equal(subject)
200
+ end
201
+
202
+ it 'returns self if there are valid Refs to resources' do
203
+ subject.Resource(:TestResource)
204
+ subject.Output('TestResourceOutput').Value(subject.Ref(:TestResource))
205
+ expect(subject.validate).to equal(subject)
206
+ end
207
+
208
+ it 'returns self if there are valid Fn::GetAtt references to resources' do
209
+ subject.Resource(:TestResource)
210
+ subject.Output('TestResourceOutput').Value(subject.FnGetAtt(:TestResource, :AnAtt))
211
+ expect(subject.validate).to equal(subject)
212
+ end
213
+
214
+ it 'raises CfnDsl::Error if references a non existent condition' do
215
+ subject.Output(:TestOutput).Condition('NoCondition')
216
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /TestOutput.*NoCondition/)
217
+ end
218
+
219
+ it 'raises CfnDsl::Error if there are invalid Refs' do
220
+ subject.Output('TestResourceOutput').Value(subject.Ref(:TestResource))
221
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /Outputs.*TestResource/)
222
+ end
223
+
224
+ it 'raises CfnDsl::Error if there are invalid Fn::GetAtt references' do
225
+ subject.Output('TestResourceOutput').Value(subject.FnGetAtt(:TestResource, :Attr))
226
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /Outputs.*TestResource/)
227
+ end
228
+
229
+ it 'raises CfnDsl::Error if there are invalid Fn::Sub attribute references' do
230
+ subject.Output('TestResourceOutput').Value(subject.FnSub('prefix ${SomeRef.attr}suffix'))
231
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /Outputs.*TestResource/)
232
+ end
233
+
234
+ it 'raises CfnDsl::Error if there are invalid Fn::Sub references' do
235
+ subject.Output('TestResourceOutput').Value(subject.FnSub('prefix ${SomeRef}suffix'))
236
+ expect { subject.validate }.to raise_error(CfnDsl::Error, /Outputs.*TestResource/)
237
+ end
238
+ end
239
+ end
7
240
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe CfnDsl::ConditionDefinition do
6
+ let(:template) { CfnDsl::OrchestrationTemplate.new }
7
+ let(:target) { File.read("#{File.dirname(__FILE__)}/fixtures/condition-assertion.json") }
8
+
9
+ context '#Condition' do
10
+ it 'formats correctly' do
11
+ template.declare do
12
+ Condition(:TestConditionTwo, FnNot(Condition(:TestConditionOne)))
13
+ Resource(:TestResource) do
14
+ Condition(:TestConditionTwo)
15
+ end
16
+ Output(:TestOutput) do
17
+ Condition(:TestConditionOne)
18
+ end
19
+ end
20
+ json = template.to_json
21
+ expect(json).to eq(target)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ class TemplateBuilder
6
+ include CfnDsl::CloudFormation
7
+ end
8
+
9
+ describe TemplateBuilder do
10
+ it 'includes Functions' do
11
+ expect(subject.FnSub('Substitution')).to be_an_instance_of(CfnDsl::Fn)
12
+ end
13
+
14
+ context('#CloudFormation') do
15
+ it 'returns a CloudFormationTemplate' do
16
+ expect(subject.CloudFormation('A Template')).to be_an_instance_of(CfnDsl::CloudFormationTemplate)
17
+ end
18
+ end
19
+ end
@@ -74,22 +74,9 @@ describe CfnDsl::ExternalParameters do
74
74
  end
75
75
  end
76
76
 
77
- context '#add_to_binding' do
78
- it 'defines the parameters as variables in the current binding' do
79
- current = binding
80
- subject.add_to_binding(current, nil)
81
- expect(current).to be_local_variable_defined(:username)
82
- end
83
-
84
- it 'prints to a logstream if given' do
85
- logstream = StringIO.new
86
- subject.add_to_binding(binding, logstream)
87
- logstream.rewind
88
- expect(logstream.read).to match('Setting local variable username to Wiz Khalifa')
89
- end
90
- end
77
+ context '#load_file JSON', type: :aruba do
78
+ before { write_file('params.json', '{"reminder":"You Know What It Is"}') }
91
79
 
92
- context '#load_file JSON' do
93
80
  it 'merges a JSON file as parameters' do
94
81
  subject.load_file(params_json)
95
82
  expect(subject[:reminder]).to eq('You Know What It Is')
@@ -0,0 +1 @@
1
+ {"AWSTemplateFormatVersion":"2010-09-09","Conditions":{"TestConditionTwo":{"Fn::Not":[{"Condition":"TestConditionOne"}]}},"Resources":{"TestResource":{"Condition":"TestConditionTwo"}},"Outputs":{"TestOutput":{"Condition":"TestConditionOne"}}}
@@ -30,7 +30,8 @@ CloudFormation do
30
30
  FnAnd(
31
31
  [
32
32
  FnEquals(Ref('One'), 'Test'),
33
- FnNot(FnEquals(Ref('Two'), 'Test'))
33
+ FnNot(FnEquals(Ref('Two'), 'Test')),
34
+ Condition('OneIsTest')
34
35
  ]
35
36
  ))
36
37