From 590c9a4c14d9e6fb45d75d06f59430c2c1aa14b9 Mon Sep 17 00:00:00 2001 From: "kirby@puppetlabs.com" Date: Mon, 11 May 2020 16:37:34 -0700 Subject: [PATCH] Add capability to delete a request by ID --- lib/vmpooler/api/v1.rb | 32 ++++++++++++++ spec/integration/api/v1/ondemandvm_spec.rb | 51 ++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/lib/vmpooler/api/v1.rb b/lib/vmpooler/api/v1.rb index aee4e93..64150ca 100644 --- a/lib/vmpooler/api/v1.rb +++ b/lib/vmpooler/api/v1.rb @@ -845,6 +845,16 @@ module Vmpooler JSON.pretty_generate(result) end + delete "#{api_prefix}/ondemandvm/:requestid/?" do + content_type :json + need_token! if Vmpooler::API.settings.config[:auth] + + status 404 + result = delete_ondemand_request(params[:requestid]) + + JSON.pretty_generate(result) + end + post "#{api_prefix}/vm/?" do content_type :json result = { 'ok' => false } @@ -961,6 +971,28 @@ module Vmpooler result end + def delete_ondemand_request(request_id) + result = { 'ok' => false } + + platforms = backend.hget("vmpooler__odrequest__#{request_id}", 'requested') + unless platforms + result['message'] = "no request found for request_id '#{request_id}'" + return result + end + + platforms.split(',').each do |platform| + pool_alias, pool, _count = platform.split(':') + backend.smembers("vmpooler__#{request_id}__#{pool_alias}__#{pool}")&.each do |vm| + backend.smove("vmpooler__running__#{pool}", "vmpooler__completed__#{pool}", vm) + end + backend.del("vmpooler__#{request_id}__#{pool_alias}__#{pool}") + end + backend.expire("vmpooler__odrequest__#{request_id}", 129_600_0) + status 200 + result['ok'] = true + result + end + post "#{api_prefix}/vm/:template/?" do content_type :json result = { 'ok' => false } diff --git a/spec/integration/api/v1/ondemandvm_spec.rb b/spec/integration/api/v1/ondemandvm_spec.rb index 07d5ad2..ac53383 100644 --- a/spec/integration/api/v1/ondemandvm_spec.rb +++ b/spec/integration/api/v1/ondemandvm_spec.rb @@ -228,5 +228,56 @@ describe Vmpooler::API::V1 do end end end + + describe 'DELETE /ondemandvm' do + let(:expiration) { 129_600_0 } + it 'returns 404 with message when request is not found' do + delete "#{prefix}/ondemandvm/#{uuid}" + expect_json(false, 404) + expected = { + "ok": false, + "message": "no request found for request_id '#{uuid}'" + } + expect(last_response.body).to eq(JSON.pretty_generate(expected)) + end + + context 'when the request is found' do + let(:platforms_string) { 'pool1:pool1:1' } + let(:score) { current_time.to_i } + before(:each) do + create_ondemand_request_for_test(uuid, score, platforms_string, redis) + end + + it 'returns 200 for a deleted request' do + delete "#{prefix}/ondemandvm/#{uuid}" + expect_json(true, 200) + expected = { 'ok': true } + expect(last_response.body).to eq(JSON.pretty_generate(expected)) + end + + it 'marks the request hash for expiration in two weeks' do + expect(redis).to receive(:expire).with("vmpooler__odrequest__#{uuid}", expiration) + delete "#{prefix}/ondemandvm/#{uuid}" + end + + context 'with running instances' do + let(:pool) { 'pool1' } + let(:pool_alias) { pool } + before(:each) do + create_ondemand_vm(vmname, uuid, pool, pool_alias, redis) + end + + it 'moves allocated instances to the completed queue' do + expect(redis).to receive(:smove).with("vmpooler__running__#{pool}", "vmpooler__completed__#{pool}", vmname) + delete "#{prefix}/ondemandvm/#{uuid}" + end + + it 'deletes the set tracking instances allocated for the request' do + expect(redis).to receive(:del).with("vmpooler__#{uuid}__#{pool_alias}__#{pool}") + delete "#{prefix}/ondemandvm/#{uuid}" + end + end + end + end end end