mirror of
https://github.com/puppetlabs/vmpooler.git
synced 2026-01-26 01:58:41 -05:00
Adding support for multiple vsphere providers
Refactoring the vmpooler.yaml format to support multiple providers. The second level key under :providers: is a unique key name that represents a provider that can be refered in the pool's parameter called provider. The code is still backward compatible to support the :vsphere: and :dummy: keys but in reality if you have more than one vsphere configuration you would give them a different name. For example :vsphere-pdx: and :vsphere-bfs: and the actual provider class would be specified as a parameter called 'provider_class'. See tests and examples for more information.
This commit is contained in:
parent
1fcb19bd7b
commit
d93ab332f7
5 changed files with 101 additions and 6 deletions
|
|
@ -58,7 +58,7 @@ The following YAML configuration sets up two pools, `debian-7-i386` and `debian-
|
||||||
provider: vsphere
|
provider: vsphere
|
||||||
```
|
```
|
||||||
|
|
||||||
See the provided YAML configuration example, [vmpooler.yaml.example](vmpooler.yaml.example), for additional configuration options and parameters.
|
See the provided YAML configuration example, [vmpooler.yaml.example](vmpooler.yaml.example), for additional configuration options and parameters or for supporting multiple providers.
|
||||||
|
|
||||||
### Running via Docker
|
### Running via Docker
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -694,14 +694,20 @@ module Vmpooler
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_provider_object(config, logger, metrics, provider_name, options)
|
# create a provider object based on the providers/*.rb class that implements providers/base.rb
|
||||||
case provider_name
|
# provider_class: needs to match a provider class in providers/*.rb ie Vmpooler::PoolManager::Provider::X
|
||||||
|
# provider_name: should be a unique provider name
|
||||||
|
#
|
||||||
|
# returns an object Vmpooler::PoolManager::Provider::*
|
||||||
|
# or raises an error if the class does not exist
|
||||||
|
def create_provider_object(config, logger, metrics, provider_class, provider_name, options)
|
||||||
|
case provider_class
|
||||||
when 'vsphere'
|
when 'vsphere'
|
||||||
Vmpooler::PoolManager::Provider::VSphere.new(config, logger, metrics, provider_name, options)
|
Vmpooler::PoolManager::Provider::VSphere.new(config, logger, metrics, provider_name, options)
|
||||||
when 'dummy'
|
when 'dummy'
|
||||||
Vmpooler::PoolManager::Provider::Dummy.new(config, logger, metrics, provider_name, options)
|
Vmpooler::PoolManager::Provider::Dummy.new(config, logger, metrics, provider_name, options)
|
||||||
else
|
else
|
||||||
raise("Provider '#{provider_name}' is unknown")
|
raise("Provider '#{provider_class}' is unknown for pool with provider '#{provider_name}'")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -731,8 +737,28 @@ module Vmpooler
|
||||||
# Create the providers
|
# Create the providers
|
||||||
$config[:pools].each do |pool|
|
$config[:pools].each do |pool|
|
||||||
provider_name = pool['provider']
|
provider_name = pool['provider']
|
||||||
|
# The provider_class parameter can be defined in the provider's data eg
|
||||||
|
#:providers:
|
||||||
|
# :vsphere:
|
||||||
|
# provider_class: 'vsphere'
|
||||||
|
# :another-vsphere:
|
||||||
|
# provider_class: 'vsphere'
|
||||||
|
# the above would create two providers/vsphere.rb class objects named 'vsphere' and 'another-vsphere'
|
||||||
|
# each pools would then define which provider definition to use: vsphere or another-vsphere
|
||||||
|
#
|
||||||
|
# if provider_class is not defined it will try to use the provider_name as the class, this is to be
|
||||||
|
# backwards compatible for example when there is only one provider listed
|
||||||
|
# :providers:
|
||||||
|
# :dummy:
|
||||||
|
# filename: 'db.txs'
|
||||||
|
# the above example would create an object based on the class providers/dummy.rb
|
||||||
|
if $config[:providers].nil? || $config[:providers][provider_name.to_sym].nil? || $config[:providers][provider_name.to_sym]['provider_class'].nil?
|
||||||
|
provider_class = provider_name
|
||||||
|
else
|
||||||
|
provider_class = $config[:providers][provider_name.to_sym]['provider_class']
|
||||||
|
end
|
||||||
begin
|
begin
|
||||||
$providers[provider_name] = create_provider_object($config, $logger, $metrics, provider_name, {}) if $providers[provider_name].nil?
|
$providers[provider_name] = create_provider_object($config, $logger, $metrics, provider_class, provider_name, {}) if $providers[provider_name].nil?
|
||||||
rescue => err
|
rescue => err
|
||||||
$logger.log('s', "Error while creating provider for pool #{pool['name']}: #{err}")
|
$logger.log('s', "Error while creating provider for pool #{pool['name']}: #{err}")
|
||||||
raise
|
raise
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ module Vmpooler
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# name of the provider class
|
||||||
def name
|
def name
|
||||||
'vsphere'
|
'vsphere'
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1754,7 +1754,7 @@ EOT
|
||||||
it 'should call create_provider_object idempotently' do
|
it 'should call create_provider_object idempotently' do
|
||||||
# Even though there are two pools using the vsphere provider (the default), it should only
|
# Even though there are two pools using the vsphere provider (the default), it should only
|
||||||
# create the provider object once.
|
# create the provider object once.
|
||||||
expect(subject).to receive(:create_provider_object).with(Object, Object, Object, 'vsphere', Object).and_return(vsphere_provider)
|
expect(subject).to receive(:create_provider_object).with(Object, Object, Object, 'vsphere', 'vsphere', Object).and_return(vsphere_provider)
|
||||||
|
|
||||||
subject.execute!(1,0)
|
subject.execute!(1,0)
|
||||||
end
|
end
|
||||||
|
|
@ -1774,6 +1774,50 @@ EOT
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'creating multiple vsphere Providers' do
|
||||||
|
let(:vsphere_provider) { double('vsphere_provider') }
|
||||||
|
let(:vsphere_provider2) { double('vsphere_provider') }
|
||||||
|
let(:provider1) { Vmpooler::PoolManager::Provider::Base.new(config, logger, metrics, 'vsphere', provider_options) }
|
||||||
|
let(:provider2) { Vmpooler::PoolManager::Provider::Base.new(config, logger, metrics, 'secondvsphere', provider_options) }
|
||||||
|
let(:config) {
|
||||||
|
YAML.load(<<-EOT
|
||||||
|
---
|
||||||
|
:providers:
|
||||||
|
:vsphere:
|
||||||
|
server: 'blah1'
|
||||||
|
provider_class: 'vsphere'
|
||||||
|
:secondvsphere:
|
||||||
|
server: 'blah2'
|
||||||
|
provider_class: 'vsphere'
|
||||||
|
:pools:
|
||||||
|
- name: #{pool}
|
||||||
|
provider: 'vsphere'
|
||||||
|
- name: 'secondpool'
|
||||||
|
provider: 'secondvsphere'
|
||||||
|
EOT
|
||||||
|
)}
|
||||||
|
|
||||||
|
it 'should call create_provider_object twice' do
|
||||||
|
# The two pools use a different provider name, but each provider_class is vsphere
|
||||||
|
expect(subject).to receive(:create_provider_object).with(Object, Object, Object, "vsphere", "vsphere", Object).and_return(vsphere_provider)
|
||||||
|
expect(subject).to receive(:create_provider_object).with(Object, Object, Object, "vsphere", "secondvsphere", Object).and_return(vsphere_provider2)
|
||||||
|
subject.execute!(1,0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have vsphere providers with different servers' do
|
||||||
|
allow(subject).to receive(:get_provider_for_pool).with(pool).and_return(provider1)
|
||||||
|
result = subject.get_provider_for_pool(pool)
|
||||||
|
allow(provider1).to receive(:provider_config).and_call_original
|
||||||
|
expect(result.provider_config['server']).to eq('blah1')
|
||||||
|
|
||||||
|
allow(subject).to receive(:get_provider_for_pool).with('secondpool').and_return(provider2)
|
||||||
|
result = subject.get_provider_for_pool('secondpool')
|
||||||
|
allow(provider1).to receive(:provider_config).and_call_original
|
||||||
|
expect(result.provider_config['server']).to eq('blah2')
|
||||||
|
subject.execute!(1,0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'modify configuration on startup' do
|
context 'modify configuration on startup' do
|
||||||
context 'move vSphere configuration to providers location' do
|
context 'move vSphere configuration to providers location' do
|
||||||
let(:config) {
|
let(:config) {
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,11 @@
|
||||||
# - insecure
|
# - insecure
|
||||||
# Whether to ignore any HTTPS negotiation errors (e.g. untrusted self-signed certificates)
|
# Whether to ignore any HTTPS negotiation errors (e.g. untrusted self-signed certificates)
|
||||||
# (optional: default true)
|
# (optional: default true)
|
||||||
|
#
|
||||||
|
# - provider_class
|
||||||
|
# For multiple providers, specify one of the supported backing services (vsphere or dummy)
|
||||||
|
# (optional: will default to it's parent :key: name eg. 'vsphere')
|
||||||
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
|
||||||
:vsphere:
|
:vsphere:
|
||||||
|
|
@ -39,6 +44,23 @@
|
||||||
username: 'vmpooler'
|
username: 'vmpooler'
|
||||||
password: 'swimsw1msw!m'
|
password: 'swimsw1msw!m'
|
||||||
|
|
||||||
|
# If you want to support more than one provider with different parameters (server, username or passwords) you have to specify the
|
||||||
|
# backing service in the provider_class configuration parameter for example 'vsphere' or 'dummy'. Each pool can specify
|
||||||
|
# the provider to use.
|
||||||
|
#
|
||||||
|
# Multiple providers example:
|
||||||
|
|
||||||
|
:vsphere-pdx:
|
||||||
|
server: 'vsphere.pdx.company.com'
|
||||||
|
username: 'vmpooler-pdx'
|
||||||
|
password: 'swimsw1msw!m'
|
||||||
|
provider_class: 'vsphere'
|
||||||
|
:vsphere-bfs:
|
||||||
|
server: 'vsphere.bfs.company.com'
|
||||||
|
username: 'vmpooler-bfs'
|
||||||
|
password: 'swimsw1msw!m'
|
||||||
|
provider_class: 'vsphere'
|
||||||
|
|
||||||
# :dummy:
|
# :dummy:
|
||||||
#
|
#
|
||||||
# The dummy backing service is a simple text file service that can be used
|
# The dummy backing service is a simple text file service that can be used
|
||||||
|
|
@ -417,6 +439,8 @@
|
||||||
# The name of the VM provider which manage this pool. This should match
|
# The name of the VM provider which manage this pool. This should match
|
||||||
# a name in the :providers: section above e.g. vsphere
|
# a name in the :providers: section above e.g. vsphere
|
||||||
# (required; will default to vsphere for backwards compatibility)
|
# (required; will default to vsphere for backwards compatibility)
|
||||||
|
# If you have more than one provider, this is where you would choose which
|
||||||
|
# one to use for this pool
|
||||||
#
|
#
|
||||||
# - clone_target
|
# - clone_target
|
||||||
# Per-pool option to override the global 'clone_target' cluster.
|
# Per-pool option to override the global 'clone_target' cluster.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue