Skip to content

Commit

Permalink
Merge pull request #421 from bdunne/request_cancel
Browse files Browse the repository at this point in the history
Request cancel
(cherry picked from commit 62de390)

https://bugzilla.redhat.com/show_bug.cgi?id=1610533
  • Loading branch information
gtanzillo authored and simaishi committed Jul 31, 2018
1 parent 8547c12 commit b704774
Show file tree
Hide file tree
Showing 20 changed files with 239 additions and 1 deletion.
1 change: 1 addition & 0 deletions app/controllers/api/automation_requests_controller.rb
@@ -1,5 +1,6 @@
module Api
class AutomationRequestsController < BaseController
include Api::Mixins::ResourceCancel
include Subcollections::RequestTasks

def create_resource(type, _id, data)
Expand Down
14 changes: 14 additions & 0 deletions app/controllers/api/mixins/resource_cancel.rb
@@ -0,0 +1,14 @@
module Api
module Mixins
module ResourceCancel
def cancel_resource(type, id, _data)
api_action(type, id) do |klass|
resource_search(id, type, klass).cancel
action_result(true, "#{klass.name} #{id} canceled")
end
rescue => err
action_result(false, err.to_s)
end
end
end
end
1 change: 1 addition & 0 deletions app/controllers/api/provision_requests_controller.rb
@@ -1,5 +1,6 @@
module Api
class ProvisionRequestsController < BaseController
include Api::Mixins::ResourceCancel
include Subcollections::RequestTasks

def create_resource(type, _id, data)
Expand Down
1 change: 1 addition & 0 deletions app/controllers/api/request_tasks_controller.rb
@@ -1,4 +1,5 @@
module Api
class RequestTasksController < BaseController
include Api::Mixins::ResourceCancel
end
end
1 change: 1 addition & 0 deletions app/controllers/api/requests_controller.rb
@@ -1,5 +1,6 @@
module Api
class RequestsController < BaseController
include Api::Mixins::ResourceCancel
include Subcollections::RequestTasks

def create_resource(type, _id, data)
Expand Down
1 change: 1 addition & 0 deletions app/controllers/api/service_requests_controller.rb
Expand Up @@ -2,6 +2,7 @@ module Api
class ServiceRequestsController < BaseController
include Subcollections::RequestTasks
include Api::Mixins::Pictures
include Api::Mixins::ResourceCancel

alias fetch_service_requests_picture fetch_picture

Expand Down
7 changes: 7 additions & 0 deletions app/controllers/api/subcollections/request_tasks.rb
Expand Up @@ -15,6 +15,13 @@ def request_tasks_edit_resource(_object, type, id = nil, data = {})
end
request_task
end

def request_tasks_cancel_resource(_object, type, id = nil, _data = {})
resource_search(id, type, collection_class(:request_tasks)).cancel
action_result(true, "RequestTask #{id} canceled")
rescue => err
action_result(false, err.to_s)
end
end
end
end
7 changes: 7 additions & 0 deletions app/controllers/api/subcollections/service_requests.rb
Expand Up @@ -27,6 +27,13 @@ def service_requests_remove_resource(target, type, id, _data)
end
end

def service_requests_cancel_resource(_target, type, id, _data)
resource_search(id, type, collection_class(:service_requests)).cancel
action_result(true, "Service request #{id} canceled")
rescue => err
action_result(false, err.to_s)
end

private

