stackup 0.2.0 → 0.3.0

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: a1cf0223b3b4769f8f08fb90e944721f19911105
4
- data.tar.gz: 809c9e18e59c5a0f92b37cd43c33dd30bbda1a1e
3
+ metadata.gz: ff49d4bc734ae1d359d0727319dfd73bafde86f9
4
+ data.tar.gz: 79b3705ee2af79a3a268e74b0a589ab2fbe8f107
5
5
  SHA512:
6
- metadata.gz: b38f0de16a9a86c5f037dae464562c27c246556e9db6bad43a0494b8c305ef159117bac4c275627dfac0284fd0666e1dbe688500829f84836f0c5bc66076ff6a
7
- data.tar.gz: 2a933cc8523a7e410e14b43345993157e070f0690286f9498bbe855201c17cd803ee7c98cd5169f2e6a1d8670f31d0a7dd39629f667c0ef5e3c848598fd01988
6
+ metadata.gz: 5ea9f0efed3b79d32fc842a5a726114a7b5d70731626c355072ebc510e0ff016361e34db90f225ff3ec952cd229411a5d4dabd505901831393c825bc8753d0b7
7
+ data.tar.gz: d6a435c32e8203114d2f671ac56e66764d044da56b6e1f5c20227a6b80cfc6de2b511079f03538aed79b592efb866d6ddce843de1ac2a7f8b699aefa693895fd
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- stackup (0.2.0)
4
+ stackup (0.3.0)
5
5
  aws-sdk (~> 2.0)
6
6
  clamp (~> 1.0)
7
7
  console_logger
@@ -62,4 +62,4 @@ DEPENDENCIES
62
62
  stackup!
63
63
 
64
64
  BUNDLED WITH
65
- 1.10.5
65
+ 1.10.6
data/README.md CHANGED
@@ -2,11 +2,21 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/realestate-com-au/stackup.svg?branch=master)](https://travis-ci.org/realestate-com-au/stackup)
4
4
 
5
- Stackup attempts to simplify AWS Cloudformation stack creation process in
6
- ruby projects by providing executable to perform common operations such
7
- as apply(create/update), delete, recreate on stack along with validations on
8
- templates. Operations which enforce a stack change will wait until
9
- the change is complete.
5
+ Stackup provides a CLI and a simplified Ruby API for dealing with
6
+ AWS CloudFormation stacks.
7
+
8
+ ## Why?
9
+
10
+ Stackup provides some advantages over using `awscli` or `aws-sdk` directly:
11
+
12
+ - It treats stack changes as synchronous, streaming stack events until the
13
+ stack reaches a stable state.
14
+
15
+ - A `Stack#up` facade for `create`/`update` frees you from having to know
16
+ whether your stack already exists or not.
17
+
18
+ - "No-op" operations - deleting a stack that doesn't exist, or updating
19
+ without a template change - are handled gracefully (i.e. without error).
10
20
 
11
21
  ## Installation
12
22
 
@@ -20,9 +30,9 @@ Most commands operate in the context of a named stack:
20
30
 
21
31
  $ stackup STACK-NAME ...
22
32
 
23
- Called without stack-name, it will list stacks:
33
+ Called with `--list`, it will list stacks:
24
34
 
25
- $ stackup
35
+ $ stackup --list
26
36
  foo-bar-test
27
37
  zzz-production
28
38
 
data/bin/stackup CHANGED
@@ -10,15 +10,15 @@ require "yaml"
10
10
 
11
11
  Clamp do
12
12
 
13
- option "--debug", :flag, "enable debugging"
14
-
15
- option ["-f", "--format"], "FORMAT", "output format", :default => "yaml"
16
-
17
13
  option ["-L", "--list"], :flag, "list stacks" do
18
14
  list_stacks
19
15
  exit 0
20
16
  end
21
17
 
18
+ option ["-Y", "--yaml"], :flag, "output data in YAML format"
19
+
20
+ option "--debug", :flag, "enable debugging"
21
+
22
22
  parameter "NAME", "Name of stack", :attribute_name => :stack_name
23
23
 
24
24
  def run(arguments)
@@ -38,11 +38,10 @@ Clamp do
38
38
  end
39
39
 
40
40
  def format_data(data)
41
- case format.downcase
42
- when "json"
43
- MultiJson.dump(data, :pretty => true)
44
- when "yaml"
41
+ if yaml?
45
42
  YAML.dump(data)
43
+ else
44
+ MultiJson.dump(data, :pretty => true)
46
45
  end
47
46
  end
48
47
 
@@ -89,8 +88,8 @@ Clamp do
89
88
 
90
89
  def execute
91
90
  options = {}
92
- options[:template_body] = load_file(template_file)
93
- options[:parameters_file] = load_file(parameters_file) if parameters_file
91
+ options[:template] = template
92
+ options[:parameters] = parameters if parameters
94
93
  options[:disable_rollback] = disable_rollback?
95
94
  report_change do
96
95
  stack.create_or_update(options)
@@ -99,12 +98,20 @@ Clamp do
99
98
 
100
99
  private
101
100
 
102
- def load_file(file)
103
- File.read(file)
101
+ def load_data(file)
102
+ YAML.load_file(file)
104
103
  rescue Errno::ENOENT
105
104
  signal_error "no such file: #{file.inspect}"
106
105
  end
107
106
 
107
+ def template
108
+ @template ||= load_data(template_file)
109
+ end
110
+
111
+ def parameters
112
+ @parameters ||= load_data(parameters_file) if parameters_file
113
+ end
114
+
108
115
  end
109
116
 
110
117
  subcommand ["down", "delete"], "Remove the stack." do
@@ -127,7 +134,23 @@ Clamp do
127
134
 
128
135
  end
129
136
 
130
- subcommand "outputs", "Stack outputs." do
137
+ subcommand "template", "Display stack template." do
138
+
139
+ def execute
140
+ display_data(stack.template)
141
+ end
142
+
143
+ end
144
+
145
+ subcommand "parameters", "Display stack parameters." do
146
+
147
+ def execute
148
+ display_data(stack.parameters)
149
+ end
150
+
151
+ end
152
+
153
+ subcommand "outputs", "Display stack outputs." do
131
154
 
132
155
  def execute
133
156
  display_data(stack.outputs)
@@ -135,4 +158,12 @@ Clamp do
135
158
 
136
159
  end
137
160
 
161
+ subcommand "resources", "Display stack resources." do
162
+
163
+ def execute
164
+ display_data(stack.resources)
165
+ end
166
+
167
+ end
168
+
138
169
  end
@@ -0,0 +1,32 @@
1
+ require "stackup/errors"
2
+
3
+ module Stackup
4
+
5
+ # Handle +Aws::CloudFormation::Errors::ValidationError+.
6
+ #
7
+ module ErrorHandling
8
+
9
+ # Invoke an Aws::CloudFormation operation
10
+ #
11
+ # If a +ValidationError+ is raised, check the message; there's often
12
+ # useful information is hidden inside. If that's the case, convert it to
13
+ # an appropriate Stackup exception.
14
+ #
15
+ def handling_validation_error
16
+ yield
17
+ rescue Aws::CloudFormation::Errors::ValidationError => e
18
+ case e.message
19
+ when /Stack .* does not exist/
20
+ raise NoSuchStack, "no such stack"
21
+ when "No updates are to be performed."
22
+ raise NoUpdateRequired, "no updates are required"
23
+ when / can ?not be /
24
+ raise InvalidStateError, e.message
25
+ else
26
+ raise ValidationError, e.message
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -3,16 +3,19 @@ module Stackup
3
3
  # Base Stackup Exception class
4
4
  class ServiceError < StandardError; end
5
5
 
6
- # Raised when the specified stack does not exist
7
- class NoSuchStack < ServiceError; end
6
+ # Raised when something else dodgy happened
7
+ class ValidationError < ServiceError; end
8
8
 
9
- # Raised to indicate a problem updating a stack
10
- class StackUpdateError < ServiceError; end
9
+ # Raised when the specified stack does not exist
10
+ class NoSuchStack < ValidationError; end
11
11
 
12
12
  # Raised if we can't perform that operation now
13
- class InvalidStateError < ServiceError; end
13
+ class InvalidStateError < ValidationError; end
14
14
 
15
15
  # Raised when a stack is already up-to-date
16
- class NoUpdateRequired < StandardError; end
16
+ class NoUpdateRequired < ValidationError; end
17
+
18
+ # Raised to indicate a problem updating a stack
19
+ class StackUpdateError < ServiceError; end
17
20
 
18
21
  end
data/lib/stackup/stack.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "aws-sdk-resources"
2
2
  require "logger"
3
- require "stackup/error_mapping_proxy"
3
+ require "multi_json"
4
+ require "stackup/error_handling"
4
5
  require "stackup/stack_watcher"
5
6
 
6
7
  module Stackup
@@ -20,7 +21,7 @@ module Stackup
20
21
 
21
22
  attr_reader :name, :cf_client, :watcher
22
23
 
23
- # Register a handler for reporting of stack events
24
+ # Register a handler for reporting of stack events.
24
25
  # @param [Proc] event_handler
25
26
  #
26
27
  def on_event(event_handler = nil, &block)
@@ -29,11 +30,15 @@ module Stackup
29
30
  @event_handler = event_handler
30
31
  end
31
32
 
33
+ include ErrorHandling
34
+
32
35
  # @return [String] the current stack status
33
36
  # @raise [Stackup::NoSuchStack] if the stack doesn't exist
34
37
  #
35
38
  def status
36
- cf_stack.stack_status
39
+ handling_validation_error do
40
+ cf_stack.stack_status
41
+ end
37
42
  end
38
43
 
39
44
  # @return [boolean] true iff the stack exists
@@ -51,11 +56,48 @@ module Stackup
51
56
  # accepts a superset of the options supported by
52
57
  # +Aws::CloudFormation::Stack#update+
53
58
  # (see http://docs.aws.amazon.com/sdkforruby/api/Aws/CloudFormation/Stack.html#update-instance_method)
54
- # @return [Symbol] `:created` or `:updated` if successful
59
+ # @option options [Array<String>] :capabilities (CAPABILITY_IAM)
60
+ # list of capabilities required for stack template
61
+ # @option options [boolean] :disable_rollback (false)
62
+ # if true, disable rollback if stack creation fails
63
+ # @option options [String] :notification_arns
64
+ # ARNs for the Amazon SNS topics associated with this stack
65
+ # @option options [String] :on_failure (DO_NOTHING)
66
+ # if stack creation fails: DO_NOTHING, ROLLBACK, or DELETE
67
+ # @option options [Hash, Array<Hash>] :parameters
68
+ # stack parameters, either as a Hash, or as an Array of
69
+ # +Aws::CloudFormation::Types::Parameter+ structures
70
+ # @option options [Array<String>] :resource_types
71
+ # resource types that you have permissions to work with
72
+ # @option options [Hash] :template
73
+ # stack template, as Ruby data
74
+ # @option options [String] :stack_policy_body
75
+ # stack policy, as JSON
76
+ # @option options [String] :stack_policy_url
77
+ # location of stack policy
78
+ # @option options [String] :stack_policy_during_update_body
79
+ # temporary stack policy, as JSON
80
+ # @option options [String] :stack_policy_during_update_url
81
+ # location of temporary stack policy
82
+ # @option options [String] :template_body
83
+ # stack template, as JSON
84
+ # @option options [String] :template_url
85
+ # location of stack template
86
+ # @option options [Integer] :timeout_in_minutes
87
+ # stack creation timeout
88
+ # @option options [boolean] :use_previous_template
89
+ # if true, reuse the existing template
90
+ # @return [Symbol] +:created+ or +:updated+ if successful
55
91
  # @raise [Stackup::StackUpdateError] if operation fails
56
92
  #
57
93
  def create_or_update(options)
58
94
  options = options.dup
95
+ if (template_data = options.delete(:template))
96
+ options[:template_body] = MultiJson.dump(template_data)
97
+ end
98
+ if (parameters = options[:parameters])
99
+ options[:parameters] = normalise_parameters(parameters)
100
+ end
59
101
  options[:capabilities] ||= ["CAPABILITY_IAM"]
60
102
  delete if ALMOST_DEAD_STATUSES.include?(status)
61
103
  update(options)
@@ -71,12 +113,14 @@ module Stackup
71
113
  #
72
114
  # @param [String] template template JSON
73
115
  # @param [Array<Hash>] parameters template parameters
74
- # @return [Symbol] `:deleted` if successful
116
+ # @return [Symbol] +:deleted+ if successful
75
117
  # @raise [Stackup::StackUpdateError] if operation fails
76
118
  #
77
119
  def delete
78
120
  begin
79
- @stack_id = cf_stack.stack_id
121
+ @stack_id = handling_validation_error do
122
+ cf_stack.stack_id
123
+ end
80
124
  rescue NoSuchStack
81
125
  return nil
82
126
  end
@@ -93,7 +137,7 @@ module Stackup
93
137
 
94
138
  # Cancel update in-progress.
95
139
  #
96
- # @return [Symbol] `:update_cancelled` if successful
140
+ # @return [Symbol] +:update_cancelled+ if successful
97
141
  # @raise [Stackup::StackUpdateError] if operation fails
98
142
  #
99
143
  def cancel_update
@@ -106,16 +150,60 @@ module Stackup
106
150
  nil
107
151
  end
108
152
 
153
+ # Get the current template.
154
+ #
155
+ # @return [Hash] current stack template, as Ruby data
156
+ # @raise [Stackup::NoSuchStack] if the stack doesn't exist
157
+ #
158
+ def template
159
+ handling_validation_error do
160
+ template_json = cf_client.get_template(:stack_name => name).template_body
161
+ MultiJson.load(template_json)
162
+ end
163
+ end
164
+
165
+ # Get the current parameters.
166
+ #
167
+ # @return [Hash] current stack parameters
168
+ # @raise [Stackup::NoSuchStack] if the stack doesn't exist
169
+ #
170
+ def parameters
171
+ handling_validation_error do
172
+ {}.tap do |h|
173
+ cf_stack.parameters.each do |p|
174
+ h[p.parameter_key] = p.parameter_value
175
+ end
176
+ end
177
+ end
178
+ end
179
+
180
+ # Get stack outputs.
181
+ #
182
+ # @return [Hash<String, String>] stack outputs
183
+ # @raise [Stackup::NoSuchStack] if the stack doesn't exist
184
+ #
185
+ def outputs
186
+ handling_validation_error do
187
+ {}.tap do |h|
188
+ cf_stack.outputs.each do |o|
189
+ h[o.output_key] = o.output_value
190
+ end
191
+ end
192
+ end
193
+ end
194
+
109
195
  # Get stack outputs.
110
196
  #
111
197
  # @return [Hash<String, String>]
112
198
  # mapping of logical resource-name to physical resource-name
113
199
  # @raise [Stackup::NoSuchStack] if the stack doesn't exist
114
200
  #
115
- def outputs
116
- {}.tap do |h|
117
- cf_stack.outputs.each do |output|
118
- h[output.output_key] = output.output_value
201
+ def resources
202
+ handling_validation_error do
203
+ {}.tap do |h|
204
+ cf_stack.resource_summaries.each do |r|
205
+ h[r.logical_resource_id] = r.physical_resource_id
206
+ end
119
207
  end
120
208
  end
121
209
  end
@@ -124,8 +212,10 @@ module Stackup
124
212
 
125
213
  def create(options)
126
214
  options[:stack_name] = name
215
+ options.delete(:stack_policy_during_update_body)
216
+ options.delete(:stack_policy_during_update_url)
127
217
  status = modify_stack do
128
- ErrorMappingProxy.new(cf).create_stack(options)
218
+ cf.create_stack(options)
129
219
  end
130
220
  fail StackUpdateError, "stack creation failed" unless status == "CREATE_COMPLETE"
131
221
  :created
@@ -133,6 +223,8 @@ module Stackup
133
223
 
134
224
  def update(options)
135
225
  options.delete(:disable_rollback)
226
+ options.delete(:on_failure)
227
+ options.delete(:timeout_in_minutes)
136
228
  status = modify_stack do
137
229
  cf_stack.update(options)
138
230
  end
@@ -153,7 +245,7 @@ module Stackup
153
245
 
154
246
  def cf_stack
155
247
  id_or_name = @stack_id || name
156
- ErrorMappingProxy.new(cf.stack(id_or_name))
248
+ cf.stack(id_or_name)
157
249
  end
158
250
 
159
251
  def event_handler
@@ -170,7 +262,9 @@ module Stackup
170
262
  def modify_stack
171
263
  watcher = Stackup::StackWatcher.new(cf_stack)
172
264
  watcher.zero
173
- yield
265
+ handling_validation_error do
266
+ yield
267
+ end
174
268
  loop do
175
269
  watcher.each_new_event(&event_handler)
176
270
  status = self.status
@@ -180,6 +274,16 @@ module Stackup
180
274
  end
181
275
  end
182
276
 
277
+ def normalise_parameters(arg)
278
+ return arg unless arg.is_a?(Hash)
279
+ arg.map do |key, value|
280
+ {
281
+ :parameter_key => key,
282
+ :parameter_value => value
283
+ }
284
+ end
285
+ end
286
+
183
287
  end
184
288
 
185
289
  end
@@ -18,6 +18,7 @@ module Stackup
18
18
  # Yield all events since the last call
19
19
  #
20
20
  def each_new_event
21
+ # rubocop:disable Lint/HandleExceptions
21
22
  buffer = []
22
23
  stack.events.each do |event|
23
24
  break if @processed_event_ids.include?(event.event_id)
@@ -28,7 +29,6 @@ module Stackup
28
29
  @processed_event_ids.add(event.event_id)
29
30
  end
30
31
  rescue Aws::CloudFormation::Errors::ValidationError
31
- # okay
32
32
  end
33
33
 
34
34
  # Consume all new events
Binary file
@@ -76,18 +76,24 @@ describe Stackup::Stack do
76
76
 
77
77
  let(:template) { "stack template" }
78
78
 
79
+ let(:options) do
80
+ { :template_body => template }
81
+ end
82
+
79
83
  def create_or_update
80
- stack.create_or_update(:template_body => template)
84
+ stack.create_or_update(options)
81
85
  end
82
86
 
83
- context "successful" do
87
+ let(:describe_stacks_responses) do
88
+ super() + [
89
+ stack_description("CREATE_IN_PROGRESS"),
90
+ stack_description(final_status)
91
+ ]
92
+ end
84
93
 
85
- let(:describe_stacks_responses) do
86
- super() + [
87
- stack_description("CREATE_IN_PROGRESS"),
88
- stack_description("CREATE_COMPLETE")
89
- ]
90
- end
94
+ let(:final_status) { "CREATE_COMPLETE" }
95
+
96
+ context "successful" do
91
97
 
92
98
  it "calls :create_stack" do
93
99
  expected_args = {
@@ -107,12 +113,7 @@ describe Stackup::Stack do
107
113
 
108
114
  context "unsuccessful" do
109
115
 
110
- let(:describe_stacks_responses) do
111
- super() + [
112
- stack_description("CREATE_IN_PROGRESS"),
113
- stack_description("CREATE_FAILED")
114
- ]
115
- end
116
+ let(:final_status) { "CREATE_FAILED" }
116
117
 
117
118
  it "raises a StackUpdateError" do
118
119
  expect { create_or_update }
@@ -121,6 +122,41 @@ describe Stackup::Stack do
121
122
 
122
123
  end
123
124
 
125
+ context "with :template as data" do
126
+
127
+ let(:options) do
128
+ { :template => { "foo" => "bar" } }
129
+ end
130
+
131
+ it "converts the template to JSON" do
132
+ create_or_update
133
+ expect(cf_client).to have_received(:create_stack)
134
+ .with(hash_including(:template_body))
135
+ end
136
+
137
+ end
138
+
139
+ context "with :parameters as Hash" do
140
+
141
+ before do
142
+ options[:parameters] = { "foo" => "bar" }
143
+ end
144
+
145
+ it "converts them to an Array" do
146
+ expected_parameters = [
147
+ {
148
+ :parameter_key => "foo",
149
+ :parameter_value => "bar"
150
+ }
151
+ ]
152
+ create_or_update
153
+ expect(cf_client).to have_received(:create_stack) do |options|
154
+ expect(options[:parameters]).to eq(expected_parameters)
155
+ end
156
+ end
157
+
158
+ end
159
+
124
160
  end
125
161
 
126
162
  end
@@ -202,13 +238,11 @@ describe Stackup::Stack do
202
238
  let(:describe_stacks_responses) do
203
239
  super() + [
204
240
  stack_description("UPDATE_IN_PROGRESS"),
205
- final_describe_stacks_response
241
+ stack_description(final_status)
206
242
  ]
207
243
  end
208
244
 
209
- let(:final_describe_stacks_response) do
210
- stack_description("UPDATE_COMPLETE")
211
- end
245
+ let(:final_status) { "UPDATE_COMPLETE" }
212
246
 
213
247
  it "calls :update_stack" do
214
248
  expected_args = {
@@ -245,9 +279,7 @@ describe Stackup::Stack do
245
279
 
246
280
  context "unsuccessful" do
247
281
 
248
- let(:final_describe_stacks_response) do
249
- stack_description("UPDATE_ROLLBACK_COMPLETE")
250
- end
282
+ let(:final_status) { "UPDATE_ROLLBACK_COMPLETE" }
251
283
 
252
284
  it "raises a StackUpdateError" do
253
285
  expect { create_or_update }.to raise_error(Stackup::StackUpdateError)
@@ -300,7 +332,7 @@ describe Stackup::Stack do
300
332
  )
301
333
  end
302
334
 
303
- it "calls :delete_stack, then :create_stack first" do
335
+ it "calls :delete_stack, then :create_stack" do
304
336
  create_or_update
305
337
  expect(cf_client).to have_received(:delete_stack)
306
338
  expect(cf_client).to have_received(:create_stack)
data/stackup.gemspec CHANGED
@@ -4,9 +4,9 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  Gem::Specification.new do |spec|
5
5
 
6
6
  spec.name = "stackup"
7
- spec.version = "0.2.0"
8
- spec.authors = ["Arvind Kunday", "Mike Williams"]
9
- spec.email = ["arvind.kunday@rea-group.com", "mike.williams@rea-group.com"]
7
+ spec.version = "0.3.0"
8
+ spec.authors = ["Mike Williams", "Arvind Kunday"]
9
+ spec.email = ["mike.williams@rea-group.com", "arvind.kunday@rea-group.com"]
10
10
  spec.summary = "Manage CloudFormation stacks"
11
11
  spec.homepage = "https://github.com/realestate-com-au/stackup"
12
12
  spec.license = "MIT"
@@ -0,0 +1,6 @@
1
+ [
2
+ {
3
+ "parameter_key": "ParameterKey",
4
+ "parameter_value": "ParameterValue"
5
+ }
6
+ ]
@@ -0,0 +1,31 @@
1
+ ---
2
+ AWSTemplateFormatVersion: '2010-09-09'
3
+ Description: 'AWS CloudFormation Sample Template S3_Website_Bucket_With_Retain_On_Delete:
4
+ Sample template showing how to create a publicly accessible S3 bucket configured
5
+ for website access with a deletion policy of retail on delete. **WARNING** This
6
+ template creates an S3 bucket that will NOT be deleted when the stack is deleted.
7
+ You will be billed for the AWS resources used if you create a stack from this template.'
8
+ Resources:
9
+ S3Bucket:
10
+ Type: AWS::S3::Bucket
11
+ Properties:
12
+ AccessControl: PublicRead
13
+ WebsiteConfiguration:
14
+ IndexDocument: index.html
15
+ ErrorDocument: error.html
16
+ Outputs:
17
+ WebsiteURL:
18
+ Value:
19
+ Fn::GetAtt:
20
+ - S3Bucket
21
+ - WebsiteURL
22
+ Description: URL for website hosted on S3
23
+ S3BucketSecureURL:
24
+ Value:
25
+ Fn::Join:
26
+ - ''
27
+ - - https://
28
+ - Fn::GetAtt:
29
+ - S3Bucket
30
+ - DomainName
31
+ Description: Name of S3 bucket to hold website content
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stackup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
- - Arvind Kunday
8
7
  - Mike Williams
8
+ - Arvind Kunday
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
@@ -69,8 +69,8 @@ dependencies:
69
69
  version: '0'
70
70
  description:
71
71
  email:
72
- - arvind.kunday@rea-group.com
73
72
  - mike.williams@rea-group.com
73
+ - arvind.kunday@rea-group.com
74
74
  executables:
75
75
  - stackup
76
76
  extensions: []
@@ -106,16 +106,19 @@ files:
106
106
  - doc/method_list.html
107
107
  - doc/top-level-namespace.html
108
108
  - lib/stackup.rb
109
- - lib/stackup/error_mapping_proxy.rb
109
+ - lib/stackup/error_handling.rb
110
110
  - lib/stackup/errors.rb
111
111
  - lib/stackup/service.rb
112
112
  - lib/stackup/stack.rb
113
113
  - lib/stackup/stack_watcher.rb
114
+ - pkg/stackup-0.2.0.gem
114
115
  - spec/spec_helper.rb
115
116
  - spec/stackup/stack_spec.rb
116
117
  - spec/stackup/stack_watcher_spec.rb
117
118
  - stackup.gemspec
119
+ - woollyams/parameters.json
118
120
  - woollyams/template.json
121
+ - woollyams/template.yml
119
122
  homepage: https://github.com/realestate-com-au/stackup
120
123
  licenses:
121
124
  - MIT
@@ -136,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
139
  version: '0'
137
140
  requirements: []
138
141
  rubyforge_project:
139
- rubygems_version: 2.4.8
142
+ rubygems_version: 2.4.5.1
140
143
  signing_key:
141
144
  specification_version: 4
142
145
  summary: Manage CloudFormation stacks
@@ -1,37 +0,0 @@
1
- require "stackup/errors"
2
-
3
- module Stackup
4
-
5
- # An error-mapping proxy for Aws::CloudFormation models.
6
- #
7
- # It exists to convert certain types of `ValidationError`, where useful
8
- # information is hidden inside the "message", to Stackup exceptions.
9
- #
10
- class ErrorMappingProxy
11
-
12
- def initialize(delegate)
13
- @delegate = delegate
14
- end
15
-
16
- def method_missing(*args)
17
- @delegate.send(*args)
18
- rescue Aws::CloudFormation::Errors::ValidationError => e
19
- case e.message
20
- when "No updates are to be performed."
21
- raise NoUpdateRequired, "no updates are required"
22
- when /Stack .* does not exist$/
23
- raise NoSuchStack, "no such stack"
24
- when / can ?not be /
25
- raise InvalidStateError, e.message
26
- else
27
- raise e
28
- end
29
- end
30
-
31
- def respond_to?(method)
32
- @delegate.respond_to?(method)
33
- end
34
-
35
- end
36
-
37
- end