Skip to content

Commit

Permalink
Add policy check to Vm retirement.
Browse files Browse the repository at this point in the history
  • Loading branch information
lfu committed Dec 16, 2019
1 parent 642cc87 commit 16543b7
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 7 deletions.
19 changes: 19 additions & 0 deletions app/models/vm_or_template.rb
Expand Up @@ -351,6 +351,25 @@ def run_command_via_parent(verb, options = {})
ext_management_system.send(verb, self, options)
end

# keep the same method signature as others in retirement mixin
def self.make_retire_request(*src_ids, requester, initiated_by: 'user')
vms = where(:id => src_ids)

missing_ids = src_ids - vms.pluck(:id)
_log.error("Retirement of [Vm] IDs: [#{missing_ids.join(', ')}] skipped - target(s) does not exist")

vms.each do |target|
target.check_policy_prevent('request_vm_retire', "retire_request_after_policy_check", requester.userid, :initiated_by => initiated_by)
end
end

def retire_request_after_policy_check(userid, initiated_by: 'user')
options = {:src_ids => [id], :__initiated_by__ => initiated_by, :__request_type__ => VmRetireRequest.request_types.first}
requester = User.find_by(:userid => userid)
self.class.set_retirement_requester(options[:src_ids], requester)
VmRetireRequest.make_request(nil, options, requester)
end

# policy_event: the event sent to automate for policy resolution
# cb_method: the MiqQueue callback method along with the parameters that is called
# when automate process is done and the event is not prevented to proceed by policy
Expand Down
45 changes: 38 additions & 7 deletions spec/models/vm/retirement_management_spec.rb
@@ -1,7 +1,7 @@
describe "VM Retirement Management" do
let!(:user) { FactoryGirl.create(:user_miq_request_approver, :userid => "admin") }
let(:region) { FactoryGirl.create(:miq_region, :region => ApplicationRecord.my_region_number) }
let(:vm2) { FactoryGirl.create(:vm) }
let(:vm2) { FactoryGirl.create(:vm, :host => FactoryBot.create(:host)) }

before do
@zone = EvmSpecHelper.local_miq_server.zone
Expand All @@ -10,12 +10,18 @@
end

describe "#retirement_check" do
before { FactoryBot.create(:miq_event_definition, :name => :request_vm_retire) }

context "with user" do
it "uses user info" do
expect(MiqEvent).to receive(:raise_evm_event).once
@vm.update_attributes(:retires_on => 90.days.ago, :retirement_warn => 60, :retirement_last_warn => nil)
expect(@vm.retirement_last_warn).to be_nil

allow(MiqAeEngine).to receive_messages(:deliver => ['ok', 'success', MiqAeEngine::MiqAeWorkspaceRuntime.new])
@vm.retirement_check
status, message, result = MiqQueue.first.deliver
MiqQueue.first.delivered(status, message, result)

@vm.reload
expect(@vm.retirement_last_warn).not_to be_nil
expect(@vm.retirement_requester).to eq(user.userid)
Expand All @@ -24,14 +30,18 @@

context "with deleted user" do
let(:user_for_deletion) { FactoryGirl.create(:user_miq_request_approver) }
let(:vm_with_non_admin_user) { FactoryGirl.create(:vm) }
let(:vm_with_non_admin_user) { FactoryGirl.create(:vm, :host => FactoryBot.create(:host)) }
it "uses admin default" do
User.with_user(user_for_deletion) do
user_for_deletion.destroy
expect(MiqEvent).to receive(:raise_evm_event)
vm_with_non_admin_user.update_attributes(:retires_on => 90.days.ago, :retirement_warn => 60, :retirement_last_warn => nil)
expect(vm_with_non_admin_user.retirement_last_warn).to be_nil

allow(MiqAeEngine).to receive_messages(:deliver => ['ok', 'success', MiqAeEngine::MiqAeWorkspaceRuntime.new])
vm_with_non_admin_user.retirement_check
status, message, result = MiqQueue.first.deliver
MiqQueue.first.delivered(status, message, result)

vm_with_non_admin_user.reload
expect(vm_with_non_admin_user.retirement_last_warn).not_to be_nil
expect(vm_with_non_admin_user.retirement_requester).to eq("admin")
Expand All @@ -41,10 +51,14 @@

context "without user" do
it "uses admin default" do
expect(MiqEvent).to receive(:raise_evm_event)
vm2.update_attributes(:retires_on => 90.days.ago, :retirement_warn => 60, :retirement_last_warn => nil)
expect(vm2.retirement_last_warn).to be_nil

allow(MiqAeEngine).to receive_messages(:deliver => ['ok', 'success', MiqAeEngine::MiqAeWorkspaceRuntime.new])
vm2.retirement_check
status, message, result = MiqQueue.first.deliver
MiqQueue.first.delivered(status, message, result)

vm2.reload
expect(vm2.retirement_last_warn).not_to be_nil
expect(vm2.retirement_requester).to eq(user.userid)
Expand Down Expand Up @@ -134,15 +148,32 @@
end

describe "retire request" do
let(:ws) { MiqAeEngine::MiqAeWorkspaceRuntime.new }
before { FactoryBot.create(:miq_event_definition, :name => :request_vm_retire) }

it "with one src_id" do
expect(VmRetireRequest).to receive(:make_request).with(nil, {:src_ids => [@vm.id], :__request_type__ => "vm_retire"}, user)
allow(Vm).to receive(:where).with(:id => [@vm.id]).and_return([@vm])
expect(@vm).to receive(:check_policy_prevent).once
Vm.make_retire_request(@vm.id, user)
end

it "with many src_ids" do
expect(VmRetireRequest).to receive(:make_request).with(nil, {:src_ids => [@vm.id, vm2.id], :__request_type__ => "vm_retire"}, user)
allow(Vm).to receive(:where).with(:id => [@vm.id, vm2.id]).and_return([@vm, vm2])
expect(@vm).to receive(:check_policy_prevent).once
expect(vm2).to receive(:check_policy_prevent).once
Vm.make_retire_request(@vm.id, vm2.id, user)
end

it "policy prevents" do
expect(VmRetireRequest).not_to receive(:make_request)

event = {:attributes => {"full_data" => {:policy => {:prevented => true}}}}
allow(ws).to receive(:get_obj_from_path).with("/").and_return(:event_stream => event)
allow(MiqAeEngine).to receive_messages(:deliver => ['ok', 'success', ws])
Vm.make_retire_request(@vm.id, user)
status, message, _result = MiqQueue.first.deliver
MiqQueue.first.delivered(status, message, ws)
end
end

it "#retire date" do
Expand Down

0 comments on commit 16543b7

Please sign in to comment.