Class: Jets::Cfn::Status
Instance Attribute Summary collapse
Instance Method Summary
collapse
#apigateway, #cfn, #lambda, #logs, #s3, #s3_resource, #sns, #sqs, #sts
#lookup, #stack_exists?, #stack_in_progress?
Constructor Details
#initialize(options = {}) ⇒ Status
Returns a new instance of Status.
6
7
8
9
10
|
# File 'lib/jets/cfn/status.rb', line 6
def initialize(options={})
@options = options
@stack_name = Jets::Naming.parent_stack_name
reset
end
|
Instance Attribute Details
#events ⇒ Object
Returns the value of attribute events.
5
6
7
|
# File 'lib/jets/cfn/status.rb', line 5
def events
@events
end
|
Instance Method Details
#completed ⇒ Object
73
74
75
76
77
|
# File 'lib/jets/cfn/status.rb', line 73
def completed
last_event_status =~ /(_COMPLETE|_FAILED)$/ &&
@events[0]["logical_resource_id"] == @stack_name &&
@events[0]["resource_type"] == "AWS::CloudFormation::Stack"
end
|
#event_time(timestamp) ⇒ Object
120
121
122
|
# File 'lib/jets/cfn/status.rb', line 120
def event_time(timestamp)
Time.parse(timestamp.to_s).localtime.strftime("%I:%M:%S%p")
end
|
#find_index(name) ⇒ Object
136
137
138
|
# File 'lib/jets/cfn/status.rb', line 136
def find_index(name)
send("#{name}_index")
end
|
#find_update_failed_event ⇒ Object
162
163
164
165
166
167
168
169
170
171
|
# File 'lib/jets/cfn/status.rb', line 162
def find_update_failed_event
i = @events.find_index do |event|
event["resource_type"] == "AWS::CloudFormation::Stack" &&
event["resource_status_reason"] == "User Initiated"
end
@events[0..i].reverse.find do |e|
e["resource_status"] == "UPDATE_FAILED"
end
end
|
#last_event_status ⇒ Object
79
80
81
|
# File 'lib/jets/cfn/status.rb', line 79
def last_event_status
@events[0]["resource_status"]
end
|
#last_shown_index ⇒ Object
147
148
149
150
151
|
# File 'lib/jets/cfn/status.rb', line 147
def last_shown_index
@events.find_index do |event|
event["event_id"] == @last_shown_event_id
end
end
|
#messages_map ⇒ Object
189
190
191
192
193
194
195
|
# File 'lib/jets/cfn/status.rb', line 189
def messages_map
{
/CloudFormation cannot update a stack when a custom-named resource requires replacing/ => "A workaround is to run ufo again with STATIC_NAME=0 and to switch to dynamic names for resources. Then run ufo again with STATIC_NAME=1 to get back to statically name resources. Note, there are caveats with the workaround.",
/cannot be associated with more than one load balancer/ => "There's was an issue updating the stack. Target groups can only be associated with one load balancer at a time. The workaround for this is to use UFO_FORCE_TARGET_GROUP=1 and run the command again. This will force the recreation of the target group resource.",
/SetSubnets is not supported for load balancers of type/ => "Changing subnets for Network Load Balancers is currently not supported. You can try workarouding this with UFO_FORCE_ELB=1 and run the command again. This will force the recreation of the elb resource."
}
end
|
#pretty_time(total_seconds) ⇒ Object
198
199
200
201
202
203
204
205
206
|
# File 'lib/jets/cfn/status.rb', line 198
def pretty_time(total_seconds)
minutes = (total_seconds / 60) % 60
seconds = total_seconds % 60
if total_seconds < 60
"#{seconds.to_i}s"
else
"#{minutes.to_i}m #{seconds.to_i}s"
end
end
|
#print_event(e) ⇒ Object
107
108
109
110
111
112
113
114
115
116
117
|
# File 'lib/jets/cfn/status.rb', line 107
def print_event(e)
message = [
event_time(e["timestamp"]),
e["resource_status"],
e["resource_type"],
e["logical_resource_id"],
e["resource_status_reason"]
].join(" ")
message = message.colorize(:red) if e["resource_status"] =~ /_FAILED/
puts message
end
|
#print_events(i) ⇒ Object
99
100
101
102
103
104
105
|
# File 'lib/jets/cfn/status.rb', line 99
def print_events(i)
@events[0..i].reverse.each do |e|
print_event(e)
end
@last_shown_event_id = @events[0]["event_id"]
end
|
#refresh_events ⇒ Object
refreshes the loaded events in memory
125
126
127
128
129
130
131
132
133
134
|
# File 'lib/jets/cfn/status.rb', line 125
def refresh_events
resp = cfn.describe_stack_events(stack_name: @stack_name)
@events = resp["stack_events"]
rescue Aws::CloudFormation::Errors::ValidationError => e
if e.message =~ /Stack .* does not exis/
@stack_deletion_completed = true
else
raise
end
end
|
#reset ⇒ Object
36
37
38
39
40
|
# File 'lib/jets/cfn/status.rb', line 36
def reset
@events = [] @last_shown_event_id = nil
@stack_deletion_completed = nil
end
|
#rollback_error_message ⇒ Object
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
# File 'lib/jets/cfn/status.rb', line 173
def rollback_error_message
return unless update_rollback?
event = find_update_failed_event
return unless event
reason = event["resource_status_reason"]
messages_map.each do |pattern, message|
if reason =~ pattern
return message
end
end
reason end
|
#run ⇒ Object
used for the jets status command
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
# File 'lib/jets/cfn/status.rb', line 13
def run
unless stack_exists?(@stack_name)
puts "The stack #{@stack_name.colorize(:green)} does not exist."
return
end
resp = cfn.describe_stacks(stack_name: @stack_name)
stack = resp.stacks.first
puts "The current status for the stack #{@stack_name.colorize(:green)} is #{stack.stack_status.colorize(:green)}"
if stack.stack_status =~ /_IN_PROGRESS$/
puts "Stack events (tailing):"
@hide_time_took = true
wait
else
puts "Stack events:"
refresh_events
show_events(true)
end
end
|
#show_events(final = false) ⇒ Object
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
# File 'lib/jets/cfn/status.rb', line 84
def show_events(final=false)
if @last_shown_event_id.nil?
i = find_index(:start)
print_events(i)
else
i = find_index(:last_shown)
print_events(i-1) unless i == 0
end
return if final
sleep 5 unless ENV['TEST']
refresh_events
end
|
#start_index ⇒ Object
140
141
142
143
144
145
|
# File 'lib/jets/cfn/status.rb', line 140
def start_index
@events.find_index do |event|
event["resource_type"] == "AWS::CloudFormation::Stack" &&
event["resource_status_reason"] == "User Initiated"
end
end
|
#success? ⇒ Boolean
153
154
155
156
|
# File 'lib/jets/cfn/status.rb', line 153
def success?
resource_status = @events[0]["resource_status"]
%w[CREATE_COMPLETE UPDATE_COMPLETE].include?(resource_status)
end
|
#update_rollback? ⇒ Boolean
158
159
160
|
# File 'lib/jets/cfn/status.rb', line 158
def update_rollback?
@events[0]["resource_status"] == "UPDATE_ROLLBACK_COMPLETE"
end
|
#wait ⇒ Object
check for /(_COMPLETE|_FAILED)$/ status
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
# File 'lib/jets/cfn/status.rb', line 43
def wait
start_time = Time.now
refresh_events
until completed || @stack_deletion_completed
show_events
end
show_events(true)
if @stack_deletion_completed
puts "Stack #{@stack_name} deleted."
return
end
if last_event_status =~ /_FAILED/
puts "Stack failed: #{last_event_status}".colorize(:red)
puts "Stack reason #{@events[0]["resource_status_reason"]}".colorize(:red)
elsif last_event_status =~ /_ROLLBACK_/
puts "Stack rolled back: #{last_event_status}".colorize(:red)
else puts "Stack success status: #{last_event_status}".colorize(:green)
end
return if @hide_time_took took = Time.now - start_time
puts "Time took for stack deployment: #{pretty_time(took).green}."
end
|