diff --git a/lib/vmpooler/api/v1.rb b/lib/vmpooler/api/v1.rb index eaeb219..55cbf53 100644 --- a/lib/vmpooler/api/v1.rb +++ b/lib/vmpooler/api/v1.rb @@ -103,6 +103,7 @@ module Vmpooler count_selection(selection) end + def fetch_single_vm(template) template_backends = [template] aliases = Vmpooler::API.settings.config[:alias] @@ -349,6 +350,7 @@ module Vmpooler if backend.exists("vmpooler__odrequest__#{request_id}") result['message'] = "request_id '#{request_id}' has already been created" + status 409 return result end @@ -793,6 +795,9 @@ module Vmpooler post "#{api_prefix}/ondemandvm/?" do content_type :json + + need_token! if Vmpooler::API.settings.config[:auth] + result = { 'ok' => false } payload = JSON.parse(request.body.read) @@ -802,7 +807,7 @@ module Vmpooler if invalid.empty? result = generate_ondemand_request(payload) else - result['bad_template'] = invalid + result[:bad_templates] = invalid invalid.each do |bad_template| metrics.increment('ondemandrequest.invalid.' + bad_template) end @@ -1230,7 +1235,7 @@ module Vmpooler invalid.each do |bad_template| metrics.increment("config.invalid.#{bad_template}") end - result[:bad_templates] = invalid + result[:not_configured] = invalid status 400 end else diff --git a/spec/integration/api/v1/ondemandvm_spec.rb b/spec/integration/api/v1/ondemandvm_spec.rb new file mode 100644 index 0000000..48ced51 --- /dev/null +++ b/spec/integration/api/v1/ondemandvm_spec.rb @@ -0,0 +1,98 @@ +require 'spec_helper' +require 'rack/test' + +describe Vmpooler::API::V1 do + include Rack::Test::Methods + + def app() + Vmpooler::API + end + + describe '/vm' do + let(:prefix) { '/api/v1' } + let(:metrics) { Vmpooler::DummyStatsd.new } + let(:config) { + { + config: { + 'site_name' => 'test pooler', + 'vm_lifetime_auth' => 2 + }, + pools: [ + {'name' => 'pool1', 'size' => 0}, + {'name' => 'pool2', 'size' => 0}, + {'name' => 'pool3', 'size' => 0} + ], + alias: { 'poolone' => ['pool1'] }, + pool_names: [ 'pool1', 'pool2', 'pool3', 'poolone', 'genericpool' ] + } + } + let(:current_time) { Time.now } + let(:vmname) { 'abcdefghijkl' } + let(:checkoutlock) { Mutex.new } + + before(:each) do + app.settings.set :config, config + app.settings.set :redis, redis + app.settings.set :metrics, metrics + app.settings.set :config, auth: false + app.settings.set :checkoutlock, checkoutlock + create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time) + end + + describe 'POST /ondemandvm' do + let(:uuid) { SecureRandom.uuid } + + context 'with a configured pool' do + it 'generates a request_id when none is provided' do + expect(SecureRandom).to receive(:uuid).and_return(uuid) + post "#{prefix}/ondemandvm", '{"pool1":"1"}' + expect_json(ok = true, http = 201) + + expected = { + "ok": true, + "request_id": uuid + } + expect(last_response.body).to eq(JSON.pretty_generate(expected)) + end + + it 'uses the given request_id when provided' do + post "#{prefix}/ondemandvm", '{"pool1":"1","request_id":"1234"}' + expect_json(ok = true, http = 201) + + expected = { + "ok": true, + "request_id": "1234" + } + expect(last_response.body).to eq(JSON.pretty_generate(expected)) + end + + it 'returns 404 when the request_id has been used' do + post "#{prefix}/ondemandvm", '{"pool1":"1","request_id":"1234"}' + post "#{prefix}/ondemandvm", '{"pool1":"1","request_id":"1234"}' + expect_json(ok = false, http = 409) + + expected = { + "ok": false, + "request_id": "1234", + "message": "request_id '1234' has already been created" + } + expect(last_response.body).to eq(JSON.pretty_generate(expected)) + end + end + + context 'with a pool that is not configured' do + let(:badpool) { 'pool4' } + it 'returns the bad template' do + post "#{prefix}/ondemandvm", '{"pool4":"1"}' + expect_json(ok = false, http = 404) + + expected = { + "ok": false, + "bad_templates": [ badpool ] + } + expect(last_response.body).to eq(JSON.pretty_generate(expected)) + end + end + end + end +end