miasma-aws 0.3.10 → 0.3.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- require 'miasma'
1
+ require "miasma"
2
2
 
3
3
  module Miasma
4
4
  module Models
@@ -8,25 +8,25 @@ module Miasma
8
8
 
9
9
  # Extended stack model to provide AWS specific stack options
10
10
  class Stack < Orchestration::Stack
11
- attribute :stack_policy_body, Hash, :coerce => lambda{|v| MultiJson.load(v).to_smash}
11
+ attribute :stack_policy_body, Hash, :coerce => lambda { |v| MultiJson.load(v).to_smash }
12
12
  attribute :stack_policy_url, String
13
13
  attribute :last_event_token, String
14
14
  end
15
15
 
16
16
  # Service name of the API
17
- API_SERVICE = 'cloudformation'.freeze
17
+ API_SERVICE = "cloudformation".freeze
18
18
  # Service name of the eucalyptus API
19
- EUCA_API_SERVICE = 'CloudFormation'.freeze
19
+ EUCA_API_SERVICE = "CloudFormation".freeze
20
20
  # Supported version of the AutoScaling API
21
- API_VERSION = '2010-05-15'.freeze
21
+ API_VERSION = "2010-05-15".freeze
22
22
 
23
23
  # Valid stack lookup states
24
24
  STACK_STATES = [
25
- 'CREATE_COMPLETE', 'CREATE_FAILED', 'CREATE_IN_PROGRESS', 'DELETE_FAILED',
26
- 'DELETE_IN_PROGRESS', 'ROLLBACK_COMPLETE', 'ROLLBACK_FAILED', 'ROLLBACK_IN_PROGRESS',
27
- 'UPDATE_COMPLETE', 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_IN_PROGRESS',
28
- 'UPDATE_ROLLBACK_COMPLETE', 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_ROLLBACK_FAILED',
29
- 'UPDATE_ROLLBACK_IN_PROGRESS'
25
+ "CREATE_COMPLETE", "CREATE_FAILED", "CREATE_IN_PROGRESS", "DELETE_FAILED",
26
+ "DELETE_IN_PROGRESS", "ROLLBACK_COMPLETE", "ROLLBACK_FAILED", "ROLLBACK_IN_PROGRESS",
27
+ "UPDATE_COMPLETE", "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", "UPDATE_IN_PROGRESS",
28
+ "UPDATE_ROLLBACK_COMPLETE", "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS", "UPDATE_ROLLBACK_FAILED",
29
+ "UPDATE_ROLLBACK_IN_PROGRESS",
30
30
  ].map(&:freeze).freeze
31
31
 
32
32
  include Contrib::AwsApiCore::ApiCommon
@@ -34,113 +34,111 @@ module Miasma
34
34
 
35
35
  # @return [Smash] external to internal resource mapping
36
36
  RESOURCE_MAPPING = Smash.new(
37
- 'AWS::EC2::Instance' => Smash.new(
37
+ "AWS::EC2::Instance" => Smash.new(
38
38
  :api => :compute,
39
- :collection => :servers
39
+ :collection => :servers,
40
40
  ),
41
- 'AWS::ElasticLoadBalancing::LoadBalancer' => Smash.new(
41
+ "AWS::ElasticLoadBalancing::LoadBalancer" => Smash.new(
42
42
  :api => :load_balancer,
43
- :collection => :balancers
43
+ :collection => :balancers,
44
44
  ),
45
- 'AWS::AutoScaling::AutoScalingGroup' => Smash.new(
45
+ "AWS::AutoScaling::AutoScalingGroup" => Smash.new(
46
46
  :api => :auto_scale,
47
- :collection => :groups
47
+ :collection => :groups,
48
48
  ),
49
- 'AWS::CloudFormation::Stack' => Smash.new(
49
+ "AWS::CloudFormation::Stack" => Smash.new(
50
50
  :api => :orchestration,
51
- :collection => :stacks
52
- )
51
+ :collection => :stacks,
52
+ ),
53
53
  ).to_smash(:freeze)
54
54
 
55
55
  # Fetch stacks or update provided stack data
56
56
  #
57
57
  # @param stack [Models::Orchestration::Stack]
58
58
  # @return [Array<Models::Orchestration::Stack>]
59
- def load_stack_data(stack=nil)
60
- d_params = Smash.new('Action' => 'DescribeStacks')
61
- l_params = Smash.new('Action' => 'ListStacks')
59
+ def load_stack_data(stack = nil)
60
+ d_params = Smash.new("Action" => "DescribeStacks")
61
+ l_params = Smash.new("Action" => "ListStacks")
62
62
  STACK_STATES.each_with_index do |state, idx|
63
63
  l_params["StackStatusFilter.member.#{idx + 1}"] = state.to_s.upcase
64
64
  end
65
- if(stack)
66
- d_params['StackName'] = stack.id
65
+ if stack
66
+ d_params["StackName"] = stack.id
67
67
  descriptions = all_result_pages(nil, :body,
68
- 'DescribeStacksResponse', 'DescribeStacksResult',
69
- 'Stacks', 'member'
70
- ) do |options|
68
+ "DescribeStacksResponse", "DescribeStacksResult",
69
+ "Stacks", "member") do |options|
71
70
  request(
72
71
  :method => :post,
73
- :path => '/',
74
- :form => options.merge(d_params)
72
+ :path => "/",
73
+ :form => options.merge(d_params),
75
74
  )
76
75
  end
77
76
  else
78
77
  lists = all_result_pages(nil, :body,
79
- 'ListStacksResponse', 'ListStacksResult',
80
- 'StackSummaries', 'member'
81
- ) do |options|
78
+ "ListStacksResponse", "ListStacksResult",
79
+ "StackSummaries", "member") do |options|
82
80
  request(
83
81
  :method => :post,
84
- :path => '/',
85
- :form => options.merge(l_params)
82
+ :path => "/",
83
+ :form => options.merge(l_params),
86
84
  )
87
85
  end
88
86
  descriptions = []
89
87
  end
90
88
  (lists || descriptions).map do |stk|
91
- if(lists)
89
+ if lists
92
90
  desc = descriptions.detect do |d_stk|
93
- d_stk['StackId'] == stk['StackId']
91
+ d_stk["StackId"] == stk["StackId"]
94
92
  end || Smash.new
95
93
  stk.merge!(desc)
96
94
  end
97
- if(stack)
98
- next if stack.id != stk['StackId'] && stk['StackId'].split('/')[1] != stack.id
95
+ if stack
96
+ next if stack.id != stk["StackId"] && stk["StackId"].split("/")[1] != stack.id
99
97
  end
100
- state = stk['StackStatus'].downcase.to_sym
101
- unless(Miasma::Models::Orchestration::VALID_RESOURCE_STATES.include?(state))
102
- parts = state.to_s.split('_')
103
- state = [parts.first, *parts.slice(-2, parts.size)].join('_').to_sym
104
- unless(Miasma::Models::Orchestration::VALID_RESOURCE_STATES.include?(parts))
98
+ state = stk["StackStatus"].downcase.to_sym
99
+ unless Miasma::Models::Orchestration::VALID_RESOURCE_STATES.include?(state)
100
+ parts = state.to_s.split("_")
101
+ state = [parts.first, *parts.slice(-2, parts.size)].join("_").to_sym
102
+ unless Miasma::Models::Orchestration::VALID_RESOURCE_STATES.include?(parts)
105
103
  state = :unknown
106
104
  end
107
105
  end
108
106
  new_stack = stack || Stack.new(self)
109
107
  new_stack.load_data(
110
- :id => stk['StackId'],
111
- :name => stk['StackName'],
112
- :capabilities => [stk.get('Capabilities', 'member')].flatten(1).compact,
113
- :description => stk['Description'],
114
- :created => stk['CreationTime'],
115
- :updated => stk['LastUpdatedTime'],
116
- :notification_topics => [stk.get('NotificationARNs', 'member')].flatten(1).compact,
117
- :timeout_in_minutes => stk['TimeoutInMinutes'] ? stk['TimeoutInMinutes'].to_i : nil,
118
- :status => stk['StackStatus'],
119
- :status_reason => stk['StackStatusReason'],
108
+ :id => stk["StackId"],
109
+ :name => stk["StackName"],
110
+ :capabilities => [stk.get("Capabilities", "member")].flatten(1).compact,
111
+ :description => stk["Description"],
112
+ :created => stk["CreationTime"],
113
+ :updated => stk["LastUpdatedTime"],
114
+ :notification_topics => [stk.get("NotificationARNs", "member")].flatten(1).compact,
115
+ :timeout_in_minutes => stk["TimeoutInMinutes"] ? stk["TimeoutInMinutes"].to_i : nil,
116
+ :status => stk["StackStatus"],
117
+ :status_reason => stk["StackStatusReason"],
120
118
  :state => state,
121
- :template_description => stk['TemplateDescription'],
122
- :disable_rollback => !!stk['DisableRollback'],
123
- :outputs => [stk.get('Outputs', 'member')].flatten(1).compact.map{|o|
119
+ :template_description => stk["TemplateDescription"],
120
+ :disable_rollback => !!stk["DisableRollback"],
121
+ :outputs => [stk.get("Outputs", "member")].flatten(1).compact.map { |o|
124
122
  Smash.new(
125
- :key => o['OutputKey'],
126
- :value => o['OutputValue'],
127
- :description => o['Description']
123
+ :key => o["OutputKey"],
124
+ :value => o["OutputValue"],
125
+ :description => o["Description"],
128
126
  )
129
127
  },
130
128
  :tags => Smash[
131
- [stk.fetch('Tags', 'member', [])].flatten(1).map{|param|
132
- [param['Key'], param['Value']]
129
+ [stk.fetch("Tags", "member", [])].flatten(1).map { |param|
130
+ [param["Key"], param["Value"]]
133
131
  }
134
132
  ],
135
133
  :parameters => Smash[
136
- [stk.fetch('Parameters', 'member', [])].flatten(1).map{|param|
137
- [param['ParameterKey'], param['ParameterValue']]
134
+ [stk.fetch("Parameters", "member", [])].flatten(1).map { |param|
135
+ [param["ParameterKey"], param["ParameterValue"]]
138
136
  }
139
137
  ],
140
138
  :custom => Smash.new(
141
- :stack_policy => stk['StackPolicyBody'],
142
- :stack_policy_url => stk['StackPolicyURL']
143
- )
139
+ :stack_policy => stk["StackPolicyBody"],
140
+ :stack_policy_url => stk["StackPolicyURL"],
141
+ ),
144
142
  ).valid_state
145
143
  end
146
144
  end
@@ -150,15 +148,15 @@ module Miasma
150
148
  # @param stack [Models::Orchestration::Stack]
151
149
  # @return [Models::Orchestration::Stack]
152
150
  def stack_save(stack)
153
- params = Smash.new('StackName' => stack.name)
154
- if(stack.dirty?(:parameters))
151
+ params = Smash.new("StackName" => stack.name)
152
+ if stack.dirty?(:parameters)
155
153
  initial_parameters = stack.data[:parameters] || {}
156
154
  else
157
155
  initial_parameters = {}
158
156
  end
159
157
  (stack.parameters || {}).each_with_index do |pair, idx|
160
158
  params["Parameters.member.#{idx + 1}.ParameterKey"] = pair.first
161
- if(initial_parameters[pair.first] == pair.last)
159
+ if initial_parameters[pair.first] == pair.last
162
160
  params["Parameters.member.#{idx + 1}.UsePreviousValue"] = true
163
161
  else
164
162
  params["Parameters.member.#{idx + 1}.ParameterValue"] = pair.last
@@ -174,46 +172,46 @@ module Miasma
174
172
  params["Tags.member.#{idx + 1}.Key"] = tag.first
175
173
  params["Tags.member.#{idx + 1}.Value"] = tag.last
176
174
  end
177
- if(stack.custom[:stack_policy_body])
178
- params['StackPolicyBody'] = MultiJson.dump(stack.custom[:stack_policy_body])
175
+ if stack.custom[:stack_policy_body]
176
+ params["StackPolicyBody"] = MultiJson.dump(stack.custom[:stack_policy_body])
179
177
  end
180
- if(stack.custom[:stack_policy_url])
181
- params['StackPolicyURL'] = stack.custom[:stack_policy_url]
178
+ if stack.custom[:stack_policy_url]
179
+ params["StackPolicyURL"] = stack.custom[:stack_policy_url]
182
180
  end
183
- unless(stack.disable_rollback.nil?)
184
- params['OnFailure'] = stack.disable_rollback ? 'DO_NOTHING' : 'ROLLBACK'
181
+ unless stack.disable_rollback.nil?
182
+ params["OnFailure"] = stack.disable_rollback ? "DO_NOTHING" : "ROLLBACK"
185
183
  end
186
- if(stack.on_failure)
187
- params['OnFailure'] = stack.on_failure == 'nothing' ? 'DO_NOTHING' : stack.on_failure.upcase
184
+ if stack.on_failure
185
+ params["OnFailure"] = stack.on_failure == "nothing" ? "DO_NOTHING" : stack.on_failure.upcase
188
186
  end
189
- if(stack.template_url)
190
- params['TemplateURL'] = stack.template_url
191
- elsif(!stack.dirty?(:template) && stack.persisted?)
192
- params['UsePreviousTemplate'] = true
187
+ if stack.template_url
188
+ params["TemplateURL"] = stack.template_url
189
+ elsif !stack.dirty?(:template) && stack.persisted?
190
+ params["UsePreviousTemplate"] = true
193
191
  else
194
- params['TemplateBody'] = MultiJson.dump(stack.template)
192
+ params["TemplateBody"] = MultiJson.dump(stack.template)
195
193
  end
196
- if(stack.persisted?)
194
+ if stack.persisted?
197
195
  result = request(
198
- :path => '/',
196
+ :path => "/",
199
197
  :method => :post,
200
198
  :form => Smash.new(
201
- 'Action' => 'UpdateStack'
202
- ).merge(params)
199
+ "Action" => "UpdateStack",
200
+ ).merge(params),
203
201
  )
204
202
  stack
205
203
  else
206
- if(stack.timeout_in_minutes)
207
- params['TimeoutInMinutes'] = stack.timeout_in_minutes
204
+ if stack.timeout_in_minutes
205
+ params["TimeoutInMinutes"] = stack.timeout_in_minutes
208
206
  end
209
207
  result = request(
210
- :path => '/',
208
+ :path => "/",
211
209
  :method => :post,
212
210
  :form => Smash.new(
213
- 'Action' => 'CreateStack'
214
- ).merge(params)
211
+ "Action" => "CreateStack",
212
+ ).merge(params),
215
213
  )
216
- stack.id = result.get(:body, 'CreateStackResponse', 'CreateStackResult', 'StackId')
214
+ stack.id = result.get(:body, "CreateStackResponse", "CreateStackResult", "StackId")
217
215
  stack.valid_state
218
216
  end
219
217
  end
@@ -223,14 +221,14 @@ module Miasma
223
221
  # @param stack [Models::Orchestration::Stack]
224
222
  # @return [Models::Orchestration::Stack]
225
223
  def stack_reload(stack)
226
- if(stack.persisted?)
224
+ if stack.persisted?
227
225
  ustack = Stack.new(self)
228
226
  ustack.id = stack.id
229
227
  load_stack_data(ustack)
230
- if(ustack.data[:name])
228
+ if ustack.data[:name]
231
229
  stack.load_data(ustack.attributes).valid_state
232
230
  else
233
- stack.status = 'DELETE_COMPLETE'
231
+ stack.status = "DELETE_COMPLETE"
234
232
  stack.state = :delete_complete
235
233
  stack.valid_state
236
234
  end
@@ -243,14 +241,14 @@ module Miasma
243
241
  # @param stack [Models::Orchestration::Stack]
244
242
  # @return [TrueClass, FalseClass]
245
243
  def stack_destroy(stack)
246
- if(stack.persisted?)
244
+ if stack.persisted?
247
245
  request(
248
246
  :method => :post,
249
- :path => '/',
247
+ :path => "/",
250
248
  :form => Smash.new(
251
- 'Action' => 'DeleteStack',
252
- 'StackName' => stack.id
253
- )
249
+ "Action" => "DeleteStack",
250
+ "StackName" => stack.id,
251
+ ),
254
252
  )
255
253
  true
256
254
  else
@@ -263,17 +261,17 @@ module Miasma
263
261
  # @param stack [Stack]
264
262
  # @return [Smash] stack template
265
263
  def stack_template_load(stack)
266
- if(stack.persisted?)
264
+ if stack.persisted?
267
265
  result = request(
268
266
  :method => :post,
269
- :path => '/',
267
+ :path => "/",
270
268
  :form => Smash.new(
271
- 'Action' => 'GetTemplate',
272
- 'StackName' => stack.id
273
- )
269
+ "Action" => "GetTemplate",
270
+ "StackName" => stack.id,
271
+ ),
274
272
  )
275
273
  MultiJson.load(
276
- result.get(:body, 'GetTemplateResponse', 'GetTemplateResult', 'TemplateBody')
274
+ result.get(:body, "GetTemplateResponse", "GetTemplateResult", "TemplateBody")
277
275
  ).to_smash
278
276
  else
279
277
  Smash.new
@@ -286,22 +284,22 @@ module Miasma
286
284
  # @return [NilClass, String] nil if valid, string error message if invalid
287
285
  def stack_template_validate(stack)
288
286
  begin
289
- if(stack.template_url)
290
- params = Smash.new('TemplateURL' => stack.template_url)
287
+ if stack.template_url
288
+ params = Smash.new("TemplateURL" => stack.template_url)
291
289
  else
