cloudformation-ruby-dsl 1.0.1 → 1.0.3
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/cloudformation-ruby-dsl.gemspec +1 -0
- data/lib/cloudformation-ruby-dsl/cfntemplate.rb +156 -14
- data/lib/cloudformation-ruby-dsl/version.rb +1 -1
- metadata +30 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a11f29dffaf1e90a64925175605665a5e4df4941
|
4
|
+
data.tar.gz: 88c50e0aa3172bdf01b200db843c1925848317fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fcf34d371bccdb4164ff7483f618464ce15f755ca11178e26f52ec191147718dc8efd1daea2e87d760353811290f2fa74fd104a8f1a90a4da459185431f7ee87
|
7
|
+
data.tar.gz: 35b55ccd50f0bdee6b52422606c1ad0c167bc8c2afa9e725d914a7fede723ae0f49621fefa3197f75351335a2fab22206e914397a4f9c2e4888545107a59d06c
|
@@ -27,15 +27,20 @@ require 'yaml'
|
|
27
27
|
require 'erb'
|
28
28
|
require 'aws-sdk'
|
29
29
|
require 'diffy'
|
30
|
+
require 'highline/import'
|
30
31
|
|
31
32
|
############################# AWS SDK Support
|
32
33
|
|
33
34
|
class AwsCfn
|
34
35
|
attr_accessor :cfn_client_instance
|
35
36
|
|
37
|
+
def initialize(**args)
|
38
|
+
Aws.config[:region] = args[:region] if args.key?(:region)
|
39
|
+
end
|
40
|
+
|
36
41
|
def cfn_client
|
37
42
|
if @cfn_client_instance == nil
|
38
|
-
#
|
43
|
+
# credentials are loaded from the environment; see http://docs.aws.amazon.com/sdkforruby/api/Aws/CloudFormation/Client.html
|
39
44
|
@cfn_client_instance = Aws::CloudFormation::Client.new(
|
40
45
|
# we don't validate parameters because the aws-ruby-sdk gets a number parameter and expects it to be a string and fails the validation
|
41
46
|
# see: https://github.com/aws/aws-sdk-ruby/issues/848
|
@@ -46,6 +51,20 @@ class AwsCfn
|
|
46
51
|
end
|
47
52
|
end
|
48
53
|
|
54
|
+
# utility class to deserialize Structs as JSON
|
55
|
+
# borrowed from http://ruhe.tumblr.com/post/565540643/generate-json-from-ruby-struct
|
56
|
+
class Struct
|
57
|
+
def to_map
|
58
|
+
map = Hash.new
|
59
|
+
self.members.each { |m| map[m] = self[m] }
|
60
|
+
map
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_json(*a)
|
64
|
+
to_map.to_json(*a)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
49
68
|
############################# Command-line support
|
50
69
|
|
51
70
|
# Parse command-line arguments and return the parameters and region
|
@@ -69,25 +88,54 @@ def parse_args
|
|
69
88
|
[stack_name, parameters, region, nopretty]
|
70
89
|
end
|
71
90
|
|
72
|
-
def
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
91
|
+
def validate_action(action)
|
92
|
+
valid = %w[
|
93
|
+
expand
|
94
|
+
diff
|
95
|
+
validate
|
96
|
+
create
|
97
|
+
update
|
98
|
+
cancel-update
|
99
|
+
delete
|
100
|
+
describe
|
101
|
+
describe-resource
|
102
|
+
get-template
|
103
|
+
]
|
104
|
+
removed = %w[
|
105
|
+
cfn-list-stack-resources
|
106
|
+
cfn-list-stacks
|
107
|
+
]
|
77
108
|
deprecated = {
|
78
|
-
"cfn-validate-template"
|
79
|
-
"cfn-create-stack"
|
80
|
-
"cfn-update-stack"
|
109
|
+
"cfn-validate-template" => "validate",
|
110
|
+
"cfn-create-stack" => "create",
|
111
|
+
"cfn-update-stack" => "update",
|
112
|
+
"cfn-cancel-update-stack" => "cancel-update",
|
113
|
+
"cfn-delete-stack" => "delete",
|
114
|
+
"cfn-describe-stack-events" => "describe",
|
115
|
+
"cfn-describe-stack-resources" => "describe",
|
116
|
+
"cfn-describe-stack-resource" => "describe-resource",
|
117
|
+
"cfn-get-template" => "get-template"
|
81
118
|
}
|
82
119
|
if deprecated.keys.include? action
|
83
120
|
replacement = deprecated[action]
|
84
|
-
$stderr.puts "WARNING: '#{action}' is deprecated and will be removed
|
121
|
+
$stderr.puts "WARNING: '#{action}' is deprecated and will be removed in a future version. Please use '#{replacement}' instead."
|
85
122
|
action = replacement
|
86
123
|
end
|
87
|
-
unless
|
88
|
-
|
124
|
+
unless valid.include? action
|
125
|
+
if removed.include? action
|
126
|
+
$stderr.puts "ERROR: native command #{action} is no longer supported by cloudformation-ruby-dsl."
|
127
|
+
end
|
128
|
+
$stderr.puts "usage: #{$PROGRAM_NAME} <#{valid.join('|')}>"
|
89
129
|
exit(2)
|
90
130
|
end
|
131
|
+
action
|
132
|
+
end
|
133
|
+
|
134
|
+
def cfn(template)
|
135
|
+
aws_cfn = AwsCfn.new(region: template.aws_region)
|
136
|
+
cfn_client = aws_cfn.cfn_client
|
137
|
+
|
138
|
+
action = validate_action( ARGV[0] )
|
91
139
|
|
92
140
|
# Find parameters where extension attribute :Immutable is true then remove it from the
|
93
141
|
# cfn template since we can't pass it to CloudFormation.
|
@@ -106,8 +154,10 @@ def cfn(template)
|
|
106
154
|
# Derive stack name from ARGV
|
107
155
|
_, options = extract_options(ARGV[1..-1], %w(--nopretty), %w(--stack-name --region --parameters --tag))
|
108
156
|
# If the first argument is not an option and stack_name is undefined, assume it's the stack name
|
157
|
+
# The second argument, if present, is the resource name used by the describe-resource command
|
109
158
|
if template.stack_name.nil?
|
110
159
|
stack_name = options.shift if options[0] && !(/^-/ =~ options[0])
|
160
|
+
resource_name = options.shift if options[0] && !(/^-/ =~ options[0])
|
111
161
|
else
|
112
162
|
stack_name = template.stack_name
|
113
163
|
end
|
@@ -201,14 +251,16 @@ def cfn(template)
|
|
201
251
|
when 'validate'
|
202
252
|
begin
|
203
253
|
valid = cfn_client.validate_template({template_body: template_string})
|
204
|
-
|
254
|
+
if valid.successful?
|
255
|
+
puts "Validation successful"
|
256
|
+
exit(true)
|
257
|
+
end
|
205
258
|
rescue Aws::CloudFormation::Errors::ValidationError => e
|
206
259
|
$stderr.puts "Validation error: #{e}"
|
207
260
|
exit(false)
|
208
261
|
end
|
209
262
|
|
210
263
|
when 'create'
|
211
|
-
|
212
264
|
begin
|
213
265
|
create_result = cfn_client.create_stack({
|
214
266
|
stack_name: stack_name,
|
@@ -226,6 +278,96 @@ def cfn(template)
|
|
226
278
|
exit(false)
|
227
279
|
end
|
228
280
|
|
281
|
+
when 'cancel-update'
|
282
|
+
begin
|
283
|
+
cancel_update_result = cfn_client.cancel_update_stack({stack_name: stack_name})
|
284
|
+
if cancel_update_result.successful?
|
285
|
+
$stderr.puts "Canceled updating stack #{stack_name}."
|
286
|
+
exit(true)
|
287
|
+
end
|
288
|
+
rescue Aws::CloudFormation::Errors::ServiceError => e
|
289
|
+
$stderr.puts "Failed to cancel updating stack: #{e}"
|
290
|
+
exit(false)
|
291
|
+
end
|
292
|
+
|
293
|
+
when 'delete'
|
294
|
+
begin
|
295
|
+
if HighLine.agree("Really delete #{stack_name} in #{cfn_client.config.region}? [Y/n]")
|
296
|
+
delete_result = cfn_client.delete_stack({stack_name: stack_name})
|
297
|
+
if delete_result.successful?
|
298
|
+
$stderr.puts "Deleted stack #{stack_name}."
|
299
|
+
exit(true)
|
300
|
+
end
|
301
|
+
else
|
302
|
+
$stderr.puts "Canceled deleting stack #{stack_name}."
|
303
|
+
exit(true)
|
304
|
+
end
|
305
|
+
rescue Aws::CloudFormation::Errors::ServiceError => e
|
306
|
+
$stderr.puts "Failed to delete stack: #{e}"
|
307
|
+
exit(false)
|
308
|
+
end
|
309
|
+
|
310
|
+
when 'describe'
|
311
|
+
begin
|
312
|
+
describe_stack = cfn_client.describe_stacks({stack_name: stack_name})
|
313
|
+
describe_stack_resources = cfn_client.describe_stack_resources({stack_name: stack_name})
|
314
|
+
if describe_stack.successful? and describe_stack_resources.successful?
|
315
|
+
stacks = {}
|
316
|
+
stack_resources = {}
|
317
|
+
describe_stack_resources.stack_resources.each { |stack_resource|
|
318
|
+
if stack_resources[stack_resource.stack_name].nil?
|
319
|
+
stack_resources[stack_resource.stack_name] = []
|
320
|
+
end
|
321
|
+
stack_resources[stack_resource.stack_name].push({
|
322
|
+
logical_resource_id: stack_resource.logical_resource_id,
|
323
|
+
physical_resource_id: stack_resource.physical_resource_id,
|
324
|
+
resource_type: stack_resource.resource_type,
|
325
|
+
timestamp: stack_resource.timestamp,
|
326
|
+
resource_status: stack_resource.resource_status,
|
327
|
+
resource_status_reason: stack_resource.resource_status_reason,
|
328
|
+
description: stack_resource.description,
|
329
|
+
})
|
330
|
+
}
|
331
|
+
describe_stack.stacks.each { |stack| stacks[stack.stack_name] = stack.to_map.merge!({resources: stack_resources[stack.stack_name]}) }
|
332
|
+
puts JSON.pretty_generate(stacks)
|
333
|
+
exit(true)
|
334
|
+
end
|
335
|
+
rescue Aws::CloudFormation::Errors::ServiceError => e
|
336
|
+
$stderr.puts "Failed describe stack #{stack_name}: #{e}"
|
337
|
+
exit(false)
|
338
|
+
end
|
339
|
+
|
340
|
+
when 'describe-resource'
|
341
|
+
begin
|
342
|
+
describe_stack_resource = cfn_client.describe_stack_resource({
|
343
|
+
stack_name: stack_name,
|
344
|
+
logical_resource_id: resource_name,
|
345
|
+
})
|
346
|
+
if describe_stack_resource.successful?
|
347
|
+
unless template.nopretty
|
348
|
+
puts JSON.pretty_generate(describe_stack_resource.stack_resource_detail)
|
349
|
+
else
|
350
|
+
puts JSON.generate(describe_stack_resource.stack_resource_detail)
|
351
|
+
end
|
352
|
+
exit(true)
|
353
|
+
end
|
354
|
+
rescue Aws::CloudFormation::Errors::ServiceError => e
|
355
|
+
$stderr.puts "Failed get stack resource details: #{e}"
|
356
|
+
exit(false)
|
357
|
+
end
|
358
|
+
|
359
|
+
when 'get-template'
|
360
|
+
begin
|
361
|
+
get_template_result = cfn_client.get_template({stack_name: stack_name})
|
362
|
+
if get_template_result.successful?
|
363
|
+
puts get_template_result.template_body
|
364
|
+
exit(true)
|
365
|
+
end
|
366
|
+
rescue Aws::CloudFormation::Errors::ServiceError => e
|
367
|
+
$stderr.puts "Failed get stack template: #{e}"
|
368
|
+
exit(false)
|
369
|
+
end
|
370
|
+
|
229
371
|
when 'update'
|
230
372
|
|
231
373
|
# Run CloudFormation command to describe the existing stack
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudformation-ruby-dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shawn Smith
|
@@ -15,76 +15,90 @@ authors:
|
|
15
15
|
autorequire:
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
|
-
date: 2015-
|
18
|
+
date: 2015-07-14 00:00:00.000000000 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: detabulator
|
22
22
|
requirement: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
type: :runtime
|
28
28
|
prerelease: false
|
29
29
|
version_requirements: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: json
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
type: :runtime
|
42
42
|
prerelease: false
|
43
43
|
version_requirements: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: bundler
|
50
50
|
requirement: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: aws-sdk
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
type: :runtime
|
70
70
|
prerelease: false
|
71
71
|
version_requirements: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
- !ruby/object:Gem::Dependency
|
77
77
|
name: diffy
|
78
78
|
requirement: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
type: :runtime
|
84
84
|
prerelease: false
|
85
85
|
version_requirements: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
name: highline
|
92
|
+
requirement: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
type: :runtime
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
88
102
|
- !ruby/object:Gem::Version
|
89
103
|
version: '0'
|
90
104
|
description: Ruby DSL library that provides a wrapper around the CloudFormation.
|
@@ -102,7 +116,7 @@ executables:
|
|
102
116
|
extensions: []
|
103
117
|
extra_rdoc_files: []
|
104
118
|
files:
|
105
|
-
-
|
119
|
+
- .gitignore
|
106
120
|
- Gemfile
|
107
121
|
- LICENSE.txt
|
108
122
|
- README.md
|
@@ -138,17 +152,17 @@ require_paths:
|
|
138
152
|
- bin
|
139
153
|
required_ruby_version: !ruby/object:Gem::Requirement
|
140
154
|
requirements:
|
141
|
-
- -
|
155
|
+
- - '>='
|
142
156
|
- !ruby/object:Gem::Version
|
143
157
|
version: '0'
|
144
158
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
159
|
requirements:
|
146
|
-
- -
|
160
|
+
- - '>='
|
147
161
|
- !ruby/object:Gem::Version
|
148
162
|
version: '0'
|
149
163
|
requirements: []
|
150
164
|
rubyforge_project:
|
151
|
-
rubygems_version: 2.
|
165
|
+
rubygems_version: 2.0.14
|
152
166
|
signing_key:
|
153
167
|
specification_version: 4
|
154
168
|
summary: Ruby DSL library that provides a wrapper around the CloudFormation. Written
|