From 42aebe6f06fc61bae548b0f8007d4784211e942c Mon Sep 17 00:00:00 2001 From: d-m-u Date: Thu, 1 Feb 2018 13:30:58 -0500 Subject: [PATCH 1/3] Add skeleton task and request for vm migrate --- app/models/miq_request.rb | 3 + app/models/mixins/retirement_mixin.rb | 10 ++- app/models/vm_retire_request.rb | 17 +++++ app/models/vm_retire_task.rb | 106 ++++++++++++++++++++++++++ spec/factories/vm_retire_request.rb | 3 + spec/factories/vm_retire_task.rb | 3 + spec/models/miq_request_spec.rb | 1 + 7 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 app/models/vm_retire_request.rb create mode 100644 app/models/vm_retire_task.rb create mode 100644 spec/factories/vm_retire_request.rb create mode 100644 spec/factories/vm_retire_task.rb diff --git a/app/models/miq_request.rb b/app/models/miq_request.rb index 06c31853abf..99849847e27 100644 --- a/app/models/miq_request.rb +++ b/app/models/miq_request.rb @@ -77,6 +77,9 @@ class MiqRequest < ApplicationRecord :VmMigrateRequest => { :vm_migrate => N_("VM Migrate") }, + :VmRetireRequest => { + :vm_retire => N_("VM Retire") + }, :ServiceTemplateProvisionRequest => { :clone_to_service => N_("Service Provision") }, diff --git a/app/models/mixins/retirement_mixin.rb b/app/models/mixins/retirement_mixin.rb index a2ee2e75c65..3c894398a1f 100644 --- a/app/models/mixins/retirement_mixin.rb +++ b/app/models/mixins/retirement_mixin.rb @@ -125,11 +125,13 @@ def retire_now(requester = nil) return if retired_validated? _log.info("#{retirement_object_title}: [#{name}], Retires On: [#{retires_on.strftime("%x %R %Z")}], was previously retired, but currently #{retired_invalid_reason}") else - update_attributes(:retirement_requester => requester) - event_name = "request_#{retirement_event_prefix}_retire" - _log.info("calling #{event_name}") + _log.info("Creating request for #{self.class.name} #{id}") begin - raise_retirement_event(event_name, requester) + options = {:src_ids => id} + VmRetireRequest.make_request(@request_id, options, User.current_user.try(:userid)) + + # still need the next line for orchestration and services + # raise_retirement_event(event_name, requester) rescue => err _log.log_backtrace(err) end diff --git a/app/models/vm_retire_request.rb b/app/models/vm_retire_request.rb new file mode 100644 index 00000000000..18052362387 --- /dev/null +++ b/app/models/vm_retire_request.rb @@ -0,0 +1,17 @@ +class VmRetireRequest < MiqRequest + TASK_DESCRIPTION = 'VM Retire'.freeze + SOURCE_CLASS_NAME = 'Vm'.freeze + ACTIVE_STATES = %w(retired) + base_class::ACTIVE_STATES + + validates :request_state, :inclusion => { :in => %w(pending finished) + ACTIVE_STATES, :message => "should be pending, #{ACTIVE_STATES.join(", ")} or finished" } + validate :must_have_user + + def my_zone + vm = Vm.find_by(:id => options[:src_ids]) + vm.nil? ? super : vm.my_zone + end + + def my_role + 'ems_operations' + end +end diff --git a/app/models/vm_retire_task.rb b/app/models/vm_retire_task.rb new file mode 100644 index 00000000000..4476e2c10e5 --- /dev/null +++ b/app/models/vm_retire_task.rb @@ -0,0 +1,106 @@ +class VmRetireTask < MiqRequestTask + alias_attribute :vm, :source + + validate :validate_request_type, :validate_state + + AUTOMATE_DRIVES = true + + def self.base_model + VmRetireTask + end + + def self.get_description(req_obj) + name = nil + if req_obj.source.nil? + # Single source has not been selected yet + if req_obj.options[:src_ids].length == 1 + v = Vm.find_by(:id => req_obj.options[:src_ids].first) + name = v.nil? ? "" : v.name + else + name = "Multiple VMs" + end + else + name = req_obj.source.name + end + + new_settings = [] + "#{request_class::TASK_DESCRIPTION} for: #{name} - #{new_settings.join(", ")}" + end + + def after_request_task_create + update_attribute(:description, get_description) + end + + def after_ae_delivery(ae_result) + _log.info("ae_result=#{ae_result.inspect}") + reload + + return if ae_result == 'retry' + return if miq_request.state == 'finished' + + if ae_result == 'ok' + update_and_notify_parent(:state => "finished", :status => "Ok", :message => display_message("#{request_class::TASK_DESCRIPTION} completed")) + else + mark_pending_items_as_finished + update_and_notify_parent(:state => "finished", :status => "Error", :message => display_message("#{request_class::TASK_DESCRIPTION} failed")) + end + end + + def deliver_to_automate(req_type = request_type, zone = nil) + task_check_on_delivery + + _log.info("Queuing #{request_class::TASK_DESCRIPTION}: [#{description}]...") + + if self.class::AUTOMATE_DRIVES + args = { + :object_type => self.class.name, + :object_id => id, + :attrs => {"request" => req_type}, + :instance_name => "AUTOMATION", + :user_id => get_user.id, + :miq_group_id => get_user.current_group.id, + :tenant_id => get_user.current_tenant.id, + } + + args[:attrs].merge!(MiqAeEngine.create_automation_attributes(source.class.base_model.name => source)) + + zone ||= source.respond_to?(:my_zone) ? source.my_zone : MiqServer.my_zone + MiqQueue.put( + :class_name => 'MiqAeEngine', + :method_name => 'deliver', + :args => [args], + :role => 'automate', + :zone => options.fetch(:miq_zone, zone), + :tracking_label => my_task_id, + ) + update_and_notify_parent(:state => "pending", :status => "Ok", :message => "Automation Starting") + else + execute_queue + end + end + + def before_ae_starts(_options) + reload + if state.to_s.downcase.in?(%w(pending queued)) + _log.info("Executing #{request_class::TASK_DESCRIPTION} request: [#{description}]") + update_and_notify_parent(:state => "active", :status => "Ok", :message => "In Process") + end + end + + def update_and_notify_parent(*args) + prev_state = state + super + task_finished if state == "finished" && prev_state != "finished" + end + + def task_finished + end + + def mark_pending_items_as_finished + miq_request.miq_request_tasks.each do |s| + if s.state == 'pending' + s.update_and_notify_parent(:state => "finished", :status => "Warn", :message => "Error in Request: #{miq_request.id}. Setting pending Task: #{id} to finished.") unless id == s.id + end + end + end +end diff --git a/spec/factories/vm_retire_request.rb b/spec/factories/vm_retire_request.rb new file mode 100644 index 00000000000..dfe5e507d63 --- /dev/null +++ b/spec/factories/vm_retire_request.rb @@ -0,0 +1,3 @@ +FactoryGirl.define do + factory :vm_retire_request +end diff --git a/spec/factories/vm_retire_task.rb b/spec/factories/vm_retire_task.rb new file mode 100644 index 00000000000..455c528008d --- /dev/null +++ b/spec/factories/vm_retire_task.rb @@ -0,0 +1,3 @@ +FactoryGirl.define do + factory :vm_retire_task +end diff --git a/spec/models/miq_request_spec.rb b/spec/models/miq_request_spec.rb index adc42414a48..36036ba2468 100644 --- a/spec/models/miq_request_spec.rb +++ b/spec/models/miq_request_spec.rb @@ -14,6 +14,7 @@ :VmReconfigureRequest => {:vm_reconfigure => "VM Reconfigure"}, :VmCloudReconfigureRequest => {:vm_cloud_reconfigure => "VM Cloud Reconfigure"}, :VmMigrateRequest => {:vm_migrate => "VM Migrate"}, + :VmRetireRequest => {:vm_retire => "VM Retire"}, :AutomationRequest => {:automation => "Automation"}, :ServiceTemplateProvisionRequest => {:clone_to_service => "Service Provision"}, :ServiceReconfigureRequest => {:service_reconfigure => "Service Reconfigure"}, From eea753fef86f3d2a6909c7277642a5b05681c126 Mon Sep 17 00:00:00 2001 From: d-m-u Date: Wed, 28 Feb 2018 11:37:17 -0500 Subject: [PATCH 2/3] Add service retire request and task for passing specs --- app/models/mixins/retirement_mixin.rb | 6 +- app/models/service_retire_request.rb | 19 ++++ app/models/service_retire_task.rb | 104 ++++++++++++++++++ .../service/retirement_management_spec.rb | 6 +- spec/models/vm/retirement_management_spec.rb | 6 +- 5 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 app/models/service_retire_request.rb create mode 100644 app/models/service_retire_task.rb diff --git a/app/models/mixins/retirement_mixin.rb b/app/models/mixins/retirement_mixin.rb index 3c894398a1f..013b8753b27 100644 --- a/app/models/mixins/retirement_mixin.rb +++ b/app/models/mixins/retirement_mixin.rb @@ -128,10 +128,8 @@ def retire_now(requester = nil) _log.info("Creating request for #{self.class.name} #{id}") begin options = {:src_ids => id} - VmRetireRequest.make_request(@request_id, options, User.current_user.try(:userid)) - - # still need the next line for orchestration and services - # raise_retirement_event(event_name, requester) + request_type = (self.class.name.demodulize + "RetireRequest").constantize + request_type.make_request(@request_id, options, User.current_user.try(:userid)) rescue => err _log.log_backtrace(err) end diff --git a/app/models/service_retire_request.rb b/app/models/service_retire_request.rb new file mode 100644 index 00000000000..d8ceb5509a0 --- /dev/null +++ b/app/models/service_retire_request.rb @@ -0,0 +1,19 @@ +class ServiceRetireRequest < MiqRequest + TASK_DESCRIPTION = 'Service Retire'.freeze + SOURCE_CLASS_NAME = 'Service'.freeze + + validates :request_state, :inclusion => { :in => %w(pending finished) + ACTIVE_STATES, :message => "should be pending, #{ACTIVE_STATES.join(", ")} or finished" } + + validate :must_have_user + delegate :service_template, :to => :source, :allow_nil => true + + default_value_for(:source_id) { |r| r.get_option(:src_id) } + default_value_for :source_type, SOURCE_CLASS_NAME + + def my_role + 'ems_operations' + end + + def my_zone + end +end diff --git a/app/models/service_retire_task.rb b/app/models/service_retire_task.rb new file mode 100644 index 00000000000..fb17573d48a --- /dev/null +++ b/app/models/service_retire_task.rb @@ -0,0 +1,104 @@ +class ServiceRetireTask < MiqRequestTask + validate :validate_request_type, :validate_state + + AUTOMATE_DRIVES = true + + def self.base_model + ServiceRetireTask + end + + def self.get_description(req_obj) + name = nil + if req_obj.source.nil? + # Single source has not been selected yet + if req_obj.options[:src_ids].length == 1 + s = Service.find_by(:id => req_obj.options[:src_ids].first) + name = s.nil? ? "" : s.name + else + name = "Multiple Services" + end + else + name = req_obj.source.name + end + + new_settings = [] + "#{request_class::TASK_DESCRIPTION} for: #{name} - #{new_settings.join(", ")}" + end + + def after_request_task_create + update_attribute(:description, get_description) + end + + def after_ae_delivery(ae_result) + _log.info("ae_result=#{ae_result.inspect}") + reload + + return if ae_result == 'retry' + return if miq_request.state == 'finished' + + if ae_result == 'ok' + update_and_notify_parent(:state => "finished", :status => "Ok", :message => display_message("#{request_class::TASK_DESCRIPTION} completed")) + else + mark_pending_items_as_finished + update_and_notify_parent(:state => "finished", :status => "Error", :message => display_message("#{request_class::TASK_DESCRIPTION} failed")) + end + end + + def deliver_to_automate(req_type = request_type, zone = nil) + task_check_on_delivery + + _log.info("Queuing #{request_class::TASK_DESCRIPTION}: [#{description}]...") + + if self.class::AUTOMATE_DRIVES + args = { + :object_type => self.class.name, + :object_id => id, + :attrs => {"request" => req_type}, + :instance_name => "AUTOMATION", + :user_id => get_user.id, + :miq_group_id => get_user.current_group.id, + :tenant_id => get_user.current_tenant.id, + } + + args[:attrs].merge!(MiqAeEngine.create_automation_attributes(source.class.base_model.name => source)) + + zone ||= source.respond_to?(:my_zone) ? source.my_zone : MiqServer.my_zone + MiqQueue.put( + :class_name => 'MiqAeEngine', + :method_name => 'deliver', + :args => [args], + :role => 'automate', + :zone => options.fetch(:miq_zone, zone), + :tracking_label => my_task_id, + ) + update_and_notify_parent(:state => "pending", :status => "Ok", :message => "Automation Starting") + else + execute_queue + end + end + + def before_ae_starts(_options) + reload + if state.to_s.downcase.in?(%w(pending queued)) + _log.info("Executing #{request_class::TASK_DESCRIPTION} request: [#{description}]") + update_and_notify_parent(:state => "active", :status => "Ok", :message => "In Process") + end + end + + def update_and_notify_parent(*args) + prev_state = state + super + task_finished if state == "finished" && prev_state != "finished" + end + + def task_finished + end + + def mark_pending_items_as_finished + miq_request.miq_request_tasks.each do |s| + if s.state == 'pending' + s.update_and_notify_parent(:state => "finished", :status => "Warn", :message => "Error in Request: #{miq_request.id}. Setting pending Task: #{id} to finished.") unless id == s.id + end + end + end +end diff --git a/spec/models/service/retirement_management_spec.rb b/spec/models/service/retirement_management_spec.rb index 0917eef7a3f..6e1338416b8 100644 --- a/spec/models/service/retirement_management_spec.rb +++ b/spec/models/service/retirement_management_spec.rb @@ -24,7 +24,7 @@ it "#retire_now" do expect(@service.retirement_state).to be_nil - expect(MiqEvent).to receive(:raise_evm_event).once + expect(ServiceRetireRequest).to receive(:make_request).once @service.retire_now @service.reload end @@ -35,7 +35,7 @@ event_hash = {:service => @service, :type => "Service", :retirement_initiator => "user", :userid => "freddy"} - expect(MiqEvent).to receive(:raise_evm_event).with(@service, event_name, event_hash, {}).once + expect(ServiceRetireRequest).to receive(:make_request).once @service.retire_now('freddy') @service.reload @@ -47,7 +47,7 @@ event_hash = {:service => @service, :type => "Service", :retirement_initiator => "system"} - expect(MiqEvent).to receive(:raise_evm_event).with(@service, event_name, event_hash, {}).once + expect(ServiceRetireRequest).to receive(:make_request).once @service.retire_now @service.reload diff --git a/spec/models/vm/retirement_management_spec.rb b/spec/models/vm/retirement_management_spec.rb index a9d2d702a30..b3c422267bb 100644 --- a/spec/models/vm/retirement_management_spec.rb +++ b/spec/models/vm/retirement_management_spec.rb @@ -26,7 +26,7 @@ end it "#retire_now" do - expect(MiqEvent).to receive(:raise_evm_event).once + expect(VmRetireRequest).to receive(:make_request).once @vm.retire_now end @@ -37,7 +37,7 @@ :retirement_initiator => "user", :userid => 'freddy'} options = {:zone => @zone.name} - expect(MiqEvent).to receive(:raise_evm_event).with(@vm, event_name, event_hash, options).once + expect(VmRetireRequest).to receive(:make_request).once @vm.retire_now('freddy') end @@ -48,7 +48,7 @@ :retirement_initiator => "system"} options = {:zone => @zone.name} - expect(MiqEvent).to receive(:raise_evm_event).with(@vm, event_name, event_hash, options).once + expect(VmRetireRequest).to receive(:make_request).once @vm.retire_now end From c4882a5bbf6e9afca1cf6244f562256eb6ce71a7 Mon Sep 17 00:00:00 2001 From: d-m-u Date: Wed, 28 Feb 2018 14:40:16 -0500 Subject: [PATCH 3/3] Add factories for service and orchestration stack retire task and request --- app/models/miq_request.rb | 6 ++ app/models/miq_retire_request.rb | 13 +++ app/models/miq_retire_task.rb | 89 +++++++++++++++ app/models/mixins/retirement_mixin.rb | 15 ++- .../orchestration_stack_retire_request.rb | 4 + app/models/orchestration_stack_retire_task.rb | 9 ++ app/models/service/retirement_management.rb | 2 + app/models/service_retire_request.rb | 15 +-- app/models/service_retire_task.rb | 92 +--------------- app/models/vm_retire_request.rb | 9 +- app/models/vm_retire_task.rb | 101 +----------------- spec/factories/vm_retire_request.rb | 3 - spec/factories/vm_retire_task.rb | 3 - spec/models/miq_request_spec.rb | 28 ++--- .../retirement_management_spec.rb | 8 +- .../service/retirement_management_spec.rb | 15 +-- spec/models/vm/retirement_management_spec.rb | 8 +- 17 files changed, 172 insertions(+), 248 deletions(-) create mode 100644 app/models/miq_retire_request.rb create mode 100644 app/models/miq_retire_task.rb create mode 100644 app/models/orchestration_stack_retire_request.rb create mode 100644 app/models/orchestration_stack_retire_task.rb delete mode 100644 spec/factories/vm_retire_request.rb delete mode 100644 spec/factories/vm_retire_task.rb diff --git a/app/models/miq_request.rb b/app/models/miq_request.rb index 99849847e27..6d6f2ba7129 100644 --- a/app/models/miq_request.rb +++ b/app/models/miq_request.rb @@ -80,6 +80,12 @@ class MiqRequest < ApplicationRecord :VmRetireRequest => { :vm_retire => N_("VM Retire") }, + :ServiceRetireRequest => { + :service_retire => N_("Service Retire") + }, + :OrchestrationStackRetireRequest => { + :orchestration_stack_retire => N_("Orchestration Stack Retire") + }, :ServiceTemplateProvisionRequest => { :clone_to_service => N_("Service Provision") }, diff --git a/app/models/miq_retire_request.rb b/app/models/miq_retire_request.rb new file mode 100644 index 00000000000..b919c01ce73 --- /dev/null +++ b/app/models/miq_retire_request.rb @@ -0,0 +1,13 @@ +class MiqRetireRequest < MiqRequest + # subclasses must set this + SOURCE_CLASS_NAME = nil + + validates :request_state, :inclusion => { :in => %w(pending finished) + ACTIVE_STATES, :message => "should be pending, #{ACTIVE_STATES.join(", ")} or finished" } + validate :must_have_user + + default_value_for(:source_id) { |r| r.get_option(:src_id) } + default_value_for :source_type, SOURCE_CLASS_NAME + + def my_zone + end +end diff --git a/app/models/miq_retire_task.rb b/app/models/miq_retire_task.rb new file mode 100644 index 00000000000..97a5d59a798 --- /dev/null +++ b/app/models/miq_retire_task.rb @@ -0,0 +1,89 @@ +class MiqRetireTask < MiqRequestTask + validate :validate_request_type, :validate_state + + AUTOMATE_DRIVES = true + + def self.get_description(req_obj) + name = if req_obj.source.nil? + # Single source has not been selected yet + if req_obj.options[:src_ids].length == 1 + m = model_being_retired.find_by(:id => req_obj.options[:src_ids].first) + m.nil? ? "" : m.name + else + "Multiple " + model_being_retired.to_s.pluralize + end + else + req_obj.source.name + end + + new_settings = [] + "#{request_class::TASK_DESCRIPTION} for: #{name} - #{new_settings.join(", ")}" + end + + def deliver_to_automate(req_type = request_type, zone = nil) + task_check_on_delivery + + _log.info("Queuing #{request_class::TASK_DESCRIPTION}: [#{description}]...") + if self.class::AUTOMATE_DRIVES + args = { + :object_type => self.class.name, + :object_id => id, + :attrs => {"request" => req_type}, + :instance_name => "AUTOMATION", + :user_id => 1, + :miq_group_id => 2, + :tenant_id => 1, + } + + args[:attrs].merge!(MiqAeEngine.create_automation_attributes(source.class.base_model.name => source)) + + zone ||= source.respond_to?(:my_zone) ? source.my_zone : MiqServer.my_zone + MiqQueue.put( + :class_name => 'MiqAeEngine', + :method_name => 'deliver', + :args => [args], + :role => 'automate', + :zone => options.fetch(:miq_zone, zone), + :tracking_label => my_task_id, + ) + update_and_notify_parent(:state => "pending", :status => "Ok", :message => "Automation Starting") + else + execute_queue + end + end + + def after_request_task_create + update_attributes(:description, get_description) + end + + def after_ae_delivery(ae_result) + _log.info("ae_result=#{ae_result.inspect}") + reload + + return if ae_result == 'retry' + return if miq_request.state == 'finished' + + if ae_result == 'ok' + update_and_notify_parent(:state => "finished", :status => "Ok", :message => display_message("#{request_class::TASK_DESCRIPTION} completed")) + else + mark_pending_items_as_finished + update_and_notify_parent(:state => "finished", :status => "Error", :message => display_message("#{request_class::TASK_DESCRIPTION} failed")) + end + end + + def before_ae_starts(_options) + reload + if state.to_s.downcase.in?(%w(pending queued)) + _log.info("Executing #{request_class::TASK_DESCRIPTION} request: [#{description}]") + update_and_notify_parent(:state => "active", :status => "Ok", :message => "In Process") + end + end + + def mark_pending_items_as_finished + miq_request.miq_request_tasks.each do |s| + if s.state == 'pending' + s.update_and_notify_parent(:state => "finished", :status => "Warn", :message => "Error in Request: #{miq_request.id}. Setting pending Task: #{id} to finished.") unless id == s.id + end + end + end +end diff --git a/app/models/mixins/retirement_mixin.rb b/app/models/mixins/retirement_mixin.rb index 013b8753b27..61273f64bc0 100644 --- a/app/models/mixins/retirement_mixin.rb +++ b/app/models/mixins/retirement_mixin.rb @@ -10,6 +10,11 @@ module RetirementMixin end module ClassMethods + def make_retire_request + options = {:task => task, :userid => current_user, :ids => objs, :src_ids => objs} + (klass.to_s + "RetireRequest").constantize.make_request(@request_id, options, current_user) + end + def retire(ids, options = {}) ids.each do |id| object = find_by(:id => id) @@ -117,7 +122,7 @@ def retirement_check end end - retire_now if retirement_due? + make_retire_request if retirement_due? end def retire_now(requester = nil) @@ -125,11 +130,11 @@ def retire_now(requester = nil) return if retired_validated? _log.info("#{retirement_object_title}: [#{name}], Retires On: [#{retires_on.strftime("%x %R %Z")}], was previously retired, but currently #{retired_invalid_reason}") else - _log.info("Creating request for #{self.class.name} #{id}") + update_attributes(:retirement_requester => requester) + event_name = "request_#{retirement_event_prefix}_retire" + _log.info("calling #{event_name}") begin - options = {:src_ids => id} - request_type = (self.class.name.demodulize + "RetireRequest").constantize - request_type.make_request(@request_id, options, User.current_user.try(:userid)) + raise_retirement_event(event_name, requester) rescue => err _log.log_backtrace(err) end diff --git a/app/models/orchestration_stack_retire_request.rb b/app/models/orchestration_stack_retire_request.rb new file mode 100644 index 00000000000..d45ec318745 --- /dev/null +++ b/app/models/orchestration_stack_retire_request.rb @@ -0,0 +1,4 @@ +class OrchestrationStackRetireRequest < MiqRetireRequest + TASK_DESCRIPTION = 'OrchestrationStack Retire'.freeze + SOURCE_CLASS_NAME = 'OrchestrationStack'.freeze +end diff --git a/app/models/orchestration_stack_retire_task.rb b/app/models/orchestration_stack_retire_task.rb new file mode 100644 index 00000000000..a0b32a5a598 --- /dev/null +++ b/app/models/orchestration_stack_retire_task.rb @@ -0,0 +1,9 @@ +class OrchestrationStackRetireTask < MiqRetireTask + def self.base_model + OrchestrationStackRetireTask + end + + def self.model_being_retired + OrchestrationStack + end +end diff --git a/app/models/service/retirement_management.rb b/app/models/service/retirement_management.rb index cc2db5109fc..7059d1fd17b 100644 --- a/app/models/service/retirement_management.rb +++ b/app/models/service/retirement_management.rb @@ -7,6 +7,8 @@ def before_retirement end def retire_service_resources + # TODO: delete me per https://github.com/ManageIQ/manageiq/pull/16933#discussion_r175805070 + return direct_service_children.each(&:retire_service_resources) service_resources.each do |sr| diff --git a/app/models/service_retire_request.rb b/app/models/service_retire_request.rb index d8ceb5509a0..afd4c3c69d4 100644 --- a/app/models/service_retire_request.rb +++ b/app/models/service_retire_request.rb @@ -1,19 +1,6 @@ -class ServiceRetireRequest < MiqRequest +class ServiceRetireRequest < MiqRetireRequest TASK_DESCRIPTION = 'Service Retire'.freeze SOURCE_CLASS_NAME = 'Service'.freeze - validates :request_state, :inclusion => { :in => %w(pending finished) + ACTIVE_STATES, :message => "should be pending, #{ACTIVE_STATES.join(", ")} or finished" } - - validate :must_have_user delegate :service_template, :to => :source, :allow_nil => true - - default_value_for(:source_id) { |r| r.get_option(:src_id) } - default_value_for :source_type, SOURCE_CLASS_NAME - - def my_role - 'ems_operations' - end - - def my_zone - end end diff --git a/app/models/service_retire_task.rb b/app/models/service_retire_task.rb index fb17573d48a..70bca689b28 100644 --- a/app/models/service_retire_task.rb +++ b/app/models/service_retire_task.rb @@ -1,88 +1,10 @@ -class ServiceRetireTask < MiqRequestTask - validate :validate_request_type, :validate_state - - AUTOMATE_DRIVES = true - +class ServiceRetireTask < MiqRetireTask def self.base_model ServiceRetireTask end - def self.get_description(req_obj) - name = nil - if req_obj.source.nil? - # Single source has not been selected yet - if req_obj.options[:src_ids].length == 1 - s = Service.find_by(:id => req_obj.options[:src_ids].first) - name = s.nil? ? "" : s.name - else - name = "Multiple Services" - end - else - name = req_obj.source.name - end - - new_settings = [] - "#{request_class::TASK_DESCRIPTION} for: #{name} - #{new_settings.join(", ")}" - end - - def after_request_task_create - update_attribute(:description, get_description) - end - - def after_ae_delivery(ae_result) - _log.info("ae_result=#{ae_result.inspect}") - reload - - return if ae_result == 'retry' - return if miq_request.state == 'finished' - - if ae_result == 'ok' - update_and_notify_parent(:state => "finished", :status => "Ok", :message => display_message("#{request_class::TASK_DESCRIPTION} completed")) - else - mark_pending_items_as_finished - update_and_notify_parent(:state => "finished", :status => "Error", :message => display_message("#{request_class::TASK_DESCRIPTION} failed")) - end - end - - def deliver_to_automate(req_type = request_type, zone = nil) - task_check_on_delivery - - _log.info("Queuing #{request_class::TASK_DESCRIPTION}: [#{description}]...") - - if self.class::AUTOMATE_DRIVES - args = { - :object_type => self.class.name, - :object_id => id, - :attrs => {"request" => req_type}, - :instance_name => "AUTOMATION", - :user_id => get_user.id, - :miq_group_id => get_user.current_group.id, - :tenant_id => get_user.current_tenant.id, - } - - args[:attrs].merge!(MiqAeEngine.create_automation_attributes(source.class.base_model.name => source)) - - zone ||= source.respond_to?(:my_zone) ? source.my_zone : MiqServer.my_zone - MiqQueue.put( - :class_name => 'MiqAeEngine', - :method_name => 'deliver', - :args => [args], - :role => 'automate', - :zone => options.fetch(:miq_zone, zone), - :tracking_label => my_task_id, - ) - update_and_notify_parent(:state => "pending", :status => "Ok", :message => "Automation Starting") - else - execute_queue - end - end - - def before_ae_starts(_options) - reload - if state.to_s.downcase.in?(%w(pending queued)) - _log.info("Executing #{request_class::TASK_DESCRIPTION} request: [#{description}]") - update_and_notify_parent(:state => "active", :status => "Ok", :message => "In Process") - end + def self.model_being_retired + Service end def update_and_notify_parent(*args) @@ -93,12 +15,4 @@ def update_and_notify_parent(*args) def task_finished end - - def mark_pending_items_as_finished - miq_request.miq_request_tasks.each do |s| - if s.state == 'pending' - s.update_and_notify_parent(:state => "finished", :status => "Warn", :message => "Error in Request: #{miq_request.id}. Setting pending Task: #{id} to finished.") unless id == s.id - end - end - end end diff --git a/app/models/vm_retire_request.rb b/app/models/vm_retire_request.rb index 18052362387..8cc69b45333 100644 --- a/app/models/vm_retire_request.rb +++ b/app/models/vm_retire_request.rb @@ -1,17 +1,10 @@ -class VmRetireRequest < MiqRequest +class VmRetireRequest < MiqRetireRequest TASK_DESCRIPTION = 'VM Retire'.freeze SOURCE_CLASS_NAME = 'Vm'.freeze ACTIVE_STATES = %w(retired) + base_class::ACTIVE_STATES - validates :request_state, :inclusion => { :in => %w(pending finished) + ACTIVE_STATES, :message => "should be pending, #{ACTIVE_STATES.join(", ")} or finished" } - validate :must_have_user - def my_zone vm = Vm.find_by(:id => options[:src_ids]) vm.nil? ? super : vm.my_zone end - - def my_role - 'ems_operations' - end end diff --git a/app/models/vm_retire_task.rb b/app/models/vm_retire_task.rb index 4476e2c10e5..730175f3430 100644 --- a/app/models/vm_retire_task.rb +++ b/app/models/vm_retire_task.rb @@ -1,106 +1,11 @@ -class VmRetireTask < MiqRequestTask +class VmRetireTask < MiqRetireTask alias_attribute :vm, :source - validate :validate_request_type, :validate_state - - AUTOMATE_DRIVES = true - def self.base_model VmRetireTask end - def self.get_description(req_obj) - name = nil - if req_obj.source.nil? - # Single source has not been selected yet - if req_obj.options[:src_ids].length == 1 - v = Vm.find_by(:id => req_obj.options[:src_ids].first) - name = v.nil? ? "" : v.name - else - name = "Multiple VMs" - end - else - name = req_obj.source.name - end - - new_settings = [] - "#{request_class::TASK_DESCRIPTION} for: #{name} - #{new_settings.join(", ")}" - end - - def after_request_task_create - update_attribute(:description, get_description) - end - - def after_ae_delivery(ae_result) - _log.info("ae_result=#{ae_result.inspect}") - reload - - return if ae_result == 'retry' - return if miq_request.state == 'finished' - - if ae_result == 'ok' - update_and_notify_parent(:state => "finished", :status => "Ok", :message => display_message("#{request_class::TASK_DESCRIPTION} completed")) - else - mark_pending_items_as_finished - update_and_notify_parent(:state => "finished", :status => "Error", :message => display_message("#{request_class::TASK_DESCRIPTION} failed")) - end - end - - def deliver_to_automate(req_type = request_type, zone = nil) - task_check_on_delivery - - _log.info("Queuing #{request_class::TASK_DESCRIPTION}: [#{description}]...") - - if self.class::AUTOMATE_DRIVES - args = { - :object_type => self.class.name, - :object_id => id, - :attrs => {"request" => req_type}, - :instance_name => "AUTOMATION", - :user_id => get_user.id, - :miq_group_id => get_user.current_group.id, - :tenant_id => get_user.current_tenant.id, - } - - args[:attrs].merge!(MiqAeEngine.create_automation_attributes(source.class.base_model.name => source)) - - zone ||= source.respond_to?(:my_zone) ? source.my_zone : MiqServer.my_zone - MiqQueue.put( - :class_name => 'MiqAeEngine', - :method_name => 'deliver', - :args => [args], - :role => 'automate', - :zone => options.fetch(:miq_zone, zone), - :tracking_label => my_task_id, - ) - update_and_notify_parent(:state => "pending", :status => "Ok", :message => "Automation Starting") - else - execute_queue - end - end - - def before_ae_starts(_options) - reload - if state.to_s.downcase.in?(%w(pending queued)) - _log.info("Executing #{request_class::TASK_DESCRIPTION} request: [#{description}]") - update_and_notify_parent(:state => "active", :status => "Ok", :message => "In Process") - end - end - - def update_and_notify_parent(*args) - prev_state = state - super - task_finished if state == "finished" && prev_state != "finished" - end - - def task_finished - end - - def mark_pending_items_as_finished - miq_request.miq_request_tasks.each do |s| - if s.state == 'pending' - s.update_and_notify_parent(:state => "finished", :status => "Warn", :message => "Error in Request: #{miq_request.id}. Setting pending Task: #{id} to finished.") unless id == s.id - end - end + def self.model_being_retired + Vm end end diff --git a/spec/factories/vm_retire_request.rb b/spec/factories/vm_retire_request.rb deleted file mode 100644 index dfe5e507d63..00000000000 --- a/spec/factories/vm_retire_request.rb +++ /dev/null @@ -1,3 +0,0 @@ -FactoryGirl.define do - factory :vm_retire_request -end diff --git a/spec/factories/vm_retire_task.rb b/spec/factories/vm_retire_task.rb deleted file mode 100644 index 455c528008d..00000000000 --- a/spec/factories/vm_retire_task.rb +++ /dev/null @@ -1,3 +0,0 @@ -FactoryGirl.define do - factory :vm_retire_task -end diff --git a/spec/models/miq_request_spec.rb b/spec/models/miq_request_spec.rb index 36036ba2468..39d7167ca17 100644 --- a/spec/models/miq_request_spec.rb +++ b/spec/models/miq_request_spec.rb @@ -7,19 +7,21 @@ context "CONSTANTS" do it "REQUEST_TYPES" do expected_request_types = { - :MiqProvisionRequest => {:template => "VM Provision", :clone_to_vm => "VM Clone", :clone_to_template => "VM Publish"}, - :MiqProvisionRequestTemplate => {:template => "VM Provision Template"}, - :MiqHostProvisionRequest => {:host_pxe_install => "Host Provision"}, - :MiqProvisionConfiguredSystemRequest => {:provision_via_foreman => "#{ui_lookup(:ui_title => 'foreman')} Provision"}, - :VmReconfigureRequest => {:vm_reconfigure => "VM Reconfigure"}, - :VmCloudReconfigureRequest => {:vm_cloud_reconfigure => "VM Cloud Reconfigure"}, - :VmMigrateRequest => {:vm_migrate => "VM Migrate"}, - :VmRetireRequest => {:vm_retire => "VM Retire"}, - :AutomationRequest => {:automation => "Automation"}, - :ServiceTemplateProvisionRequest => {:clone_to_service => "Service Provision"}, - :ServiceReconfigureRequest => {:service_reconfigure => "Service Reconfigure"}, - :PhysicalServerProvisionRequest => {:provision_physical_server => "Physical Server Provision"}, - :ServiceTemplateTransformationPlanRequest => {:transformation_plan => "Transformation Plan"} + :MiqProvisionRequest => {:template => "VM Provision", :clone_to_vm => "VM Clone", :clone_to_template => "VM Publish"}, + :MiqProvisionRequestTemplate => {:template => "VM Provision Template"}, + :MiqHostProvisionRequest => {:host_pxe_install => "Host Provision"}, + :MiqProvisionConfiguredSystemRequest => {:provision_via_foreman => "#{ui_lookup(:ui_title => 'foreman')} Provision"}, + :VmReconfigureRequest => {:vm_reconfigure => "VM Reconfigure"}, + :VmCloudReconfigureRequest => {:vm_cloud_reconfigure => "VM Cloud Reconfigure"}, + :VmMigrateRequest => {:vm_migrate => "VM Migrate"}, + :VmRetireRequest => {:vm_retire => "VM Retire"}, + :ServiceRetireRequest => {:service_retire => "Service Retire"}, + :OrchestrationStackRetireRequest => {:orchestration_stack_retire => "Orchestration Stack Retire"}, + :AutomationRequest => {:automation => "Automation"}, + :ServiceTemplateProvisionRequest => {:clone_to_service => "Service Provision"}, + :ServiceReconfigureRequest => {:service_reconfigure => "Service Reconfigure"}, + :PhysicalServerProvisionRequest => {:provision_physical_server => "Physical Server Provision"}, + :ServiceTemplateTransformationPlanRequest => {:transformation_plan => "Transformation Plan"} } expect(described_class::REQUEST_TYPES).to eq(expected_request_types) diff --git a/spec/models/orchestration_stack/retirement_management_spec.rb b/spec/models/orchestration_stack/retirement_management_spec.rb index 20cfd6b5501..a681d589487 100644 --- a/spec/models/orchestration_stack/retirement_management_spec.rb +++ b/spec/models/orchestration_stack/retirement_management_spec.rb @@ -8,7 +8,7 @@ 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 - expect_any_instance_of(@stack.class).to receive(:retire_now).once + expect(@stack).to receive(:make_retire_request).once @stack.retirement_check @stack.reload expect(@stack.retirement_last_warn).not_to be_nil @@ -24,7 +24,7 @@ it "#retire_now" do expect(@stack.retirement_state).to be_nil - expect(MiqEvent).to receive(:raise_evm_event).once + expect(OrchestrationStackRetireRequest).to_not receive(:make_request) @stack.retire_now @stack.reload end @@ -35,7 +35,7 @@ event_hash = {:orchestration_stack => @stack, :type => "OrchestrationStack", :retirement_initiator => "user", :userid => "freddy"} - expect(MiqEvent).to receive(:raise_evm_event).with(@stack, event_name, event_hash, {}).once + expect(OrchestrationStackRetireRequest).to_not receive(:make_request) @stack.retire_now('freddy') @stack.reload @@ -47,7 +47,7 @@ event_hash = {:orchestration_stack => @stack, :type => "OrchestrationStack", :retirement_initiator => "system"} - expect(MiqEvent).to receive(:raise_evm_event).with(@stack, event_name, event_hash, {}).once + expect(OrchestrationStackRetireRequest).to_not receive(:make_request) @stack.retire_now @stack.reload diff --git a/spec/models/service/retirement_management_spec.rb b/spec/models/service/retirement_management_spec.rb index 6e1338416b8..f6ca597cb98 100644 --- a/spec/models/service/retirement_management_spec.rb +++ b/spec/models/service/retirement_management_spec.rb @@ -4,11 +4,12 @@ @service = FactoryGirl.create(:service) end + # shouldn't be running make_retire_request because it's the bimodal not from ui part 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 - expect_any_instance_of(@service.class).to receive(:retire_now).once + expect(@service).to receive(:make_retire_request).once @service.retirement_check @service.reload expect(@service.retirement_last_warn).not_to be_nil @@ -24,7 +25,7 @@ it "#retire_now" do expect(@service.retirement_state).to be_nil - expect(ServiceRetireRequest).to receive(:make_request).once + expect(MiqEvent).to receive(:raise_evm_event).once @service.retire_now @service.reload end @@ -35,7 +36,7 @@ event_hash = {:service => @service, :type => "Service", :retirement_initiator => "user", :userid => "freddy"} - expect(ServiceRetireRequest).to receive(:make_request).once + expect(MiqEvent).to receive(:raise_evm_event).with(@service, event_name, event_hash, {}).once @service.retire_now('freddy') @service.reload @@ -47,7 +48,7 @@ event_hash = {:service => @service, :type => "Service", :retirement_initiator => "system"} - expect(ServiceRetireRequest).to receive(:make_request).once + expect(MiqEvent).to receive(:raise_evm_event).with(@service, event_name, event_hash, {}).once @service.retire_now @service.reload @@ -76,7 +77,7 @@ vm = FactoryGirl.create(:vm_vmware, :ems_id => ems.id) @service << vm expect(@service.service_resources.size).to eq(1) - expect(@service.service_resources.first.resource).to receive(:retire_now).once + expect(@service.service_resources.first.resource).to_not receive(:retire_now) @service.retire_service_resources end @@ -87,7 +88,7 @@ @service.update_attributes(:retirement_requester => userid) @service << vm expect(@service.service_resources.size).to eq(1) - expect(@service.service_resources.first.resource).to receive(:retire_now).with(userid).once + expect(@service.service_resources.first.resource).to_not receive(:retire_now).with(userid) @service.retire_service_resources end @@ -96,7 +97,7 @@ vm = FactoryGirl.create(:vm_vmware, :ems_id => ems.id) @service << vm expect(@service.service_resources.size).to eq(1) - expect(@service.service_resources.first.resource).to receive(:retire_now).with(nil).once + expect(@service.service_resources.first.resource).to_not receive(:retire_now).with(nil) @service.retire_service_resources end diff --git a/spec/models/vm/retirement_management_spec.rb b/spec/models/vm/retirement_management_spec.rb index b3c422267bb..ab14fafdc5e 100644 --- a/spec/models/vm/retirement_management_spec.rb +++ b/spec/models/vm/retirement_management_spec.rb @@ -10,7 +10,7 @@ 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 - expect_any_instance_of(@vm.class).to receive(:retire_now).once + expect(@vm).to receive(:make_retire_request).once @vm.retirement_check @vm.reload expect(@vm.retirement_last_warn).not_to be_nil @@ -26,7 +26,7 @@ end it "#retire_now" do - expect(VmRetireRequest).to receive(:make_request).once + expect(MiqEvent).to receive(:raise_evm_event).once @vm.retire_now end @@ -37,7 +37,7 @@ :retirement_initiator => "user", :userid => 'freddy'} options = {:zone => @zone.name} - expect(VmRetireRequest).to receive(:make_request).once + expect(MiqEvent).to receive(:raise_evm_event).with(@vm, event_name, event_hash, options).once @vm.retire_now('freddy') end @@ -48,7 +48,7 @@ :retirement_initiator => "system"} options = {:zone => @zone.name} - expect(VmRetireRequest).to receive(:make_request).once + expect(MiqEvent).to receive(:raise_evm_event).with(@vm, event_name, event_hash, options).once @vm.retire_now end