diff --git a/lib/vmpooler/api/v1.rb b/lib/vmpooler/api/v1.rb index 6ceb5c3..c397b7c 100644 --- a/lib/vmpooler/api/v1.rb +++ b/lib/vmpooler/api/v1.rb @@ -176,23 +176,33 @@ module Vmpooler # ], # "uptime": 179585.9 # } + # + # If the query parameter 'view' is provided, it will be used to select which top level + # element to compute and return. Select them by specifying them in a comma separated list. + # For example /status?view=capacity,boot + # would return only the "capacity" and "boot" statistics. "status" is always returned + get "#{api_prefix}/status/?" do content_type :json + if params[:view] + views = params[:view].split(",") + end + result = { - pools: {}, status: { ok: true, message: 'Battle station fully armed and operational.' } } - result[:capacity] = get_capacity_metrics(pools, backend) - result[:queue] = get_queue_metrics(pools, backend) - result[:clone] = get_task_metrics(backend, 'clone', Date.today.to_s) - result[:boot] = get_task_metrics(backend, 'boot', Date.today.to_s) + result[:capacity] = get_capacity_metrics(pools, backend) unless views and not views.include?("capacity") + result[:queue] = get_queue_metrics(pools, backend) unless views and not views.include?("queue") + result[:clone] = get_task_metrics(backend, 'clone', Date.today.to_s) unless views and not views.include?("clone") + result[:boot] = get_task_metrics(backend, 'boot', Date.today.to_s) unless views and not views.include?("boot") # Check for empty pools + result[:pools] = {} unless views and not views.include?("pools") pools.each do |pool| # REMIND: move this out of the API and into the back-end ready = backend.scard('vmpooler__ready__' + pool['name']).to_i @@ -220,7 +230,7 @@ module Vmpooler result[:status][:ok] = false result[:status][:message] = "Found #{result[:status][:empty].length} empty pools." end - end + end unless views and not views.include?("pools") result[:status][:uptime] = (Time.now - Vmpooler::API.settings.config[:uptime]).round(1) if Vmpooler::API.settings.config[:uptime] diff --git a/spec/integration/api/v1/status_spec.rb b/spec/integration/api/v1/status_spec.rb index 96b54f1..2f2f1ba 100644 --- a/spec/integration/api/v1/status_spec.rb +++ b/spec/integration/api/v1/status_spec.rb @@ -118,5 +118,85 @@ describe Vmpooler::API::V1 do expect(result["status"]["empty"].sort).to eq(["pool1", "pool2", "pool3"]) end end + describe 'GET /status with view query parameter' do + it 'returns capacity when specified' do + get "#{prefix}/status?view=capacity" + + # of course /status doesn't conform to the weird standard everything else uses... + expect(last_response.header['Content-Type']).to eq('application/json') + result = JSON.parse(last_response.body) + expect(result["capacity"]).to_not be(nil) + expect(result["queue"]).to be(nil) + expect(result["clone"]).to be(nil) + expect(result["boot"]).to be(nil) + expect(result["pools"]).to be(nil) + expect(result["status"]).to_not be(nil) + end + it 'returns pools and queue when specified' do + get "#{prefix}/status?view=pools,queue" + + # of course /status doesn't conform to the weird standard everything else uses... + expect(last_response.header['Content-Type']).to eq('application/json') + result = JSON.parse(last_response.body) + expect(result["capacity"]).to be(nil) + expect(result["queue"]).to_not be(nil) + expect(result["clone"]).to be(nil) + expect(result["boot"]).to be(nil) + expect(result["pools"]).to_not be(nil) + expect(result["status"]).to_not be(nil) + end + it 'does nothing with invalid view names' do + get "#{prefix}/status?view=clone,boot,invalidThingToView" + + # of course /status doesn't conform to the weird standard everything else uses... + expect(last_response.header['Content-Type']).to eq('application/json') + result = JSON.parse(last_response.body) + expect(result["capacity"]).to be(nil) + expect(result["queue"]).to be(nil) + expect(result["clone"]).to_not be(nil) + expect(result["boot"]).to_not be(nil) + expect(result["pools"]).to be(nil) + expect(result["status"]).to_not be(nil) + end + it 'returns everything when view is not specified' do + get "#{prefix}/status" + + # of course /status doesn't conform to the weird standard everything else uses... + expect(last_response.header['Content-Type']).to eq('application/json') + result = JSON.parse(last_response.body) + expect(result["capacity"]).to_not be(nil) + expect(result["queue"]).to_not be(nil) + expect(result["clone"]).to_not be(nil) + expect(result["boot"]).to_not be(nil) + expect(result["pools"]).to_not be(nil) + expect(result["status"]).to_not be(nil) + end + it 'returns everything when view is alone' do + get "#{prefix}/status?view" + + # of course /status doesn't conform to the weird standard everything else uses... + expect(last_response.header['Content-Type']).to eq('application/json') + result = JSON.parse(last_response.body) + expect(result["capacity"]).to_not be(nil) + expect(result["queue"]).to_not be(nil) + expect(result["clone"]).to_not be(nil) + expect(result["boot"]).to_not be(nil) + expect(result["pools"]).to_not be(nil) + expect(result["status"]).to_not be(nil) + end + it 'returns status only when view is empty' do + get "#{prefix}/status?view=" + + # of course /status doesn't conform to the weird standard everything else uses... + expect(last_response.header['Content-Type']).to eq('application/json') + result = JSON.parse(last_response.body) + expect(result["capacity"]).to be(nil) + expect(result["queue"]).to be(nil) + expect(result["clone"]).to be(nil) + expect(result["boot"]).to be(nil) + expect(result["pools"]).to be(nil) + expect(result["status"]).to_not be(nil) + end + end end end