diff --git a/README.md b/README.md index 40e29ef..8dcbfbb 100644 --- a/README.md +++ b/README.md @@ -29,10 +29,11 @@ The following YAML configuration sets up two pools, `debian-7-i386` and `debian- ``` --- -:vsphere: - server: 'vsphere.company.com' - username: 'vmpooler' - password: 'swimsw1msw!m' +:providers: + :vsphere: + server: 'vsphere.company.com' + username: 'vmpooler' + password: 'swimsw1msw!m' :redis: server: 'redis.company.com' @@ -47,12 +48,14 @@ The following YAML configuration sets up two pools, `debian-7-i386` and `debian- pool: 'Pooled VMs/debian-7-i386' datastore: 'vmstorage' size: 5 + provider: vsphere - name: 'debian-7-x86_64' template: 'Templates/debian-7-x86_64' folder: 'Pooled VMs/debian-7-x86_64' pool: 'Pooled VMs/debian-7-x86_64' datastore: 'vmstorage' size: 5 + provider: vsphere ``` See the provided YAML configuration example, [vmpooler.yaml.example](vmpooler.yaml.example), for additional configuration options and parameters. diff --git a/lib/vmpooler/providers/vsphere.rb b/lib/vmpooler/providers/vsphere.rb index 38c6d51..6dc9819 100644 --- a/lib/vmpooler/providers/vsphere.rb +++ b/lib/vmpooler/providers/vsphere.rb @@ -2,12 +2,6 @@ module Vmpooler class PoolManager class Provider class VSphere < Vmpooler::PoolManager::Provider::Base - def initialize(config, logger, metrics, name, options) - super(config, logger, metrics, name, options) - @credentials = provider_config - @conf = global_config[:config] - end - def name 'vsphere' end @@ -239,12 +233,6 @@ module Vmpooler true end - def provider_config - # The vSphere configuration is currently in it's own root. This will - # eventually shift into the same location base expects it - global_config[:vsphere] - end - # VSphere Helper methods def get_target_cluster_from_config(pool_name) @@ -279,21 +267,21 @@ module Vmpooler begin @connection.serviceInstance.CurrentTime rescue - @connection = connect_to_vsphere @credentials + @connection = connect_to_vsphere end @connection end - def connect_to_vsphere(credentials) - max_tries = @conf['max_tries'] || 3 - retry_factor = @conf['retry_factor'] || 10 + def connect_to_vsphere + max_tries = global_config[:config]['max_tries'] || 3 + retry_factor = global_config[:config]['retry_factor'] || 10 try = 1 begin - connection = RbVmomi::VIM.connect host: credentials['server'], - user: credentials['username'], - password: credentials['password'], - insecure: credentials['insecure'] || true + connection = RbVmomi::VIM.connect host: provider_config['server'], + user: provider_config['username'], + password: provider_config['password'], + insecure: provider_config['insecure'] || true metrics.increment('connect.open') return connection rescue => err diff --git a/spec/unit/providers/vsphere_spec.rb b/spec/unit/providers/vsphere_spec.rb index 906f1b3..948e6da 100644 --- a/spec/unit/providers/vsphere_spec.rb +++ b/spec/unit/providers/vsphere_spec.rb @@ -47,11 +47,12 @@ describe 'Vmpooler::PoolManager::Provider::VSphere' do :config: max_tries: 3 retry_factor: 10 -:vsphere: - server: "vcenter.domain.local" - username: "vcenter_user" - password: "vcenter_password" - insecure: true +:providers: + :vsphere: + server: "vcenter.domain.local" + username: "vcenter_user" + password: "vcenter_password" + insecure: true :pools: - name: '#{poolname}' alias: [ 'mockpool' ] @@ -66,8 +67,6 @@ EOT ) } - let(:credentials) { config[:vsphere] } - let(:connection_options) {{}} let(:connection) { mock_RbVmomi_VIM_Connection(connection_options) } let(:vmname) { 'vm1' } @@ -912,14 +911,14 @@ EOT it 'should call connect_to_vsphere to reconnect' do allow(metrics).to receive(:increment) - expect(subject).to receive(:connect_to_vsphere).with(credentials) + expect(subject).to receive(:connect_to_vsphere).with(no_args) subject.get_connection() end it 'should return a new connection' do new_connection = mock_RbVmomi_VIM_Connection(connection_options) - expect(subject).to receive(:connect_to_vsphere).with(credentials).and_return(new_connection) + expect(subject).to receive(:connect_to_vsphere).with(no_args).and_return(new_connection) result = subject.get_connection() @@ -933,6 +932,8 @@ EOT allow(RbVmomi::VIM).to receive(:connect).and_return(connection) end + let (:credentials) { config[:providers][:vsphere] } + context 'succesful connection' do it 'should use the supplied credentials' do expect(RbVmomi::VIM).to receive(:connect).with({ @@ -941,7 +942,7 @@ EOT :password => credentials['password'], :insecure => credentials['insecure'] }).and_return(connection) - subject.connect_to_vsphere(credentials) + subject.connect_to_vsphere end it 'should honor the insecure setting' do @@ -954,11 +955,11 @@ EOT :password => credentials['password'], :insecure => false, }).and_return(connection) - subject.connect_to_vsphere(credentials) + subject.connect_to_vsphere end it 'should default to an insecure connection' do - config[:vsphere][:insecure] = nil + config[:providers][:vsphere][:insecure] = nil expect(RbVmomi::VIM).to receive(:connect).with({ :host => credentials['server'], @@ -967,18 +968,18 @@ EOT :insecure => true }).and_return(connection) - subject.connect_to_vsphere(credentials) + subject.connect_to_vsphere end it 'should return the connection object' do - result = subject.connect_to_vsphere(credentials) + result = subject.connect_to_vsphere expect(result).to be(connection) end it 'should increment the connect.open counter' do expect(metrics).to receive(:increment).with('connect.open') - subject.connect_to_vsphere(credentials) + subject.connect_to_vsphere end end @@ -992,7 +993,7 @@ EOT end it 'should return the connection object' do - result = subject.connect_to_vsphere(credentials) + result = subject.connect_to_vsphere expect(result).to be(connection) end @@ -1000,7 +1001,7 @@ EOT it 'should increment the connect.fail and then connect.open counter' do expect(metrics).to receive(:increment).with('connect.fail').exactly(1).times expect(metrics).to receive(:increment).with('connect.open').exactly(1).times - subject.connect_to_vsphere(credentials) + subject.connect_to_vsphere end end @@ -1011,7 +1012,7 @@ EOT end it 'should raise an error' do - expect{subject.connect_to_vsphere(credentials)}.to raise_error(RuntimeError,'MockError') + expect{subject.connect_to_vsphere}.to raise_error(RuntimeError,'MockError') end it 'should retry the connection attempt config.max_tries times' do @@ -1020,7 +1021,7 @@ EOT begin # Swallow any errors - subject.connect_to_vsphere(credentials) + subject.connect_to_vsphere rescue end end @@ -1031,7 +1032,7 @@ EOT begin # Swallow any errors - subject.connect_to_vsphere(credentials) + subject.connect_to_vsphere rescue end end @@ -1051,7 +1052,7 @@ EOT begin # Swallow any errors - subject.connect_to_vsphere(credentials) + subject.connect_to_vsphere rescue end end diff --git a/vmpooler.yaml.example b/vmpooler.yaml.example index 2aab60c..b7d3ea6 100644 --- a/vmpooler.yaml.example +++ b/vmpooler.yaml.example @@ -1,9 +1,20 @@ --- +:providers: +# :providers: +# +# This section contains the VM providers for VMs and Pools +# The currently supported backing services are: +# - vsphere +# - dummy + # :vsphere: # # This section contains the server hostname and authentication credentials # needed for vmpooler to connect to VMware vSphere. # +# NOTE - To support older configuration files, a :vsphere: configuration section +# will be copied into :providers:/:vsphere: if one does not already exist. +# # Available configuration parameters: # # - server @@ -17,20 +28,16 @@ # - password # The password used to authenticate VMware vSphere. # (required) - +# +# - insecure +# Whether to ignore any HTTPS negotiation errors (e.g. untrusted self-signed certificates) +# (optional: default true) # Example: -:vsphere: - server: 'vsphere.company.com' - username: 'vmpooler' - password: 'swimsw1msw!m' - -:providers: -# :providers: -# -# This section contains the VM providers for VMs and Pools -# The currently supported backing services are: -# - dummy + :vsphere: + server: 'vsphere.company.com' + username: 'vmpooler' + password: 'swimsw1msw!m' # :dummy: # @@ -146,58 +153,58 @@ server: 'redis.company.com' - # :graphs: - # - # This section contains the server and prefix information for a graphite- - # compatible web front-end where graphs may be viewed. This is used by the - # vmpooler dashboard to retrieve statistics and graphs for a given instance. - # - # NOTE: This is not the endpoint for publishing metrics data. See `graphite:` - # and `statsd:` below. - # - # NOTE: If `graphs:` is not set, for legacy compatibility, `graphite:` will be - # consulted for `server`/`prefix` information to use in locating a - # graph server for our dashboard. `graphs:` is recommended over - # `graphite:` - # - # - # Available configuration parameters: - # - # - # - server - # The FQDN hostname of the statsd daemon. - # (required) - # - # - prefix - # The prefix to use while storing statsd data. - # (optional; default: 'vmpooler') +# :graphs: +# +# This section contains the server and prefix information for a graphite- +# compatible web front-end where graphs may be viewed. This is used by the +# vmpooler dashboard to retrieve statistics and graphs for a given instance. +# +# NOTE: This is not the endpoint for publishing metrics data. See `graphite:` +# and `statsd:` below. +# +# NOTE: If `graphs:` is not set, for legacy compatibility, `graphite:` will be +# consulted for `server`/`prefix` information to use in locating a +# graph server for our dashboard. `graphs:` is recommended over +# `graphite:` +# +# +# Available configuration parameters: +# +# +# - server +# The FQDN hostname of the statsd daemon. +# (required) +# +# - prefix +# The prefix to use while storing statsd data. +# (optional; default: 'vmpooler') - # :statsd: - # - # This section contains the connection information required to store - # historical data via statsd. This is mutually exclusive with graphite - # and takes precedence. - # - # Available configuration parameters: - # - # - server - # The FQDN hostname of the statsd daemon. - # (required) - # - # - prefix - # The prefix to use while storing statsd data. - # (optional; default: 'vmpooler') - # - # - port - # The UDP port to communicate with the statsd daemon. - # (optional; default: 8125) +# :statsd: +# +# This section contains the connection information required to store +# historical data via statsd. This is mutually exclusive with graphite +# and takes precedence. +# +# Available configuration parameters: +# +# - server +# The FQDN hostname of the statsd daemon. +# (required) +# +# - prefix +# The prefix to use while storing statsd data. +# (optional; default: 'vmpooler') +# +# - port +# The UDP port to communicate with the statsd daemon. +# (optional; default: 8125) - # Example: +# Example: - :statsd: - server: 'statsd.company.com' - prefix: 'vmpooler' - port: 8125 +:statsd: + server: 'statsd.company.com' + prefix: 'vmpooler' + port: 8125 # :graphite: # @@ -309,7 +316,7 @@ # (optional; default: same cluster/host as origin template) # # - task_limit -# The number of concurrent VMware vSphere tasks to perform. +# The number of concurrent VM creation tasks to perform. # (optional; default: '10') # # - timeout @@ -341,21 +348,23 @@ # # - migration_limit # When set to any value greater than 0 enable VM migration at checkout. -# When enabled this capability will evaluate a VM for migration when it is requested +# When enabled this capability will evaluate a VM for migration to a different host when it is requested # in an effort to maintain a more even distribution of load across compute resources. -# The migration_limit ensures that no more than n migrations will be evaluated at any one time +# The migration_limit ensures that no more than the specified migrations will be evaluated at any one time # and greatly reduces the possibilty of VMs ending up bunched together on a particular host. # -# - max_tries -# Set the max number of times a connection should retry in vsphere helper. -# This optional setting allows a user to dial in retry limits to -# suit your environment. +# - max_tries +# Set the max number of times a connection should retry in VM providers. +# This optional setting allows a user to dial in retry limits to +# suit your environment. +# (optional; default: 3) # -# - retry_factor -# When retrying, each attempt sleeps for the try count * retry_factor. -# Increase this number to lengthen the delay between retry attempts. -# This is particularly useful for instances with a large number of pools -# to prevent a thundering herd when retrying connections. +# - retry_factor +# When retrying, each attempt sleeps for the try count * retry_factor. +# Increase this number to lengthen the delay between retry attempts. +# This is particularly useful for instances with a large number of pools +# to prevent a thundering herd when retrying connections. +# (optional; default: 10) # Example: @@ -392,18 +401,15 @@ # The template or virtual machine target to spawn clones from. # (required) # -# - folder -# The vSphere 'folder' destination for spawned clones. -# (required) -# -# - datastore -# The vSphere 'datastore' destination for spawned clones. -# (required) -# # - size # The number of waiting VMs to keep in a pool. # (required) # +# - provider +# The name of the VM provider which manage this pool. This should match +# a name in the :providers: section above e.g. vsphere +# (required; will default to vsphere for backwards compatibility) +# # - clone_target # Per-pool option to override the global 'clone_target' cluster. # (optional) @@ -415,8 +421,18 @@ # # - ready_ttl # How long (in minutes) to keep VMs in 'ready' queues before destroying. -# (optional) - +# (optional; default: no limit) +# +# Provider specific pool settings +# vSphere provider +# - folder +# The vSphere 'folder' destination for spawned clones. +# (required) +# +# - datastore +# The vSphere 'datastore' destination for spawned clones. +# (required) +# # Example: :pools: @@ -428,6 +444,7 @@ size: 5 timeout: 15 ready_ttl: 1440 + provider: vsphere - name: 'debian-7-x86_64' alias: [ 'debian-7-64', 'debian-7-amd64' ] template: 'Templates/debian-7-x86_64' @@ -436,3 +453,4 @@ size: 5 timeout: 15 ready_ttl: 1440 + provider: vsphere