diff --git a/manifests/db.pp b/manifests/db.pp index 219c8b5..df4b426 100644 --- a/manifests/db.pp +++ b/manifests/db.pp @@ -79,7 +79,7 @@ # [*db_inc_retry_interval*] # (Optional) If True, increases the interval between retries of # a database operation up to db_max_retry_interval. -# Defaults to $::os_service_default. +# Defaults to $::os_service_default # # [*db_max_retry_interval*] # (Optional) If db_inc_retry_interval is set, the maximum seconds between @@ -119,10 +119,12 @@ define oslo::db( $use_tpool = $::os_service_default, ){ + include ::oslo::params + if !is_service_default($connection) { validate_re($connection, - '^(sqlite|mysql(\+pymysql)?|postgresql):\/\/(\S+:\S+@\S+\/\S+)?') + '^(sqlite|mysql(\+pymysql)?|postgresql|mongodb):\/\/(\S+:\S+@\S+\/\S+)?') case $connection { /^mysql(\+pymysql)?:\/\//: { @@ -138,6 +140,9 @@ define oslo::db( $backend_package = false require 'postgresql::lib::python' } + /^mongodb:\/\//: { + $backend_package = $::oslo::params::pymongo_package_name + } /^sqlite:\/\//: { $backend_package = $::oslo::params::sqlite_package_name } @@ -150,30 +155,35 @@ define oslo::db( package { 'db_backend_package': ensure => present, name => $backend_package, + tag => 'openstack', } } } - create_resources($name, {'database/sqlite_db' => { value => $sqlite_db }}) - create_resources($name, {'database/sqlite_synchronous' => { value => $sqlite_synchronous }}) - create_resources($name, {'database/backend' => { value => $backend }}) - create_resources($name, {'database/connection' => { value => $connection, secret => true }}) - create_resources($name, {'database/slave_connection' => { value => $slave_connection, secret => true }}) - create_resources($name, {'database/mysql_sql_mode' => { value => $mysql_sql_mode }}) - create_resources($name, {'database/idle_timeout' => { value => $idle_timeout }}) - create_resources($name, {'database/min_pool_size' => { value => $min_pool_size }}) - create_resources($name, {'database/max_pool_size' => { value => $max_pool_size }}) - create_resources($name, {'database/max_retries' => { value => $max_retries }}) - create_resources($name, {'database/retry_interval' => { value => $retry_interval }}) - create_resources($name, {'database/max_overflow' => { value => $max_overflow }}) - create_resources($name, {'database/connection_debug' => { value => $connection_debug }}) - create_resources($name, {'database/connection_trace' => { value => $connection_trace }}) - create_resources($name, {'database/pool_timeout' => { value => $pool_timeout }}) - create_resources($name, {'database/use_db_reconnect' => { value => $use_db_reconnect }}) - create_resources($name, {'database/db_retry_interval' => { value => $db_retry_interval }}) - create_resources($name, {'database/db_inc_retry_interval' => { value => $db_inc_retry_interval }}) - create_resources($name, {'database/db_max_retry_interval' => { value => $db_max_retry_interval }}) - create_resources($name, {'database/db_max_retries' => { value => $db_max_retries }}) - create_resources($name, {'database/use_tpool' => { value => $use_tpool }}) + $database_options = { + 'database/sqlite_db' => { value => $sqlite_db }, + 'database/sqlite_synchronous' => { value => $sqlite_synchronous }, + 'database/backend' => { value => $backend }, + 'database/connection' => { value => $connection, secret => true }, + 'database/slave_connection' => { value => $slave_connection, secret => true }, + 'database/mysql_sql_mode' => { value => $mysql_sql_mode }, + 'database/idle_timeout' => { value => $idle_timeout }, + 'database/min_pool_size' => { value => $min_pool_size }, + 'database/max_pool_size' => { value => $max_pool_size }, + 'database/max_retries' => { value => $max_retries }, + 'database/retry_interval' => { value => $retry_interval }, + 'database/max_overflow' => { value => $max_overflow }, + 'database/connection_debug' => { value => $connection_debug }, + 'database/connection_trace' => { value => $connection_trace }, + 'database/pool_timeout' => { value => $pool_timeout }, + 'database/use_db_reconnect' => { value => $use_db_reconnect }, + 'database/db_retry_interval' => { value => $db_retry_interval }, + 'database/db_inc_retry_interval' => { value => $db_inc_retry_interval }, + 'database/db_max_retry_interval' => { value => $db_max_retry_interval }, + 'database/db_max_retries' => { value => $db_max_retries }, + 'database/use_tpool' => { value => $use_tpool }, + } + + create_resources($name, $database_options) } diff --git a/manifests/params.pp b/manifests/params.pp index 03ec40b..9797938 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -6,10 +6,12 @@ class oslo::params { 'RedHat': { $sqlite_package_name = undef $pymysql_package_name = undef + $pymongo_package_name = 'python-pymongo' } 'Debian': { $sqlite_package_name = 'python-pysqlite2' $pymysql_package_name = 'python-pymysql' + $pymongo_package_name = 'python-pymongo' } default: { fail("Unsupported osfamily: ${::osfamily} operatingsystem") diff --git a/spec/defines/oslo_db_spec.rb b/spec/defines/oslo_db_spec.rb new file mode 100644 index 0000000..59de844 --- /dev/null +++ b/spec/defines/oslo_db_spec.rb @@ -0,0 +1,196 @@ +require 'spec_helper' + +describe 'oslo::db' do + + let (:title) { 'keystone_config' } + + shared_examples 'shared examples' do + + context 'with default parameters' do + it 'configure oslo_db default params' do + is_expected.to contain_keystone_config('database/sqlite_db').with_value('') + is_expected.to contain_keystone_config('database/sqlite_synchronous').with_value('') + is_expected.to contain_keystone_config('database/backend').with_value('') + is_expected.to contain_keystone_config('database/connection').with_value('') + is_expected.to contain_keystone_config('database/slave_connection').with_value('') + is_expected.to contain_keystone_config('database/mysql_sql_mode').with_value('') + is_expected.to contain_keystone_config('database/idle_timeout').with_value('') + is_expected.to contain_keystone_config('database/min_pool_size').with_value('') + is_expected.to contain_keystone_config('database/max_pool_size').with_value('') + is_expected.to contain_keystone_config('database/max_retries').with_value('') + is_expected.to contain_keystone_config('database/retry_interval').with_value('') + is_expected.to contain_keystone_config('database/max_overflow').with_value('') + is_expected.to contain_keystone_config('database/connection_debug').with_value('') + is_expected.to contain_keystone_config('database/connection_trace').with_value('') + is_expected.to contain_keystone_config('database/pool_timeout').with_value('') + is_expected.to contain_keystone_config('database/use_db_reconnect').with_value('') + is_expected.to contain_keystone_config('database/db_retry_interval').with_value('') + is_expected.to contain_keystone_config('database/db_inc_retry_interval').with_value('') + is_expected.to contain_keystone_config('database/db_max_retry_interval').with_value('') + is_expected.to contain_keystone_config('database/db_max_retries').with_value('') + is_expected.to contain_keystone_config('database/use_tpool').with_value('') + end + end + + context 'with overridden parameters' do + let :params do + { + :backend => 'sqlalchemy', + :connection => 'mysql+pymysql://db:db@localhost/db', + :mysql_sql_mode => 'TRADITIONAL', + :idle_timeout => '3601', + :min_pool_size => '2', + :max_pool_size => '100', + :max_retries => '10', + :retry_interval => '10', + :max_overflow => '50', + :connection_debug => '0', + :connection_trace => true, + :pool_timeout => '10', + :use_db_reconnect => true, + :db_retry_interval => '1', + :db_inc_retry_interval => true, + :db_max_retry_interval => '10', + :db_max_retries => '20', + :use_tpool => true, + } + end + + it 'configures database parameters' do + is_expected.to contain_keystone_config('database/backend').with_value('sqlalchemy') + is_expected.to contain_keystone_config('database/connection').with_value('mysql+pymysql://db:db@localhost/db') + is_expected.to contain_keystone_config('database/mysql_sql_mode').with_value('TRADITIONAL') + is_expected.to contain_keystone_config('database/idle_timeout').with_value('3601') + is_expected.to contain_keystone_config('database/min_pool_size').with_value('2') + is_expected.to contain_keystone_config('database/max_pool_size').with_value('100') + is_expected.to contain_keystone_config('database/max_retries').with_value('10') + is_expected.to contain_keystone_config('database/retry_interval').with_value('10') + is_expected.to contain_keystone_config('database/max_overflow').with_value('50') + is_expected.to contain_keystone_config('database/connection_debug').with_value('0') + is_expected.to contain_keystone_config('database/connection_trace').with_value(true) + is_expected.to contain_keystone_config('database/pool_timeout').with_value('10') + is_expected.to contain_keystone_config('database/use_db_reconnect').with_value(true) + is_expected.to contain_keystone_config('database/db_retry_interval').with_value('1') + is_expected.to contain_keystone_config('database/db_inc_retry_interval').with_value(true) + is_expected.to contain_keystone_config('database/db_max_retry_interval').with_value('10') + is_expected.to contain_keystone_config('database/db_max_retries').with_value('20') + is_expected.to contain_keystone_config('database/use_tpool').with_value(true) + end + end + + context 'with mongodb backend' do + let :params do + { :connection => 'mongodb://localhost:1234/db' } + end + + it 'install the proper backend package' do + is_expected.to contain_package('db_backend_package').with( + :ensure => 'present', + :name => 'python-pymongo', + :tag => 'openstack' + ) + end + end + + context 'with specific mongodb connection string' do + let :params do + { :connection => 'mongodb://user:password@host1:27017,host2:27017,host3:27017/db_name?replicaSet=replica&readPreference=primaryPreferred' } + end + + it { is_expected.to contain_keystone_config('database/connection').with_value( + 'mongodb://user:password@host1:27017,host2:27017,host3:27017/db_name?replicaSet=replica&readPreference=primaryPreferred').with_secret(true) } + end + + context 'with pymysql connection' do + let :params do + { :connection => 'mysql+pymysql://db:db@localhost/db' } + end + + it { is_expected.to contain_class('oslo::params') } + it { is_expected.to contain_keystone_config('database/connection').with_value('mysql+pymysql://db:db@localhost/db').with_secret(true) } + end + + context 'with postgresql backend' do + let :params do + { :connection => 'postgresql://db:db@localhost/db', } + end + + it 'install the proper backend package' do + is_expected.to contain_package('python-psycopg2').with(:ensure => 'present') + end + end + + context 'with incorrect database_connection string' do + let :params do + { :connection => 'foo://db:db@localhost/db', } + end + + it_raises 'a Puppet::Error', /validate_re/ + end + + context 'with incorrect pymysql database_connection string' do + let :params do + { :connection => 'foo+pymysql://db:db@localhost/db', } + end + + it_raises 'a Puppet::Error', /validate_re/ + end + end + + context 'on Debian platforms' do + let :facts do + @default_facts.merge({ :osfamily => 'Debian', + :operatingsystem => 'Debian', + :operatingsystemrelease => 'jessie', + }) + end + + context 'using pymysql driver' do + let :params do + { :connection => 'mysql+pymysql:///db:db@localhost/db', } + end + + it 'install the proper backend package' do + is_expected.to contain_package('db_backend_package').with( + :ensure => 'present', + :name => 'python-pymysql', + :tag => 'openstack' + ) + end + end + + context 'with sqlite backend' do + let :params do + { :connection => 'sqlite:///var/lib/db.db', } + end + + it 'install the proper backend package' do + is_expected.to contain_package('db_backend_package').with( + :ensure => 'present', + :name => 'python-pysqlite2', + :tag => 'openstack' + ) + end + end + + include_examples 'shared examples' + end + + context 'on Redhat platforms' do + let :facts do + @default_facts.merge({ :osfamily => 'RedHat', + :operatingsystemrelease => '7.1', + }) + end + + context 'using pymysql driver' do + let :params do + { :connection => 'mysql+pymysql:///db:db@localhost/db', } + end + + it { is_expected.not_to contain_package('db_backend_package') } + end + + include_examples 'shared examples' + end +end