Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/controllers/api/subcollections/snapshots.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ def snapshots_create_resource(parent, _type, _id, data)
action_result(false, e.to_s)
end

def snapshots_rename_snapshot_resource(parent, type, id, data)
raise "Must specify a new name for the snapshot" if data["name"].blank?
raise parent.unsupported_reason(:rename_snapshot) unless parent.supports?(:rename_snapshot)

snapshot = resource_search(id, type)
message = "Renaming snapshot #{snapshot.name} to #{data["name"]} for #{snapshot_ident(parent)}"
task_id = queue_object_action(parent, message, :method_name => "rename_snapshot", :role => "ems_operations", :args => [id, data["name"]])
action_result(true, message, :task_id => task_id)
rescue StandardError => e
action_result(false, e.to_s)
end

def delete_resource_snapshots(parent, type, id, _data)
snapshot = resource_search(id, type)
begin
Expand Down
4 changes: 4 additions & 0 deletions config/api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2087,6 +2087,8 @@
- :name: read
:identifier: cloud_volume_snapshot_view
:post:
- :name: rename_snapshot
:identifier: cloud_volume_snapshot_control
- :name: delete
:identifier: cloud_volume_snapshot_delete
:custom_attributes_subcollection_actions:
Expand Down Expand Up @@ -4934,6 +4936,8 @@
:post:
- :name: revert
:identifier: vm_snapshot_revert
- :name: rename_snapshot
:identifier: vm_snapshot_rename
- :name: delete
:identifier:
- vm_snapshot_delete
Expand Down
92 changes: 92 additions & 0 deletions spec/requests/snapshots_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
RSpec.describe "Snapshots API" do
include Spec::Support::SupportsHelper

describe "as a subcollection of VMs" do
describe "GET /api/vms/:c_id/snapshots" do
it "can list the snapshots of a VM" do
Expand Down Expand Up @@ -211,6 +213,62 @@
end
end

describe "POST /api/vms/:c_id/snapshots/:s_id with rename_snapshot action" do
it "can queue a VM for renaming a snapshot" do
api_basic_authorize(action_identifier(:vms, :rename_snapshot, :snapshots_subresource_actions))
ems = FactoryBot.create(:ext_management_system)
host = FactoryBot.create(:host, :ext_management_system => ems)
vm = FactoryBot.create(:vm_vmware, :name => "Alice's VM", :host => host, :ext_management_system => ems)
snapshot = FactoryBot.create(:snapshot, :name => "Alice's snapshot", :vm_or_template => vm)

stub_supports(vm, :rename_snapshot)

post(api_vm_snapshot_url(nil, vm, snapshot), :params => {:action => "rename_snapshot", :name => "renamed snapshot"})

expected = {
"message" => "Renaming snapshot Alice's snapshot to renamed snapshot for Virtual Machine id:#{vm.id} name:'Alice's VM'",
"success" => true,
"task_href" => a_string_matching(api_tasks_url),
"task_id" => anything
}

expect(response.parsed_body).to include(expected)
expect(response).to have_http_status(:ok)

queue_item = MiqQueue.find_by(:class_name => vm.class.name, :method_name => "rename_snapshot")
expect(queue_item).to have_attributes(
:zone => ems.zone_name,
:queue_name => ems.queue_name_for_ems_operations,
:args => [snapshot.id, "renamed snapshot"]
)
end

it "requires a name for renaming" do
api_basic_authorize(action_identifier(:vms, :rename_snapshot, :snapshots_subresource_actions))
vm = FactoryBot.create(:vm_vmware)
snapshot = FactoryBot.create(:snapshot, :vm_or_template => vm)

post(api_vm_snapshot_url(nil, vm, snapshot), :params => {:action => "rename_snapshot"})

expected = {
"success" => false,
"message" => "Must specify a new name for the snapshot"
}
expect(response.parsed_body).to include(expected)
expect(response).to have_http_status(:bad_request)
end

it "will not rename a snapshot unless authorized" do
api_basic_authorize
vm = FactoryBot.create(:vm_vmware)
snapshot = FactoryBot.create(:snapshot, :vm_or_template => vm)

post(api_vm_snapshot_url(nil, vm, snapshot), :params => {:action => "rename_snapshot", :name => "renamed snapshot"})

expect(response).to have_http_status(:forbidden)
end
end

describe "POST /api/vms/:c_id/snapshots/:s_id with delete action" do
it "can queue a snapshot for deletion" do
api_basic_authorize(action_identifier(:vms, :delete, :snapshots_subresource_actions, :delete))
Expand Down Expand Up @@ -518,6 +576,40 @@
end
end

describe "POST /api/instances/:c_id/snapshots/:s_id with rename_snapshot action" do
it "can queue an Instance for renaming a snapshot" do
api_basic_authorize(action_identifier(:instances, :rename_snapshot, :snapshots_subresource_actions))

ems = FactoryBot.create(:ems_openstack_infra)
host = FactoryBot.create(:host_openstack_infra, :ext_management_system => ems)
instance = FactoryBot.create(:vm_openstack, :name => "Alice's Instance", :ext_management_system => ems, :host => host)
snapshot = FactoryBot.create(:snapshot, :name => "Alice's snapshot", :vm_or_template => instance)

stub_supports(instance, :rename_snapshot)

post(api_instance_snapshot_url(nil, instance, snapshot), :params => {:action => "rename_snapshot", :name => "renamed snapshot"})

expected = {
"message" => "Renaming snapshot Alice's snapshot to renamed snapshot for Instance id:#{instance.id} name:'Alice's Instance'",
"success" => true,
"task_href" => a_string_matching(api_tasks_url),
"task_id" => anything
}
expect(response.parsed_body).to include(expected)
expect(response).to have_http_status(:ok)
end

it "will not rename an instance snapshot unless authorized" do
api_basic_authorize
instance = FactoryBot.create(:vm_openstack)
snapshot = FactoryBot.create(:snapshot, :vm_or_template => instance)

post(api_instance_snapshot_url(nil, instance, snapshot), :params => {:action => "rename_snapshot", :name => "renamed snapshot"})

expect(response).to have_http_status(:forbidden)
end
end

describe "POST /api/instances/:c_id/snapshots/:s_id with delete action" do
it "can queue a snapshot for deletion" do
api_basic_authorize(action_identifier(:instances, :delete, :snapshots_subresource_actions, :delete))
Expand Down
Loading