Skip to content

Commit

Permalink
Add zone to service provisioning.
Browse files Browse the repository at this point in the history
  • Loading branch information
lfu committed Mar 29, 2019
1 parent 0b6e5e5 commit 156eda5
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 31 deletions.
12 changes: 12 additions & 0 deletions app/models/mixins/miq_request_mixin.rb
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions app/models/service_template.rb
Expand Up @@ -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
Expand Down Expand Up @@ -450,6 +451,12 @@ def self.display_name(number = 1)
n_('Service Catalog Item', 'Service Catalog Items', number)
end

def my_zone
# Catalog items can specify a zone to run in.
# Catalog bundle are used for grouping catalog items and are therefore treated as zone-agnostic.
zone&.name if atomic?
end

private

def update_service_resources(config_info, auth_user = nil)
Expand Down
1 change: 1 addition & 0 deletions app/models/service_template_provision_request.rb
Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions app/models/service_template_provision_task.rb
Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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")
Expand Down
84 changes: 55 additions & 29 deletions spec/models/service_template_provision_task_spec.rb
Expand Up @@ -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
Expand Down

0 comments on commit 156eda5

Please sign in to comment.