Browse Source

(MODULES-661) Remote DB support

Adds connection-settings (for remote DB support) when creating DB resources.

Connection-settings allows a hash of options that can be used
when connecting the a remote DB (such as PGHOST, PGPORT, PGPASSWORD
PGSSLKEY) and a special option DBVERSION indicating the version
of the remote database.

Including
- Puppet updates
- Documentation updates
- RSpec unit test updates
- RSpec acceptance test updates
- Some test coverage for connection-settings
- Working acceptance test...
    Basic vagrant setup:
    * Two boxes, server and client
    * Runs puppet code to on server to setup a postgres server that allows all connections and md5 connections, creates db puppet to look at
    * Runs puppet code on client to make a server that a psql command can be run against puppet db on other server
    * Does some fancy stuff to get the fact of the IP from the first server to connect to
- Backwards compatible, with deprecation warnings around old parameters
Tom Hey 9 years ago
parent
commit
6a29636155

+ 61 - 1
README.md

@@ -120,6 +120,43 @@ In this example, you would grant ALL privileges on the test1 database and on the
 
 At this point, you would just need to plunk these database name/username/password values into your PuppetDB config files, and you are good to go.
 
+###Managing remote users, roles and permissions
+
+Remote SQL objects are managed using the same Puppet resources as local SQL objects with the additional of a connect_settings hash. This provides control over how Puppet should connect to the remote Postgres instances and the version that should be used when generating SQL commands.
+
+When provided the connect_settings hash can contain environment variables to control Postgres client connections, such as: PGHOST, PGPORT, PGPASSWORD PGSSLKEY (see http://www.postgresql.org/docs/9.4/static/libpq-envars.html) Additionally the special value of DBVERSION can be provided to specify the target database's version. If the connect_settings hash is omitted or empty then Puppet will connect to the local Postgres instance.
+
+A connect_settings hash can be provided with each of the Puppet resources or a default connect_settings hash can be set in postgresql::globals. Per resource configuration of connect_settings allows for SQL object to be creating on multiple database by multiple users.
+
+    $connection_settings_super2 = {
+                                     'PGUSER'     => "super2",
+                                     'PGPASSWORD' => "foobar2",
+                                     'PGHOST'     => "127.0.0.1",
+                                     'PGPORT'     => "5432",
+                                     'PGDATABASE' => "postgres",
+                                  }
+
+    include postgresql::server
+
+    # Connect with no special settings, i.e domain sockets, user postges
+    postgresql::server::role{'super2':
+      password_hash => "foobar2",
+      superuser => true,
+
+      connect_settings => {},
+      require => [
+                   Class['postgresql::globals'],
+                   Class['postgresql::server::service'],
+                 ],
+    }
+
+    # Now using this new user connect via TCP
+    postgresql::server::database { 'db1':
+      connect_settings => $connection_settings_super2,
+
+      require => Postgresql::Server::Role['super2'],
+    }
+
 Reference
 ---------
 
@@ -241,6 +278,7 @@ This setting is used to specify the name of the default database to connect with
 Path to the `initdb` command.
 
 ####`createdb_path`
+**Deprecated**
 Path to the `createdb` command.
 
 ####`psql_path`
@@ -370,6 +408,7 @@ List of strings for access control for connection method, users, databases, IPv6
 Path to the `initdb` command.
 
 ####`createdb_path`
+**Deprecated**
 Path to the `createdb` command.
 
 ####`psql_path`
@@ -539,7 +578,7 @@ Value for the setting.
 
 
 ###Resource: postgresql::server::db
-This is a convenience resource that creates a database, user and assigns necessary permissions in one go.
+This is a convenience resource that creates a local database, user and assigns necessary permissions in one go.
 
 For example, to create a database called `test1` with a corresponding user of the same name, you can use:
 
@@ -612,6 +651,8 @@ Override the locale during creation of the database. Defaults to the default def
 ####`istemplate`
 Define database as a template. Defaults to `false`.
 
+####`connect_settings`
+Hash of environment variable used when connecting to a remote server. Defaults to connecting to the local Postgres instance.
 
 ###Resource: postgresql::server::database\_grant
 This defined type manages grant based access privileges for users, wrapping the `postgresql::server::database_grant` for database specific permissions. Consult the PostgreSQL documentation for `grant` for more information.
@@ -634,6 +675,8 @@ Database to execute the grant against. This should not ordinarily be changed fro
 ####`psql_user`
 OS user for running `psql`. Defaults to the default user for the module, usually `postgres`.
 
+####`connect_settings`
+Hash of environment variable used when connecting to a remote server. Defaults to connecting to the local Postgres instance.
 
 ###Resource: postgresql::server::extension
 Manages a postgresql extension.
@@ -683,6 +726,9 @@ OS user for running `psql`. Defaults to the default user for the module, usually
 ####`port`
 Port to use when connecting. Default to 'undef' which generally defaults to 5432 depending on your PostgreSQL packaging.
 
+####`connect_settings`
+Hash of environment variable used when connecting to a remote server. Defaults to connecting to the local Postgres instance.
+
 ###Resource: postgresql::server::pg\_hba\_rule
 This defined type allows you to create an access rule for `pg_hba.conf`. For more details see the [PostgreSQL documentation](http://www.postgresql.org/docs/8.2/static/auth-pg-hba-conf.html).
 
@@ -886,6 +932,9 @@ Specifies how many concurrent connections the role can make. Defaults to `-1` me
 ####`username`
 The username of the role to create, defaults to `namevar`.
 
+####`connect_settings`
+Hash of environment variable used when connecting to a remote server. Defaults to connecting to the local Postgres instance.
+
 ###Resource: postgresql::server::schema
 This defined type can be used to create a schema. For example:
 
@@ -909,6 +958,9 @@ The default owner of the schema.
 ####`schema`
 Name of the schma. Defaults to `namevar`.
 
+####`connect_settings`
+Hash of environment variable used when connecting to a remote server. Defaults to connecting to the local Postgres instance.
+
 
 ###Resource: postgresql::server::table\_grant
 This defined type manages grant based access privileges for users. Consult the PostgreSQL documentation for `grant` for more information.
@@ -934,6 +986,8 @@ Database to execute the grant against. This should not ordinarily be changed fro
 ####`psql_user`
 OS user for running `psql`. Defaults to the default user for the module, usually `postgres`.
 
+####`connect_settings`
+Hash of environment variable used when connecting to a remote server. Defaults to connecting to the local Postgres instance.
 
 ###Resource: postgresql::server::tablespace
 This defined type can be used to create a tablespace. For example:
@@ -957,8 +1011,11 @@ The default owner of the tablespace.
 ####`spcname`
 Name of the tablespace. Defaults to `namevar`.
 
+####`connect_settings`
+Hash of environment variable used when connecting to a remote server. Defaults to connecting to the local Postgres instance.
 
 ###Resource: postgresql::validate\_db\_connection
+
 This resource can be utilised inside composite manifests to validate that a client has a valid connection with a remote PostgreSQL database. It can be ran from any node where the PostgreSQL client software is installed to validate connectivity before commencing other dependent tasks in your Puppet manifests, so it is often used when chained to other tasks such as: starting an application server, performing a database migration.
 
 Example usage:
@@ -991,6 +1048,9 @@ Username to connect with. Defaults to 'undef', which when using a unix socket an
 ####`database_password`
 Password to connect with. Can be left blank, but that is not recommended.
 
+####`connect_settings`
+Hash of environment variable used when connecting to a remote server, this is an alternative to providing individual parameters (database_host, etc.). If provided the individual parameters take precedence.
+
 ####`run_as`
 The user to run the `psql` command with for authenticiation. This is important when trying to connect to a database locally using Unix sockets and `ident` authentication. It is not needed for remote testing.
 

+ 7 - 5
lib/puppet/provider/postgresql_psql/ruby.rb

@@ -16,19 +16,21 @@ Puppet::Type.type(:postgresql_psql).provide(:ruby) do
     command.push("-p", resource[:port]) if resource[:port]
     command.push("-t", "-c", '"' + sql.gsub('"', '\"') + '"')
 
+    environment = get_environment
+
     if resource[:cwd]
       Dir.chdir resource[:cwd] do
-        run_command(command, resource[:psql_user], resource[:psql_group])
+        run_command(command, resource[:psql_user], resource[:psql_group], environment)
       end
     else
-      run_command(command, resource[:psql_user], resource[:psql_group])
+      run_command(command, resource[:psql_user], resource[:psql_group], environment)
     end
   end
 
   private
 
   def get_environment
-    environment = {}
+    environment = resource[:connect_settings] || {}
     if envlist = resource[:environment]
       envlist = [envlist] unless envlist.is_a? Array
       envlist.each do |setting|
@@ -47,7 +49,7 @@ Puppet::Type.type(:postgresql_psql).provide(:ruby) do
     return environment
   end
 
-  def run_command(command, user, group)
+  def run_command(command, user, group, environment)
     command = command.join ' '
     environment = get_environment
     if Puppet::PUPPETVERSION.to_f < 3.0
@@ -66,7 +68,7 @@ Puppet::Type.type(:postgresql_psql).provide(:ruby) do
         :failonfail         => false,
         :combine            => true,
         :override_locale    => true,
-        :custom_environment => environment
+        :custom_environment => environment,
       })
       [output, $CHILD_STATUS.dup]
     end

