diff --git a/devops-service/core/devops-messages.rb b/devops-service/core/devops-messages.rb index 0ec4ab4..1ccf886 100644 --- a/devops-service/core/devops-messages.rb +++ b/devops-service/core/devops-messages.rb @@ -30,7 +30,7 @@ module Devops raise "Invalid message value with key '#{key}', it must be a string" unless msg.is_a?(String) unless msg.nil? params.each do |k, v| - msg = msg.gsub("%{#{k}}", v) + msg = msg.gsub("%{#{k}}", v.to_s) end end msg diff --git a/devops-service/lib/helpers/result_object.rb b/devops-service/lib/helpers/result_object.rb index 2fc8f83..e9cf634 100644 --- a/devops-service/lib/helpers/result_object.rb +++ b/devops-service/lib/helpers/result_object.rb @@ -1,10 +1,11 @@ module Devops module Helpers class ResultObject - attr_reader :code + attr_reader :code, :reason def initialize(code) @code = code + @reason = self.class.result_codes.key(@code) || :unknown_error end def ok? @@ -15,10 +16,6 @@ module Devops !ok? end - def reason - self.class.result_codes.key(@code) || :unknown_error - end - class << self def result_codes @result_codes || {ok: 0} diff --git a/devops-service/messages/en.yml b/devops-service/messages/en.yml index 1708b5e..df4ad56 100644 --- a/devops-service/messages/en.yml +++ b/devops-service/messages/en.yml @@ -18,4 +18,12 @@ en: ok: "Server '%{server_id}' has been bootstraped (job %{job_id})." timeout_reached: "Waiting for bootstrapping '%{server_id}' (job %{job_id}) halted: timeout reached." bootstrap_error: "Server '%{server_id}' bootstrapping failed (job %{job_id})." - deploy_error: "Server '%{server_id}' deploy failed (job %{job_id})." \ No newline at end of file + deploy_error: "Server '%{server_id}' deploy failed (job %{job_id})." + stack_synchronizer: + result: + ok: "Stack '%{stack_id}' status is now %{status}" + stack_rolled_back: "Stack '%{stack_id}' status is now %{status}" + stack_deleted: "Stack '%{stack_id}' status is now %{status}" + stack_not_found: "Stack '%{stack_id}' status is now %{status}" + unkown_status: "Unknown stack status: '%{status}'" + timeout: "Stack hasn't been synced in %{seconds} seconds." \ No newline at end of file diff --git a/devops-service/spec/workers/stack_bootstrap/stack_synchronizer_spec.rb b/devops-service/spec/workers/stack_bootstrap/stack_synchronizer_spec.rb index be7c13b..9d5a305 100644 --- a/devops-service/spec/workers/stack_bootstrap/stack_synchronizer_spec.rb +++ b/devops-service/spec/workers/stack_bootstrap/stack_synchronizer_spec.rb @@ -1,5 +1,5 @@ require 'workers/stack_bootstrap/stack_synchronizer' -RSpec.describe StackSynchronizer, stubbed_connector: true do +RSpec.describe StackSynchronizer, stubbed_connector: true, init_messages: true do let(:out) { double(:out, puts: nil, flush: nil) } let(:stack) { build(:stack) } let(:syncer) { described_class.new(stack, out) } @@ -9,9 +9,6 @@ RSpec.describe StackSynchronizer, stubbed_connector: true do allow(stack).to receive(:events).and_return( [{'event_id' => 1}] ) allow(syncer).to receive(:sleep) allow(stubbed_connector).to receive(:stack_update) - - # lots_of_statuses = ['CREATE_IN_PROGRESS'] * 10 + ['CREATE_COMPLETE'] - # allow(stack).to receive(:stack_status).and_return(*lots_of_statuses) end def setup_statuses(statuses_array) @@ -36,15 +33,15 @@ RSpec.describe StackSynchronizer, stubbed_connector: true do allow(stack).to receive(:events).and_return([event1], [event1, event2], [event1, event2, event3]) setup_statuses(['CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_COMPLETE']) + expect(syncer).to receive(:sleep).exactly(4).times + expect(out).to receive(:puts).with(/t1/).once.ordered + expect(out).to receive(:puts).with(/t2/).once.ordered + expect(out).to receive(:puts).with(/t3/).once.ordered syncer.sync - expect(out).to have_received(:puts).with(/t1/).once.ordered - expect(out).to have_received(:puts).with(/t2/).once.ordered - expect(out).to have_received(:puts).with(/t3/).once.ordered end it 'updates stack when status is changed' do setup_statuses(['CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE']) - expect(stubbed_connector).to receive(:stack_update).exactly(3).times syncer.sync end @@ -53,6 +50,7 @@ RSpec.describe StackSynchronizer, stubbed_connector: true do it 'updates stack in DB when stack creating is finished and returns 0' do setup_statuses(['CREATE_COMPLETE']) expect(stubbed_connector).to receive(:stack_update).with(stack) + expect(out).to receive(:puts).with(/CREATE_COMPLETE/) expect(syncer.sync).to be_ok end end @@ -60,6 +58,7 @@ RSpec.describe StackSynchronizer, stubbed_connector: true do context 'when stack was rollbacked' do it 'returns 1 (:stack_rolled_back)' do setup_statuses(['CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE']) + expect(out).to receive(:puts).with(/ROLLBACK_COMPLETE/) expect(syncer.sync).to be_stack_rolled_back end end @@ -67,6 +66,7 @@ RSpec.describe StackSynchronizer, stubbed_connector: true do context 'when unkown stack status was found' do it 'returns 2 (:unkown_status)' do setup_statuses(['CREATE_IN_PROGRESS', 'unknown']) + expect(out).to receive(:puts).with(/unknown/) expect(syncer.sync).to be_unkown_status end end @@ -74,6 +74,7 @@ RSpec.describe StackSynchronizer, stubbed_connector: true do context "when stack hasn't been synced in an hour" do it 'returns 3 (:timeout)' do allow(stack).to receive(:stack_status) {'CREATE_IN_PROGRESS'} + expect(out).to receive(:puts).with(/hasn't been synced/) expect(syncer.sync).to be_timeout end end diff --git a/devops-service/workers/stack_bootstrap/stack_synchronizer.rb b/devops-service/workers/stack_bootstrap/stack_synchronizer.rb index 26c4972..d036ec1 100644 --- a/devops-service/workers/stack_bootstrap/stack_synchronizer.rb +++ b/devops-service/workers/stack_bootstrap/stack_synchronizer.rb @@ -18,30 +18,24 @@ class StackSynchronizer def initialize(stack, out) @stack, @out = stack, out @printed_events = [] + @sync_result = nil end def sync puts_and_flush "Syncing stack '#{stack.id}'..." - sleep_times.each do |sleep_time| + sleep_times.detect do |sleep_time| sleep sleep_time stack.sync! print_new_events update_stack_status if stack_status_changed? - - case stack.stack_status - when 'CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'DELETE_IN_PROGRESS' - when 'CREATE_COMPLETE', 'ROLLBACK_COMPLETE', 'DELETE_COMPLETE', 'CREATE_FAILED', 'NOT_FOUND' - puts_and_flush "Stack '#{stack.id}' status is now #{stack.stack_status}" - return result_for_provider_status(stack.stack_status) - else - puts_and_flush "Unknown stack status: '#{stack.stack_status}'" - return result(:unkown_status) - end + stack_is_already_created_or_failed? end - puts_and_flush "Stack hasn't been synced in #{sleep_times.inject(&:+)} seconds." - result(:timeout) + + @sync_result ||= result(:timeout) + print_result_message + @sync_result rescue StandardError => e DevopsLogger.logger.error e.message puts_and_flush "Error: #{e.class}: #{e.message}\n#{e.backtrace.join("\n")}" @@ -50,6 +44,17 @@ class StackSynchronizer private + 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 + def sleep_times [5]*5 + [10]*400 end @@ -68,6 +73,11 @@ class StackSynchronizer result(provider_status_mapping.fetch(status)) end + 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 + def update_stack_status ::Devops::Db.connector.stack_update(stack) @last_status = stack.stack_status