292
- params = Smash.new('TemplateBody' => MultiJson.dump(stack.template))
290
+ params = Smash.new("TemplateBody" => MultiJson.dump(stack.template))
293
291
  end
294
292
  result = request(
295
293
  :method => :post,
296
- :path => '/',
294
+ :path => "/",
297
295
  :form => params.merge(
298
- 'Action' => 'ValidateTemplate'
299
- )
296
+ "Action" => "ValidateTemplate",
297
+ ),
300
298
  )
301
299
  nil
302
300
  rescue Error::ApiError::RequestError => e
303
301
  MultiXml.parse(e.response.body.to_s).to_smash.get(
304
- 'ErrorResponse', 'Error', 'Message'
302
+ "ErrorResponse", "Error", "Message"
305
303
  )
306
304
  end
307
305
  end
@@ -332,29 +330,28 @@ module Miasma
332
330
  # @return [Array<Models::Orchestration::Stack::Resource>]
333
331
  def resource_all(stack)
334
332
  all_result_pages(nil, :body,
335
- 'ListStackResourcesResponse', 'ListStackResourcesResult',
336
- 'StackResourceSummaries', 'member'
337
- ) do |options|
333
+ "ListStackResourcesResponse", "ListStackResourcesResult",
334
+ "StackResourceSummaries", "member") do |options|
338
335
  request(
339
336
  :method => :post,
340
- :path => '/',
337
+ :path => "/",
341
338
  :form => options.merge(
342
339
  Smash.new(
343
- 'Action' => 'ListStackResources',
344
- 'StackName' => stack.id
340
+ "Action" => "ListStackResources",
341
+ "StackName" => stack.id,
345
342
  )
346
- )
343
+ ),
347
344
  )
