miasma-aws 0.3.10 → 0.3.12
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 +5 -5
- data/CHANGELOG.md +4 -0
- data/lib/miasma-aws.rb +2 -2
- data/lib/miasma-aws/api.rb +3 -3
- data/lib/miasma-aws/api/iam.rb +16 -17
- data/lib/miasma-aws/api/sts.rb +29 -30
- data/lib/miasma-aws/version.rb +1 -1
- data/lib/miasma/contrib/aws.rb +170 -185
- data/lib/miasma/contrib/aws/auto_scale.rb +23 -25
- data/lib/miasma/contrib/aws/compute.rb +51 -56
- data/lib/miasma/contrib/aws/load_balancer.rb +64 -70
- data/lib/miasma/contrib/aws/orchestration.rb +153 -159
- data/lib/miasma/contrib/aws/storage.rb +109 -113
- data/miasma-aws.gemspec +3 -2
- metadata +33 -19
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
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 =
|
17
|
+
API_SERVICE = "cloudformation".freeze
|
18
18
|
# Service name of the eucalyptus API
|
19
|
-
EUCA_API_SERVICE =
|
19
|
+
EUCA_API_SERVICE = "CloudFormation".freeze
|
20
20
|
# Supported version of the AutoScaling API
|
21
|
-
API_VERSION =
|
21
|
+
API_VERSION = "2010-05-15".freeze
|
22
22
|
|
23
23
|
# Valid stack lookup states
|
24
24
|
STACK_STATES = [
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
37
|
+
"AWS::EC2::Instance" => Smash.new(
|
38
38
|
:api => :compute,
|
39
|
-
:collection => :servers
|
39
|
+
:collection => :servers,
|
40
40
|
),
|
41
|
-
|
41
|
+
"AWS::ElasticLoadBalancing::LoadBalancer" => Smash.new(
|
42
42
|
:api => :load_balancer,
|
43
|
-
:collection => :balancers
|
43
|
+
:collection => :balancers,
|
44
44
|
),
|
45
|
-
|
45
|
+
"AWS::AutoScaling::AutoScalingGroup" => Smash.new(
|
46
46
|
:api => :auto_scale,
|
47
|
-
:collection => :groups
|
47
|
+
:collection => :groups,
|
48
48
|
),
|
49
|
-
|
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(
|
61
|
-
l_params = Smash.new(
|
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
|
66
|
-
d_params[
|
65
|
+
if stack
|
66
|
+
d_params["StackName"] = stack.id
|
67
67
|
descriptions = all_result_pages(nil, :body,
|
68
|
-
|
69
|
-
|
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
|
-
|
80
|
-
|
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
|
89
|
+
if lists
|
92
90
|
desc = descriptions.detect do |d_stk|
|
93
|
-
d_stk[
|
91
|
+
d_stk["StackId"] == stk["StackId"]
|
94
92
|
end || Smash.new
|
95
93
|
stk.merge!(desc)
|
96
94
|
end
|
97
|
-
if
|
98
|
-
next if stack.id != stk[
|
95
|
+
if stack
|
96
|
+
next if stack.id != stk["StackId"] && stk["StackId"].split("/")[1] != stack.id
|
99
97
|
end
|
100
|
-
state = stk[
|
101
|
-
unless
|
102
|
-
parts = state.to_s.split(
|
103
|
-
state = [parts.first, *parts.slice(-2, parts.size)].join(
|
104
|
-
unless
|
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[
|
111
|
-
:name => stk[
|
112
|
-
:capabilities => [stk.get(
|
113
|
-
:description => stk[
|
114
|
-
:created => stk[
|
115
|
-
:updated => stk[
|
116
|
-
:notification_topics => [stk.get(
|
117
|
-
:timeout_in_minutes => stk[
|
118
|
-
:status => stk[
|
119
|
-
:status_reason => stk[
|
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[
|
122
|
-
:disable_rollback => !!stk[
|
123
|
-
:outputs => [stk.get(
|
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[
|
126
|
-
:value => o[
|
127
|
-
:description => o[
|
123
|
+
:key => o["OutputKey"],
|
124
|
+
:value => o["OutputValue"],
|
125
|
+
:description => o["Description"],
|
128
126
|
)
|
129
127
|
},
|
130
128
|
:tags => Smash[
|
131
|
-
[stk.fetch(
|
132
|
-
[param[
|
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(
|
137
|
-
[param[
|
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[
|
142
|
-
:stack_policy_url => stk[
|
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(
|
154
|
-
if
|
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
|
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
|
178
|
-
params[
|
175
|
+
if stack.custom[:stack_policy_body]
|
176
|
+
params["StackPolicyBody"] = MultiJson.dump(stack.custom[:stack_policy_body])
|
179
177
|
end
|
180
|
-
if
|
181
|
-
params[
|
178
|
+
if stack.custom[:stack_policy_url]
|
179
|
+
params["StackPolicyURL"] = stack.custom[:stack_policy_url]
|
182
180
|
end
|
183
|
-
unless
|
184
|
-
params[
|
181
|
+
unless stack.disable_rollback.nil?
|
182
|
+
params["OnFailure"] = stack.disable_rollback ? "DO_NOTHING" : "ROLLBACK"
|
185
183
|
end
|
186
|
-
if
|
187
|
-
params[
|
184
|
+
if stack.on_failure
|
185
|
+
params["OnFailure"] = stack.on_failure == "nothing" ? "DO_NOTHING" : stack.on_failure.upcase
|
188
186
|
end
|
189
|
-
if
|
190
|
-
params[
|
191
|
-
elsif
|
192
|
-
params[
|
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[
|
192
|
+
params["TemplateBody"] = MultiJson.dump(stack.template)
|
195
193
|
end
|
196
|
-
if
|
194
|
+
if stack.persisted?
|
197
195
|
result = request(
|
198
|
-
:path =>
|
196
|
+
:path => "/",
|
199
197
|
:method => :post,
|
200
198
|
:form => Smash.new(
|
201
|
-
|
202
|
-
).merge(params)
|
199
|
+
"Action" => "UpdateStack",
|
200
|
+
).merge(params),
|
203
201
|
)
|
204
202
|
stack
|
205
203
|
else
|
206
|
-
if
|
207
|
-
params[
|
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
|
-
|
214
|
-
).merge(params)
|
211
|
+
"Action" => "CreateStack",
|
212
|
+
).merge(params),
|
215
213
|
)
|
216
|
-
stack.id = result.get(:body,
|
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
|
224
|
+
if stack.persisted?
|
227
225
|
ustack = Stack.new(self)
|
228
226
|
ustack.id = stack.id
|
229
227
|
load_stack_data(ustack)
|
230
|
-
if
|
228
|
+
if ustack.data[:name]
|
231
229
|
stack.load_data(ustack.attributes).valid_state
|
232
230
|
else
|
233
|
-
stack.status =
|
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
|
244
|
+
if stack.persisted?
|
247
245
|
request(
|
248
246
|
:method => :post,
|
249
|
-
:path =>
|
247
|
+
:path => "/",
|
250
248
|
:form => Smash.new(
|
251
|
-
|
252
|
-
|
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
|
264
|
+
if stack.persisted?
|
267
265
|
result = request(
|
268
266
|
:method => :post,
|
269
|
-
:path =>
|
267
|
+
:path => "/",
|
270
268
|
:form => Smash.new(
|
271
|
-
|
272
|
-
|
273
|
-
)
|
269
|
+
"Action" => "GetTemplate",
|
270
|
+
"StackName" => stack.id,
|
271
|
+
),
|
274
272
|
)
|
275
273
|
MultiJson.load(
|
276
|
-
result.get(:body,
|
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
|
290
|
-
params = Smash.new(
|
287
|
+
if stack.template_url
|
288
|
+
params = Smash.new("TemplateURL" => stack.template_url)
|
291
289
|
else
|
292
|
-
params = Smash.new(
|
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
|
-
|
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
|
-
|
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
|
-
|
336
|
-
|
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
|
-
|
344
|
-
|
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[
|
352
|
-
:name => res[
|
353
|
-
:logical_id => res[
|
354
|
-
:type => res[
|
355
|
-
:state => res[
|
356
|
-
:status => res[
|
357
|
-
:updated => res[
|
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
|
-
|
372
|
-
|
373
|
-
)
|
368
|
+
"LogicalResourceId" => resource.logical_id,
|
369
|
+
"StackName" => resource.stack.name,
|
370
|
+
),
|
374
371
|
).get(:body,
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
resource.
|
379
|
-
resource.
|
380
|
-
resource.
|
381
|
-
resource.
|
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
|
-
|
395
|
-
|
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
|
-
|
402
|
-
|
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[
|
402
|
+
stack.last_event_token = event["NextToken"] if event["NextToken"]
|
408
403
|
Stack::Event.new(
|
409
404
|
stack,
|
410
|
-
:id => event[
|
411
|
-
:resource_id => event[
|
412
|
-
:resource_name => event[
|
413
|
-
:resource_logical_id => event[
|
414
|
-
:resource_state => event[
|
415
|
-
:resource_status => event[
|
416
|
-
:resource_status_reason => event[
|
417
|
-
:time => Time.parse(event[
|
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
|
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
|