| 
									
										
										
										
											2016-03-27 23:37:57 +03:00
										 |  |  | # Polling stack status until it's completed or failed. | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  | class StackSynchronizer | 
					
						
							|  |  |  |   include PutsAndFlush | 
					
						
							|  |  |  |   attr_reader :out, :stack | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-25 14:50:22 +03:00
										 |  |  |   class SyncResult < Devops::Helpers::ResultObject | 
					
						
							| 
									
										
										
										
											2016-03-27 23:37:57 +03:00
										 |  |  |     set_result_codes( | 
					
						
							|  |  |  |       ok: 0, | 
					
						
							|  |  |  |       stack_rolled_back: 1, | 
					
						
							|  |  |  |       unkown_status: 2, | 
					
						
							|  |  |  |       timeout: 3, | 
					
						
							|  |  |  |       error: 5, | 
					
						
							|  |  |  |       stack_deleted: 6, | 
					
						
							|  |  |  |       stack_not_found: 7
 | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2016-03-25 14:50:22 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |   def initialize(stack, out) | 
					
						
							|  |  |  |     @stack, @out = stack, out | 
					
						
							|  |  |  |     @printed_events = [] | 
					
						
							| 
									
										
										
										
											2016-03-28 00:16:11 +03:00
										 |  |  |     @sync_result = nil | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def sync | 
					
						
							|  |  |  |     puts_and_flush "Syncing stack '#{stack.id}'..." | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-28 00:16:11 +03:00
										 |  |  |     sleep_times.detect do |sleep_time| | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |       sleep sleep_time | 
					
						
							| 
									
										
										
										
											2016-02-24 21:26:44 +03:00
										 |  |  |       stack.sync! | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |       print_new_events | 
					
						
							| 
									
										
										
										
											2016-03-23 18:35:05 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |       update_stack_status if stack_status_changed? | 
					
						
							| 
									
										
										
										
											2016-03-28 00:16:11 +03:00
										 |  |  |       stack_is_already_created_or_failed? | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-03-28 00:16:11 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @sync_result ||= result(:timeout) | 
					
						
							|  |  |  |     print_result_message | 
					
						
							|  |  |  |     @sync_result | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |   rescue StandardError => e | 
					
						
							|  |  |  |     DevopsLogger.logger.error e.message | 
					
						
							| 
									
										
										
										
											2016-03-23 18:35:05 +03:00
										 |  |  |     puts_and_flush "Error: #{e.class}: #{e.message}\n#{e.backtrace.join("\n")}" | 
					
						
							| 
									
										
										
										
											2016-03-25 14:50:22 +03:00
										 |  |  |     result(:error) | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-25 14:50:22 +03:00
										 |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-28 00:16:11 +03:00
										 |  |  |   def stack_is_already_created_or_failed? | 
					
						
							|  |  |  |     case stack.stack_status | 
					
						
							|  |  |  |     when 'CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'DELETE_IN_PROGRESS' | 
					
						
							|  |  |  |       false | 
					
						
							|  |  |  |     when 'CREATE_COMPLETE', 'ROLLBACK_COMPLETE', 'DELETE_COMPLETE', 'CREATE_FAILED', 'NOT_FOUND' | 
					
						
							|  |  |  |       @sync_result = result_for_provider_status(stack.stack_status) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       @sync_result = result(:unkown_status) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-25 14:50:22 +03:00
										 |  |  |   def sleep_times | 
					
						
							|  |  |  |     [5]*5 + [10]*400
 | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-25 14:50:22 +03:00
										 |  |  |   def result(reason) | 
					
						
							|  |  |  |     SyncResult.from_reason(reason) | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-25 14:50:22 +03:00
										 |  |  |   def result_for_provider_status(status) | 
					
						
							|  |  |  |     provider_status_mapping = { | 
					
						
							|  |  |  |       'CREATE_COMPLETE' => :ok, | 
					
						
							|  |  |  |       'ROLLBACK_COMPLETE' => :stack_rolled_back, | 
					
						
							|  |  |  |       'DELETE_COMPLETE' => :stack_deleted, | 
					
						
							|  |  |  |       'NOT_FOUND' => :stack_not_found | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     result(provider_status_mapping.fetch(status)) | 
					
						
							| 
									
										
										
										
											2016-03-23 18:35:05 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-28 00:16:11 +03:00
										 |  |  |   def print_result_message | 
					
						
							|  |  |  |     puts_and_flush Devops::Messages.t("stack_synchronizer.result.#{@sync_result.reason}", | 
					
						
							|  |  |  |       stack_id: stack.id, status: stack.stack_status, seconds: sleep_times.inject(&:+)) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 18:35:05 +03:00
										 |  |  |   def update_stack_status | 
					
						
							|  |  |  |     ::Devops::Db.connector.stack_update(stack) | 
					
						
							|  |  |  |     @last_status = stack.stack_status | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def stack_status_changed? | 
					
						
							|  |  |  |     @last_status != stack.stack_status | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |   def print_new_events | 
					
						
							|  |  |  |     stack.events.each do |event| | 
					
						
							|  |  |  |       unless @printed_events.include?(event["event_id"]) | 
					
						
							|  |  |  |         @printed_events << event["event_id"] | 
					
						
							|  |  |  |         out.puts "#{event["timestamp"]} - #{event["status"]}: #{event["reason"]}" | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     out.flush | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |