aws-cfn-dsl 0.6.0 → 0.7.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.
@@ -0,0 +1,59 @@
1
+ module Aws
2
+ module Cfn
3
+ module Dsl
4
+ module Simplify
5
+
6
+ def simplify(val,start=false)
7
+ logStep "Simplify a block ..." if start
8
+ if val.is_a?(Hash)
9
+ val = Hash[val.map { |k,v| [k, simplify(v)] }]
10
+ if val.length != 1
11
+ val
12
+ else
13
+ k, v = val.entries[0]
14
+ case @config[:functions]
15
+ when @on_yes_regex then
16
+ case
17
+ # CloudFormation functions
18
+ when k == 'Fn::Base64'
19
+ FnCall.new 'base64', [v], true
20
+ when k == 'Fn::FindInMap'
21
+ FnCall.new 'find_in_map', v
22
+ when k == 'Fn::GetAtt'
23
+ FnCall.new 'get_att', v
24
+ when k == 'Fn::GetAZs'
25
+ FnCall.new 'get_azs', v != '' ? [v] : []
26
+ when k == 'Fn::Join'
27
+ FnCall.new 'join', [v[0]] + v[1], true
28
+ when k == 'Fn::Select'
29
+ FnCall.new 'select', v
30
+ when k == 'Ref' && v == 'AWS::Region'
31
+ FnCall.new 'aws_region', []
32
+ when k == 'Ref' && v == 'AWS::StackName'
33
+ FnCall.new 'aws_stack_name', []
34
+ # CloudFormation internal references
35
+ when k == 'Ref'
36
+ FnCall.new 'ref', [v]
37
+ else
38
+ val
39
+ end
40
+ else
41
+ val
42
+ end
43
+ end
44
+ elsif val.is_a?(Array)
45
+ val.map { |v| simplify(v) }
46
+ else
47
+ val
48
+ end
49
+ end
50
+
51
+
52
+ def self.included(includer)
53
+
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -91,170 +91,6 @@ module Aws
91
91
  end
92
92
  end
93
93
 
