diff --git a/app/models/mixins/process_tasks_mixin.rb b/app/models/mixins/process_tasks_mixin.rb index ee40a7298d4..f6bb7ed86b2 100644 --- a/app/models/mixins/process_tasks_mixin.rb +++ b/app/models/mixins/process_tasks_mixin.rb @@ -7,7 +7,7 @@ module ClassMethods def process_tasks(options) raise _("No ids given to process_tasks") if options[:ids].blank? if options[:task] == 'retire_now' - name.constantize.make_retire_request(*options[:ids]) + name.constantize.make_retire_request(*options[:ids], User.current_user) elsif options[:task] == "refresh_ems" && respond_to?("refresh_ems") refresh_ems(options[:ids]) msg = "'#{options[:task]}' initiated for #{options[:ids].length} #{ui_lookup(:table => base_class.name).pluralize}" diff --git a/app/models/mixins/retirement_mixin.rb b/app/models/mixins/retirement_mixin.rb index b683991cd31..4ebdfd8d088 100644 --- a/app/models/mixins/retirement_mixin.rb +++ b/app/models/mixins/retirement_mixin.rb @@ -10,10 +10,10 @@ module RetirementMixin end module ClassMethods - def make_retire_request(*src_ids) + def make_retire_request(*src_ids, requester) klass = (name.demodulize + "RetireRequest").constantize - options = {:src_ids => src_ids.presence || id, :__request_type__ => klass.request_types.first} - klass.make_request(nil, options, User.current_user, true) + options = {:src_ids => src_ids.presence, :__request_type__ => klass.request_types.first} + klass.make_request(nil, options, requester, true) end def retire(ids, options = {}) @@ -112,18 +112,19 @@ def raise_retire_audit_event(message) def retirement_check return if retired? || retiring? || retirement_initialized? + requester = system_context_requester if !retirement_warned? && retirement_warning_due? begin self.retirement_last_warn = Time.now.utc save - raise_retirement_event(retire_warn_event_name) + raise_retirement_event(retire_warn_event_name, requester) rescue => err _log.log_backtrace(err) end end - self.class.make_retire_request(self.id) if retirement_due? + self.class.make_retire_request(id, requester) if retirement_due? end def retire_now(requester = nil) @@ -140,7 +141,7 @@ def retire_now(requester = nil) event_name = "request_#{retirement_event_prefix}_retire" _log.info("calling #{event_name}") begin - raise_retirement_event(event_name, requester) + raise_retirement_event(event_name, requester ||= current_user) rescue => err _log.log_backtrace(err) end @@ -201,14 +202,12 @@ def retired_event_name end def raise_retirement_event(event_name, requester = nil) - requester ||= User.current_user.try(:userid) - q_options = retire_queue_options - $log.info("Requester [#{requester}] raising Retirement Event for [#{name}] with queue options: #{q_options.inspect}") + q_options = q_user_info(retire_queue_options, requester) + $log.info("Raising Retirement Event for [#{name}] with queue options: #{q_options.inspect}") MiqEvent.raise_evm_event(self, event_name, setup_event_hash(requester), q_options) end def raise_audit_event(event_name, message, requester = nil) - requester ||= User.current_user.try(:userid) event_hash = { :target_class => retirement_base_model_name, :target_id => id.to_s, @@ -237,15 +236,39 @@ def valid_zone? respond_to?(:my_zone) && my_zone.present? end + def system_context_requester + if try(:evm_owner_id).present? + User.find(evm_owner_id) + else + $log.info("System context defaulting to admin user because owner of #{name} not set.") + User.find_by(:userid => 'admin') + end + end + + def current_user + User.find_by(:userid => User.current_user.try(:userid)) + end + + def q_user_info(q_options, requester) + if requester.present? + if requester.kind_of?(String) + requester = User.find_by(:userid => requester) + end + q_options[:user_id] = requester.id + if requester.current_group.present? && requester.current_tenant.present? + q_options[:group_id] = requester.current_group.id + q_options[:tenant_id] = requester.current_tenant.id + end + end + q_options + end + def setup_event_hash(requester) - event_hash = {:retirement_initiator => "system"} - event_hash[retirement_base_model_name.underscore.to_sym] = self - event_hash[:host] = host if self.respond_to?(:host) - if requester - event_hash[:userid] = requester - event_hash[:retirement_initiator] = "user" + {}.tap do |event| + event[:userid] = requester + event[retirement_base_model_name.underscore.to_sym] = self + event[:host] = host if respond_to?(:host) + event[:type] ||= self.class.name end - event_hash[:type] ||= self.class.name - event_hash end end diff --git a/spec/models/orchestration_stack/retirement_management_spec.rb b/spec/models/orchestration_stack/retirement_management_spec.rb index 07db310ded3..be71e50205b 100644 --- a/spec/models/orchestration_stack/retirement_management_spec.rb +++ b/spec/models/orchestration_stack/retirement_management_spec.rb @@ -1,12 +1,14 @@ describe "Service Retirement Management" do - let(:user) { FactoryGirl.create(:user_miq_request_approver, :userid => "admin") } - before do - @miq_server = EvmSpecHelper.local_miq_server - @stack = FactoryGirl.create(:orchestration_stack) - end + let!(:user) { FactoryGirl.create(:user_miq_request_approver, :userid => "admin") } + context "with zone/ems" do + before do + @miq_server = EvmSpecHelper.local_miq_server + @zone = @miq_server.zone + ems = FactoryGirl.create(:ext_management_system, :zone => @zone) + @stack = FactoryGirl.create(:orchestration_stack, :ext_management_system => ems) + end - it "#retirement_check" do - User.with_user(user) do + it "#retirement_check" do expect(MiqEvent).to receive(:raise_evm_event) @stack.update_attributes(:retires_on => 90.days.ago, :retirement_warn => 60, :retirement_last_warn => nil) expect(@stack.retirement_last_warn).to be_nil @@ -14,140 +16,147 @@ @stack.reload expect(@stack.retirement_last_warn).not_to be_nil end - end - it "#start_retirement" do - expect(@stack.retirement_state).to be_nil - @stack.start_retirement - @stack.reload - expect(@stack.retirement_state).to eq("retiring") - end - - it "#retire_now" do - expect(@stack.retirement_state).to be_nil - expect(OrchestrationStackRetireRequest).to_not receive(:make_request) - @stack.retire_now - @stack.reload - end + it "#start_retirement" do + expect(@stack.retirement_state).to be_nil + @stack.start_retirement + @stack.reload + expect(@stack.retirement_state).to eq("retiring") + end - it "#retire_now with userid" do - expect(@stack.retirement_state).to be_nil - event_name = 'request_orchestration_stack_retire' - event_hash = {:orchestration_stack => @stack, :type => "OrchestrationStack", - :retirement_initiator => "user", :userid => "freddy"} + it "#retire_now" do + expect(@stack.retirement_state).to be_nil + expect(OrchestrationStackRetireRequest).to_not receive(:make_request) + @stack.retire_now + @stack.reload + end - expect(OrchestrationStackRetireRequest).to_not receive(:make_request) + it "#retire_now with userid" do + expect(@stack.retirement_state).to be_nil + expect(OrchestrationStackRetireRequest).to_not receive(:make_request) - @stack.retire_now('freddy') - @stack.reload - end + @stack.retire_now('freddy') + @stack.reload + end - it "#retire_now without userid" do - expect(@stack.retirement_state).to be_nil - event_name = 'request_orchestration_stack_retire' - event_hash = {:orchestration_stack => @stack, :type => "OrchestrationStack", - :retirement_initiator => "system"} + it "#retire_now without userid" do + expect(@stack.retirement_state).to be_nil + expect(OrchestrationStackRetireRequest).to_not receive(:make_request) - expect(OrchestrationStackRetireRequest).to_not receive(:make_request) + @stack.retire_now + @stack.reload + end - @stack.retire_now - @stack.reload - end + it "#retire warn" do + expect(AuditEvent).to receive(:success).once + options = {} + options[:warn] = 2.days.to_i + @stack.retire(options) + @stack.reload + expect(@stack.retirement_warn).to eq(options[:warn]) + end - it "#retire warn" do - expect(AuditEvent).to receive(:success).once - options = {} - options[:warn] = 2.days.to_i - @stack.retire(options) - @stack.reload - expect(@stack.retirement_warn).to eq(options[:warn]) - end + it "#retire date" do + expect(AuditEvent).to receive(:success).once + options = {} + options[:date] = Time.zone.today + @stack.retire(options) + @stack.reload + expect(@stack.retires_on).to eq(options[:date]) + end - it "#retire date" do - expect(AuditEvent).to receive(:success).once - options = {} - options[:date] = Time.zone.today - @stack.retire(options) - @stack.reload - expect(@stack.retires_on).to eq(options[:date]) - end + it "#finish_retirement" do + expect(@stack.retirement_state).to be_nil + @stack.finish_retirement + @stack.reload + expect(@stack.retired).to be_truthy + expect(@stack.retires_on).to be_between(Time.zone.now - 1.hour, Time.zone.now + 1.second) + expect(@stack.retirement_state).to eq("retired") + end - it "#finish_retirement" do - expect(@stack.retirement_state).to be_nil - @stack.finish_retirement - @stack.reload - expect(@stack.retired).to be_truthy - expect(@stack.retires_on).to be_between(Time.zone.now - 1.hour, Time.zone.now + 1.second) - expect(@stack.retirement_state).to eq("retired") - end + it "#retiring - false" do + expect(@stack.retirement_state).to be_nil + expect(@stack.retiring?).to be_falsey + end - it "#retiring - false" do - expect(@stack.retirement_state).to be_nil - expect(@stack.retiring?).to be_falsey - end + it "#retiring - true" do + @stack.update_attributes(:retirement_state => 'retiring') + expect(@stack.retiring?).to be_truthy + end - it "#retiring - true" do - @stack.update_attributes(:retirement_state => 'retiring') - expect(@stack.retiring?).to be_truthy - end + it "#error_retiring - false" do + expect(@stack.retirement_state).to be_nil + expect(@stack.error_retiring?).to be_falsey + end - it "#error_retiring - false" do - expect(@stack.retirement_state).to be_nil - expect(@stack.error_retiring?).to be_falsey - end + it "#error_retiring - true" do + @stack.update_attributes(:retirement_state => 'error') + expect(@stack.error_retiring?).to be_truthy + end - it "#error_retiring - true" do - @stack.update_attributes(:retirement_state => 'error') - expect(@stack.error_retiring?).to be_truthy - end + it "#retires_on - today" do + expect(@stack.retirement_due?).to be_falsey + @stack.retires_on = Time.zone.today + expect(@stack.retirement_due?).to be_truthy + end - it "#retires_on - today" do - expect(@stack.retirement_due?).to be_falsey - @stack.retires_on = Time.zone.today - expect(@stack.retirement_due?).to be_truthy - end + it "#retires_on - tomorrow" do + expect(@stack.retirement_due?).to be_falsey + @stack.retires_on = Time.zone.today + 1 + expect(@stack.retirement_due?).to be_falsey + end - it "#retires_on - tomorrow" do - expect(@stack.retirement_due?).to be_falsey - @stack.retires_on = Time.zone.today + 1 - expect(@stack.retirement_due?).to be_falsey - end + it "#retirement_due?" do + expect(@stack.retirement_due?).to be_falsey - it "#retirement_due?" do - expect(@stack.retirement_due?).to be_falsey + @stack.update_attributes(:retires_on => Time.zone.today + 1.day) + expect(@stack.retirement_due?).to be_falsey - @stack.update_attributes(:retires_on => Time.zone.today + 1.day) - expect(@stack.retirement_due?).to be_falsey + @stack.update_attributes(:retires_on => Time.zone.today) + expect(@stack.retirement_due?).to be_truthy - @stack.update_attributes(:retires_on => Time.zone.today) - expect(@stack.retirement_due?).to be_truthy + @stack.update_attributes(:retires_on => Time.zone.today - 1.day) + expect(@stack.retirement_due?).to be_truthy + end - @stack.update_attributes(:retires_on => Time.zone.today - 1.day) - expect(@stack.retirement_due?).to be_truthy - end + it "#raise_retirement_event" do + event_name = 'foo' + event_hash = { + :userid => nil, + :orchestration_stack => @stack, + :type => "OrchestrationStack", + } - it "#raise_retirement_event" do - event_name = 'foo' - event_hash = { - :orchestration_stack => @stack, - :type => "OrchestrationStack", - :retirement_initiator => "system" - } + expect(MiqEvent).to receive(:raise_evm_event).with(@stack, event_name, event_hash, :zone => @zone.name) + @stack.raise_retirement_event(event_name) + end - expect(MiqEvent).to receive(:raise_evm_event).with(@stack, event_name, event_hash, {}) - @stack.raise_retirement_event(event_name) + it "#raise_audit_event" do + event_name = 'foo' + message = 'bar' + event_hash = { + :target_class => "OrchestrationStack", + :target_id => @stack.id.to_s, + :event => event_name, + :message => message + } + expect(AuditEvent).to receive(:success).with(event_hash) + @stack.raise_audit_event(event_name, message) + end end - it "#raise_audit_event" do - event_name = 'foo' - message = 'bar' - event_hash = { - :target_class => "OrchestrationStack", - :target_id => @stack.id.to_s, - :event => event_name, - :message => message - } - expect(AuditEvent).to receive(:success).with(event_hash) - @stack.raise_audit_event(event_name, message) + context "without zone/ems" do + it "#raise_retirement_event" do + stack_without_zone = FactoryGirl.create(:orchestration_stack, :ext_management_system => nil) + event_name = 'foo' + event_hash = { + :userid => nil, + :orchestration_stack => stack_without_zone, + :type => "OrchestrationStack", + } + + expect(MiqEvent).to receive(:raise_evm_event).with(stack_without_zone, event_name, event_hash, {}) + stack_without_zone.raise_retirement_event(event_name) + end end end diff --git a/spec/models/service/retirement_management_spec.rb b/spec/models/service/retirement_management_spec.rb index 691c8eb0a33..8cefda8f357 100644 --- a/spec/models/service/retirement_management_spec.rb +++ b/spec/models/service/retirement_management_spec.rb @@ -1,19 +1,34 @@ describe "Service Retirement Management" do - let(:user) { FactoryGirl.create(:user_miq_request_approver, :userid => "admin") } + let!(:user) { FactoryGirl.create(:user_miq_request_approver, :userid => 'admin') } + let(:service_without_owner) { FactoryGirl.create(:service) } before do @server = EvmSpecHelper.local_miq_server - @service = FactoryGirl.create(:service) + @service = FactoryGirl.create(:service, :evm_owner_id => user.id) end # shouldn't be running make_retire_request because it's the bimodal not from ui part - it "#retirement_check" do - User.with_user(user) do + context "with user" do + it "#retirement_check" do + User.with_user(user) do + expect(MiqEvent).to receive(:raise_evm_event) + @service.update_attributes(:retires_on => 90.days.ago, :retirement_warn => 60, :retirement_last_warn => nil) + expect(@service.retirement_last_warn).to be_nil + @service.retirement_check + @service.reload + expect(@service.retirement_last_warn).not_to be_nil + end + end + end + + context "without user" do + it "#retirement_check" do expect(MiqEvent).to receive(:raise_evm_event) - @service.update_attributes(:retires_on => 90.days.ago, :retirement_warn => 60, :retirement_last_warn => nil) - expect(@service.retirement_last_warn).to be_nil - @service.retirement_check - @service.reload - expect(@service.retirement_last_warn).not_to be_nil + service_without_owner.update_attributes(:retires_on => 90.days.ago, :retirement_warn => 60, :retirement_last_warn => nil) + expect(service_without_owner.retirement_last_warn).to be_nil + service_without_owner.retirement_check + service_without_owner.reload + expect(service_without_owner.retirement_last_warn).not_to be_nil + expect(MiqRequest.first.userid).to eq("admin") end end @@ -53,19 +68,18 @@ it "#retire_now with userid" do expect(@service.retirement_state).to be_nil event_name = 'request_service_retire' - event_hash = {:service => @service, :type => "Service", - :retirement_initiator => "user", :userid => "freddy"} + event_hash = {:userid => user.userid, :service => @service, :type => "Service"} + options = {:user_id => user.id, :group_id => MiqGroup.last.id, :tenant_id => Tenant.first.id} - expect(MiqEvent).to receive(:raise_evm_event).with(@service, event_name, event_hash, {}).once + expect(MiqEvent).to receive(:raise_evm_event).with(@service, event_name, event_hash, options).once - @service.retire_now('freddy') + @service.retire_now(user.userid) end it "#retire_now without userid" do expect(@service.retirement_state).to be_nil event_name = 'request_service_retire' - event_hash = {:service => @service, :type => "Service", - :retirement_initiator => "system"} + event_hash = {:userid => nil, :service => @service, :type => "Service"} expect(MiqEvent).to receive(:raise_evm_event).with(@service, event_name, event_hash, {}).once @@ -84,13 +98,13 @@ it "with one src_id" do User.current_user = user expect(ServiceRetireRequest).to receive(:make_request).with(nil, {:src_ids => ['yabadabadoo'], :__request_type__ => "service_retire"}, User.current_user, true) - @service.class.to_s.demodulize.constantize.make_retire_request('yabadabadoo') + @service.class.to_s.demodulize.constantize.make_retire_request('yabadabadoo', User.current_user) end it "with many src_ids" do User.current_user = user expect(ServiceRetireRequest).to receive(:make_request).with(nil, {:src_ids => [1, 2, 3], :__request_type__ => "service_retire"}, User.current_user, true) - @service.class.to_s.demodulize.constantize.make_retire_request(1, 2, 3) + @service.class.to_s.demodulize.constantize.make_retire_request(1, 2, 3, User.current_user) end it "#retire date" do @@ -187,7 +201,7 @@ it "#raise_retirement_event" do event_name = 'foo' - event_hash = {:service => @service, :type => "Service", :retirement_initiator => "system"} + event_hash = {:userid => nil, :service => @service, :type => "Service"} expect(MiqEvent).to receive(:raise_evm_event).with(@service, event_name, event_hash, {}) @service.raise_retirement_event(event_name) end diff --git a/spec/models/vm/retirement_management_spec.rb b/spec/models/vm/retirement_management_spec.rb index f68b92633ea..27587740326 100644 --- a/spec/models/vm/retirement_management_spec.rb +++ b/spec/models/vm/retirement_management_spec.rb @@ -1,23 +1,20 @@ describe "VM Retirement Management" do - let(:user) { FactoryGirl.create(:user_miq_request_approver, :userid => "admin") } + let!(:user) { FactoryGirl.create(:user_miq_request_approver) } let(:region) { FactoryGirl.create(:miq_region, :region => ApplicationRecord.my_region_number) } before do - miq_server = EvmSpecHelper.local_miq_server - @zone = miq_server.zone + @zone = EvmSpecHelper.local_miq_server.zone @ems = FactoryGirl.create(:ems_vmware, :zone => @zone) - @vm = FactoryGirl.create(:vm_vmware, :ems_id => @ems.id) + @vm = FactoryGirl.create(:vm_vmware, :ems_id => @ems.id, :evm_owner => user) end it "#retirement_check" do - User.with_user(user) do - expect(MiqEvent).to receive(:raise_evm_event).once - @vm.update_attributes(:retires_on => 90.days.ago, :retirement_warn => 60, :retirement_last_warn => nil) - expect(@vm.retirement_last_warn).to be_nil - @vm.retirement_check - @vm.reload - expect(@vm.retirement_last_warn).not_to be_nil - end + expect(MiqEvent).to receive(:raise_evm_event).once + @vm.update_attributes(:retires_on => 90.days.ago, :retirement_warn => 60, :retirement_last_warn => nil) + expect(@vm.retirement_last_warn).to be_nil + @vm.retirement_check + @vm.reload + expect(@vm.retirement_last_warn).not_to be_nil end it "#start_retirement" do @@ -30,14 +27,13 @@ it "#retire_now" do expect(MiqEvent).to receive(:raise_evm_event).once - @vm.retire_now expect(@vm.retirement_state).to eq('initializing') end it "#retire_now when called more than once" do expect(MiqEvent).to receive(:raise_evm_event).once - 3.times { @vm.retire_now } + 3.times { @vm.retire_now(user) } expect(@vm.retirement_state).to eq('initializing') end @@ -55,22 +51,20 @@ it "#retire_now with userid" do event_name = 'request_vm_retire' - event_hash = {:vm => @vm, :host => @vm.host, :type => "ManageIQ::Providers::Vmware::InfraManager::Vm", - :retirement_initiator => "user", :userid => 'freddy'} - options = {:zone => @zone.name} + event_hash = {:userid => user.userid, :vm => @vm, :host => @vm.host, :type => "ManageIQ::Providers::Vmware::InfraManager::Vm"} + options = {:zone => @zone.name, :user_id => user.id, :group_id => MiqGroup.last.id, :tenant_id => Tenant.last.id} expect(MiqEvent).to receive(:raise_evm_event).with(@vm, event_name, event_hash, options).once - @vm.retire_now('freddy') + @vm.retire_now(user.userid) end it "#retire_now without userid" do event_name = 'request_vm_retire' - event_hash = {:vm => @vm, :host => @vm.host, :type => "ManageIQ::Providers::Vmware::InfraManager::Vm", - :retirement_initiator => "system"} + event_hash = {:userid => nil, :vm => @vm, :host => @vm.host, :type => "ManageIQ::Providers::Vmware::InfraManager::Vm"} options = {:zone => @zone.name} - expect(MiqEvent).to receive(:raise_evm_event).with(@vm, event_name, event_hash, options).once + expect(MiqEvent).to receive(:raise_evm_event).with(@vm, event_name, event_hash, :zone => @zone.name).once @vm.retire_now end @@ -86,15 +80,13 @@ describe "retire request" do it "with one src_id" do - User.current_user = user expect(VmRetireRequest).to receive(:make_request).with(nil, {:src_ids => ['yabadabadoo'], :__request_type__ => "vm_retire"}, User.current_user, true) - @vm.class.to_s.demodulize.constantize.make_retire_request('yabadabadoo') + @vm.class.to_s.demodulize.constantize.make_retire_request('yabadabadoo', User.current_user) end it "with many src_ids" do - User.current_user = user expect(VmRetireRequest).to receive(:make_request).with(nil, {:src_ids => [1, 2, 3], :__request_type__ => "vm_retire"}, User.current_user, true) - @vm.class.to_s.demodulize.constantize.make_retire_request(1, 2, 3) + @vm.class.to_s.demodulize.constantize.make_retire_request(1, 2, 3, User.current_user) end end @@ -168,28 +160,22 @@ expect(vm.retirement_due?).to be_truthy end - it "#raise_retirement_event without current user" do + it "#raise_retirement_event without user" do event_name = 'foo' - event_hash = {:vm => @vm, :host => @vm.host, :type => "ManageIQ::Providers::Vmware::InfraManager::Vm", - :retirement_initiator => "system"} - options = {:zone => @vm.my_zone} + event_hash = {:userid => nil, :vm => @vm, :host => @vm.host, :type => "ManageIQ::Providers::Vmware::InfraManager::Vm"} - expect(MiqEvent).to receive(:raise_evm_event).with(@vm, event_name, event_hash, options).once + expect(MiqEvent).to receive(:raise_evm_event).with(@vm, event_name, event_hash, :zone => @zone.name).once @vm.raise_retirement_event(event_name) end - it "#raise_retirement_event with current user" do - user = FactoryGirl.create(:user_with_group, :userid => 'freddy') + it "#raise_retirement_event with user" do event_name = 'foo' - event_hash = {:vm => @vm, :host => @vm.host, :type => "ManageIQ::Providers::Vmware::InfraManager::Vm", - :retirement_initiator => "user", :userid => 'freddy'} - options = {:zone => @vm.my_zone} + event_hash = {:userid => user, :vm => @vm, :host => @vm.host, :type => "ManageIQ::Providers::Vmware::InfraManager::Vm"} + options = {:zone => @zone.name, :user_id => user.id, :group_id => user.current_group_id, :tenant_id => user.current_tenant.id } - User.with_user(user) do - expect(MiqEvent).to receive(:raise_evm_event).with(@vm, event_name, event_hash, options).once - @vm.raise_retirement_event(event_name) - end + expect(MiqEvent).to receive(:raise_evm_event).with(@vm, event_name, event_hash, options).once + @vm.raise_retirement_event(event_name, user) end it "#raise_audit_event" do