Connect domain settings to pools, create v2 API

This commit is contained in:
Gene Liverman 2021-12-30 14:04:34 -05:00 committed by Samuel Beaulieu
parent 7786c9193e
commit 6b9eb2369f
No known key found for this signature in database
GPG key ID: 12030F74136D0F34
19 changed files with 3964 additions and 19 deletions

View file

@ -0,0 +1,352 @@
require 'spec_helper'
require 'rack/test'
def has_set_tag?(vm, tag, value)
value == redis.hget("vmpooler__vm__#{vm}", "tag:#{tag}")
end
describe Vmpooler::API::V2 do
include Rack::Test::Methods
def app()
Vmpooler::API
end
# Added to ensure no leakage in rack state from previous tests.
# Removes all routes, filters, middleware and extension hooks from the current class
# https://rubydoc.info/gems/sinatra/Sinatra/Base#reset!-class_method
before(:each) do
app.reset!
end
describe '/vm/:hostname' do
let(:prefix) { '/api/v2' }
let(:metrics) { Vmpooler::Metrics::DummyStatsd.new }
let(:config) {
{
config: {
'site_name' => 'test pooler',
'vm_lifetime_auth' => 2,
},
pools: [
{'name' => 'pool1', 'size' => 5},
{'name' => 'pool2', 'size' => 10}
],
alias: { 'poolone' => 'pool1' },
auth: false
}
}
let(:current_time) { Time.now }
before(:each) do
expect(app).to receive(:run!).once
app.execute([:api], config, redis, metrics, nil)
create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time)
end
describe 'PUT /vm/:hostname' do
it 'allows tags to be set' do
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"tags":{"tested_by":"rspec"}}'
expect_json(ok = true, http = 200)
expect has_set_tag?('testhost', 'tested_by', 'rspec')
end
it 'skips empty tags' do
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"tags":{"tested_by":""}}'
expect_json(ok = true, http = 200)
expect !has_set_tag?('testhost', 'tested_by', '')
end
it 'does not set tags if request body format is invalid' do
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"tags":{"tested"}}'
expect_json(ok = false, http = 400)
expect !has_set_tag?('testhost', 'tested', '')
end
context '(allowed_tags configured)' do
it 'fails if specified tag is not in allowed_tags array' do
app.settings.set :config,
{ :config => { 'allowed_tags' => ['created_by', 'project', 'url'] } }
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"tags":{"created_by":"rspec","tested_by":"rspec"}}'
expect_json(ok = false, http = 400)
expect !has_set_tag?('testhost', 'tested_by', 'rspec')
end
end
context '(tagfilter configured)' do
before(:each) do
app.settings.set :config, tagfilter: { 'url' => '(.*)\/' }
end
it 'correctly filters tags' do
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"tags":{"url":"foo.com/something.html"}}'
expect_json(ok = true, http = 200)
expect has_set_tag?('testhost', 'url', 'foo.com')
end
it "doesn't eat tags not matching filter" do
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"tags":{"url":"foo.com"}}'
expect_json(ok = true, http = 200)
expect has_set_tag?('testhost', 'url', 'foo.com')
end
end
context '(auth not configured)' do
before(:each) do
app.settings.set :config, auth: false
end
it 'allows VM lifetime to be modified without a token' do
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"lifetime":"1"}'
expect_json(ok = true, http = 200)
vm = fetch_vm('testhost')
expect(vm['lifetime'].to_i).to eq(1)
end
it 'does not allow a lifetime to be 0' do
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"lifetime":"0"}'
expect_json(ok = false, http = 400)
vm = fetch_vm('testhost')
expect(vm['lifetime']).to be_nil
end
it 'does not enforce a lifetime' do
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"lifetime":"20000"}'
expect_json(ok = true, http = 200)
vm = fetch_vm('testhost')
expect(vm['lifetime']).to eq("20000")
end
it 'does not allow a lifetime to be initially past config max_lifetime_upper_limit' do
app.settings.set :config,
{ :config => { 'max_lifetime_upper_limit' => 168 } }
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"lifetime":"200"}'
expect_json(ok = false, http = 400)
vm = fetch_vm('testhost')
expect(vm['lifetime']).to be_nil
end
# it 'does not allow a lifetime to be extended past config 168' do
# app.settings.set :config,
# { :config => { 'max_lifetime_upper_limit' => 168 } }
# create_vm('testhost', redis)
#
# set_vm_data('testhost', "checkout", (Time.now - (69*60*60)), redis)
# puts redis.hget("vmpooler__vm__testhost", 'checkout')
# put "#{prefix}/vm/testhost", '{"lifetime":"100"}'
# expect_json(ok = false, http = 400)
#
# vm = fetch_vm('testhost')
# expect(vm['lifetime']).to be_nil
# end
end
context '(auth configured)' do
before(:each) do
app.settings.set :config, auth: true
end
it 'allows VM lifetime to be modified with a token' do
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"lifetime":"1"}', {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
}
expect_json(ok = true, http = 200)
vm = fetch_vm('testhost')
expect(vm['lifetime'].to_i).to eq(1)
end
it 'does not allows VM lifetime to be modified without a token' do
create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"lifetime":"1"}'
expect_json(ok = false, http = 401)
end
end
end
describe 'DELETE /vm/:hostname' do
context '(auth not configured)' do
it 'does not delete a non-existant VM' do
delete "#{prefix}/vm/testhost"
expect_json(ok = false, http = 404)
end
it 'deletes an existing VM' do
create_running_vm('pool1', 'testhost', redis)
expect fetch_vm('testhost')
delete "#{prefix}/vm/testhost"
expect_json(ok = true, http = 200)
expect !fetch_vm('testhost')
end
end
context '(auth configured)' do
before(:each) do
app.settings.set :config, auth: true
end
context '(checked-out without token)' do
it 'deletes a VM without supplying a token' do
create_running_vm('pool1', 'testhost', redis)
expect fetch_vm('testhost')
delete "#{prefix}/vm/testhost"
expect_json(ok = true, http = 200)
expect !fetch_vm('testhost')
end
end
context '(checked-out with token)' do
it 'fails to delete a VM without supplying a token' do
create_running_vm('pool1', 'testhost', redis, 'abcdefghijklmnopqrstuvwxyz012345')
expect fetch_vm('testhost')
delete "#{prefix}/vm/testhost"
expect_json(ok = false, http = 401)
expect fetch_vm('testhost')
end
it 'deletes a VM when token is supplied' do
create_running_vm('pool1', 'testhost', redis, 'abcdefghijklmnopqrstuvwxyz012345')
expect fetch_vm('testhost')
delete "#{prefix}/vm/testhost", "", {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
}
expect_json(ok = true, http = 200)
expect !fetch_vm('testhost')
end
end
end
end
describe 'POST /vm/:hostname/snapshot' do
context '(auth not configured)' do
it 'creates a snapshot' do
create_vm('testhost', redis)
post "#{prefix}/vm/testhost/snapshot"
expect_json(ok = true, http = 202)
expect(JSON.parse(last_response.body)['testhost']['snapshot'].length).to be(32)
end
end
context '(auth configured)' do
before(:each) do
app.settings.set :config, auth: true
end
it 'returns a 401 if not authed' do
post "#{prefix}/vm/testhost/snapshot"
expect_json(ok = false, http = 401)
expect !has_vm_snapshot?('testhost', redis)
end
it 'creates a snapshot if authed' do
create_vm('testhost', redis)
snapshot_vm('testhost', 'testsnapshot', redis)
post "#{prefix}/vm/testhost/snapshot", "", {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
}
expect_json(ok = true, http = 202)
expect(JSON.parse(last_response.body)['testhost']['snapshot'].length).to be(32)
expect has_vm_snapshot?('testhost', redis)
end
end
end
describe 'POST /vm/:hostname/snapshot/:snapshot' do
context '(auth not configured)' do
it 'reverts to a snapshot' do
create_vm('testhost', redis)
snapshot_vm('testhost', 'testsnapshot', redis)
post "#{prefix}/vm/testhost/snapshot/testsnapshot"
expect_json(ok = true, http = 202)
expect vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot')
end
it 'fails if the specified snapshot does not exist' do
create_vm('testhost', redis)
post "#{prefix}/vm/testhost/snapshot/testsnapshot", "", {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
}
expect_json(ok = false, http = 404)
expect !vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot')
end
end
context '(auth configured)' do
before(:each) do
app.settings.set :config, auth: true
end
it 'returns a 401 if not authed' do
create_vm('testhost', redis)
snapshot_vm('testhost', 'testsnapshot', redis)
post "#{prefix}/vm/testhost/snapshot/testsnapshot"
expect_json(ok = false, http = 401)
expect !vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot')
end
it 'fails if authed and the specified snapshot does not exist' do
create_vm('testhost', redis)
post "#{prefix}/vm/testhost/snapshot/testsnapshot", "", {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
}
expect_json(ok = false, http = 404)
expect !vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot')
end
it 'reverts to a snapshot if authed' do
create_vm('testhost', redis)
snapshot_vm('testhost', 'testsnapshot', redis)
post "#{prefix}/vm/testhost/snapshot/testsnapshot", "", {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
}
expect_json(ok = true, http = 202)
expect vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot')
end
end
end
end
end