diff --git a/README.md b/README.md index 02b5bd7..9cff390 100644 --- a/README.md +++ b/README.md @@ -792,7 +792,7 @@ Defines the value for the setting. #### postgresql::server::db -Creates a local database, user, and assigns necessary permissions. +Creates or modifies a local database, user, and assigns necessary permissions. ##### `comment` @@ -842,9 +842,13 @@ Specifies the name of the template database from which to build this database. D User to create and assign access to the database upon creation. Mandatory. +##### `change_ownership` + +Specifies whether to create a new database or change the owner of an existing one. Default: false. + #### postgresql::server::database -Creates a database with no users and no permissions. +Creates or modifies a database with no users and no permissions. ##### `dbname` @@ -874,6 +878,10 @@ Sets tablespace for where to create this database. Default: The defaults defined Specifies the name of the template database from which to build this database. Default: `template0`. +##### `change_ownership` + +Specifies whether to create a new database or change the owner of an existing one. Default: false. + #### postgresql::server::database_grant Manages grant-based access privileges for users, wrapping the `postgresql::server::database_grant` for database specific permissions. Consult the [PostgreSQL documentation for `grant`](http://www.postgresql.org/docs/current/static/sql-grant.html) for more information. @@ -1114,7 +1122,7 @@ Defines the username of the role to create. Defaults to the namevar. #### postgresql::server::schema -Creates a schema. +Creates or modifies a schema. ##### `connect_settings` @@ -1132,6 +1140,10 @@ Sets the default owner of the schema. Sets the name of the schema. Defaults to the namevar. +##### `change_ownership` + +Specifies whether to create a new schema or change the owner of an existing one. Default: false. + #### postgresql::server::table_grant Manages grant-based access privileges for users. Consult the PostgreSQL documentation for `grant` for more information. diff --git a/manifests/server/database.pp b/manifests/server/database.pp index fab12b5..0d453bc 100644 --- a/manifests/server/database.pp +++ b/manifests/server/database.pp @@ -9,6 +9,7 @@ define postgresql::server::database( $locale = $postgresql::server::locale, $istemplate = false, $connect_settings = $postgresql::server::default_connect_settings, + $change_ownership = false, ) { $createdb_path = $postgresql::server::createdb_path $user = $postgresql::server::user @@ -40,73 +41,87 @@ define postgresql::server::database( connect_settings => $connect_settings, } - # Optionally set the locale switch. Older versions of createdb may not accept - # --locale, so if the parameter is undefined its safer not to pass it. - if ($version != '8.1') { - $locale_option = $locale ? { - undef => '', - default => "LC_COLLATE='${locale}' LC_CTYPE='${locale}'", + if $change_ownership { + # Change owner for existing database + if !$owner { + fail('Must specify an owner to change database ownership.') + } + postgresql_psql { "Change owner of db '${dbname}' to ${owner}": + command => "ALTER DATABASE \"${dbname}\" OWNER TO ${owner}", + onlyif => "SELECT datname FROM pg_database WHERE datname='${dbname}'", + db => $default_db, + require => Class['postgresql::server::service'] } - $public_revoke_privilege = 'CONNECT' } else { - $locale_option = '' - $public_revoke_privilege = 'ALL' - } - - $template_option = $template ? { - undef => '', - default => "TEMPLATE=\"${template}\"", - } - - $encoding_option = $encoding ? { - undef => '', - default => "ENCODING='${encoding}'", - } - - $tablespace_option = $tablespace ? { - undef => '', - default => "TABLESPACE=\"${tablespace}\"", - } - - if $createdb_path != undef{ - warning('Passing "createdb_path" to postgresql::database is deprecated, it can be removed safely for the same behaviour') - } - - 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, - require => Class['postgresql::server::service'] - }~> - - # 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, - refreshonly => true, - } - - 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, - } - - if $comment { - # The shobj_description function was only introduced with 8.2 - $comment_information_function = $version ? { - '8.1' => 'obj_description', - default => 'shobj_description', + # Create a new database + # Optionally set the locale switch. Older versions of createdb may not accept + # --locale, so if the parameter is undefined its safer not to pass it. + if ($version != '8.1') { + $locale_option = $locale ? { + undef => '', + default => "LC_COLLATE='${locale}' LC_CTYPE='${locale}'", + } + $public_revoke_privilege = 'CONNECT' + } else { + $locale_option = '' + $public_revoke_privilege = 'ALL' } + + $template_option = $template ? { + undef => '', + default => "TEMPLATE=\"${template}\"", + } + + $encoding_option = $encoding ? { + undef => '', + default => "ENCODING='${encoding}'", + } + + $tablespace_option = $tablespace ? { + undef => '', + default => "TABLESPACE=\"${tablespace}\"", + } + + if $createdb_path != undef{ + warning('Passing "createdb_path" to postgresql::database is deprecated, it can be removed safely for the same behaviour') + } + + 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, + require => Class['postgresql::server::service'] + }~> + + # 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, + refreshonly => true, + } + 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, + 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, } - } - # Build up dependencies on tablespace - if($tablespace != undef and defined(Postgresql::Server::Tablespace[$tablespace])) { - Postgresql::Server::Tablespace[$tablespace]->Postgresql_psql[ "Create db '${dbname}'" ] + if $comment { + # The shobj_description function was only introduced with 8.2 + $comment_information_function = $version ? { + '8.1' => 'obj_description', + default => 'shobj_description', + } + 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, + } + } + + # Build up dependencies on tablespace + if($tablespace != undef and defined(Postgresql::Server::Tablespace[$tablespace])) { + Postgresql::Server::Tablespace[$tablespace]->Postgresql_psql[ "Create db '${dbname}'" ] + } } } diff --git a/manifests/server/db.pp b/manifests/server/db.pp index b4c1232..b170ee5 100644 --- a/manifests/server/db.pp +++ b/manifests/server/db.pp @@ -3,26 +3,28 @@ define postgresql::server::db ( $user, $password, - $comment = undef, - $dbname = $title, - $encoding = $postgresql::server::encoding, - $locale = $postgresql::server::locale, - $grant = 'ALL', - $tablespace = undef, - $template = 'template0', - $istemplate = false, - $owner = undef + $comment = undef, + $dbname = $title, + $encoding = $postgresql::server::encoding, + $locale = $postgresql::server::locale, + $grant = 'ALL', + $tablespace = undef, + $template = 'template0', + $istemplate = false, + $owner = undef, + $change_ownership = false, ) { if ! defined(Postgresql::Server::Database[$dbname]) { postgresql::server::database { $dbname: - comment => $comment, - encoding => $encoding, - tablespace => $tablespace, - template => $template, - locale => $locale, - istemplate => $istemplate, - owner => $owner, + comment => $comment, + encoding => $encoding, + tablespace => $tablespace, + template => $template, + locale => $locale, + istemplate => $istemplate, + owner => $owner, + change_ownership => $change_ownership, } } diff --git a/manifests/server/schema.pp b/manifests/server/schema.pp index 74a00de..bbf4bc4 100644 --- a/manifests/server/schema.pp +++ b/manifests/server/schema.pp @@ -17,6 +17,7 @@ define postgresql::server::schema( $owner = undef, $schema = $title, $connect_settings = $postgresql::server::default_connect_settings, + $change_ownership = false, ) { $user = $postgresql::server::user $group = $postgresql::server::group @@ -39,19 +40,33 @@ define postgresql::server::schema( connect_settings => $connect_settings, } - $schema_title = "Create Schema '${title}'" + $schema_exists = "SELECT nspname FROM pg_namespace WHERE nspname='${schema}'" $authorization = $owner? { undef => '', default => "AUTHORIZATION \"${owner}\"", } - $schema_command = "CREATE SCHEMA \"${schema}\" ${authorization}" - $unless = "SELECT nspname FROM pg_namespace WHERE nspname='${schema}'" - - postgresql_psql { $schema_title: - command => $schema_command, - unless => $unless, - require => Class['postgresql::server'], + if $change_ownership { + # Change owner for existing schema + if !$owner { + fail('Must specify an owner to change schema ownership.') + } + $schema_title = "Change owner of schema '${schema}' to ${owner}" + $schema_command = "ALTER SCHEMA \"${schema}\" OWNER TO ${owner}" + postgresql_psql { $schema_title: + command => $schema_command, + onlyif => $schema_exists, + require => Class['postgresql::server'], + } + } else { + # Create a new schema + $schema_title = "Create Schema '${title}'" + $schema_command = "CREATE SCHEMA \"${schema}\" ${authorization}" + postgresql_psql { $schema_title: + command => $schema_command, + unless => $schema_exists, + require => Class['postgresql::server'], + } } if($owner != undef and defined(Postgresql::Server::Role[$owner])) { diff --git a/spec/unit/defines/server/database_spec.rb b/spec/unit/defines/server/database_spec.rb index 232ee31..1148cc7 100644 --- a/spec/unit/defines/server/database_spec.rb +++ b/spec/unit/defines/server/database_spec.rb @@ -69,4 +69,11 @@ describe 'postgresql::server::database', :type => :define do 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 ) } end + + context "with change_ownership set to true" do + let (:params) {{ :change_ownership => true, + :owner => 'test_owner' }} + + it { is_expected.to contain_postgresql_psql("Change owner of db 'test' to test_owner") } + end end diff --git a/spec/unit/defines/server/schema_spec.rb b/spec/unit/defines/server/schema_spec.rb index f5d106f..4589f74 100644 --- a/spec/unit/defines/server/schema_spec.rb +++ b/spec/unit/defines/server/schema_spec.rb @@ -29,4 +29,16 @@ describe 'postgresql::server::schema', :type => :define do end it { should contain_postgresql__server__schema('test') } + + context "with change_ownership set to true" do + let :params do + { + :owner => 'nate', + :db => 'natedb', + :change_ownership => true, + } + end + + it { is_expected.to contain_postgresql_psql("Change owner of schema 'test' to nate") } + end end