def service_request_ident(service_request)
Expand Down
31 changes: 31 additions & 0 deletions config/api.yml
Expand Up @@ -292,6 +292,8 @@
:identifier: miq_request_approval
- :name: deny
:identifier: miq_request_approval
- :name: cancel
:identifier: miq_request_control
- :name: edit
:identifier: miq_request_edit
:resource_actions:
Expand All @@ -303,6 +305,8 @@
:identifier: miq_request_approval
- :name: deny
:identifier: miq_request_approval
- :name: cancel
:identifier: miq_request_control
- :name: edit
:identifier: miq_request_edit
:availability_zones:
Expand Down Expand Up @@ -1785,6 +1789,8 @@
:identifier: miq_request_approval
- :name: deny
:identifier: miq_request_approval
- :name: cancel
:identifier: miq_request_control
- :name: edit
:identifier: miq_request_edit
:resource_actions:
Expand All @@ -1796,6 +1802,8 @@
:identifier: miq_request_approval
- :name: deny
:identifier: miq_request_approval
- :name: cancel
:identifier: miq_request_control
- :name: edit
:identifier: miq_request_edit
:quotas:
Expand Down Expand Up @@ -1921,15 +1929,26 @@
:get:
- :name: read
:identifier: miq_request_show
:post:
- :name: cancel
:identifier: miq_request_control
:resource_actions:
:post:
- :name: cancel
:identifier: miq_request_control
:subcollection_actions:
:get:
- :name: read
:identifier: miq_request_show
:post:
- :name: cancel
:identifier: miq_request_control
- :name: edit
:identifier: miq_request_edit
:subresource_actions:
:post:
- :name: cancel
:identifier: miq_request_control
- :name: edit
:identifier: miq_request_edit
:requests:
Expand All @@ -1948,6 +1967,8 @@
:post:
- :name: query
:identifier: miq_request_show_list
- :name: cancel
:identifier: miq_request_control
- :name: create
:identifiers:
- :klass: AutomationRequest
Expand Down Expand Up @@ -1976,6 +1997,8 @@
- :name: read
:identifier: miq_request_show
:post:
- :name: cancel
:identifier: miq_request_control
- :name: edit
:identifier: miq_request_edit
- :name: approve
Expand Down Expand Up @@ -2298,6 +2321,8 @@
:post:
- :name: query
:identifier: miq_request_view
- :name: cancel
:identifier: miq_request_control
- :name: approve
:identifier: miq_request_approval
- :name: deny
Expand All @@ -2317,6 +2342,8 @@
:post:
- :name: approve
:identifier: miq_request_approval
- :name: cancel
:identifier: miq_request_control
- :name: deny
:identifier: miq_request_approval
- :name: delete
Expand All @@ -2337,13 +2364,17 @@
:post:
- :name: add
:identifier: svc_catalog_provision
- :name: cancel
:identifier: miq_request_control
- :name: remove
:identifier: svc_catalog_provision
:subresource_actions:
:get:
- :name: read
:identifier: miq_request_view
:post:
- :name: cancel
:identifier: miq_request_control
- :name: remove
:identifier: svc_catalog_provision
:service_templates:
Expand Down
12 changes: 12 additions & 0 deletions spec/requests/automation_requests_spec.rb
Expand Up @@ -311,5 +311,17 @@
expect(response.parsed_body['options']).to match(hash_including(options))
expect(task.reload.options.keys).to all(be_kind_of(Symbol))
end

context "SubResource#cancel" do
let(:resource_1_response) { {"success" => false, "message" => "Cancel operation is not supported for AutomationTask"} }
let(:resource_2_response) { {"success" => false, "message" => "Cancel operation is not supported for AutomationTask"} }
include_context "SubResource#cancel", [:automation_request, :request_task], :automation_request, :automation_task
end
end

context "Resource#cancel" do
let(:resource_1_response) { {"success" => false, "message" => "Cancel operation is not supported for AutomationRequest"} }
let(:resource_2_response) { {"success" => false, "message" => "Cancel operation is not supported for AutomationRequest"} }
include_context "Resource#cancel", "automation_request", :automation_request
end
end
12 changes: 12 additions & 0 deletions spec/requests/provision_requests_spec.rb
Expand Up @@ -501,5 +501,17 @@
expect(response.parsed_body['options']).to match(hash_including(options))
expect(task.reload.options.keys).to all(be_kind_of(Symbol))
end

