Skip to content

Commit

Permalink
Support operations on CloudObjectStoreContainer
Browse files Browse the repository at this point in the history
CloudObjectStoreContainer model had no support for operations
(e.g. delete) since they were not supported by backend. Well,
now the backend supports deleting bucket hence we add "Configuration"
menu option for this.

This commit brings a new mid-page menu item "Configuration->Remove
Object Storage Container" to the following pages:

* cloud object container details page
* cloud object container full list
* cloud object container list per StorageManager

Signed-off-by: Miha Pleško <[email protected]>
  • Loading branch information
miha-plesko committed Mar 7, 2017
1 parent 3a5c784 commit b3b5cc2
Show file tree
Hide file tree
Showing 8 changed files with 342 additions and 6 deletions.
50 changes: 50 additions & 0 deletions app/controllers/application_controller/ci_processing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1840,6 +1840,49 @@ def vm_button_operation(method, display_name, partial_after_single_selection = n
vms.count
end

def process_cloud_object_storage_buttons(pressed)
assert_privileges(pressed)

klass = get_rec_cls
task = pressed.sub("#{klass.name.underscore.to_sym}_", "")

return tag(klass) if task == "tag"

cloud_object_store_button_operation(klass, task)
end

def cloud_object_store_button_operation(klass, task)
method = "#{task}_#{klass.name.underscore.to_sym}"
display_name = _(task.capitalize)

items = []

# Either a list or coming from a different controller
if @lastaction == "show_list" || !%w(cloud_object_store_container).include?(request.parameters["controller"])
items = find_checked_items
if items.empty?
add_flash(_("No %{model} were selected for %{task}") %
{:model => ui_lookup(:models => klass.name), :task => display_name}, :error)
elsif klass.find(items).any? { |item| !item.supports?(task) }
add_flash(_("%{task} does not apply to at least one of the selected items") %
{:task => display_name}, :error)
else
process_objects(items, method, display_name)
end
elsif params[:id].nil? || klass.find_by(:id => params[:id]).nil?
add_flash(_("%{record} no longer exists") %
{:record => ui_lookup(:table => request.parameters["controller"])}, :error)
show_list unless @explorer
@refresh_partial = "layouts/gtl"
elsif !klass.find_by(:id => params[:id]).supports?(task)
add_flash(_("%{task} does not apply to this item") %
{:task => display_name}, :error)
else
items.push(params[:id])
process_objects(items, method, display_name) unless items.empty?
end
end

def get_rec_cls
case request.parameters["controller"]
when "miq_template"
Expand All @@ -1848,6 +1891,10 @@ def get_rec_cls
return OrchestrationStack
when "service"
return Service
when "cloud_object_store_container"
CloudObjectStoreContainer
when "ems_storage"
CloudObjectStoreContainer
else
return VmOrTemplate
end
Expand All @@ -1864,6 +1911,9 @@ def process_objects(objs, task, display_name = nil)
when "VmOrTemplate"
objs, _objs_out_reg = filter_ids_in_region(objs, "VM") unless VmOrTemplate::REMOTE_REGION_TASKS.include?(task)
klass = Vm
when "CloudObjectStoreContainer"
objs, _objs_out_reg = filter_ids_in_region(objs, "CloudObjectStoreContainer")
klass = CloudObjectStoreContainer
end

assert_rbac(current_user, get_rec_cls, objs)
Expand Down
11 changes: 10 additions & 1 deletion app/controllers/cloud_object_store_container_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@ def breadcrumb_name(_model)
def button
@edit = session[:edit] # Restore @edit for adv search box
params[:page] = @current_page unless @current_page.nil? # Save current page for list refresh
return tag("CloudObjectStoreContainer") if params[:pressed] == 'cloud_object_store_container_tag'

process_cloud_object_storage_buttons(params[:pressed])

if !@flash_array.nil? && params[:pressed].ends_with?("delete")
javascript_redirect :action => 'show_list',
:flash_msg => @flash_array[0][:message],
:flash_error => @flash_array[0][:level] == :error
elsif !@flash_array.nil?
render_flash unless performed?
end
end

def self.display_methods
Expand Down
8 changes: 5 additions & 3 deletions app/controllers/ems_common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,6 @@ def button
# Handle buttons from sub-items screen
if params[:pressed].starts_with?("availability_zone_",
"cloud_network_",
"cloud_object_store_container_",
"cloud_subnet_",
"cloud_tenant_",
"cloud_volume_",
Expand Down Expand Up @@ -380,7 +379,6 @@ def button
# Edit Tags for Network Manager Relationship pages
when "availability_zone_tag" then tag(AvailabilityZone)
when "cloud_network_tag" then tag(CloudNetwork)
when "cloud_object_store_container_tag" then tag(CloudObjectStoreContainer)
when "cloud_subnet_tag" then tag(CloudSubnet)
when "cloud_tenant_tag" then tag(CloudTenant)
when "cloud_volume_tag" then tag(CloudVolume)
Expand Down Expand Up @@ -416,6 +414,8 @@ def button
show # Handle EMS buttons
end
end
elsif params[:pressed].starts_with?("cloud_object_store_")
process_cloud_object_storage_buttons(params[:pressed])
else
@refresh_div = "main_div" # Default div for button.rjs to refresh
redirect_to :action => "new" if params[:pressed] == "new"
Expand Down Expand Up @@ -496,7 +496,9 @@ def button
end

if !@flash_array.nil? && params[:pressed] == "#{@table_name}_delete" && @single_delete
javascript_redirect :action => 'show_list', :flash_msg => @flash_array[0][:message] # redirect to build the retire screen
javascript_redirect :action => 'show_list',
:flash_msg => @flash_array[0][:message],
:flash_error => @flash_array[0][:level] == :error
elsif params[:pressed] == "host_aggregate_edit"
javascript_redirect :controller => "host_aggregate", :action => "edit", :id => find_checked_items[0]
elsif params[:pressed] == "cloud_tenant_edit"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@
class ApplicationHelper::Toolbar::CloudObjectStoreContainerCenter < ApplicationHelper::Toolbar::Basic
button_group(
'cloud_object_store_container_vmdb',
[
select(
:cloud_object_store_container_vmdb_choice,
'fa fa-cog fa-lg',
t = N_('Configuration'),
t,
:items => [
button(
:cloud_object_store_container_delete,
'pficon pficon-delete fa-lg',
N_('Remove Object Storage Container'),
N_('Remove Object Storage Container'),
:url_parms => "main_div",
:confirm => N_("Warning: The selected Object Storage Container and ALL related Objects will be "\
"permanently removed!"),
:klass => ApplicationHelper::Button::GenericFeatureButtonWithDisable,
:options => {:feature => :delete}
),
]
),
]
)
button_group('cloud_object_store_container_policy', [
select(
:cloud_object_store_container_policy_choice,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
class ApplicationHelper::Toolbar::CloudObjectStoreContainersCenter < ApplicationHelper::Toolbar::Basic
button_group(
'cloud_object_store_container_vmdb',
[
select(
:cloud_object_store_container_vmdb_choice,
'fa fa-cog fa-lg',
t = N_('Configuration'),
t,
:enabled => false,
:onwhen => "1+",
:items => [
button(
:cloud_object_store_container_delete,
'pficon pficon-delete fa-lg',
N_('Remove selected Object Storage Containers'),
N_('Remove Object Storage Containers'),
:url_parms => "main_div",
:confirm => N_("Warning: The selected Object Storage Containers and ALL related Objects will be "\
"permanently removed!"),
:enabled => false,
:onwhen => "1+"
),
]
),
]
)
button_group('cloud_object_store_container_policy', [
select(
:cloud_object_store_container_policy_choice,
Expand Down
156 changes: 156 additions & 0 deletions spec/controllers/application_controller/ci_processing_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,162 @@
end
end

context "Delete object store container" do
before do
allow(controller).to receive(:assert_rbac).and_return(nil)
allow_any_instance_of(CloudObjectStoreContainer).to receive(:supports?).and_return(true)
end

let :container1 do
FactoryGirl.create(:cloud_object_store_container)
end

let :container2 do
FactoryGirl.create(:cloud_object_store_container)
end

context "from list view" do
before do
controller.params[:pressed] = "cloud_object_store_container_delete"
request.parameters["controller"] = "ems_storage"
end

it "get_rec_cls" do
expect(controller.send(:get_rec_cls)).to eq(CloudObjectStoreContainer)
end

it "invokes cloud_object_store_button_operation" do
expect(controller).to receive(:cloud_object_store_button_operation).with(
CloudObjectStoreContainer,
'delete'
)
controller.send(:process_cloud_object_storage_buttons, "cloud_object_store_container_delete")
end

it "invokes process_objects" do
controller.params[:miq_grid_checks] = "#{container1.id}, #{container2.id}"
expect(controller).to receive(:process_objects).with(
[container1.id, container2.id],
'delete_cloud_object_store_container',
'Delete'
)
controller.send(:cloud_object_store_button_operation, CloudObjectStoreContainer, 'delete')
end

it "invokes process_tasks on container class" do
expect(CloudObjectStoreContainer).to receive(:process_tasks).with(
:ids => [container1.id, container2.id],
:task => 'delete_cloud_object_store_container',
:userid => anything
)
controller.send(:process_objects, [container1.id, container2.id], 'delete_cloud_object_store_container',
'delete')
end

it "invokes process_tasks overall (when selected)" do
controller.params[:miq_grid_checks] = "#{container1.id}, #{container2.id}"
expect(CloudObjectStoreContainer).to receive(:process_tasks).with(
:ids => [container1.id, container2.id],
:task => 'delete_cloud_object_store_container',
:userid => anything
)
controller.send(:process_cloud_object_storage_buttons, "cloud_object_store_container_delete")
end

it "does not invoke process_tasks overall when nothing selected" do
controller.params[:miq_grid_checks] = ''
expect(CloudObjectStoreContainer).not_to receive(:process_tasks)
controller.send(:process_cloud_object_storage_buttons, "cloud_object_store_container_delete")
end

it "flash - nothing selected" do
controller.params[:miq_grid_checks] = ''
controller.send(:process_cloud_object_storage_buttons, "cloud_object_store_container_delete")
expect(assigns(:flash_array).first[:message]).to include(
"No Cloud Object Store Containers were selected for Delete"
)
end

it "flash - task not supported" do
controller.params[:miq_grid_checks] = "#{container1.id}, #{container2.id}"
allow_any_instance_of(CloudObjectStoreContainer).to receive(:supports?).and_return(false)
controller.send(:process_cloud_object_storage_buttons, "cloud_object_store_container_delete")
expect(assigns(:flash_array).first[:message]).to include(
"Delete does not apply to at least one of the selected items"
)
end
end

context "from details view" do
before do
allow(controller).to receive(:show_list).and_return(nil)
controller.params[:pressed] = "cloud_object_store_container_delete"
request.parameters["controller"] = "cloud_object_store_container"
end

let :container do
FactoryGirl.create(:cloud_object_store_container)
end

it "get_rec_cls" do
expect(controller.send(:get_rec_cls)).to eq(CloudObjectStoreContainer)
end

it "invokes cloud_object_store_button_operation" do
expect(controller).to receive(:cloud_object_store_button_operation).with(
CloudObjectStoreContainer,
'delete'
)
controller.send(:process_cloud_object_storage_buttons, "cloud_object_store_container_delete")
end

it "invokes process_objects" do
controller.params[:id] = container.id
expect(controller).to receive(:process_objects).with(
[container.id],
'delete_cloud_object_store_container',
'Delete'
)
controller.send(:cloud_object_store_button_operation, CloudObjectStoreContainer, 'delete')
end

it "invokes process_tasks on container class" do
expect(CloudObjectStoreContainer).to receive(:process_tasks).with(
:ids => [container.id],
:task => 'delete_cloud_object_store_container',
:userid => anything
)
controller.send(:process_objects, [container.id], 'delete_cloud_object_store_container', 'delete')
end

it "invokes process_tasks overall" do
controller.params[:id] = container.id
expect(CloudObjectStoreContainer).to receive(:process_tasks).with(
:ids => [container.id],
:task => 'delete_cloud_object_store_container',
:userid => anything
)
controller.send(:process_cloud_object_storage_buttons, "cloud_object_store_container_delete")
end

it "flash - container no longer exists" do
controller.send(:process_cloud_object_storage_buttons, "cloud_object_store_container_delete")
expect(assigns(:flash_array).first[:message]).to include(
"Cloud Object Store Container no longer exists"
)
end

it "flash - task not supported" do
controller.params[:id] = container.id
allow_any_instance_of(CloudObjectStoreContainer).to receive(:supports?).and_return(false)
controller.send(:process_cloud_object_storage_buttons, "cloud_object_store_container_delete")
expect(assigns(:flash_array).first[:message]).to include(
"Delete does not apply to this item"
)
end
end
end

# some methods should not be accessible through the legacy routes
# either by being private or through the hide_action mechanism
it 'should not allow call of hidden/private actions' do
Expand Down
Loading

0 comments on commit b3b5cc2

Please sign in to comment.