From 49ec06e151d5c9caf63c5a33916d857f50911cfa Mon Sep 17 00:00:00 2001 From: "kirby@puppetlabs.com" Date: Thu, 17 Jan 2019 13:35:19 -0800 Subject: [PATCH] (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. --- .travis.yml | 2 -- CHANGELOG.md | 2 ++ lib/vmpooler.rb | 7 +++-- lib/vmpooler/api/v1.rb | 8 +++-- spec/helpers.rb | 5 ++-- spec/integration/api/v1/config_spec.rb | 2 -- spec/integration/api/v1/status_spec.rb | 2 -- spec/integration/api/v1/vm_hostname_spec.rb | 2 -- spec/integration/api/v1/vm_spec.rb | 33 +++++++++++++++++---- spec/integration/api/v1/vm_template_spec.rb | 2 -- spec/integration/dashboard_spec.rb | 4 --- 11 files changed, 41 insertions(+), 28 deletions(-) diff --git a/.travis.yml b/.travis.yml index 17974e9..978a549 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ cache: bundler sudo: false language: ruby -services: - - redis-server matrix: include: diff --git a/CHANGELOG.md b/CHANGELOG.md index d8e9bde..3323cca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ git logs & PR history. ### Fixed - 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) diff --git a/lib/vmpooler.rb b/lib/vmpooler.rb index eac072e..a614752 100644 --- a/lib/vmpooler.rb +++ b/lib/vmpooler.rb @@ -108,10 +108,11 @@ module Vmpooler parsed_config[:pool_names] << pool['name'] if pool['alias'] if pool['alias'].is_a?(Array) - pool['alias'].each do |a| + pool['alias'].each do |pool_alias| parsed_config[:alias] ||= {} - parsed_config[:alias][a] = pool['name'] - parsed_config[:pool_names] << a + parsed_config[:alias][pool_alias] = [pool['name']] unless parsed_config[:alias].key? pool_alias + parsed_config[:alias][pool_alias] << pool['name'] unless parsed_config[:alias][pool_alias].include? pool['name'] + parsed_config[:pool_names] << pool_alias end elsif pool['alias'].is_a?(String) parsed_config[:alias][pool['alias']] = pool['name'] diff --git a/lib/vmpooler/api/v1.rb b/lib/vmpooler/api/v1.rb index 00497a1..2efe2cc 100644 --- a/lib/vmpooler/api/v1.rb +++ b/lib/vmpooler/api/v1.rb @@ -40,8 +40,8 @@ module Vmpooler template_backends = [template] aliases = Vmpooler::API.settings.config[:alias] 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) weighted_pools = {} template_backends.each do |t| @@ -61,7 +61,9 @@ module Vmpooler template_backends.delete(selection) template_backends.unshift(selection) else - template_backends = template_backends.sample(template_backends.count) + first = template_backends.sample + template_backends.delete(first) + template_backends.unshift(first) end end diff --git a/spec/helpers.rb b/spec/helpers.rb index cff93e6..77820f7 100644 --- a/spec/helpers.rb +++ b/spec/helpers.rb @@ -1,7 +1,8 @@ +require 'mock_redis' + def redis unless @redis - @redis = Redis.new - @redis.select(15) # let's use the highest numbered database available in a default install + @redis = MockRedis.new end @redis end diff --git a/spec/integration/api/v1/config_spec.rb b/spec/integration/api/v1/config_spec.rb index e5136d7..5c3e0ed 100644 --- a/spec/integration/api/v1/config_spec.rb +++ b/spec/integration/api/v1/config_spec.rb @@ -32,8 +32,6 @@ describe Vmpooler::API::V1 do let(:current_time) { Time.now } before(:each) do - redis.flushdb - app.settings.set :config, config app.settings.set :redis, redis app.settings.set :metrics, metrics diff --git a/spec/integration/api/v1/status_spec.rb b/spec/integration/api/v1/status_spec.rb index 3ec6cfc..553188b 100644 --- a/spec/integration/api/v1/status_spec.rb +++ b/spec/integration/api/v1/status_spec.rb @@ -32,8 +32,6 @@ describe Vmpooler::API::V1 do let(:current_time) { Time.now } before(:each) do - redis.flushdb - app.settings.set :config, config app.settings.set :redis, redis app.settings.set :config, auth: false diff --git a/spec/integration/api/v1/vm_hostname_spec.rb b/spec/integration/api/v1/vm_hostname_spec.rb index f8ade07..1e6ac19 100644 --- a/spec/integration/api/v1/vm_hostname_spec.rb +++ b/spec/integration/api/v1/vm_hostname_spec.rb @@ -32,8 +32,6 @@ describe Vmpooler::API::V1 do let(:current_time) { Time.now } before(:each) do - redis.flushdb - app.settings.set :config, config app.settings.set :redis, redis app.settings.set :config, auth: false diff --git a/spec/integration/api/v1/vm_spec.rb b/spec/integration/api/v1/vm_spec.rb index 4615949..8eac59f 100644 --- a/spec/integration/api/v1/vm_spec.rb +++ b/spec/integration/api/v1/vm_spec.rb @@ -19,19 +19,17 @@ describe Vmpooler::API::V1 do }, pools: [ {'name' => 'pool1', 'size' => 5}, - {'name' => 'pool2', 'size' => 10} + {'name' => 'pool2', 'size' => 10}, + {'name' => 'pool3', 'size' => 10} ], statsd: { 'prefix' => 'stats_prefix'}, - alias: { 'poolone' => 'pool1' }, - pool_names: [ 'pool1', 'pool2', 'poolone' ] + alias: { 'poolone' => ['pool1'] }, + pool_names: [ 'pool1', 'pool2', 'pool3', 'poolone', 'genericpool' ] } } - let(:current_time) { Time.now } before(:each) do - redis.flushdb - app.settings.set :config, config app.settings.set :redis, redis app.settings.set :metrics, metrics @@ -192,6 +190,29 @@ describe Vmpooler::API::V1 do expect_json(ok = true, http = 200) 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 create_ready_vm 'pool1', '1abcdefghijklmnop' diff --git a/spec/integration/api/v1/vm_template_spec.rb b/spec/integration/api/v1/vm_template_spec.rb index 0f71395..73549a5 100644 --- a/spec/integration/api/v1/vm_template_spec.rb +++ b/spec/integration/api/v1/vm_template_spec.rb @@ -30,8 +30,6 @@ describe Vmpooler::API::V1 do let(:current_time) { Time.now } before(:each) do - redis.flushdb - app.settings.set :config, config app.settings.set :redis, redis app.settings.set :metrics, metrics diff --git a/spec/integration/dashboard_spec.rb b/spec/integration/dashboard_spec.rb index 147ec46..5bb9ac2 100644 --- a/spec/integration/dashboard_spec.rb +++ b/spec/integration/dashboard_spec.rb @@ -10,10 +10,6 @@ describe Vmpooler::API do describe 'Dashboard' do - before(:each) do - redis.flushdb - end - context '/' do before { get '/' }