mirror of
https://github.com/puppetlabs/vmpooler.git
synced 2026-01-26 18:08:42 -05:00
Merge 662584dd7f into 331ac33b53
This commit is contained in:
commit
fb80cf25d2
4 changed files with 197 additions and 18 deletions
|
|
@ -4,6 +4,35 @@ module Vmpooler
|
||||||
|
|
||||||
module Helpers
|
module Helpers
|
||||||
|
|
||||||
|
def authenticate(auth, username_str, password_str)
|
||||||
|
case auth['provider']
|
||||||
|
when 'ldap'
|
||||||
|
require 'rubygems'
|
||||||
|
require 'net/ldap'
|
||||||
|
|
||||||
|
ldap = Net::LDAP.new(
|
||||||
|
:host => auth[:ldap]['host'],
|
||||||
|
:port => auth[:ldap]['port'] || 389,
|
||||||
|
:encryption => {
|
||||||
|
:method => :start_tls,
|
||||||
|
:tls_options => { :ssl_version => 'TLSv1' }
|
||||||
|
},
|
||||||
|
:base => auth[:ldap]['base'],
|
||||||
|
:auth => {
|
||||||
|
:method => :simple,
|
||||||
|
:username => "#{auth[:ldap]['user_object']}=#{username_str},#{auth[:ldap]['base']}",
|
||||||
|
:password => password_str
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if ldap.bind
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
def mean(list)
|
def mean(list)
|
||||||
s = list.map(&:to_f).reduce(:+).to_f
|
s = list.map(&:to_f).reduce(:+).to_f
|
||||||
(s > 0 && list.length > 0) ? s / list.length.to_f : 0
|
(s > 0 && list.length > 0) ? s / list.length.to_f : 0
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,18 @@ module Vmpooler
|
||||||
call env.merge("PATH_INFO" => "/api/v#{api_version}/summary")
|
call env.merge("PATH_INFO" => "/api/v#{api_version}/summary")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
post '/token/?' do
|
||||||
|
call env.merge("PATH_INFO" => "/api/v#{api_version}/token")
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/token/:token/?' do
|
||||||
|
call env.merge("PATH_INFO" => "/api/v#{api_version}/token/#{params[:token]}")
|
||||||
|
end
|
||||||
|
|
||||||
|
delete '/token/:token/?' do
|
||||||
|
call env.merge("PATH_INFO" => "/api/v#{api_version}/token/#{params[:token]}")
|
||||||
|
end
|
||||||
|
|
||||||
get '/vm/?' do
|
get '/vm/?' do
|
||||||
call env.merge("PATH_INFO" => "/api/v#{api_version}/vm")
|
call env.merge("PATH_INFO" => "/api/v#{api_version}/vm")
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,69 @@ module Vmpooler
|
||||||
JSON.pretty_generate(result)
|
JSON.pretty_generate(result)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
get "#{api_prefix}/token/:token/?" do
|
||||||
|
content_type :json
|
||||||
|
|
||||||
|
result = { 'ok' => false }
|
||||||
|
|
||||||
|
Vmpooler::API.settings.config[:auth] ? status(401) : status(404)
|
||||||
|
|
||||||
|
result[params[:token]] = Vmpooler::API.settings.redis.hgetall('vmpooler__token__' + params[:token])
|
||||||
|
|
||||||
|
if Vmpooler::API.settings.config[:auth] and result[params[:token]]['timestamp']
|
||||||
|
status(200)
|
||||||
|
result['ok'] = true
|
||||||
|
else
|
||||||
|
result.delete(params[:token])
|
||||||
|
end
|
||||||
|
|
||||||
|
JSON.pretty_generate(result)
|
||||||
|
end
|
||||||
|
|
||||||
|
delete "#{api_prefix}/token/:token/?" do
|
||||||
|
content_type :json
|
||||||
|
|
||||||
|
result = { 'ok' => false }
|
||||||
|
|
||||||
|
Vmpooler::API.settings.config[:auth] ? status(401) : status(404)
|
||||||
|
|
||||||
|
if Vmpooler::API.settings.config[:auth] and Vmpooler::API.settings.redis.del('vmpooler__token__' + params[:token])
|
||||||
|
status(200)
|
||||||
|
result['ok'] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
JSON.pretty_generate(result)
|
||||||
|
end
|
||||||
|
|
||||||
|
post "#{api_prefix}/token" do
|
||||||
|
content_type :json
|
||||||
|
|
||||||
|
result = { 'ok' => false }
|
||||||
|
|
||||||
|
Vmpooler::API.settings.config[:auth] ? status(401) : status(404)
|
||||||
|
|
||||||
|
jdata = JSON.parse(request.body.read)
|
||||||
|
|
||||||
|
if Vmpooler::API.settings.config[:auth] and jdata['username'] and jdata['password']
|
||||||
|
if authenticate(
|
||||||
|
Vmpooler::API.settings.config[:auth],
|
||||||
|
jdata['username'].to_s,
|
||||||
|
jdata['password'].to_s
|
||||||
|
)
|
||||||
|
status(200)
|
||||||
|
result['ok'] = true
|
||||||
|
|
||||||
|
o = [('a'..'z'), ('0'..'9')].map(&:to_a).flatten
|
||||||
|
result['token'] = o[rand(25)] + (0...31).map { o[rand(o.length)] }.join
|
||||||
|
|
||||||
|
Vmpooler::API.settings.redis.hset('vmpooler__token__' + result['token'], 'user', jdata['username'].to_s)
|
||||||
|
Vmpooler::API.settings.redis.hset('vmpooler__token__' + result['token'], 'timestamp', Time.now)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
JSON.pretty_generate(result)
|
||||||
|
end
|
||||||
|
|
||||||
get "#{api_prefix}/vm/?" do
|
get "#{api_prefix}/vm/?" do
|
||||||
content_type :json
|
content_type :json
|
||||||
|
|
||||||
|
|
@ -229,13 +292,13 @@ module Vmpooler
|
||||||
else
|
else
|
||||||
result[key]['ok'] = false ##
|
result[key]['ok'] = false ##
|
||||||
|
|
||||||
status 503
|
status(503)
|
||||||
result['ok'] = false
|
result['ok'] = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
status 503
|
status(503)
|
||||||
result['ok'] = false
|
result['ok'] = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -291,12 +354,12 @@ module Vmpooler
|
||||||
else
|
else
|
||||||
result[template]['ok'] = false ##
|
result[template]['ok'] = false ##
|
||||||
|
|
||||||
status 503
|
status(503)
|
||||||
result['ok'] = false
|
result['ok'] = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
status 503
|
status(503)
|
||||||
result['ok'] = false
|
result['ok'] = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -310,15 +373,14 @@ module Vmpooler
|
||||||
get "#{api_prefix}/vm/:hostname/?" do
|
get "#{api_prefix}/vm/:hostname/?" do
|
||||||
content_type :json
|
content_type :json
|
||||||
|
|
||||||
result = {}
|
result = { 'ok' => false }
|
||||||
|
|
||||||
status 404
|
status(404)
|
||||||
result['ok'] = false
|
|
||||||
|
|
||||||
params[:hostname] = hostname_shorten(params[:hostname], Vmpooler::API.settings.config[:config]['domain'])
|
params[:hostname] = hostname_shorten(params[:hostname], Vmpooler::API.settings.config[:config]['domain'])
|
||||||
|
|
||||||
if Vmpooler::API.settings.redis.exists('vmpooler__vm__' + params[:hostname])
|
if Vmpooler::API.settings.redis.exists('vmpooler__vm__' + params[:hostname])
|
||||||
status 200
|
status(200)
|
||||||
result['ok'] = true
|
result['ok'] = true
|
||||||
|
|
||||||
rdata = Vmpooler::API.settings.redis.hgetall('vmpooler__vm__' + params[:hostname])
|
rdata = Vmpooler::API.settings.redis.hgetall('vmpooler__vm__' + params[:hostname])
|
||||||
|
|
@ -352,10 +414,9 @@ module Vmpooler
|
||||||
delete "#{api_prefix}/vm/:hostname/?" do
|
delete "#{api_prefix}/vm/:hostname/?" do
|
||||||
content_type :json
|
content_type :json
|
||||||
|
|
||||||
result = {}
|
result = { 'ok' => false }
|
||||||
|
|
||||||
status 404
|
status(404)
|
||||||
result['ok'] = false
|
|
||||||
|
|
||||||
params[:hostname] = hostname_shorten(params[:hostname], Vmpooler::API.settings.config[:config]['domain'])
|
params[:hostname] = hostname_shorten(params[:hostname], Vmpooler::API.settings.config[:config]['domain'])
|
||||||
|
|
||||||
|
|
@ -364,7 +425,7 @@ module Vmpooler
|
||||||
Vmpooler::API.settings.redis.srem('vmpooler__running__' + pool['name'], params[:hostname])
|
Vmpooler::API.settings.redis.srem('vmpooler__running__' + pool['name'], params[:hostname])
|
||||||
Vmpooler::API.settings.redis.sadd('vmpooler__completed__' + pool['name'], params[:hostname])
|
Vmpooler::API.settings.redis.sadd('vmpooler__completed__' + pool['name'], params[:hostname])
|
||||||
|
|
||||||
status 200
|
status(200)
|
||||||
result['ok'] = true
|
result['ok'] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -377,10 +438,9 @@ module Vmpooler
|
||||||
|
|
||||||
failure = false
|
failure = false
|
||||||
|
|
||||||
result = {}
|
result = { 'ok' => false }
|
||||||
|
|
||||||
status 404
|
status(404)
|
||||||
result['ok'] = false
|
|
||||||
|
|
||||||
params[:hostname] = hostname_shorten(params[:hostname], Vmpooler::API.settings.config[:config]['domain'])
|
params[:hostname] = hostname_shorten(params[:hostname], Vmpooler::API.settings.config[:config]['domain'])
|
||||||
|
|
||||||
|
|
@ -388,7 +448,7 @@ module Vmpooler
|
||||||
begin
|
begin
|
||||||
jdata = JSON.parse(request.body.read)
|
jdata = JSON.parse(request.body.read)
|
||||||
rescue
|
rescue
|
||||||
status 400
|
status(400)
|
||||||
return JSON.pretty_generate(result)
|
return JSON.pretty_generate(result)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -409,7 +469,7 @@ module Vmpooler
|
||||||
end
|
end
|
||||||
|
|
||||||
if failure
|
if failure
|
||||||
status 400
|
status(400)
|
||||||
else
|
else
|
||||||
jdata.each do |param, arg|
|
jdata.each do |param, arg|
|
||||||
case param
|
case param
|
||||||
|
|
@ -424,7 +484,7 @@ module Vmpooler
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
status 200
|
status(200)
|
||||||
result['ok'] = true
|
result['ok'] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
78
spec/vmpooler/api/v1_spec.rb
Normal file
78
spec/vmpooler/api/v1_spec.rb
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
require 'rack/test'
|
||||||
|
|
||||||
|
describe Vmpooler::API::V1 do
|
||||||
|
include Rack::Test::Methods
|
||||||
|
|
||||||
|
def app()
|
||||||
|
# because of how Vmpooler::API.settings are used
|
||||||
|
# we need to test the whole thing...
|
||||||
|
Vmpooler::API
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'tokens' do
|
||||||
|
let(:redis) { double('redis') }
|
||||||
|
let(:config) {
|
||||||
|
{
|
||||||
|
config: {'site_name' => 'test pooler'},
|
||||||
|
auth: {exists: 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let(:prefix) { '/api/v1' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
$config = config
|
||||||
|
|
||||||
|
app.settings.set :config, config
|
||||||
|
app.settings.set :redis, redis
|
||||||
|
app.settings.set :environment, :test
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET /token/:token' do
|
||||||
|
|
||||||
|
context 'valid tokens' do
|
||||||
|
before do
|
||||||
|
allow(redis).to receive(:exists).and_return 1
|
||||||
|
allow(redis).to receive(:hgetall).and_return 'atoken'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets key to passed value (:token)' do
|
||||||
|
get "#{prefix}/token/this"
|
||||||
|
|
||||||
|
expect(last_response).to be_ok
|
||||||
|
expect(last_response.body).to eq(JSON.pretty_generate({'ok' => true, 'this' => 'atoken'}))
|
||||||
|
expect(last_response.header['Content-Type']).to eq('application/json')
|
||||||
|
|
||||||
|
get "#{prefix}/token/that"
|
||||||
|
|
||||||
|
expect(last_response).to be_ok
|
||||||
|
expect(last_response.body).to eq(JSON.pretty_generate({'ok' => true, 'that' => 'atoken'}))
|
||||||
|
expect(last_response.header['Content-Type']).to eq('application/json')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'DELETE /token/:token' do
|
||||||
|
|
||||||
|
context 'valid tokens' do
|
||||||
|
before do
|
||||||
|
allow(redis).to receive(:exists).with(String).and_return 1
|
||||||
|
allow(redis).to receive(:del)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'deletes the key' do
|
||||||
|
expect(redis).to receive(:del)
|
||||||
|
|
||||||
|
delete "#{prefix}/token/this"
|
||||||
|
|
||||||
|
expect(last_response).to be_ok
|
||||||
|
expect(last_response.header['Content-Type']).to eq('application/json')
|
||||||
|
expect(last_response.body).to eq(JSON.pretty_generate({'ok' => true}))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
Loading…
Add table
Add a link
Reference in a new issue