cloudformation-ruby-dsl 1.0.1 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
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