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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b15b3c213315ed742f352355a160fef24a34caf9
4
- data.tar.gz: eb14df333ca82b033edfc5f9c01c86bafd6f52fa
3
+ metadata.gz: a11f29dffaf1e90a64925175605665a5e4df4941
4
+ data.tar.gz: 88c50e0aa3172bdf01b200db843c1925848317fa
5
5
  SHA512:
6
- metadata.gz: d246665dff0d61b0a92199c2eef070f82e2f7fd5c1702552c3998675a809e40b30d7d4dfd927804331c7cf9da3897f0c7b7bcfa76a5a6a34c8000bea2e5a9597
7
- data.tar.gz: 20ad8cb58f3bd94d8bf4639236517c0555598a181490000376f4ecf7e66444a9836da7713a2cfe480c9b56d6023270cfbc1c183a96c27ef4f2d8e8d9bf5f46f8
6
+ metadata.gz: fcf34d371bccdb4164ff7483f618464ce15f755ca11178e26f52ec191147718dc8efd1daea2e87d760353811290f2fa74fd104a8f1a90a4da459185431f7ee87
7
+ data.tar.gz: 35b55ccd50f0bdee6b52422606c1ad0c167bc8c2afa9e725d914a7fede723ae0f49621fefa3197f75351335a2fab22206e914397a4f9c2e4888545107a59d06c
@@ -37,4 +37,5 @@ Gem::Specification.new do |gem|
37
37
  gem.add_runtime_dependency 'bundler'
38
38
  gem.add_runtime_dependency 'aws-sdk'
39
39
  gem.add_runtime_dependency 'diffy'
40
+ gem.add_runtime_dependency 'highline'
40
41
  end
@@ -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
- # region and credentials are loaded from the environment; see http://docs.aws.amazon.com/sdkforruby/api/Aws/CloudFormation/Client.html
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 cfn(template)
73
- aws_cfn = AwsCfn.new
74
- cfn_client = aws_cfn.cfn_client
75
-
76
- action = ARGV[0]
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" => "validate",
79
- "cfn-create-stack" => "create",
80
- "cfn-update-stack" => "update"
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; use '#{replacement}' instead"
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 %w(expand diff validate create update).include? action
88
- $stderr.puts "usage: #{$PROGRAM_NAME} <expand|diff|validate|create|update>"
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
- exit(valid.successful?)
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
@@ -15,7 +15,7 @@
15
15
  module Cfn
16
16
  module Ruby
17
17
  module Dsl
18
- VERSION = "1.0.1"
18
+ VERSION = "1.0.3"
19
19
  end
20
20
  end
21
21
  end
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.1
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-06-19 00:00:00.000000000 Z
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
- - ".gitignore"
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.2.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