context "SubResource#cancel" do
let(:resource_1_response) { {"success" => false, "message" => "Cancel operation is not supported for MiqRequestTask"} }
let(:resource_2_response) { {"success" => false, "message" => "Cancel operation is not supported for MiqRequestTask"} }
include_context "SubResource#cancel", [:provision_request, :request_task], :miq_provision_request, :miq_request_task
end
end

context "Resource#cancel" do
let(:resource_1_response) { {"success" => false, "message" => "Cancel operation is not supported for MiqProvisionRequest"} }
let(:resource_2_response) { {"success" => false, "message" => "Cancel operation is not supported for MiqProvisionRequest"} }
include_context "Resource#cancel", "provision_request", :miq_provision_request
end
end
7 changes: 7 additions & 0 deletions spec/requests/request_tasks_spec.rb
@@ -0,0 +1,7 @@
RSpec.describe "Request Tasks API" do
context "Resource#cancel" do
let(:resource_1_response) { {"success" => false, "message" => "Cancel operation is not supported for MiqRequestTask"} }
let(:resource_2_response) { {"success" => false, "message" => "Cancel operation is not supported for MiqRequestTask"} }
include_context "Resource#cancel", "request_task", :miq_request_task
end
end
12 changes: 12 additions & 0 deletions spec/requests/requests_spec.rb
Expand Up @@ -538,5 +538,17 @@
expect(response).to have_http_status(:ok)
expect(task.reload.options.keys).to all(be_kind_of(Symbol))
end

context "SubResource#cancel" do
let(:resource_1_response) { {"success" => false, "message" => "Cancel operation is not supported for MiqRequestTask"} }
let(:resource_2_response) { {"success" => false, "message" => "Cancel operation is not supported for MiqRequestTask"} }
include_context "SubResource#cancel", [:request, :request_task], :service_template_provision_request, :miq_request_task
end
end

context "Resource#cancel" do
let(:resource_1_response) { {"success" => false, "message" => "Cancel operation is not supported for VmMigrateRequest"} }
let(:resource_2_response) { {"success" => false, "message" => "Cancel operation is not supported for VmMigrateRequest"} }
include_context "Resource#cancel", "request", :vm_migrate_request
end
end
6 changes: 6 additions & 0 deletions spec/requests/service_orders_spec.rb
Expand Up @@ -613,6 +613,12 @@
expect(shopping_cart.reload.state).to eq(ServiceOrder::STATE_CART)
end
end

context "ServiceRequest#cancel" do
let(:resource_1_response) { {"success" => false, "message" => "Cancel operation is not supported for ServiceTemplateProvisionRequest"} }
let(:resource_2_response) { {"success" => false, "message" => "Cancel operation is not supported for ServiceTemplateProvisionRequest"} }
include_context "SubResource#cancel", [:service_order, :service_request], :shopping_cart, :service_template_provision_request
end
end

context 'Copy Service Order' do
Expand Down
12 changes: 12 additions & 0 deletions spec/requests/service_requests_spec.rb
Expand Up @@ -649,5 +649,17 @@ def expect_result_to_have_user_email(email)
expect(response.parsed_body['options']).to match(hash_including(options))
expect(task.reload.options.keys).to all(be_kind_of(Symbol))
end

context "SubResource#cancel" do
let(:resource_1_response) { {"success" => true, "message" => "RequestTask #{resource_1.id} canceled"} }
let(:resource_2_response) { {"success" => true, "message" => "RequestTask #{resource_2.id} canceled"} }
include_context "SubResource#cancel", [:service_request, :request_task], :service_template_transformation_plan_request, :service_template_transformation_plan_task
end
end

context "Resource#cancel" do
let(:resource_1_response) { {"success" => true, "message" => "ServiceTemplateProvisionRequest #{resource_1.id} canceled", "href" => instance_url(resource_1)} }
let(:resource_2_response) { {"success" => true, "message" => "ServiceTemplateProvisionRequest #{resource_2.id} canceled", "href" => instance_url(resource_2)} }
include_context "Resource#cancel", "service_request", :service_template_transformation_plan_request
end
end
6 changes: 6 additions & 0 deletions spec/requests/service_templates_spec.rb
Expand Up @@ -293,6 +293,12 @@
expect(response.parsed_body).to include(expected)
expect(response).to have_http_status(:ok)
end