94
- def exec!(argv=ARGV)
95
- @opts = Slop.parse(help: true) do
96
- banner "usage: #{$PROGRAM_NAME} <expand|diff|validate|create|update|delete>"
97
- on :o, :output=, 'The template file to save this DSL expansion to', as: String
98
- end
99
-
100
- action = argv[0] || 'expand'
101
- unless %w(expand diff validate create update delete).include? action
102
- $stderr.puts "usage: #{$PROGRAM_NAME} <expand|diff|validate|create|update|delete>"
103
- exit(2)
104
- end
105
- unless (argv & %w(--template-file --template-url)).empty?
106
- $stderr.puts "#{File.basename($PROGRAM_NAME)}: The --template-file and --template-url command-line options are not allowed. (You are running the template itself right now ... !)"
107
- exit(2)
108
- end
109
-
110
- # Find parameters where extension attribute :Immutable is true then remove it from the
111
- # cfn template since we can't pass it to CloudFormation.
112
- immutable_parameters = excise_parameter_attribute!(:Immutable)
113
-
114
- # Tag CloudFormation stacks based on :Tags defined in the template
115
- cfn_tags = excise_tags!
116
- # The command line string looks like: --tag "Key=key; Value=value" --tag "Key2=key2; Value2=value"
117
- cfn_tags_options = cfn_tags.sort.map { |tag| ["--tag", "Key=%s; Value=%s" % tag.split('=')] }.flatten
118
-
119
- # example: <template.rb> cfn-create-stack my-stack-name --parameters "Env=prod" --region eu-west-1
120
- # Execute the AWS CLI cfn-cmd command to validate/create/update a CloudFormation stack.
121
- if action == 'diff' or (action == 'expand' and not nopretty)
122
- template_string = JSON.pretty_generate(self)
123
- else
124
- template_string = JSON.generate(self)
125
- end
126
-
127
- if action == 'expand'
128
- # Write the pretty-printed JSON template to stdout and exit. [--nopretty] option writes output with minimal whitespace
129
- # example: <template.rb> expand --parameters "Env=prod" --region eu-west-1 --nopretty
130
- if @opts[:output]
131
- dest = @opts[:output]
132
- if File.directory? dest
133
- file = File.basename $PROGRAM_NAME
134
- file.gsub!(%r'\.rb', '.json')
135
- dest = File.join dest, file
136
- end
137
- IO.write(dest, template_string)
138
- else
139
- puts template_string
140
- end
141
- exit(true)
142
- end
143
-
144
- temp_file = File.absolute_path("#{$PROGRAM_NAME}.expanded.json")
145
- File.write(temp_file, template_string)
146
-
147
- cmdline = ['cfn-cmd'] + argv + ['--template-file', temp_file] + cfn_tags_options
148
-
149
- case action
150
- when 'diff'
151
- # example: <template.rb> diff my-stack-name --parameters "Env=prod" --region eu-west-1
152
- # Diff the current template for an existing stack with the expansion of this template.
153
-
154
- # The --parameters and --tag options were used to expand the template but we don't need them anymore. Discard.
155
- _, cfn_options = extract_options(argv[1..-1], %w(), %w(--parameters --tag))
156
-
157
- # Separate the remaining command-line options into options for 'cfn-cmd' and options for 'diff'.
158
- cfn_options, diff_options = extract_options(cfn_options, %w(),
159
- %w(--stack-name --region --parameters --connection-timeout -I --access-key-id -S --secret-key -K --ec2-private-key-file-path -U --url))
160
-
161
- # If the first argument is a stack name then shift it from diff_options over to cfn_options.
162
- if diff_options[0] && !(/^-/ =~ diff_options[0])
163
- cfn_options.unshift(diff_options.shift)
164
- end
165
-
166
- # Run CloudFormation commands to describe the existing stack
167
- cfn_options_string = cfn_options.map { |arg| "'#{arg}'" }.join(' ')
168
- old_template_raw = exec_capture_stdout("cfn-cmd cfn-get-template #{cfn_options_string}")
169
- # ec2 template output is not valid json: TEMPLATE "<json>\n"\n
170
- old_template_object = JSON.parse(old_template_raw[11..-3])
171
- old_template_string = JSON.pretty_generate(old_template_object)
172
- old_stack_attributes = exec_describe_stack(cfn_options_string)
173
- old_tags_string = old_stack_attributes["TAGS"]
174
- old_parameters_string = old_stack_attributes["PARAMETERS"]
175
-
176
- # Sort the tag strings alphabetically to make them easily comparable
177
- old_tags_string = (old_tags_string || '').split(';').sort.map { |tag| %Q(TAG "#{tag}"\n) }.join
178
- tags_string = cfn_tags.sort.map { |tag| "TAG \"#{tag}\"\n" }.join
179
-
180
- # Sort the parameter strings alphabetically to make them easily comparable
181
- old_parameters_string = (old_parameters_string || '').split(';').sort.map { |param| %Q(PARAMETER "#{param}"\n) }.join
182
- parameters_string = parameters.sort.map { |key, value| "PARAMETER \"#{key}=#{value}\"\n" }.join
183
-
184
- # Diff the expanded template with the template from CloudFormation.
185
- old_temp_file = File.absolute_path("#{$PROGRAM_NAME}.current.json")
186
- new_temp_file = File.absolute_path("#{$PROGRAM_NAME}.expanded.json")
187
- File.write(old_temp_file, old_tags_string + old_parameters_string + old_template_string)
188
- File.write(new_temp_file, tags_string + parameters_string + template_string)
189
-
190
- # Compare templates
191
- system(*["diff"] + diff_options + [old_temp_file, new_temp_file])
192
-
193
- File.delete(old_temp_file)
194
- File.delete(new_temp_file)
195
-
196
- exit(true)
197
-
198
- when 'cfn-validate-template'
199
- # The cfn-validate-template command doesn't support --parameters so remove it if it was provided for template expansion.
200
- _, cmdline = extract_options(cmdline, %w(), %w(--parameters --tag))
201
-
202
- when 'cfn-update-stack'
203
- # Pick out the subset of cfn-update-stack options that apply to cfn-describe-stacks.
204
- cfn_options, other_options = extract_options(argv[1..-1], %w(),
205
- %w(--stack-name --region --connection-timeout -I --access-key-id -S --secret-key -K --ec2-private-key-file-path -U --url))
206
-
207
- # If the first argument is a stack name then shift it over to cfn_options.
208
- if other_options[0] && !(/^-/ =~ other_options[0])
209
- cfn_options.unshift(other_options.shift)
210
- end
211
-
212
- # Run CloudFormation command to describe the existing stack
213
- cfn_options_string = cfn_options.map { |arg| "'#{arg}'" }.join(' ')
214
- old_stack_attributes = exec_describe_stack(cfn_options_string)
215
-
216
- # If updating a stack and some parameters are marked as immutable, fail if the new parameters don't match the old ones.
217
- if not immutable_parameters.empty?
218
- old_parameters_string = old_stack_attributes["PARAMETERS"]
219
- old_parameters = Hash[(old_parameters_string || '').split(';').map { |pair| pair.split('=', 2) }]
220
- new_parameters = parameters
221
-
222
- immutable_parameters.sort.each do |param|
223
- if old_parameters[param].to_s != new_parameters[param].to_s
224
- $stderr.puts "Error: cfn-update-stack may not update immutable parameter " +
225
- "'#{param}=#{old_parameters[param]}' to '#{param}=#{new_parameters[param]}'."
226
- exit(false)
227
- end
228
- end
229
- end
230
-
231
- # Tags are immutable in CloudFormation. The cfn-update-stack command doesn't support --tag options, so remove
232
- # the argument (if it exists) and validate against the existing stack to ensure tags haven't changed.
233
- # Compare the sorted arrays for an exact match
234
- old_cfn_tags = old_stack_attributes['TAGS'].split(';').sort rescue [] # Use empty Array if .split fails
235
- if cfn_tags != old_cfn_tags
236
- $stderr.puts "CloudFormation stack tags do not match and cannot be updated. You must either use the same tags or create a new stack." +
237
- "\n" + (old_cfn_tags - cfn_tags).map {|tag| "< #{tag}" }.join("\n") +
238
- "\n" + "---" +
239
- "\n" + (cfn_tags - old_cfn_tags).map {|tag| "> #{tag}"}.join("\n")
240
- exit(false)
241
- end
242
- _, cmdline = extract_options(cmdline, %w(), %w(--tag))
243
- end
244
-
245
- # Execute command cmdline
246
- unless system(*cmdline)
247
- $stderr.puts "\nExecution of 'cfn-cmd' failed. To facilitate debugging, the generated JSON template " +
248
- "file was not deleted. You may delete the file manually if it isn't needed: #{temp_file}"
249
- exit(false)
250
- end
251
-
252
- File.delete(temp_file)
253
-
254
- exit(true)
255
- end
256
-
257
-
258
94
  end