+ 6 - 2
lib/puppet/type/postgresql_psql.rb

@@ -62,12 +62,16 @@ Puppet::Type.newtype(:postgresql_psql) do
     end
   end
 
+  newparam(:connect_settings) do
+    desc "Connection settings that will be used when connecting to postgres"
+  end
+
   newparam(:db) do
-    desc "The name of the database to execute the SQL command against."
+    desc "The name of the database to execute the SQL command against, this overrides any PGDATABASE value in connect_settings"
   end
 
   newparam(:port) do
-    desc "The port of the database server to execute the SQL command against."
+    desc "The port of the database server to execute the SQL command against, this overrides any PGPORT value in connect_settings."
   end
 
   newparam(:search_path) do

+ 42 - 41
manifests/globals.pp

@@ -1,58 +1,59 @@
 # Class for setting cross-class global overrides. See README.md for more
 # details.
 class postgresql::globals (
-  $client_package_name    = undef,
-  $server_package_name    = undef,
-  $contrib_package_name   = undef,
-  $devel_package_name     = undef,
-  $java_package_name      = undef,
-  $docs_package_name      = undef,
-  $perl_package_name      = undef,
-  $plperl_package_name    = undef,
-  $plpython_package_name  = undef,
-  $python_package_name    = undef,
-  $postgis_package_name   = undef,
+  $client_package_name      = undef,
+  $server_package_name      = undef,
+  $contrib_package_name     = undef,
+  $devel_package_name       = undef,
+  $java_package_name        = undef,
+  $docs_package_name        = undef,
+  $perl_package_name        = undef,
+  $plperl_package_name      = undef,
+  $plpython_package_name    = undef,
+  $python_package_name      = undef,
+  $postgis_package_name     = undef,
 
-  $service_name           = undef,
-  $service_provider       = undef,
-  $service_status         = undef,
-  $default_database       = undef,
+  $service_name             = undef,
+  $service_provider         = undef,
+  $service_status           = undef,
+  $default_database         = undef,
 
-  $validcon_script_path   = undef,
+  $validcon_script_path     = undef,
 
-  $initdb_path            = undef,
-  $createdb_path          = undef,
-  $psql_path              = undef,
-  $pg_hba_conf_path       = undef,
-  $pg_ident_conf_path     = undef,
-  $postgresql_conf_path   = undef,
-  $recovery_conf_path     = undef,
+  $initdb_path              = undef,
+  $createdb_path            = undef,
+  $psql_path                = undef,
+  $pg_hba_conf_path         = undef,
+  $pg_ident_conf_path       = undef,
+  $postgresql_conf_path     = undef,
+  $recovery_conf_path       = undef,
+  $default_connect_settings = undef,
 
-  $pg_hba_conf_defaults   = undef,
+  $pg_hba_conf_defaults     = undef,
 
-  $datadir                = undef,
-  $confdir                = undef,
-  $bindir                 = undef,
-  $xlogdir                = undef,
-  $logdir                 = undef,
+  $datadir                  = undef,
+  $confdir                  = undef,
+  $bindir                   = undef,
+  $xlogdir                  = undef,
+  $logdir                   = undef,
 
-  $user                   = undef,
-  $group                  = undef,
+  $user                     = undef,
+  $group                    = undef,
 
-  $version                = undef,
-  $postgis_version        = undef,
-  $repo_proxy             = undef,
+  $version                  = undef,
+  $postgis_version          = undef,
+  $repo_proxy               = undef,
 
-  $needs_initdb           = undef,
+  $needs_initdb             = undef,
 
-  $encoding               = undef,
-  $locale                 = undef,
+  $encoding                 = undef,
+  $locale                   = undef,
 
-  $manage_pg_hba_conf     = undef,
-  $manage_pg_ident_conf   = undef,
-  $manage_recovery_conf   = undef,
+  $manage_pg_hba_conf       = undef,
+  $manage_pg_ident_conf     = undef,
+  $manage_recovery_conf     = undef,
 
-  $manage_package_repo    = undef,
+  $manage_package_repo      = undef,
 ) {
   # We are determining this here, because it is needed by the package repo
   # class.

+ 0 - 1
manifests/params.pp

@@ -253,7 +253,6 @@ class postgresql::params inherits postgresql::globals {
 
   $validcon_script_path = pick($validcon_script_path, '/usr/local/bin/validate_postgresql_connection.sh')
   $initdb_path          = pick($initdb_path, "${bindir}/initdb")
-  $createdb_path        = pick($createdb_path, "${bindir}/createdb")
   $pg_hba_conf_path     = pick($pg_hba_conf_path, "${confdir}/pg_hba.conf")
   $pg_hba_conf_defaults = pick($pg_hba_conf_defaults, true)
   $pg_ident_conf_path   = pick($pg_ident_conf_path, "${confdir}/pg_ident.conf")

+ 4 - 0
manifests/server.pp

@@ -63,6 +63,10 @@ class postgresql::server (
     $_version = $postgresql::params::version
   }
 
+  if $createdb_path != undef{
+    warning('Passing "createdb_path" to postgresql::server is deprecated, it can be removed safely for the same behaviour')
+  }
+
   # Reload has its own ordering, specified by other defines
   class { "${pg}::reload": require => Class["${pg}::install"] }
 

+ 45 - 30
manifests/server/database.pp

@@ -1,28 +1,43 @@
 # Define for creating a database. See README.md for more details.
 define postgresql::server::database(
-  $comment    = undef,
-  $dbname     = $title,
-  $owner      = $postgresql::server::user,
-  $tablespace = undef,
-  $template   = 'template0',
-  $encoding   = $postgresql::server::encoding,
-  $locale     = $postgresql::server::locale,
-  $istemplate = false
+  $comment          = undef,
+  $dbname           = $title,
+  $owner            = $postgresql::server::user,
+  $tablespace       = undef,
+  $template         = 'template0',
+  $encoding         = $postgresql::server::encoding,
+  $locale           = $postgresql::server::locale,
+  $istemplate       = false,
+  $connect_settings = $postgresql::server::default_connect_settings,
 ) {
   $createdb_path = $postgresql::server::createdb_path
   $user          = $postgresql::server::user
   $group         = $postgresql::server::group
   $psql_path     = $postgresql::server::psql_path
-  $port          = $postgresql::server::port
-  $version       = $postgresql::server::_version
   $default_db    = $postgresql::server::default_database
 
+  # If possible use the version of the remote database, otherwise
+  # fallback to our local DB version
+  if $connect_settings != undef and has_key( $connect_settings, 'DBVERSION') {
+    $version = $connect_settings['DBVERSION']
+  } else {
+    $version = $postgresql::server::_version
+  }
+
+  # If the connection settings do not contain a port, then use the local server port
+  if $connect_settings != undef and has_key( $connect_settings, 'PGPORT') {
+    $port = undef
+  } else {
+    $port = $postgresql::server::port
+  }
+
   # Set the defaults for the postgresql_psql resource
   Postgresql_psql {
-    psql_user  => $user,
-    psql_group => $group,
-    psql_path  => $psql_path,
-    port       => $port,
+    psql_user        => $user,
+    psql_group       => $group,
+    psql_path        => $psql_path,
+    port             => $port,
+    connect_settings => $connect_settings,
   }
 
   # Optionally set the locale switch. Older versions of createdb may not accept
@@ -30,7 +45,7 @@ define postgresql::server::database(
   if ($version != '8.1') {
     $locale_option = $locale ? {
       undef   => '',
-      default => "--locale=${locale} ",
+      default => "LC_COLLATE=${locale} LC_CTYPE=${locale}",
     }
     $public_revoke_privilege = 'CONNECT'
   } else {
@@ -38,40 +53,40 @@ define postgresql::server::database(
     $public_revoke_privilege = 'ALL'
   }
 
+  $template_option = $template ? {
+    undef   => '',
+    default => "TEMPLATE=${template}",
+  }
+
   $encoding_option = $encoding ? {
     undef   => '',
-    default => "--encoding '${encoding}' ",
+    default => "ENCODING=${encoding}",
   }
 
   $tablespace_option = $tablespace ? {
     undef   => '',
-    default => "--tablespace='${tablespace}' ",
+    default => "TABLESPACE=${tablespace}",
   }
 
-  $createdb_command = "${createdb_path} --port='${port}' --owner='${owner}' --template=${template} ${encoding_option}${locale_option}${tablespace_option} '${dbname}'"
+  if $createdb_path != undef{
+    warning('Passing "createdb_path" to postgresql::database is deprecated, it can be removed safely for the same behaviour')
+  }
 
-  postgresql_psql { "Check for existence of db '${dbname}'":
-    command => 'SELECT 1',
+  postgresql_psql { "Create db '${dbname}'":
+    command => "CREATE DATABASE ${dbname} WITH OWNER=${owner} ${template_option} ${encoding_option} ${locale_option} ${tablespace_option}",
     unless  => "SELECT datname FROM pg_database WHERE datname='${dbname}'",
     db      => $default_db,
-    port    => $port,
     require => Class['postgresql::server::service']
   }~>
-  exec { $createdb_command :
-    refreshonly => true,
-    user        => $user,
-    logoutput   => on_failure,
-  }~>
 
   # This will prevent users from connecting to the database unless they've been
   #  granted privileges.
   postgresql_psql {"REVOKE ${public_revoke_privilege} ON DATABASE \"${dbname}\" FROM public":
     db          => $default_db,
-    port        => $port,
     refreshonly => true,
   }
 
-  Exec[ $createdb_command ]->
+  Postgresql_psql[ "Create db '${dbname}'" ]->
   postgresql_psql {"UPDATE pg_database SET datistemplate = ${istemplate} WHERE datname = '${dbname}'":
     unless => "SELECT datname FROM pg_database WHERE datname = '${dbname}' AND datistemplate = ${istemplate}",
     db     => $default_db,
@@ -83,7 +98,7 @@ define postgresql::server::database(
       '8.1'   => 'obj_description',
       default => 'shobj_description',
     }
-    Exec[ $createdb_command ]->
+    Postgresql_psql[ "Create db '${dbname}'" ]->
     postgresql_psql {"COMMENT ON DATABASE ${dbname} IS '${comment}'":
       unless => "SELECT pg_catalog.${comment_information_function}(d.oid, 'pg_database') as \"Description\" FROM pg_catalog.pg_database d WHERE datname = '${dbname}' AND pg_catalog.${comment_information_function}(d.oid, 'pg_database') = '${comment}'",
       db     => $dbname,
@@ -92,6 +107,6 @@ define postgresql::server::database(
 
   # Build up dependencies on tablespace
   if($tablespace != undef and defined(Postgresql::Server::Tablespace[$tablespace])) {
-    Postgresql::Server::Tablespace[$tablespace]->Exec[$createdb_command]
+    Postgresql::Server::Tablespace[$tablespace]->Postgresql_psql[ "Create db '${dbname}'" ]
   }
 }

+ 11 - 9
manifests/server/database_grant.pp

@@ -3,16 +3,18 @@ define postgresql::server::database_grant(
   $privilege,
   $db,
   $role,
-  $psql_db   = undef,
-  $psql_user = undef
+  $psql_db          = undef,
+  $psql_user        = undef,
+  $connect_settings = undef,
 ) {
   postgresql::server::grant { "database:${name}":
-    role        => $role,
-    db          => $db,
-    privilege   => $privilege,
-    object_type => 'DATABASE',
-    object_name => $db,
-    psql_db     => $psql_db,
-    psql_user   => $psql_user,
+    role             => $role,
+    db               => $db,
+    privilege        => $privilege,
+    object_type      => 'DATABASE',
+    object_name      => $db,
+    psql_db          => $psql_db,
+    psql_user        => $psql_user,
+    connect_settings => $connect_settings,
   }
 }

+ 11 - 13
manifests/server/extension.pp

@@ -4,19 +4,11 @@ define postgresql::server::extension (
   $ensure = 'present',
   $package_name = undef,
   $package_ensure = undef,
+  $connect_settings = $postgresql::server::default_connect_settings,
 ) {
   $user          = $postgresql::server::user
   $group         = $postgresql::server::group
   $psql_path     = $postgresql::server::psql_path
-  $port          = $postgresql::server::port
-
-  # Set the defaults for the postgresql_psql resource
-  Postgresql_psql {
-    psql_user  => $user,
-    psql_group => $group,
-    psql_path  => $psql_path,
-    port       => $port,
-  }
 
   case $ensure {
     'present': {
@@ -39,10 +31,16 @@ define postgresql::server::extension (
   }
 
   postgresql_psql {"Add ${title} extension to ${database}":
-    db      => $database,
-    command => $command,
-    unless  => "SELECT t.count FROM (SELECT count(extname) FROM pg_extension WHERE extname = '${name}') as t WHERE t.count ${unless_comp} 1",
-    require => Postgresql::Server::Database[$database],
+
+    psql_user        => $user,
+    psql_group       => $group,
+    psql_path        => $psql_path,
+    connect_settings => $connect_settings,
+
+    db               => $database,
+    command          => $command,
+    unless           => "SELECT t.count FROM (SELECT count(extname) FROM pg_extension WHERE extname = '${name}') as t WHERE t.count ${unless_comp} 1",
+    require          => Postgresql::Server::Database[$database],
   }
 
   if $package_name {

+ 29 - 17
manifests/server/grant.pp

@@ -2,13 +2,14 @@
 define postgresql::server::grant (
   $role,
   $db,
-  $privilege     = undef,
-  $object_type   = 'database',
-  $object_name   = undef,
-  $psql_db       = $postgresql::server::default_database,
-  $psql_user     = $postgresql::server::user,
-  $port          = $postgresql::server::port,
-  $onlyif_exists = false,
+  $privilege        = undef,
+  $object_type      = 'database',
+  $object_name      = undef,
+  $psql_db          = $postgresql::server::default_database,
+  $psql_user        = $postgresql::server::user,
+  $port             = $postgresql::server::port,
+  $onlyif_exists    = false,
+  $connect_settings = $postgresql::server::default_connect_settings,
 ) {
   $group     = $postgresql::server::group
   $psql_path = $postgresql::server::psql_path
@@ -20,6 +21,16 @@ define postgresql::server::grant (
   }
 
   validate_bool($onlyif_exists)
+  #
+  # Port, order of precedence: $port parameter, $connect_settings[PGPORT], $postgresql::server::port
+  #
+  if $port != undef {
+    $port_override = $port
+  } elsif $connect_settings != undef and has_key( $connect_settings, 'PGPORT') {
+    $port_override = undef
+  } else {
+    $port_override = $postgresql::server::port
+  }
 
   ## Munge the input values
   $_object_type = upcase($object_type)
@@ -217,15 +228,16 @@ define postgresql::server::grant (
   $grant_cmd = "GRANT ${_privilege} ON ${_object_type} \"${_togrant_object}\" TO
       \"${role}\""
   postgresql_psql { "grant:${name}":
-    command    => $grant_cmd,
-    db         => $on_db,
-    port       => $port,
-    psql_user  => $psql_user,
-    psql_group => $group,
-    psql_path  => $psql_path,
-    unless     => $_unless,
-    onlyif     => $_onlyif,
-    require    => Class['postgresql::server']
+    command          => $grant_cmd,
+    db               => $on_db,
+    port             => $port_override,
+    connect_settings => $connect_settings,
+    psql_user        => $psql_user,
+    psql_group       => $group,
+    psql_path        => $psql_path,
+    unless           => $_unless,
+    onlyif           => $_onlyif,
+    require          => Class['postgresql::server']
   }
 
   if($role != undef and defined(Postgresql::Server::Role[$role])) {
@@ -235,4 +247,4 @@ define postgresql::server::grant (
   if($db != undef and defined(Postgresql::Server::Database[$db])) {
     Postgresql::Server::Database[$db]->Postgresql_psql["grant:${name}"]
   }
-}
+}

+ 24 - 4
manifests/server/role.pp

@@ -4,18 +4,37 @@ define postgresql::server::role(
   $createdb         = false,
   $createrole       = false,
   $db               = $postgresql::server::default_database,
-  $port             = $postgresql::server::port,
+  $port             = undef,
   $login            = true,
   $inherit          = true,
   $superuser        = false,
   $replication      = false,
   $connection_limit = '-1',
-  $username         = $title
+  $username         = $title,
+  $connect_settings = $postgresql::server::default_connect_settings,
 ) {
   $psql_user  = $postgresql::server::user
   $psql_group = $postgresql::server::group
   $psql_path  = $postgresql::server::psql_path
-  $version    = $postgresql::server::_version
+
+  #
+  # Port, order of precedence: $port parameter, $connect_settings[PGPORT], $postgresql::server::port
+  #
+  if $port != undef {
+    $port_override = $port
+  } elsif $connect_settings != undef and has_key( $connect_settings, 'PGPORT') {
+    $port_override = undef
+  } else {
+    $port_override = $postgresql::server::port
+  }
+
+  # If possible use the version of the remote database, otherwise
+  # fallback to our local DB version
+  if $connect_settings != undef and has_key( $connect_settings, 'DBVERSION') {
+    $version = $connect_settings['DBVERSION']
+  } else {
+    $version = $postgresql::server::_version
+  }
 
   $login_sql       = $login       ? { true => 'LOGIN',       default => 'NOLOGIN' }
   $inherit_sql     = $inherit     ? { true => 'INHERIT',     default => 'NOINHERIT' }
@@ -33,10 +52,11 @@ define postgresql::server::role(
 
   Postgresql_psql {
     db         => $db,
-    port       => $port,
+    port       => $port_override,
     psql_user  => $psql_user,
     psql_group => $psql_group,
     psql_path  => $psql_path,
+    connect_settings => $connect_settings,
     require    => [
       Postgresql_psql["CREATE ROLE ${username} ENCRYPTED PASSWORD ****"],
       Class['postgresql::server'],

+ 10 - 2
manifests/server/schema.pp

@@ -13,22 +13,30 @@
 # }
 #
 define postgresql::server::schema(
-  $db,
+  $db = $postgresql::server::default_database,
   $owner  = undef,
   $schema = $title,
+  $connect_settings = $postgresql::server::default_connect_settings,
 ) {
   $user      = $postgresql::server::user
   $group     = $postgresql::server::group
-  $port      = $postgresql::server::port
   $psql_path = $postgresql::server::psql_path
   $version   = $postgresql::server::_version
 
+  # If the connection settings do not contain a port, then use the local server port
+  if $connect_settings != undef and has_key( $connect_settings, 'PGPORT') {
+    $port = undef
+  } else {
+    $port = $postgresql::server::port
+  }
+
   Postgresql_psql {
     db         => $db,
     psql_user  => $user,
     psql_group => $group,
     psql_path  => $psql_path,
     port       => $port,
+    connect_settings => $connect_settings,
   }
 
   $schema_title   = "Create Schema '${title}'"

+ 16 - 14
manifests/server/table_grant.pp

@@ -5,20 +5,22 @@ define postgresql::server::table_grant(
   $table,
   $db,
   $role,
-  $port          = $postgresql::server::port,
-  $psql_db       = undef,
-  $psql_user     = undef,
-  $onlyif_exists = false,
+  $port             = undef,
+  $psql_db          = undef,
+  $psql_user        = undef,
+  $connect_settings = undef,
+  $onlyif_exists    = false,
 ) {
   postgresql::server::grant { "table:${name}":
-    role          => $role,
-    db            => $db,
-    port          => $port,
-    privilege     => $privilege,
-    object_type   => 'TABLE',
-    object_name   => $table,
-    psql_db       => $psql_db,
-    psql_user     => $psql_user,
-    onlyif_exists => $onlyif_exists,
+    role             => $role,
+    db               => $db,
+    port             => $port,
+    privilege        => $privilege,
+    object_type      => 'TABLE',
+    object_name      => $table,
+    psql_db          => $psql_db,
+    psql_user        => $psql_user,
+    onlyif_exists    => $onlyif_exists,
+    connect_settings => $connect_settings,
   }
-}
+}

+ 14 - 6
manifests/server/tablespace.pp

@@ -2,18 +2,26 @@
 define postgresql::server::tablespace(
   $location,
   $owner   = undef,
-  $spcname = $title
+  $spcname = $title,
+  $connect_settings = $postgresql::server::default_connect_settings,
 ) {
   $user      = $postgresql::server::user
   $group     = $postgresql::server::group
-  $port      = $postgresql::server::port
   $psql_path = $postgresql::server::psql_path
 
+  # If the connection settings do not contain a port, then use the local server port
+  if $connect_settings != undef and has_key( $connect_settings, 'PGPORT') {
+    $port = undef
+  } else {
+    $port = $postgresql::server::port
+  }
+
   Postgresql_psql {
-    psql_user  => $user,
-    psql_group => $group,
-    psql_path  => $psql_path,
-    port       => $port,
+    psql_user        => $user,
+    psql_group       => $group,
+    psql_path        => $psql_path,
+    port             => $port,
+    connect_settings => $connect_settings,
   }
 
   if ($owner == undef) {

+ 16 - 1
manifests/validate_db_connection.pp

@@ -9,6 +9,7 @@ define postgresql::validate_db_connection(
   $database_password = undef,
   $database_username = undef,
   $database_port     = undef,
+  $connect_settings  = undef,
   $run_as            = undef,
   $sleep             = 2,
   $tries             = 10,
@@ -37,7 +38,7 @@ define postgresql::validate_db_connection(
     undef   => "--dbname ${postgresql::params::default_database} ",
     default => "--dbname ${database_name} ",
   }
-  $env = $database_password ? {
+  $pass_env = $database_password ? {
     undef   => undef,
     default => "PGPASSWORD=${database_password}",
   }
@@ -48,7 +49,21 @@ define postgresql::validate_db_connection(
   # time it takes to run each psql command.
   $timeout = (($sleep + 2) * $tries)
 
+  # Combine $database_password and $connect_settings into an array of environment
+  # variables, ensure $database_password is last, allowing it to override a password
+  # from the $connect_settings hash
+  if $connect_settings != undef {
+    if $pass_env != undef {
+      $env = concat(join_keys_to_values( $connect_settings, '='), $pass_env)
+    } else {
+      $env = join_keys_to_values( $connect_settings, '=')
+    }
+  } else {
+    $env = $pass_env
+  }
+
   $exec_name = "validate postgres connection for ${database_username}@${database_host}:${database_port}/${database_name}"
+
   exec { $exec_name:
     command     => "echo 'Unable to connect to defined database using: ${cmd}' && false",
     unless      => $validate_cmd,

+ 18 - 0
spec/acceptance/nodesets/centos-64-x64-2-hosts.yml

@@ -0,0 +1,18 @@
+HOSTS:
+  database:
+    roles:
+      - default
+      - database
+    platform: el-6-x86_64
+    box : centos-64-x64-vbox4210-nocm
+    box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box
+    hypervisor : vagrant
+  client:
+    roles:
+      - client
+    platform: el-6-x86_64
+    box : centos-64-x64-vbox4210-nocm
+    box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box
+    hypervisor : vagrant
+CONFIG:
+ type: foss

+ 72 - 0
spec/acceptance/remote_access_spec.rb

@@ -0,0 +1,72 @@
+require 'spec_helper_acceptance'
+
+describe 'remote-access', :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do
+
+  if hosts.length > 1
+    describe "configuring multi-node postgresql" do
+
+      # Get the database's IP to connect to from the client
+      let(:database_ip_address) do
+        hosts_as('database').inject({}) do |memo,host|
+          fact_on host, "ipaddress_eth1"
+        end
+      end
+
+      hosts_as('database').each do |host|
+        it "should be able to configure a host as database on #{host}" do
+          pp = <<-EOS
+          # Stop firewall so we can easily connect
+          service {'iptables':
+            ensure => 'stopped',
+          }
+
+          class { 'postgresql::server':
+            ip_mask_allow_all_users => '0.0.0.0/0',
+            listen_addresses        => '*',
+          }
+
+          postgresql::server::db { 'puppet':
+            user     => 'puppet',
+            password => postgresql_password('puppet', 'puppet'),
+          }
+
+          postgresql::server::pg_hba_rule { 'allow full yolo access password':
+            type        => 'host',
+            database    => 'all',
+            user        => 'all',
+            address     => '0.0.0.0/0',
+            auth_method => 'password',
+            order       => '002',
+          }
+          EOS
+          apply_manifest_on(host, pp, :catch_failures => true)
+        end
+      end
+
+      hosts_as('client').each do |host|
+        it "should be able to configure a host as client on #{host} and then access database" do
+          pp = <<-EOS
+          class { 'postgresql::client':}
+
+          $connection_settings = {
+                                       'PGUSER'     => "puppet",
+                                       'PGPASSWORD' => "puppet",
+                                       'PGHOST'     => "#{database_ip_address}",
+                                       'PGPORT'     => "5432",
+                                       'PGDATABASE' => "puppet",
+                                    }
+
+          postgresql_psql { 'run using connection_settings':
+            command             => 'select 1',
+            psql_user           => 'root',
+            psql_group          => 'root',
+            connect_settings    => $connection_settings,
+          }
+          EOS
+          apply_manifest_on(host, pp, :catch_failures => true)
+        end
+      end
+
+    end
+  end
+end

+ 45 - 3
spec/unit/defines/server/database_spec.rb

@@ -21,11 +21,53 @@ describe 'postgresql::server::database', :type => :define do
   end
 
   it { is_expected.to contain_postgresql__server__database('test') }
-  it { is_expected.to contain_postgresql_psql("Check for existence of db 'test'") }
+  it { is_expected.to contain_postgresql_psql("Create db 'test'") }
 
   context "with comment set to 'test comment'" do
-    let (:params) {{ :comment => 'test comment' }}
+    let (:params) {{ :comment => 'test comment',
+                     :connect_settings => {} }}
+
+    it { is_expected.to contain_postgresql_psql("COMMENT ON DATABASE test IS 'test comment'").with_connect_settings( {} ) }
+  end
+
+  context "with specific db connection settings - default port" do
+    let :pre_condition do
+      "class {'postgresql::server':}"
+    end
+
+    let (:params) {{ :connect_settings => { 'PGHOST'    => 'postgres-db-server',
+                                            'DBVERSION' => '9.1', }}}
+
+    it { is_expected.to contain_postgresql_psql("Create db 'test'").with_connect_settings( { 'PGHOST'    => 'postgres-db-server','DBVERSION' => '9.1' } ).with_port( 5432 ) }
+  end
+
+  context "with specific db connection settings - including port" do
+    let :pre_condition do
+      "class {'postgresql::globals':}
+
+       class {'postgresql::server':}"
+    end
+
+    let (:params) {{ :connect_settings => { 'PGHOST'    => 'postgres-db-server',
+                                            'DBVERSION' => '9.1',
+                                            'PGPORT'    => '1234' }}}
+
+    it { is_expected.to contain_postgresql_psql("Create db 'test'").with_connect_settings( { 'PGHOST'    => 'postgres-db-server','DBVERSION' => '9.1','PGPORT'    => '1234' } ).with_port( nil ) }
+
+  end
+
+  context "with global db connection settings - including port" do
+    let :pre_condition do
+      "class {'postgresql::globals':
+           default_connect_settings => { 'PGHOST'    => 'postgres-db-server',
+                                         'DBVERSION' => '9.2',
+                                         'PGPORT'    => '1234' }
+       }
+
+       class {'postgresql::server':}"
+    end
+
+    it { is_expected.to contain_postgresql_psql("Create db 'test'").with_connect_settings( { 'PGHOST'    => 'postgres-db-server','DBVERSION' => '9.2','PGPORT'    => '1234' } ).with_port( nil ) }
 
-    it { is_expected.to contain_postgresql_psql("COMMENT ON DATABASE test IS 'test comment'") }
   end
 end

+ 58 - 1
spec/unit/defines/server/grant_spec.rb

@@ -76,4 +76,61 @@ describe 'postgresql::server::grant', :type => :define do
                             'unless' => "SELECT 1 FROM (\n        SELECT sequence_name\n        FROM information_schema.sequences\n        WHERE sequence_schema='public'\n          EXCEPT DISTINCT\n        SELECT object_name as sequence_name\n        FROM information_schema.role_usage_grants\n        WHERE object_type='SEQUENCE'\n        AND grantee='test'\n        AND object_schema='public'\n        AND privilege_type='USAGE'\n        ) P\n        HAVING count(P.sequence_name) = 0",
                           }) }
   end
-end
+
+  context "with specific db connection settings - default port" do
+    let :params do
+      {
+        :db => 'test',
+        :role => 'test',
+        :connect_settings => { 'PGHOST'    => 'postgres-db-server',
+                               'DBVERSION' => '9.1', },
+      }
+    end
+
+    let :pre_condition do
+      "class {'postgresql::server':}"
+    end
+
+    it { is_expected.to contain_postgresql__server__grant('test') }
+    it { is_expected.to contain_postgresql_psql("grant:test").with_connect_settings( { 'PGHOST'    => 'postgres-db-server','DBVERSION' => '9.1' } ).with_port( 5432 ) }
+  end
+
+  context "with specific db connection settings - including port" do
+    let :params do
+      {
+        :db => 'test',
+        :role => 'test',
+        :connect_settings => { 'PGHOST'    => 'postgres-db-server',
+                               'DBVERSION' => '9.1',
+                               'PGPORT'    => '1234', },
+      }
+    end
+
+    let :pre_condition do
+      "class {'postgresql::server':}"
+    end
+
+    it { is_expected.to contain_postgresql__server__grant('test') }
+    it { is_expected.to contain_postgresql_psql("grant:test").with_connect_settings( { 'PGHOST'    => 'postgres-db-server','DBVERSION' => '9.1','PGPORT'    => '1234' } ) }
+  end
+
+  context "with specific db connection settings - port overriden by explicit parameter" do
+    let :params do
+      {
+        :db => 'test',
+        :role => 'test',
+        :connect_settings => { 'PGHOST'    => 'postgres-db-server',
+                               'DBVERSION' => '9.1',
+             'PGPORT'    => '1234', },
+        :port => '5678',
+      }
+    end
+
+    let :pre_condition do
+      "class {'postgresql::server':}"
+    end
+
+    it { is_expected.to contain_postgresql__server__grant('test') }
+    it { is_expected.to contain_postgresql_psql("grant:test").with_connect_settings( { 'PGHOST'    => 'postgres-db-server','DBVERSION' => '9.1','PGPORT'    => '1234' } ).with_port( '5678' ) }
+  end
+end

+ 93 - 0
spec/unit/defines/server/role_spec.rb

@@ -20,6 +20,7 @@ describe 'postgresql::server::role', :type => :define do
   let :params do
     {
       :password_hash => 'new-pa$s',
+      :connect_settings => {},
     }
   end
 
@@ -33,6 +34,8 @@ describe 'postgresql::server::role', :type => :define do
       'command'     => "CREATE ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD' LOGIN NOCREATEROLE NOCREATEDB NOSUPERUSER  CONNECTION LIMIT -1",
       'environment' => "NEWPGPASSWD=new-pa$s",
       'unless'      => "SELECT rolname FROM pg_roles WHERE rolname='test'",
+      'port'        => "5432",
+      'connect_settings' => {},
     })
   end
   it 'should have alter role for "test" user with password as ****' do
@@ -40,6 +43,96 @@ describe 'postgresql::server::role', :type => :define do
       'command'     => "ALTER ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD'",
       'environment' => "NEWPGPASSWD=new-pa$s",
       'unless'      => "SELECT usename FROM pg_shadow WHERE usename='test' and passwd='md5b6f7fcbbabb4befde4588a26c1cfd2fa'",
+      'port'        => "5432",
+      'connect_settings' => {},
     })
   end
+
+  context "with specific db connection settings - default port" do
+    let :params do
+      {
+        :password_hash => 'new-pa$s',
+        :connect_settings => { 'PGHOST'     => 'postgres-db-server',
+	                       'DBVERSION'  => '9.1',
+	                       'PGUSER'     => 'login-user',
+			       'PGPASSWORD' => 'login-pass' },
+      }
+    end
+
+    let :pre_condition do
+     "class {'postgresql::server':}"
+    end
+
+    it { is_expected.to contain_postgresql__server__role('test') }
+    it 'should have create role for "test" user with password as ****' do
+      is_expected.to contain_postgresql_psql('CREATE ROLE test ENCRYPTED PASSWORD ****').with({
+        'command'     => "CREATE ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD' LOGIN NOCREATEROLE NOCREATEDB NOSUPERUSER  CONNECTION LIMIT -1",
+        'environment' => "NEWPGPASSWD=new-pa$s",
+        'unless'      => "SELECT rolname FROM pg_roles WHERE rolname='test'",
+        'port'        => "5432",
+
+        'connect_settings' => { 'PGHOST'     => 'postgres-db-server',
+                                'DBVERSION'  => '9.1',
+                                'PGUSER'     => 'login-user',
+                                'PGPASSWORD' => 'login-pass' },
+      })
+    end
+    it 'should have alter role for "test" user with password as ****' do
+      is_expected.to contain_postgresql_psql('ALTER ROLE test ENCRYPTED PASSWORD ****').with({
+        'command'     => "ALTER ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD'",
+        'environment' => "NEWPGPASSWD=new-pa$s",
+        'unless'      => "SELECT usename FROM pg_shadow WHERE usename='test' and passwd='md5b6f7fcbbabb4befde4588a26c1cfd2fa'",
+        'port'        => "5432",
+
+        'connect_settings' => { 'PGHOST'     => 'postgres-db-server',
+                                'DBVERSION'  => '9.1',
+                                'PGUSER'     => 'login-user',
+                                'PGPASSWORD' => 'login-pass' },
+      })
+    end
+  end
+
+  context "with specific db connection settings - including port" do
+    let :params do
+      {
+        :password_hash => 'new-pa$s',
+        :connect_settings => { 'PGHOST'     => 'postgres-db-server',
+	                       'DBVERSION'  => '9.1',
+	                       'PGPORT'     => '1234',
+	                       'PGUSER'     => 'login-user',
+			       'PGPASSWORD' => 'login-pass' },
+      }
+    end
+
+    let :pre_condition do
+     "class {'postgresql::server':}"
+    end
+
+    it { is_expected.to contain_postgresql__server__role('test') }
+    it 'should have create role for "test" user with password as ****' do
+      is_expected.to contain_postgresql_psql('CREATE ROLE test ENCRYPTED PASSWORD ****').with({
+        'command'     => "CREATE ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD' LOGIN NOCREATEROLE NOCREATEDB NOSUPERUSER  CONNECTION LIMIT -1",
+        'environment' => "NEWPGPASSWD=new-pa$s",
+        'unless'      => "SELECT rolname FROM pg_roles WHERE rolname='test'",
+        'connect_settings' => { 'PGHOST'     => 'postgres-db-server',
+                                'DBVERSION'  => '9.1',
+                                'PGPORT'     => '1234',
+                                'PGUSER'     => 'login-user',
+                                'PGPASSWORD' => 'login-pass' },
+      })
+    end
+    it 'should have alter role for "test" user with password as ****' do
+      is_expected.to contain_postgresql_psql('ALTER ROLE test ENCRYPTED PASSWORD ****').with({
+        'command'     => "ALTER ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD'",
+        'environment' => "NEWPGPASSWD=new-pa$s",
+        'unless'      => "SELECT usename FROM pg_shadow WHERE usename='test' and passwd='md5b6f7fcbbabb4befde4588a26c1cfd2fa'",
+        'connect_settings' => { 'PGHOST'     => 'postgres-db-server',
+                                'DBVERSION'  => '9.1',
+                                'PGPORT'     => '1234',
+                                'PGUSER'     => 'login-user',
+                                'PGPASSWORD' => 'login-pass' },
+      })
+    end
+  end
+
 end

+ 18 - 5
spec/unit/puppet/provider/postgresql_psql/ruby_spec.rb

@@ -15,7 +15,7 @@ describe Puppet::Type.type(:postgresql_psql).provider(:ruby) do
       it "executes with the given psql_path on the given DB" do
         expect(provider).to receive(:run_command).with(['psql', '-d',
           attributes[:db], '-t', '-c', '"SELECT \'something\' as \"Custom column\""'], 'postgres',
-          'postgres')
+          'postgres', {})
 
         provider.run_sql_command('SELECT \'something\' as "Custom column"')
       end
@@ -33,7 +33,7 @@ describe Puppet::Type.type(:postgresql_psql).provider(:ruby) do
         expect(Dir).to receive(:chdir).with(attributes[:cwd]).and_yield
         expect(provider).to receive(:run_command).with([attributes[:psql_path],
           '-d', attributes[:db], '-t', '-c', '"SELECT \'something\' as \"Custom column\""'],
-          attributes[:psql_user], attributes[:psql_group])
+          attributes[:psql_user], attributes[:psql_group], {})
 
         provider.run_sql_command('SELECT \'something\' as "Custom column"')
       end
@@ -46,7 +46,7 @@ describe Puppet::Type.type(:postgresql_psql).provider(:ruby) do
       it "executes with the given search_path" do
         expect(provider).to receive(:run_command).with(['psql', '-t', '-c',
           '"set search_path to schema1; SELECT \'something\' as \"Custom column\""'],
-          'postgres', 'postgres')
+          'postgres', 'postgres', {})
 
         provider.run_sql_command('SELECT \'something\' as "Custom column"')
       end
@@ -60,7 +60,8 @@ describe Puppet::Type.type(:postgresql_psql).provider(:ruby) do
         expect(provider).to receive(:run_command).with(['psql', '-t', '-c',
           '"set search_path to schema1,schema2; SELECT \'something\' as \"Custom column\""'],
           'postgres',
-          'postgres'
+          'postgres',
+          {}
         )
 
         provider.run_sql_command('SELECT \'something\' as "Custom column"')
@@ -74,7 +75,19 @@ describe Puppet::Type.type(:postgresql_psql).provider(:ruby) do
         expect(provider).to receive(:run_command).with(["psql",
         "-p", "5555",
         "-t", "-c", "\"SELECT something\""],
-        "postgres", "postgres")
+        "postgres", "postgres", {} )
+
+        provider.run_sql_command("SELECT something")
+      end
+    end
+    describe "with connect_settings" do
+      let(:attributes) do { :connect_settings => { 'PGHOST' => '127.0.0.1' } } end
+
+      it "executes with the given host" do
+        expect(provider).to receive(:run_command).with(["psql",
+          "-t", "-c",
+          "\"SELECT something\""],
+          "postgres", "postgres", { 'PGHOST' => '127.0.0.1' } )
 
         provider.run_sql_command("SELECT something")
       end

+ 13 - 11
spec/unit/puppet/type/postgresql_psql_spec.rb

@@ -1,7 +1,7 @@
 require 'spec_helper'
 
 describe Puppet::Type.type(:postgresql_psql), "when validating attributes" do
-  [:name, :unless, :db, :psql_path, :psql_user, :psql_group].each do |attr|
+  [:name, :unless, :db, :psql_path, :psql_user, :psql_group, :connect_settings].each do |attr|
     it "should have a #{attr} parameter" do
       expect(Puppet::Type.type(:postgresql_psql).attrtype(attr)).to eq(:param)
     end
@@ -21,16 +21,18 @@ describe Puppet::Type.type(:postgresql_psql), :unless => Puppet.features.microso
 
   describe "available attributes" do
     {
-      :name        => "rspec",
-      :command     => "SELECT stuff",
-      :unless      => "SELECT other,stuff",
-      :db          => "postgres",
-      :psql_path   => "/bin/false",
-      :psql_user   => "postgres",
-      :psql_group  => "postgres",
-      :cwd         => "/var/lib",
-      :refreshonly => :true,
-      :search_path => [ "schema1", "schema2"]
+      :name             => "rspec",
+      :command          => "SELECT stuff",
+      :unless           => "SELECT other,stuff",
+      :db               => "postgres",
+      :psql_path        => "/bin/false",
+      :psql_user        => "postgres",
+      :psql_group       => "postgres",
+      :cwd              => "/var/lib",
+      :refreshonly      => :true,
+      :search_path      => [ "schema1", "schema2"],
+      :connect_settings => { 'PGHOST' => 'postgres-db-server',
+                             'DBVERSION' => '9.1', },
     }.each do |attr, value|
       context attr do
         let(:attributes) do { attr => value } end