Skip to content

Commit

Permalink
Use Mistral workflows, if available, to scale stacks
Browse files Browse the repository at this point in the history
Modifies update_stack to queue tasks to scale up or down stacks
using Mistral if the workflows are available. Workflows are
available starting with OSP10.

For OSP9 and older environments, the existing behavior of updating
the stack directly is used.

Depends on ManageIQ/manageiq-providers-openstack#55
  • Loading branch information
rwsu committed Jun 27, 2017
1 parent c9e5ecb commit 3dd79a0
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 24 deletions.
84 changes: 64 additions & 20 deletions app/controllers/ems_infra_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def scaling
end
end

update_stack(@stack, scale_parameters_formatted, params[:id], return_message, 'scaleup')
update_stack_up(@stack, scale_parameters_formatted, params[:id], return_message)
end
end

Expand Down Expand Up @@ -109,8 +109,8 @@ def scaledown

# figure out scaledown parameters and update stack
stack_parameters = get_scaledown_parameters(hosts, @infra, @compute_hosts)
return_message = _(" Scaling down to %{a} compute nodes") % {:a => stack_parameters['ComputeCount']}
update_stack(@stack, stack_parameters, params[:id], return_message, 'scaledown', {:services => services})

update_stack_down(@stack, stack_parameters, params[:id], hosts, :services => services)
end
end

Expand Down Expand Up @@ -184,33 +184,77 @@ def log_and_flash_message(message)
$log.error(message)
end

def update_stack(stack, stack_parameters, provider_id, return_message, operation, additional_args = {})
def update_stack_up(stack, stack_parameters, provider_id, return_message)
if stack_is_ready?(stack) && stack_parameters_changed?(stack_parameters)
begin
if can_use_scale_up_workflow?
# OSP >= 10 use workflows
stack.scale_up_queue(session[:userid], stack_parameters)
else
# OSP < 10 use heat stack update
stack.update_stack_queue(session[:userid], nil, stack_parameters)
end
redirect_to ems_infra_path(provider_id, :flash_msg => return_message)
rescue => ex
log_and_flash_message(_("Unable to initiate scale up: %{message}") % {:message => ex})
end
end
end

def update_stack_down(stack, stack_parameters, provider_id, hosts, additional_args = {})
return_message = _(" Scaling down to %{a} compute nodes") % {:a => stack_parameters['ComputeCount']}
if stack_is_ready?(stack) && stack_parameters_changed?(stack_parameters)
begin
if can_use_scale_down_workflow?
# OSP >= 10 use workflows
stack.scale_down_queue(session[:userid], hosts)
else
# OSP < 10 use heat stack update
task_id = stack.update_stack_queue(session[:userid], nil, stack_parameters)
stack.queue_post_scaledown_task(additional_args[:services], task_id)
end
redirect_to ems_infra_path(provider_id, :flash_msg => return_message)
rescue => ex
log_and_flash_message(_("Unable to initiate scale down: %{message}") % {:message => ex})
end
end
end

def stack_is_ready?(stack)
begin
# Check if stack is ready to be updated
update_ready = stack.update_ready?
rescue => ex
log_and_flash_message(_("Unable to update stack, obtaining of status failed: %{message}") %
{:message => ex})
return
{:message => ex})
false
end

if !update_ready
unless update_ready
add_flash(_("Provider stack is not ready to be updated, another operation is in progress."), :error)
elsif !stack_parameters.empty?
# A value was changed
begin
task_id = stack.update_stack_queue(session[:userid], nil, stack_parameters)
if operation == 'scaledown'
@stack.queue_post_scaledown_task(additional_args[:services], task_id)
end
redirect_to ems_infra_path(provider_id, :flash_msg => return_message)
rescue => ex
log_and_flash_message(_("Unable to initiate scaling: %{message}") % {:message => ex})
end
else
end
update_ready
end

def stack_parameters_changed?(stack_parameters)
if stack_parameters.empty?
# No values were changed
add_flash(_("A value must be changed or provider stack will not be updated."), :error)
false
end
true
end

def can_use_scale_up_workflow?
!workflow_service.nil? && workflow_service.has_action?("tripleo.parameters.update") && workflow_service.has_workflow?("tripleo.deployment.v1.deploy_plan")
end

def can_use_scale_down_workflow?
!workflow_service.nil? && workflow_service.has_workflow?("tripleo.scale.v1.delete_node")
end

def workflow_service
@infra.workflow_service
end

def verify_hosts_for_scaledown(hosts)
Expand Down Expand Up @@ -257,7 +301,7 @@ def get_scaledown_parameters(hosts, provider, compute_hosts)
stack_parameters = {}
stack_parameters['ComputeCount'] = compute_hosts.length - hosts.length
stack_parameters['ComputeRemovalPolicies'] = [{:resource_list => parent_resource_names}]
return stack_parameters
stack_parameters
end

def restful?
Expand Down
42 changes: 38 additions & 4 deletions spec/controllers/ems_infra_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,13 @@
"Assigning #{@ems.hosts.count * 2} but only have #{@ems.hosts.count} hosts available.")
end

it "when values are changed, and values do not exceed number of hosts available" do
it "when values are changed, values do not exceed number of hosts available, and not using workflows" do
allow_any_instance_of(ManageIQ::Providers::Openstack::InfraManager::OrchestrationStack)
.to receive(:raw_update_stack)
expect_any_instance_of(ManageIQ::Providers::Openstack::InfraManager::OrchestrationStack)
.not_to receive(:queue_post_scaledown_task)
allow_any_instance_of(EmsInfraController)
.to receive(:can_use_scale_up_workflow?).and_return(false)
post :scaling, :params => { :id => @ems.id, :scale => "", :orchestration_stack_id => @ems.orchestration_stacks.first.id,
@orchestration_stack_parameter_compute.name => 2 }
expect(controller.send(:flash_errors?)).to be_falsey
Expand All @@ -140,6 +142,19 @@
expect(response.body).to include("1+to+2")
end

it "when values are changed, values do not exceed number of hosts available, and using workflows" do
allow_any_instance_of(EmsInfraController)
.to receive(:can_use_scale_up_workflow?).and_return(true)
allow_any_instance_of(ManageIQ::Providers::Openstack::InfraManager::OrchestrationStack)
.to receive(:scale_up_queue)
post :scaling, :params => { :id => @ems.id, :scale => "", :orchestration_stack_id => @ems.orchestration_stacks.first.id,
@orchestration_stack_parameter_compute.name => 2 }
expect(controller.send(:flash_errors?)).to be_falsey
expect(response.body).to include("redirected")
expect(response.body).to include("ems_infra")
expect(response.body).to include("1+to+2")
end

it "when no orchestration stack is available" do
@ems = FactoryGirl.create(:ems_openstack_infra)
post :scaling, :params => { :id => @ems.id, :scale => "", :orchestration_stack_id => nil }
Expand All @@ -151,11 +166,13 @@
it "when patch operation fails, an error message should be displayed" do
allow_any_instance_of(ManageIQ::Providers::Openstack::InfraManager::OrchestrationStack)
.to receive(:update_stack_queue) { raise "my error" }
allow_any_instance_of(EmsInfraController)
.to receive(:can_use_scale_up_workflow?).and_return(false)
post :scaling, :params => { :id => @ems.id, :scale => "", :orchestration_stack_id => @ems.orchestration_stacks.first.id,
@orchestration_stack_parameter_compute.name => 2 }
expect(controller.send(:flash_errors?)).to be_truthy
flash_messages = assigns(:flash_array)
expect(flash_messages.first[:message]).to include("Unable to initiate scaling: my error")
expect(flash_messages.first[:message]).to include("Unable to initiate scale up: my error")
end

it "when operation in progress, an error message should be displayed" do
Expand Down Expand Up @@ -196,11 +213,13 @@
"Not all hosts can be removed from the deployment.")
end

it "when values are changed, and selected host is in correct state" do
it "when values are changed, selected host is in correct state, and workflows are not used" do
allow_any_instance_of(ManageIQ::Providers::Openstack::InfraManager::OrchestrationStack)
.to receive(:raw_update_stack)
expect_any_instance_of(ManageIQ::Providers::Openstack::InfraManager::OrchestrationStack)
.to receive(:queue_post_scaledown_task)
allow_any_instance_of(EmsInfraController)
.to receive(:can_use_scale_down_workflow?).and_return(false)
post :scaledown, :params => {:id => @ems.id, :scaledown => "",
:orchestration_stack_id => @ems.orchestration_stacks.first.id, :host_ids => [@ems.hosts[1].id]}
expect(controller.send(:flash_errors?)).to be_falsey
Expand All @@ -209,6 +228,19 @@
expect(response.body).to include("down+to+1")
end

it "when values are changed, selected host is in correct state, and workflows are used" do
allow_any_instance_of(EmsInfraController)
.to receive(:can_use_scale_down_workflow?).and_return(true)
allow_any_instance_of(ManageIQ::Providers::Openstack::InfraManager::OrchestrationStack)
.to receive(:scale_down_queue)
post :scaledown, :params => {:id => @ems.id, :scaledown => "",
:orchestration_stack_id => @ems.orchestration_stacks.first.id, :host_ids => [@ems.hosts[1].id]}
expect(controller.send(:flash_errors?)).to be_falsey
expect(response.body).to include("redirected")
expect(response.body).to include("ems_infra")
expect(response.body).to include("down+to+1")
end

it "when no orchestration stack is available" do
@ems = FactoryGirl.create(:ems_openstack_infra)
post :scaledown, :params => {:id => @ems.id, :scaledown => "", :orchestration_stack_id => nil}
Expand All @@ -220,11 +252,13 @@
it "when patch operation fails, an error message should be displayed" do
allow_any_instance_of(ManageIQ::Providers::Openstack::InfraManager::OrchestrationStack)
.to receive(:update_stack_queue) { raise "my error" }
allow_any_instance_of(EmsInfraController)
.to receive(:can_use_scale_down_workflow?).and_return(false)
post :scaledown, :params => {:id => @ems.id, :scaledown => "",
:orchestration_stack_id => @ems.orchestration_stacks.first.id, :host_ids => [@ems.hosts[1].id]}
expect(controller.send(:flash_errors?)).to be_truthy
flash_messages = assigns(:flash_array)
expect(flash_messages.first[:message]).to include("Unable to initiate scaling: my error")
expect(flash_messages.first[:message]).to include("Unable to initiate scale down: my error")
end

it "when operation in progress, an error message should be displayed" do
Expand Down

0 comments on commit 3dd79a0

Please sign in to comment.