context "ServiceRequest#cancel" do
let(:resource_1_response) { {"success" => true, "message" => "Service request #{resource_1.id} canceled"} }
let(:resource_2_response) { {"success" => true, "message" => "Service request #{resource_2.id} canceled"} }
include_context "SubResource#cancel", [:service_template, :service_request], :service_template, :service_template_transformation_plan_request
end
end

describe "Service Templates create" do
Expand Down
8 changes: 7 additions & 1 deletion spec/support/api/helpers.rb
Expand Up @@ -171,7 +171,7 @@ def expect_single_resource_query(attr_hash)

def expect_single_action_result(options = {})
expect(response).to have_http_status(:ok)
expected = {}
expected = options.slice("href", "message", "success")
expected["success"] = options[:success] if options.key?(:success)
expected["message"] = a_string_matching(options[:message]) if options[:message]
expected["href"] = a_string_matching(options[:href]) if options[:href]
Expand Down Expand Up @@ -223,6 +223,12 @@ def expect_options_results(type, data = {})
expect(response.headers['Access-Control-Allow-Methods']).to include('OPTIONS')
end

def expect_forbidden_request
api_basic_authorize
yield
expect(response).to have_http_status(:forbidden)
end

def select_attributes(attrlist)
attrlist.sort.select { |attr| !::Api.encrypted_attribute?(attr) }
end
Expand Down
23 changes: 23 additions & 0 deletions spec/support/factory_overrides.rb
@@ -0,0 +1,23 @@
FactoryGirl.modify do
factory :miq_request do
trait :with_api_user do
requester { User.find_by(:name=>"API User") }
end
end

factory :miq_request_task do
trait :with_api_user do
userid { User.find_by(:name=>"API User").userid }
end
end

factory :service_order do
trait :with_api_user do
user { User.find_by(:name=>"API User") }
end
end

factory :service_template do
trait :with_api_user
end
end
40 changes: 40 additions & 0 deletions spec/support/shared_examples/resource_cancel.rb
@@ -0,0 +1,40 @@
RSpec.shared_context "Resource#cancel" do |ns, factory|
let(:collection_identifier) { namespace.pluralize.to_sym }
let(:collection_url) { send("api_#{collection_identifier}_url") }
let(:namespace) { ns } # ns is not available from #instance_url method, but namespace is.
let(:resource_1) { FactoryGirl.create(factory, :with_api_user) }
let(:resource_2) { FactoryGirl.create(factory, :with_api_user) }

def instance_url(instance)
send("api_#{namespace}_url", nil, instance)
end

context "on a single instance" do
it "unauthorized" do
expect_forbidden_request { post(instance_url(resource_1), :params => gen_request(:cancel)) }
end

it "authorized" do
api_basic_authorize collection_action_identifier(collection_identifier, :cancel)

post(instance_url(resource_1), :params => gen_request(:cancel))

expect_single_action_result(resource_1_response)
end
end

context "on multiple instances" do
it "unauthorized" do
expect_forbidden_request { post(collection_url, :params => gen_request(:cancel, [{"href" => instance_url(resource_1)}, {"href" => instance_url(resource_2)}])) }
end

it "authorized" do
api_basic_authorize collection_action_identifier(collection_identifier, :cancel)

post(collection_url, :params => gen_request(:cancel, [{"href" => instance_url(resource_1)}, {"href" => instance_url(resource_2)}]))

expect(response.parsed_body).to include("results" => a_collection_containing_exactly(resource_1_response, resource_2_response))
expect(response).to have_http_status(:ok)
end
end
end

0 comments on commit b704774

Please sign in to comment.