From 48557e971a0dae40ea65c08ca8a4105a7e712234 Mon Sep 17 00:00:00 2001 From: Lucy Fu Date: Tue, 19 Mar 2019 10:59:04 -0400 Subject: [PATCH] Add zone to service provisioning. https://bugzilla.redhat.com/show_bug.cgi?id=1415106 --- app/models/mixins/miq_request_mixin.rb | 12 +++ app/models/service_template.rb | 7 ++ .../service_template_provision_request.rb | 1 + app/models/service_template_provision_task.rb | 8 +- .../service_template_provision_task_spec.rb | 84 ++++++++++++------- 5 files changed, 81 insertions(+), 31 deletions(-) diff --git a/app/models/mixins/miq_request_mixin.rb b/app/models/mixins/miq_request_mixin.rb index 71e05388ba15..3c684f2b01bd 100644 --- a/app/models/mixins/miq_request_mixin.rb +++ b/app/models/mixins/miq_request_mixin.rb @@ -170,6 +170,18 @@ def request_dialog(action_name) DialogSerializer.new.serialize(Array[dialog]).first end + def dialog_zone + zone = options.fetch_path(:dialog, "dialog_zone") + return nil if zone.blank? + + unless Zone.where(:name => zone).exists? + _log.warn("unknown zone #{zone} specified in dialog, ignored.") + return nil + end + + zone + end + def mark_execution_servers options[:executed_on_servers] ||= [] options[:executed_on_servers] << MiqServer.my_server.id diff --git a/app/models/service_template.rb b/app/models/service_template.rb index 783378d16e53..04dd8f9bc947 100644 --- a/app/models/service_template.rb +++ b/app/models/service_template.rb @@ -59,6 +59,7 @@ class ServiceTemplate < ApplicationRecord has_one :picture, :dependent => :destroy, :as => :resource, :autosave => true belongs_to :service_template_catalog + belongs_to :zone has_many :dialogs, -> { distinct }, :through => :resource_actions has_many :miq_schedules, :as => :resource, :dependent => :destroy @@ -450,6 +451,12 @@ def self.display_name(number = 1) n_('Service Catalog Item', 'Service Catalog Items', number) end + def my_zone + # each individual catalog items could specify their zones to run in, + # but the catalog bundle is zone-agnostic as it's not a real workflow item, more of an organizational / container thing. + zone&.name if atomic? + end + private def update_service_resources(config_info, auth_user = nil) diff --git a/app/models/service_template_provision_request.rb b/app/models/service_template_provision_request.rb index 7ccf8f062665..bad80f8c67f7 100644 --- a/app/models/service_template_provision_request.rb +++ b/app/models/service_template_provision_request.rb @@ -43,6 +43,7 @@ def my_role(action = nil) end def my_zone + @my_zone ||= dialog_zone || service_template.my_zone end def provision_dialog diff --git a/app/models/service_template_provision_task.rb b/app/models/service_template_provision_task.rb index 8eb8cf59fbf6..12811fc46863 100644 --- a/app/models/service_template_provision_task.rb +++ b/app/models/service_template_provision_task.rb @@ -9,6 +9,10 @@ def self.base_model ServiceTemplateProvisionTask end + def my_zone + dialog_zone || source.my_zone || MiqServer.my_zone + end + def provision_priority return 0 if service_resource.nil? service_resource.provision_index @@ -97,6 +101,7 @@ def queue_post_provision :class_name => self.class.name, :instance_id => id, :method_name => "do_post_provision", + :zone => my_zone, :deliver_on => 1.minutes.from_now.utc, :tracking_label => tracking_label_id, :miq_callback => {:class_name => self.class.name, :instance_id => id, :method_name => :execute_callback} @@ -143,13 +148,12 @@ def deliver_to_automate(req_type = request_type, _zone = nil) args[:miq_group_id] = get_user.current_group.id args[:tenant_id] = get_user.current_tenant.id - 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), + :zone => options.fetch(:miq_zone, my_zone), :tracking_label => tracking_label_id ) update_and_notify_parent(:state => "pending", :status => "Ok", :message => "Automation Starting") diff --git a/spec/models/service_template_provision_task_spec.rb b/spec/models/service_template_provision_task_spec.rb index 33dd2ad1e44c..2bddc54eb2bd 100644 --- a/spec/models/service_template_provision_task_spec.rb +++ b/spec/models/service_template_provision_task_spec.rb @@ -76,35 +76,61 @@ def service_resource_id(index, scaling_max) end describe "#deliver_to_automate" do - it "delivers to the queue when the state is not active" do - @service = FactoryBot.create(:service, :name => 'Test Service') - @task_0.destination = @service - @task_0.state = 'pending' - zone = FactoryBot.create(:zone, :name => "special") - orchestration_manager = FactoryBot.create(:ext_management_system, :zone => zone) - @task_0.source = FactoryBot.create(:service_template_orchestration, :orchestration_manager => orchestration_manager) - automate_args = { - :object_type => 'ServiceTemplateProvisionTask', - :object_id => @task_0.id, - :namespace => 'Service/Provisioning/StateMachines', - :class_name => 'ServiceProvision_Template', - :instance_name => 'clone_to_service', - :automate_message => 'create', - :attrs => {'request' => 'clone_to_service', 'Service::Service' => @service.id}, - :user_id => @admin.id, - :miq_group_id => @admin.current_group_id, - :tenant_id => @admin.current_tenant.id, - } - allow(@request).to receive(:approved?).and_return(true) - expect(MiqQueue).to receive(:put).with( - :class_name => 'MiqAeEngine', - :method_name => 'deliver', - :args => [automate_args], - :role => 'automate', - :zone => 'special', - :tracking_label => tracking_label - ) - @task_0.deliver_to_automate + context "when the state is not active" do + before do + @st_zone = FactoryBot.create(:zone, :name => "service_template_zone") + @service = FactoryBot.create(:service, :name => 'Test Service') + @task_0.source = FactoryBot.create(:service_template, :zone => @st_zone) + @task_0.destination = @service + @task_0.state = 'pending' + allow(MiqServer).to receive(:my_zone).and_return('a_server_zone') + allow(@request).to receive(:approved?).and_return(true) + end + + it "delivers to the queue" do + zone = FactoryBot.create(:zone, :name => "special") + orchestration_manager = FactoryBot.create(:ext_management_system, :zone => zone) + @task_0.source = FactoryBot.create(:service_template_orchestration, :orchestration_manager => orchestration_manager) + automate_args = { + :object_type => 'ServiceTemplateProvisionTask', + :object_id => @task_0.id, + :namespace => 'Service/Provisioning/StateMachines', + :class_name => 'ServiceProvision_Template', + :instance_name => 'clone_to_service', + :automate_message => 'create', + :attrs => {'request' => 'clone_to_service', 'Service::Service' => @service.id}, + :user_id => @admin.id, + :miq_group_id => @admin.current_group_id, + :tenant_id => @admin.current_tenant.id, + } + expect(MiqQueue).to receive(:put).with( + :class_name => 'MiqAeEngine', + :method_name => 'deliver', + :args => [automate_args], + :role => 'automate', + :zone => 'special', + :tracking_label => tracking_label + ) + @task_0.deliver_to_automate + end + + it "sets queue item to zone specified in dialog" do + zone = FactoryBot.create(:zone, :name => 'dialog_zone') + @task_0.update_attributes(:options => {:dialog => {"dialog_zone" => zone.name}}) + expect(MiqQueue).to receive(:put).with(hash_including(:zone => zone.name)) + @task_0.deliver_to_automate + end + + it "sets queue item to zone specified in service template without dialog" do + expect(MiqQueue).to receive(:put).with(hash_including(:zone => @st_zone.name)) + @task_0.deliver_to_automate + end + + it "sets queue item to server's zone if not specified in dialog and service template" do + @task_0.source.update_attributes(:zone => nil) + expect(MiqQueue).to receive(:put).with(hash_including(:zone => 'a_server_zone')) + @task_0.deliver_to_automate + end end it "raises an error when the state is already active" do