348
345
  end.map do |res|
349
346
  Stack::Resource.new(
350
347
  stack,
351
- :id => res['PhysicalResourceId'],
352
- :name => res['LogicalResourceId'],
353
- :logical_id => res['LogicalResourceId'],
354
- :type => res['ResourceType'],
355
- :state => res['ResourceStatus'].downcase.to_sym,
356
- :status => res['ResourceStatus'],
357
- :updated => res['LastUpdatedTimestamp']
348
+ :id => res["PhysicalResourceId"],
349
+ :name => res["LogicalResourceId"],
350
+ :logical_id => res["LogicalResourceId"],
351
+ :type => res["ResourceType"],
352
+ :state => res["ResourceStatus"].downcase.to_sym,
353
+ :status => res["ResourceStatus"],
354
+ :updated => res["LastUpdatedTimestamp"],
358
355
  ).valid_state
359
356
  end
360
357
  end
@@ -366,20 +363,19 @@ module Miasma
366
363
  def resource_reload(resource)
367
364
  result = request(
368
365
  :method => :post,
369
- :path => '/',
366
+ :path => "/",
370
367
  :form => Smash.new(
371
- 'LogicalResourceId' => resource.logical_id,
372
- 'StackName' => resource.stack.name
373
- )
368
+ "LogicalResourceId" => resource.logical_id,
369
+ "StackName" => resource.stack.name,
370
+ ),
374
371
  ).get(:body,
375
- 'DescribeStackResourceResponse', 'DescribeStackResourceResult',
376
- 'StackResourceDetail'
377
- )
378
- resource.updated = result['LastUpdatedTimestamp']
379
- resource.type = result['ResourceType']
380
- resource.state = result['ResourceStatus'].downcase.to_sym
381
- resource.status = result['ResourceStatus']
382
- resource.status_reason = result['ResourceStatusReason']
372
+ "DescribeStackResourceResponse", "DescribeStackResourceResult",
373
+ "StackResourceDetail")
374
+ resource.updated = result["LastUpdatedTimestamp"]
375
+ resource.type = result["ResourceType"]
376
+ resource.state = result["ResourceStatus"].downcase.to_sym
377
+ resource.status = result["ResourceStatus"]
378
+ resource.status_reason = result["ResourceStatusReason"]
383
379
  resource.valid_state
384
380
  resource
385
381
  end
@@ -388,37 +384,36 @@ module Miasma
388
384
  #
389
385
  # @param stack [Models::Orchestration::Stack]
390
386
  # @return [Array<Models::Orchestration::Stack::Event>]
391
- def event_all(stack, evt_id=nil)
387
+ def event_all(stack, evt_id = nil)
392
388
  evt_id = stack.last_event_token if evt_id
393
389
  results = all_result_pages(evt_id, :body,
394
- 'DescribeStackEventsResponse', 'DescribeStackEventsResult',
395
- 'StackEvents', 'member'
396
- ) do |options|
390
+ "DescribeStackEventsResponse", "DescribeStackEventsResult",
391
+ "StackEvents", "member") do |options|
397
392
  request(
398
393
  :method => :post,
399
- :path => '/',
394
+ :path => "/",
400
395
  :form => options.merge(
401
- 'Action' => 'DescribeStackEvents',
402
- 'StackName' => stack.id
403
- )
396
+ "Action" => "DescribeStackEvents",
397
+ "StackName" => stack.id,
398
+ ),
404
399
  )
405
400
  end
406
401
  events = results.map do |event|
407
- stack.last_event_token = event['NextToken'] if event['NextToken']
402
+ stack.last_event_token = event["NextToken"] if event["NextToken"]
408
403
  Stack::Event.new(
409
404
  stack,
410
- :id => event['EventId'],
411
- :resource_id => event['PhysicalResourceId'],
412
- :resource_name => event['LogicalResourceId'],
413
- :resource_logical_id => event['LogicalResourceId'],
414
- :resource_state => event['ResourceStatus'].downcase.to_sym,
415
- :resource_status => event['ResourceStatus'],
416
- :resource_status_reason => event['ResourceStatusReason'],
417
- :time => Time.parse(event['Timestamp'])
405
+ :id => event["EventId"],
406
+ :resource_id => event["PhysicalResourceId"],
407
+ :resource_name => event["LogicalResourceId"],
408
+ :resource_logical_id => event["LogicalResourceId"],
409
+ :resource_state => event["ResourceStatus"].downcase.to_sym,
410
+ :resource_status => event["ResourceStatus"],
411
+ :resource_status_reason => event["ResourceStatusReason"],
412
+ :time => Time.parse(event["Timestamp"]),
418
413
  ).valid_state
419
414
  end
420
- if(evt_id)
421
- idx = events.index{|d| d.id == evt_id}
415
+ if evt_id
416
+ idx = events.index { |d| d.id == evt_id }
422
417
  idx ? events.slice(0, idx) : events
423
418
  else
424
419
  events
@@ -441,7 +436,6 @@ module Miasma
441
436
  event.stack.events.reload
442
437
  event.stack.events.get(event.id)
443
438
  end
444
-
445
439
  end
446
440
  end
447
441
  end