diff --git a/manifests/server/default_privileges.pp b/manifests/server/default_privileges.pp index 9cc9093..4a6f846 100644 --- a/manifests/server/default_privileges.pp +++ b/manifests/server/default_privileges.pp @@ -1,175 +1,191 @@ # @summary Manage a database defaults privileges. Only works with PostgreSQL version 9.6 and above. # # @param target_role Target role whose created objects will receive the default privileges. Defaults to the current user. # @param ensure Specifies whether to grant or revoke the privilege. # @param role Specifies the role or user whom you are granting access to. # @param db Specifies the database to which you are granting access. # @param object_type Specify target object type: 'FUNCTIONS', 'ROUTINES', 'SEQUENCES', 'TABLES', 'TYPES'. # @param privilege Specifies comma-separated list of privileges to grant. Valid options: depends on object type. # @param schema Target schema. Defaults to 'public'. Can be set to '' to apply to all schemas. # @param psql_db Defines the database to execute the grant against. This should not ordinarily be changed from the default. # @param psql_user Specifies the OS user for running psql. Default value: The default user for the module, usually 'postgres'. # @param psql_path Specifies the OS user for running psql. Default value: The default user for the module, usually 'postgres'. # @param port Specifies the port to access the server. Default value: The default user for the module, usually '5432'. # @param connect_settings Specifies a hash of environment variables used when connecting to a remote server. # @param psql_path Specifies the path to the psql command. define postgresql::server::default_privileges ( Optional[String] $target_role = undef, String $role, String $db, String $privilege, Pattern[ /(?i:^FUNCTIONS$)/, /(?i:^ROUTINES$)/, /(?i:^SEQUENCES$)/, /(?i:^TABLES$)/, - /(?i:^TYPES$)/ + /(?i:^TYPES$)/, + /(?i:^SCHEMAS$)/ ] $object_type, String $schema = 'public', String $psql_db = $postgresql::server::default_database, String $psql_user = $postgresql::server::user, Integer $port = $postgresql::server::port, Hash $connect_settings = $postgresql::server::default_connect_settings, Enum['present', 'absent' ] $ensure = 'present', String $group = $postgresql::server::group, String $psql_path = $postgresql::server::psql_path, ) { # 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 (versioncmp($version, '9.6') == -1) { fail 'Default_privileges is only useable with PostgreSQL >= 9.6' } case $ensure { default: { # default is 'present' $sql_command = 'ALTER DEFAULT PRIVILEGES%s%s GRANT %s ON %s TO "%s"' $unless_is = true } 'absent': { $sql_command = 'ALTER DEFAULT PRIVILEGES%s%s REVOKE %s ON %s FROM "%s"' $unless_is = false } } # # 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 $target_role != undef { $_target_role = " FOR ROLE $target_role" $_check_target_role = "/$target_role" } else { $_target_role = '' $_check_target_role = '' } if $schema != '' { $_schema = " IN SCHEMA $schema" $_check_schema = " AND nspname = '$schema'" } else { $_schema = '' $_check_schema = ' AND nspname IS NULL' } ## Munge the input values $_object_type = upcase($object_type) $_privilege = upcase($privilege) case $_object_type { # Routines and functions ends up with the same definition Pattern[ /^ROUTINES$/, /^FUNCTIONS$/, ]: { case $_privilege { Pattern[ /^ALL$/, /^EXECUTE$/, ]: { $_check_privilege = 'X' } default: { fail('Illegal value for $privilege parameter') } } $_check_type = 'f' } 'SEQUENCES': { case $_privilege { /^(ALL)$/: { $_check_privilege = 'rwU' } /^SELECT$/: { $_check_privilege = 'r'} /^UPDATE$/: { $_check_privilege = 'w'} /^USAGE$/: { $_check_privilege = 'U'} default: { fail('Illegal value for $privilege parameter') } } $_check_type = 'S' } 'TABLES': { case $_privilege { /^ALL$/: { $_check_privilege = 'arwdDxt' } /^DELETE$/: { $_check_privilege = 'd' } /^INSERT$/: { $_check_privilege = 'a' } /^REFERENCES$/: { $_check_privilege = 'x' } /^SELECT$/: { $_check_privilege = 'r' } /^TRIGGER$/: { $_check_privilege = 'd' } /^TRUNCATE$/: { $_check_privilege = 'D' } /^UPDATE$/: { $_check_privilege = 'w' } default: { fail('Illegal value for $privilege parameter') } } $_check_type = 'r' } 'TYPES': { case $_privilege { /^(ALL|USAGE)$/: { $_check_privilege = 'U'} default: { fail('Illegal value for $privilege parameter') } } $_check_type = 'T' } + 'SCHEMAS': { + if (versioncmp($version, '10') == -1) { + fail 'Default_privileges on schemas is only supported on PostgreSQL >= 10.0' + } + if $schema != '' { + fail('Cannot alter default schema permissions within a schema') + } + case $_privilege { + /^ALL$/: { $_check_privilege = 'UC' } + /^USAGE$/: { $_check_privilege = 'U' } + /^CREATE$/: { $_check_privilege = 'C' } + default: { fail('Illegal value for $privilege parameter') } + } + $_check_type = 'n' + } default: { fail("Missing privilege validation for object type ${_object_type}") } } $_unless = $ensure ? { 'absent' => "SELECT 1 WHERE NOT EXISTS (SELECT * FROM pg_default_acl AS da LEFT JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE '%s=%s%s' = ANY (defaclacl)%s and defaclobjtype = '%s')", default => "SELECT 1 WHERE EXISTS (SELECT * FROM pg_default_acl AS da LEFT JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE '%s=%s%s' = ANY (defaclacl)%s and defaclobjtype = '%s')" } $unless_cmd = sprintf($_unless, $role, $_check_privilege, $_check_target_role, $_check_schema, $_check_type) $grant_cmd = sprintf($sql_command, $_target_role, $_schema, $_privilege, $_object_type, $role) postgresql_psql { "default_privileges:${name}": command => $grant_cmd, db => $db, port => $port_override, connect_settings => $connect_settings, psql_user => $psql_user, psql_group => $group, psql_path => $psql_path, unless => $unless_cmd, environment => 'PGOPTIONS=--client-min-messages=error' } if($role != undef and defined(Postgresql::Server::Role[$role])) { Postgresql::Server::Role[$role]->Postgresql_psql["default_privileges:${name}"] } if($db != undef and defined(Postgresql::Server::Database[$db])) { Postgresql::Server::Database[$db]->Postgresql_psql["default_privileges:${name}"] } } diff --git a/spec/acceptance/server/default_privileges_spec.rb b/spec/acceptance/server/default_privileges_spec.rb index db474da..c3eac9c 100644 --- a/spec/acceptance/server/default_privileges_spec.rb +++ b/spec/acceptance/server/default_privileges_spec.rb @@ -1,299 +1,383 @@ # frozen_string_literal: true require 'spec_helper_acceptance' describe 'postgresql::server::default_privileges:' do let(:db) { 'grant_role_test' } let(:user) { 'psql_grant_role_tester' } let(:group) { 'test_group' } let(:password) { 'psql_grant_role_pw' } # Check that the default privileges were revoked let(:check_command) do "SELECT * FROM pg_default_acl a LEFT JOIN pg_namespace b ON a.defaclnamespace = b.oid WHERE '#{user}=arwdDxt' = ANY (defaclacl) AND nspname = 'public' and defaclobjtype = 'r';" end let(:pp_one) do <<-MANIFEST.unindent $db = #{db} $user = #{user} $group = #{group} $password = #{password} class { 'postgresql::server': } postgresql::server::role { $user: password_hash => postgresql::postgresql_password($user, $password), } postgresql::server::database { $db: require => Postgresql::Server::Role[$user], } # Set default privileges on tables postgresql::server::default_privileges { "alter default privileges grant all on tables to ${user}": db => $db, role => $user, privilege => 'ALL', object_type => 'TABLES', require => Postgresql::Server::Database[$db], } MANIFEST end let(:pp_two) do <<-MANIFEST $db = #{db} $user = #{user} $group = #{group} $password = #{password} class { 'postgresql::server': } postgresql::server::role { $user: password_hash => postgresql::postgresql_password($user, $password), } postgresql::server::database { $db: require => Postgresql::Server::Role[$user], } # Removes default privileges on tables postgresql::server::default_privileges { "alter default privileges revoke all on tables for ${user}": db => $db, role => $user, privilege => 'ALL', object_type => 'TABLES', ensure => 'absent', require => Postgresql::Server::Database[$db], } MANIFEST end let(:target_user) { 'target_role_user' } let(:target_password) { 'target_role_password' } let(:target_check_command) do "SELECT 1 FROM pg_default_acl a LEFT JOIN pg_namespace AS b ON a.defaclnamespace = b.oid WHERE '#{user}=arwdDxt/#{target_user}' = ANY (defaclacl) AND nspname = 'public' AND defaclobjtype = 'r';" end let(:pp_target_role) do <<-MANIFEST.unindent $db = #{db} $user = #{user} $group = #{group} $password = #{password} $target_user = #{target_user} $target_password = #{target_password} user {$user: ensure => present, } postgresql::server::database_grant { "allow connect for ${user}": privilege => 'CONNECT', db => $db, role => $user, } class { 'postgresql::server': } postgresql::server::role { $user: password_hash => postgresql::postgresql_password($user, $password), } postgresql::server::role { $target_user: password_hash => postgresql::postgresql_password($target_user, $target_password), } postgresql::server::database { $db: require => Postgresql::Server::Role[$user], } # Set default privileges on tables postgresql::server::default_privileges { "alter default privileges grant all on tables to ${user}": db => $db, role => $user, target_role => $target_user, psql_user => 'postgres', privilege => 'ALL', object_type => 'TABLES', require => Postgresql::Server::Database[$db], } MANIFEST end let(:pp_target_role_revoke) do <<-MANIFEST.unindent $db = #{db} $user = #{user} $group = #{group} $password = #{password} $target_user = #{target_user} $target_password = #{target_password} user {$user: ensure => present, } postgresql::server::database_grant { "allow connect for ${user}": privilege => 'CONNECT', db => $db, role => $user, } class { 'postgresql::server': } postgresql::server::role { $user: password_hash => postgresql::postgresql_password($user, $password), } postgresql::server::role { $target_user: password_hash => postgresql::postgresql_password($target_user, $target_password), } postgresql::server::database { $db: require => Postgresql::Server::Role[$user], } # Set default privileges on tables postgresql::server::default_privileges { "alter default privileges grant all on tables to ${user}": db => $db, role => $user, target_role => $target_user, psql_user => 'postgres', privilege => 'ALL', object_type => 'TABLES', ensure => 'absent', require => Postgresql::Server::Database[$db], } MANIFEST end + let(:schema_check_command) do + "SELECT * FROM pg_default_acl WHERE '#{user}=UC' = ANY (defaclacl) AND defaclnamespace = 0 and defaclobjtype = 'n';" + end + + let(:pp_schema) do + <<-MANIFEST.unindent + $db = #{db} + $user = #{user} + $group = #{group} + $password = #{password} + + class { 'postgresql::server': } + + postgresql::server::role { $user: + password_hash => postgresql::postgresql_password($user, $password), + } + + postgresql::server::database { $db: + require => Postgresql::Server::Role[$user], + } + + # Set default privileges on tables + postgresql::server::default_privileges { "alter default privileges grant all on tables to ${user}": + db => $db, + role => $user, + privilege => 'ALL', + object_type => 'SCHEMAS', + schema => '', + require => Postgresql::Server::Database[$db], + } + MANIFEST + end + let(:pp_schema_revoke) do + <<-MANIFEST + $db = #{db} + $user = #{user} + $group = #{group} + $password = #{password} + + class { 'postgresql::server': } + + postgresql::server::role { $user: + password_hash => postgresql::postgresql_password($user, $password), + } + postgresql::server::database { $db: + require => Postgresql::Server::Role[$user], + } + + # Removes default privileges on tables + postgresql::server::default_privileges { "alter default privileges revoke all on tables for ${user}": + db => $db, + role => $user, + privilege => 'ALL', + object_type => 'SCHEMAS', + schema => '', + ensure => 'absent', + require => Postgresql::Server::Database[$db], + } + MANIFEST + end + let(:all_schemas_check_command) do "SELECT * FROM pg_default_acl a WHERE '#{user}=arwdDxt' = ANY (defaclacl) AND defaclnamespace = 0 and defaclobjtype = 'r';" end let(:pp_unset_schema) do <<-MANIFEST.unindent $db = #{db} $user = #{user} $group = #{group} $password = #{password} class { 'postgresql::server': } postgresql::server::role { $user: password_hash => postgresql::postgresql_password($user, $password), } postgresql::server::database { $db: require => Postgresql::Server::Role[$user], } # Set default privileges on tables postgresql::server::default_privileges { "alter default privileges grant all on tables to ${user}": db => $db, role => $user, privilege => 'ALL', object_type => 'TABLES', schema => '', require => Postgresql::Server::Database[$db], } MANIFEST end let(:pp_unset_schema_revoke) do <<-MANIFEST $db = #{db} $user = #{user} $group = #{group} $password = #{password} class { 'postgresql::server': } postgresql::server::role { $user: password_hash => postgresql::postgresql_password($user, $password), } postgresql::server::database { $db: require => Postgresql::Server::Role[$user], } # Removes default privileges on tables postgresql::server::default_privileges { "alter default privileges revoke all on tables for ${user}": db => $db, role => $user, privilege => 'ALL', object_type => 'TABLES', schema => '', ensure => 'absent', require => Postgresql::Server::Database[$db], } MANIFEST end it 'grants default privileges to an user' do if Gem::Version.new(postgresql_version) >= Gem::Version.new('9.6') idempotent_apply(pp_one) psql("--command=\"SET client_min_messages = 'error';#{check_command}\" --db=#{db}") do |r| expect(r.stdout).to match(%r{\(1 row\)}) expect(r.stderr).to eq('') end end end it 'revokes default privileges for an user' do if Gem::Version.new(postgresql_version) >= Gem::Version.new('9.6') apply_manifest(pp_one, catch_failures: true) apply_manifest(pp_two, expect_changes: true) psql("--command=\"SET client_min_messages = 'error';#{check_command}\" --db=#{db}") do |r| expect(r.stdout).to match(%r{\(0 rows\)}) expect(r.stderr).to eq('') end end end it 'grants default privileges to a user on a specific target role' do if Gem::Version.new(postgresql_version) >= Gem::Version.new('9.6') idempotent_apply(pp_target_role) psql("--command=\"SET client_min_messages = 'error'; #{target_check_command}\" --db=#{db}", user) do |r| expect(r.stdout).to match(%r{^\(1 row\)$}) expect(r.stderr).to eq('') end end end it 'revokes default privileges from a user on a specific target role' do if Gem::Version.new(postgresql_version) >= Gem::Version.new('9.6') idempotent_apply(pp_target_role) idempotent_apply(pp_target_role_revoke) psql("--command=\"SET client_min_messages = 'error'; #{target_check_command}\" --db=#{db}", user) do |r| expect(r.stdout).to match(%r{^\(0 rows\)$}) expect(r.stderr).to eq('') end end end + it 'grants default privileges to an user on schemas' do + if Gem::Version.new(postgresql_version) >= Gem::Version.new('10.0') + idempotent_apply(pp_schema) + + psql("--command=\"SET client_min_messages = 'error';#{schema_check_command}\" --db=#{db}") do |r| + expect(r.stdout).to match(%r{\(1 row\)}) + expect(r.stderr).to eq('') + end + end + end + + it 'revokes default privileges for an user on schemas' do + if Gem::Version.new(postgresql_version) >= Gem::Version.new('10.0') + apply_manifest(pp_schema, catch_failures: true) + apply_manifest(pp_schema_revoke, expect_changes: true) + + psql("--command=\"SET client_min_messages = 'error';#{schema_check_command}\" --db=#{db}") do |r| + expect(r.stdout).to match(%r{\(0 rows\)}) + expect(r.stderr).to eq('') + end + end + end + it 'grants default privileges on all schemas to a user' do if Gem::Version.new(postgresql_version) >= Gem::Version.new('9.6') idempotent_apply(pp_unset_schema) psql("--command=\"SET client_min_messages = 'error';#{all_schemas_check_command}\" --db=#{db}") do |r| expect(r.stdout).to match(%r{\(1 row\)}) expect(r.stderr).to eq('') end end end it 'revokes default privileges on all schemas for a user' do if Gem::Version.new(postgresql_version) >= Gem::Version.new('9.6') apply_manifest(pp_unset_schema, catch_failures: true) apply_manifest(pp_unset_schema_revoke, expect_changes: true) psql("--command=\"SET client_min_messages = 'error';#{all_schemas_check_command}\" --db=#{db}") do |r| expect(r.stdout).to match(%r{\(0 rows\)}) expect(r.stderr).to eq('') end end end end diff --git a/spec/unit/defines/server/default_privileges_spec.rb b/spec/unit/defines/server/default_privileges_spec.rb index d6612ff..d56b79f 100644 --- a/spec/unit/defines/server/default_privileges_spec.rb +++ b/spec/unit/defines/server/default_privileges_spec.rb @@ -1,331 +1,442 @@ # frozen_string_literal: true require 'spec_helper' describe 'postgresql::server::default_privileges', type: :define do let :facts do { os: { family: 'Debian', name: 'Debian', release: { 'full' => '9.0', 'major' => '9' }, }, kernel: 'Linux', id: 'root', path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', } end let :title do 'test' end context 'with unsupported PostgreSQL version' do let(:facts) do { os: { family: 'Debian', name: 'Debian', release: { 'full' => '8.0', 'major' => '8' }, }, kernel: 'Linux', id: 'root', path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', } end let :params do { db: 'test', role: 'test', privilege: 'all', object_type: 'tables', } end let :pre_condition do "class {'postgresql::server': }" end it { is_expected.to compile.and_raise_error(%r{Default_privileges is only useable with PostgreSQL >= 9.6}m) } end context 'case insensitive object_type and privilege match' do let :params do { db: 'test', role: 'test', privilege: 'aLl', object_type: 'TaBlEs', } end let :pre_condition do "class {'postgresql::server':}" end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_postgresql__server__default_privileges('test') } it do is_expected.to contain_postgresql_psql('default_privileges:test') .with_command('ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO "test"') end end context 'invalid object_type' do context 'tables' do let :params do { db: 'test', role: 'test', privilege: 'all', object_type: 'wrong_type', } end let :pre_condition do "class {'postgresql::server':}" end it { is_expected.to compile.and_raise_error(%r{parameter 'object_type' expects a match for Pattern}) } end end context 'valid object_type' do context 'supported privilege' do let :params do { db: 'test', role: 'test', privilege: 'all', object_type: 'tables', } end let :pre_condition do "class {'postgresql::server':}" end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_postgresql__server__default_privileges('test') } it do # rubocop:disable Layout/LineLength is_expected.to contain_postgresql_psql('default_privileges:test') .with_command('ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO "test"') .with_unless("SELECT 1 WHERE EXISTS (SELECT * FROM pg_default_acl AS da LEFT JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE 'test=arwdDxt' = ANY (defaclacl) AND nspname = 'public' and defaclobjtype = 'r')") # rubocop:enable Layout/LineLength end end context 'unsupported privilege' do let :params do { db: 'test', role: 'test', privilege: 'wrong_privilege', object_type: 'tables', } end let :pre_condition do "class {'postgresql::server':}" end it { is_expected.to compile.and_raise_error(%r{Illegal value for \$privilege parameter}) } end + + context 'schemas on postgres < 10.0' do + let(:facts) do + { + os: { + family: 'Debian', + name: 'Debian', + release: { 'full' => '9.0', 'major' => '9' }, + }, + kernel: 'Linux', + id: 'root', + path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + } + end + + let :params do + { + db: 'test', + role: 'test', + privilege: 'all', + object_type: 'schemas', + schema: '', + } + end + + let :pre_condition do + "class {'postgresql::server':}" + end + + it { is_expected.to compile.and_raise_error(%r{Default_privileges on schemas is only supported on PostgreSQL >= 10.0}m) } + end + + context 'schemas on postgres >= 10.0' do + let :facts do + { + os: { + family: 'Debian', + name: 'Debian', + release: { 'full' => '10.0', 'major' => '10' }, + }, + kernel: 'Linux', + id: 'root', + path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + } + end + + let :params do + { + db: 'test', + role: 'test', + privilege: 'all', + object_type: 'schemas', + schema: '', + } + end + + let :pre_condition do + <<-MANIFEST + class { 'postgresql::globals': + version => '10.0', + } + class { 'postgresql::server': } + MANIFEST + end + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_postgresql__server__default_privileges('test') } + it do + # rubocop:disable Layout/LineLength + is_expected.to contain_postgresql_psql('default_privileges:test') + .with_command('ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO "test"') + .with_unless("SELECT 1 WHERE EXISTS (SELECT * FROM pg_default_acl AS da LEFT JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE 'test=UC' = ANY (defaclacl) AND nspname IS NULL and defaclobjtype = 'n')") + # rubocop:enable Layout/LineLength + end + end + + context 'nested schemas are invalid' do + let :facts do + { + os: { + family: 'Debian', + name: 'Debian', + release: { 'full' => '10.0', 'major' => '10' }, + }, + kernel: 'Linux', + id: 'root', + path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + } + end + + let :params do + { + db: 'test', + role: 'test', + privilege: 'all', + object_type: 'schemas', + schema: 'public', + } + end + + let :pre_condition do + <<-MANIFEST + class { 'postgresql::globals': + version => '10.0', + } + class { 'postgresql::server': } + MANIFEST + end + + it { is_expected.to compile.and_raise_error(%r{Cannot alter default schema permissions within a schema}) } + end end context 'with specific db connection settings - default port' do let :params do { db: 'test', role: 'test', privilege: 'all', object_type: 'tables', connect_settings: { 'PGHOST' => 'postgres-db-server', 'DBVERSION' => '9.6' }, } end let :pre_condition do "class {'postgresql::server':}" end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_postgresql__server__default_privileges('test') } it { is_expected.to contain_postgresql_psql('default_privileges:test').with_connect_settings('PGHOST' => 'postgres-db-server', 'DBVERSION' => '9.6').with_port(5432) } end context 'with specific db connection settings - including port' do let :params do { db: 'test', role: 'test', privilege: 'all', object_type: 'tables', connect_settings: { 'PGHOST' => 'postgres-db-server', 'DBVERSION' => '9.6', 'PGPORT' => '1234' }, } end let :pre_condition do "class {'postgresql::server':}" end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_postgresql__server__default_privileges('test') } it { is_expected.to contain_postgresql_psql('default_privileges:test').with_connect_settings('PGHOST' => 'postgres-db-server', 'DBVERSION' => '9.6', 'PGPORT' => '1234') } end context 'with specific db connection settings - port overriden by explicit parameter' do let :params do { db: 'test', role: 'test', privilege: 'all', object_type: 'tables', connect_settings: { 'PGHOST' => 'postgres-db-server', 'DBVERSION' => '9.6', 'PGPORT' => '1234' }, port: 5678, } end let :pre_condition do "class {'postgresql::server':}" end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_postgresql__server__default_privileges('test') } it { is_expected.to contain_postgresql_psql('default_privileges:test').with_connect_settings('PGHOST' => 'postgres-db-server', 'DBVERSION' => '9.6', 'PGPORT' => '1234').with_port('5678') } end context 'with specific schema name' do let :params do { db: 'test', role: 'test', privilege: 'all', object_type: 'tables', schema: 'my_schema' } end let :pre_condition do "class {'postgresql::server':}" end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_postgresql__server__default_privileges('test') } it do # rubocop:disable Layout/LineLength is_expected.to contain_postgresql_psql('default_privileges:test') .with_command('ALTER DEFAULT PRIVILEGES IN SCHEMA my_schema GRANT ALL ON TABLES TO "test"') .with_unless("SELECT 1 WHERE EXISTS (SELECT * FROM pg_default_acl AS da LEFT JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE 'test=arwdDxt' = ANY (defaclacl) AND nspname = 'my_schema' and defaclobjtype = 'r')") # rubocop:enable Layout/LineLength end end context 'with unset schema name' do let :params do { db: 'test', role: 'test', privilege: 'all', object_type: 'tables', schema: '' } end let :pre_condition do "class {'postgresql::server':}" end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_postgresql__server__default_privileges('test') } it do # rubocop:disable Layout/LineLength is_expected.to contain_postgresql_psql('default_privileges:test') .with_command('ALTER DEFAULT PRIVILEGES GRANT ALL ON TABLES TO "test"') .with_unless("SELECT 1 WHERE EXISTS (SELECT * FROM pg_default_acl AS da LEFT JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE 'test=arwdDxt' = ANY (defaclacl) AND nspname IS NULL and defaclobjtype = 'r')") # rubocop:enable Layout/LineLength end end context 'with a role defined' do let :params do { db: 'test', role: 'test', privilege: 'all', object_type: 'tables', } end let :pre_condition do <<-EOS class {'postgresql::server':} postgresql::server::role { 'test': } EOS end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_postgresql__server__default_privileges('test') } it { is_expected.to contain_postgresql__server__role('test') } it do is_expected.to contain_postgresql_psql('default_privileges:test') \ .that_requires(['Service[postgresqld]', 'Postgresql::Server::Role[test]']) end end context 'with a target role' do let :params do { target_role: 'target', db: 'test', role: 'test', privilege: 'all', object_type: 'tables', } end let :pre_condition do <<-EOS class {'postgresql::server':} postgresql::server::role { 'target': } EOS end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_postgresql__server__default_privileges('test') } it { is_expected.to contain_postgresql__server__role('target') } it do # rubocop:disable Layout/LineLength is_expected.to contain_postgresql_psql('default_privileges:test') .with_command('ALTER DEFAULT PRIVILEGES FOR ROLE target IN SCHEMA public GRANT ALL ON TABLES TO "test"') .with_unless("SELECT 1 WHERE EXISTS (SELECT * FROM pg_default_acl AS da LEFT JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE 'test=arwdDxt/target' = ANY (defaclacl) AND nspname = 'public' and defaclobjtype = 'r')") # rubocop:enable Layout/LineLength end end context 'standalone not managing server' do let :params do { db: 'test', role: 'test', privilege: 'execute', object_type: 'functions', group: 'postgresql', psql_path: '/usr/bin', psql_user: 'postgres', psql_db: 'db', port: 1542, connect_settings: { 'DBVERSION' => '9.6' }, } end it { is_expected.to compile.with_all_deps } it { is_expected.not_to contain_class('postgresql::server') } end end