259
95
  end
260
96
  end
@@ -1,7 +1,7 @@
1
1
  module Aws
2
2
  module Cfn
3
3
  module Dsl
4
- VERSION = "0.6.0"
4
+ VERSION = '0.7.0'
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,77 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-cfn-dsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christo DeLange
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-28 00:00:00.000000000 Z
11
+ date: 2014-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.2'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.2.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - ! '>='
27
+ - - "~>"
25
28
  - !ruby/object:Gem::Version
26
- version: '0'
29
+ version: '1.2'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.2.0
27
33
  - !ruby/object:Gem::Dependency
28
- name: json
34
+ name: psych
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - ! '>='
37
+ - - ">="
32
38
  - !ruby/object:Gem::Version
33
39
  version: '0'
34
40
  type: :runtime
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
- - - ! '>='
44
+ - - ">="
39
45
  - !ruby/object:Gem::Version
40
46
  version: '0'
41
47
  - !ruby/object:Gem::Dependency
42
- name: cloudformation-ruby-dsl
48
+ name: json
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
- - - ~>
46
- - !ruby/object:Gem::Version
47
- version: '0.4'
48
- - - ! '>='
51
+ - - ">="
49
52
  - !ruby/object:Gem::Version
50
- version: 0.4.3
53
+ version: '0'
51
54
  type: :runtime
52
55
  prerelease: false
53
56
  version_requirements: !ruby/object:Gem::Requirement
54
57
  requirements:
55
- - - ~>
56
- - !ruby/object:Gem::Version
57
- version: '0.4'
58
- - - ! '>='
58
+ - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: 0.4.3
60
+ version: '0'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: slop
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - ! '>='
65
+ - - ">="
66
66
  - !ruby/object:Gem::Version
67
67
  version: '0'
68
68
  type: :runtime
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - ! '>='
72
+ - - ">="
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: cloudformation-ruby-dsl
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.4'
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 0.4.3
85
+ type: :runtime
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '0.4'
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 0.4.3
75
95
  description: Ruby DSL for creating Cloudformation templates
76
96
  email:
77
97
  - rubygems@dldinternet.com
@@ -80,7 +100,7 @@ executables:
80
100
  extensions: []
81
101
  extra_rdoc_files: []
82
102
  files:
83
- - .gitignore
103
+ - ".gitignore"
84
104
  - Gemfile
85
105
  - LICENSE
86
106
  - LICENSE.txt
@@ -93,6 +113,12 @@ files:
93
113
  - lib/aws/cfn/dsl/base.rb
94
114
  - lib/aws/cfn/dsl/fncall.rb
95
115
  - lib/aws/cfn/dsl/main.rb
116
+ - lib/aws/cfn/dsl/mixins/dsl.rb
117
+ - lib/aws/cfn/dsl/mixins/maintainer.rb
118
+ - lib/aws/cfn/dsl/mixins/options.rb
119
+ - lib/aws/cfn/dsl/mixins/output.rb
120
+ - lib/aws/cfn/dsl/mixins/prettyprint.rb
121
+ - lib/aws/cfn/dsl/mixins/simplify.rb
96
122
  - lib/aws/cfn/dsl/template.rb
97
123
  - lib/aws/cfn/dsl/version.rb
98
124
  homepage: ''
@@ -105,12 +131,12 @@ require_paths:
105
131
  - lib
106
132
  required_ruby_version: !ruby/object:Gem::Requirement
107
133
  requirements:
108
- - - ! '>='
134
+ - - ">="
109
135
  - !ruby/object:Gem::Version
110
136
  version: '0'
111
137
  required_rubygems_version: !ruby/object:Gem::Requirement
112
138
  requirements:
113
- - - ! '>='
139
+ - - ">="
114
140
  - !ruby/object:Gem::Version
115
141
  version: '0'
116
142
  requirements: []