(POOLER-138) Support multiple pools per alias

This change updates handling of pool aliases to allow for more than a
single pool to be configured as an alias pool. Without this change if
multiple pools are configured as an alias the last one to configure it
is set as the alias for that pool.

Additionally, redis testing requirements are removed in favor of
mock_redis. Without this change a redis server is required to run
vmpooler tests.
This commit is contained in:
kirby@puppetlabs.com 2019-01-17 13:35:19 -08:00
parent d36e7dbee2
commit 49ec06e151
11 changed files with 41 additions and 28 deletions

View file

@ -1,8 +1,6 @@
cache: bundler cache: bundler
sudo: false sudo: false
language: ruby language: ruby
services:
- redis-server
matrix: matrix:
include: include:

View file

@ -14,6 +14,8 @@ git logs & PR history.
### Fixed ### Fixed
- Improve support for configuration via environment variables (POOLER-137) - Improve support for configuration via environment variables (POOLER-137)
- Support multiple pool backends per alias (POOLER-138)
- Remove redis server testing requirement
# [0.3.0](https://github.com/puppetlabs/vmpooler/compare/0.2.2...0.3.0) # [0.3.0](https://github.com/puppetlabs/vmpooler/compare/0.2.2...0.3.0)

View file

@ -108,10 +108,11 @@ module Vmpooler
parsed_config[:pool_names] << pool['name'] parsed_config[:pool_names] << pool['name']
if pool['alias'] if pool['alias']
if pool['alias'].is_a?(Array) if pool['alias'].is_a?(Array)
pool['alias'].each do |a| pool['alias'].each do |pool_alias|
parsed_config[:alias] ||= {} parsed_config[:alias] ||= {}
parsed_config[:alias][a] = pool['name'] parsed_config[:alias][pool_alias] = [pool['name']] unless parsed_config[:alias].key? pool_alias
parsed_config[:pool_names] << a parsed_config[:alias][pool_alias] << pool['name'] unless parsed_config[:alias][pool_alias].include? pool['name']
parsed_config[:pool_names] << pool_alias
end end
elsif pool['alias'].is_a?(String) elsif pool['alias'].is_a?(String)
parsed_config[:alias][pool['alias']] = pool['name'] parsed_config[:alias][pool['alias']] = pool['name']

View file

@ -40,8 +40,8 @@ module Vmpooler
template_backends = [template] template_backends = [template]
aliases = Vmpooler::API.settings.config[:alias] aliases = Vmpooler::API.settings.config[:alias]
if aliases if aliases
template_backends << aliases[template] if aliases[template] template_backends = template_backends + aliases[template] if aliases[template].is_a?(Array)
template_backends << aliases[template] if aliases[template].is_a?(String)
pool_index = pool_index(pools) pool_index = pool_index(pools)
weighted_pools = {} weighted_pools = {}
template_backends.each do |t| template_backends.each do |t|
@ -61,7 +61,9 @@ module Vmpooler
template_backends.delete(selection) template_backends.delete(selection)
template_backends.unshift(selection) template_backends.unshift(selection)
else else
template_backends = template_backends.sample(template_backends.count) first = template_backends.sample
template_backends.delete(first)
template_backends.unshift(first)
end end
end end

View file

@ -1,7 +1,8 @@
require 'mock_redis'
def redis def redis
unless @redis unless @redis
@redis = Redis.new @redis = MockRedis.new
@redis.select(15) # let's use the highest numbered database available in a default install
end end
@redis @redis
end end

View file

@ -32,8 +32,6 @@ describe Vmpooler::API::V1 do
let(:current_time) { Time.now } let(:current_time) { Time.now }
before(:each) do before(:each) do
redis.flushdb
app.settings.set :config, config app.settings.set :config, config
app.settings.set :redis, redis app.settings.set :redis, redis
app.settings.set :metrics, metrics app.settings.set :metrics, metrics

View file

@ -32,8 +32,6 @@ describe Vmpooler::API::V1 do
let(:current_time) { Time.now } let(:current_time) { Time.now }
before(:each) do before(:each) do
redis.flushdb
app.settings.set :config, config app.settings.set :config, config
app.settings.set :redis, redis app.settings.set :redis, redis
app.settings.set :config, auth: false app.settings.set :config, auth: false

View file

@ -32,8 +32,6 @@ describe Vmpooler::API::V1 do
let(:current_time) { Time.now } let(:current_time) { Time.now }
before(:each) do before(:each) do
redis.flushdb
app.settings.set :config, config app.settings.set :config, config
app.settings.set :redis, redis app.settings.set :redis, redis
app.settings.set :config, auth: false app.settings.set :config, auth: false

View file

@ -19,19 +19,17 @@ describe Vmpooler::API::V1 do
}, },
pools: [ pools: [
{'name' => 'pool1', 'size' => 5}, {'name' => 'pool1', 'size' => 5},
{'name' => 'pool2', 'size' => 10} {'name' => 'pool2', 'size' => 10},
{'name' => 'pool3', 'size' => 10}
], ],
statsd: { 'prefix' => 'stats_prefix'}, statsd: { 'prefix' => 'stats_prefix'},
alias: { 'poolone' => 'pool1' }, alias: { 'poolone' => ['pool1'] },
pool_names: [ 'pool1', 'pool2', 'poolone' ] pool_names: [ 'pool1', 'pool2', 'pool3', 'poolone', 'genericpool' ]
} }
} }
let(:current_time) { Time.now } let(:current_time) { Time.now }
before(:each) do before(:each) do
redis.flushdb
app.settings.set :config, config app.settings.set :config, config
app.settings.set :redis, redis app.settings.set :redis, redis
app.settings.set :metrics, metrics app.settings.set :metrics, metrics
@ -192,6 +190,29 @@ describe Vmpooler::API::V1 do
expect_json(ok = true, http = 200) expect_json(ok = true, http = 200)
end end
it 'returns VMs from multiple backend pools requested by an alias' do
Vmpooler::API.settings.config[:alias]['genericpool'] = ['pool1', 'pool2', 'pool3']
create_ready_vm 'pool1', '1abcdefghijklmnop'
create_ready_vm 'pool2', '2abcdefghijklmnop'
create_ready_vm 'pool3', '1qrstuvwxyz012345'
post "#{prefix}/vm", '{"genericpool":"3"}'
expected = {
ok: true,
genericpool: {
hostname: [ '1abcdefghijklmnop', '2abcdefghijklmnop', '1qrstuvwxyz012345' ]
}
}
result = JSON.parse(last_response.body)
expect(result['ok']).to eq(true)
expect(result['genericpool']['hostname']).to include('1abcdefghijklmnop', '2abcdefghijklmnop', '1qrstuvwxyz012345')
expect_json(ok = true, http = 200)
end
it 'fails when not all requested vms can be allocated' do it 'fails when not all requested vms can be allocated' do
create_ready_vm 'pool1', '1abcdefghijklmnop' create_ready_vm 'pool1', '1abcdefghijklmnop'

View file

@ -30,8 +30,6 @@ describe Vmpooler::API::V1 do
let(:current_time) { Time.now } let(:current_time) { Time.now }
before(:each) do before(:each) do
redis.flushdb
app.settings.set :config, config app.settings.set :config, config
app.settings.set :redis, redis app.settings.set :redis, redis
app.settings.set :metrics, metrics app.settings.set :metrics, metrics

View file

@ -10,10 +10,6 @@ describe Vmpooler::API do
describe 'Dashboard' do describe 'Dashboard' do
before(:each) do
redis.flushdb
end
context '/' do context '/' do
before { get '/' } before { get '/' }