From 340dd706dd75a6ab0ea62bb709743f2ecdcb9b08 Mon Sep 17 00:00:00 2001 From: Chris Le Sueur Date: Wed, 15 Sep 2021 15:16:58 +0100 Subject: [PATCH] Support setting default_privileges on all schemas The Postgres default is for the absent specification of a schema name when altering default privileges to apply to all schemas. Support that behaviour, but keep the current default behaviour for an unset schema parameter. --- manifests/server/default_privileges.pp | 21 ++++++++----- .../defines/server/default_privileges_spec.rb | 30 +++++++++++++++++-- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/manifests/server/default_privileges.pp b/manifests/server/default_privileges.pp index 7311d5eb1a..9288f2e81e 100644 --- a/manifests/server/default_privileges.pp +++ b/manifests/server/default_privileges.pp @@ -5,7 +5,7 @@ # @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'. +# @param schema Target schema. Defaults 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'. @@ -50,11 +50,11 @@ case $ensure { default: { # default is 'present' - $sql_command = 'ALTER DEFAULT PRIVILEGES IN SCHEMA %s GRANT %s ON %s TO "%s"' + $sql_command = 'ALTER DEFAULT PRIVILEGES%s GRANT %s ON %s TO "%s"' $unless_is = true } 'absent': { - $sql_command = 'ALTER DEFAULT PRIVILEGES IN SCHEMA %s REVOKE %s ON %s FROM "%s"' + $sql_command = 'ALTER DEFAULT PRIVILEGES%s REVOKE %s ON %s FROM "%s"' $unless_is = false } } @@ -70,6 +70,13 @@ $port_override = $postgresql::server::port } + if $schema != '' { + $_schema = " IN SCHEMA $schema" + $_check_schema = " AND nspname = '$schema'" + } else { + $_schema = '' + $_check_schema = '' + } ## Munge the input values $_object_type = upcase($object_type) $_privilege = upcase($privilege) @@ -128,12 +135,12 @@ } $_unless = $ensure ? { - 'absent' => "SELECT 1 WHERE NOT EXISTS (SELECT * FROM pg_default_acl AS da JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE '%s=%s' = ANY (defaclacl) AND nspname = '%s' and defaclobjtype = '%s')", - default => "SELECT 1 WHERE EXISTS (SELECT * FROM pg_default_acl AS da JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE '%s=%s' = ANY (defaclacl) AND nspname = '%s' and defaclobjtype = '%s')" + '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' = 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' = ANY (defaclacl)%s and defaclobjtype = '%s')" } - $unless_cmd = sprintf($_unless, $role, $_check_privilege, $schema, $_check_type) - $grant_cmd = sprintf($sql_command, $schema, $_privilege, $_object_type, $role) + $unless_cmd = sprintf($_unless, $role, $_check_privilege, $_check_schema, $_check_type) + $grant_cmd = sprintf($sql_command, $_schema, $_privilege, $_object_type, $role) postgresql_psql { "default_privileges:${name}": command => $grant_cmd, diff --git a/spec/unit/defines/server/default_privileges_spec.rb b/spec/unit/defines/server/default_privileges_spec.rb index 9b47538159..94d4c75fee 100644 --- a/spec/unit/defines/server/default_privileges_spec.rb +++ b/spec/unit/defines/server/default_privileges_spec.rb @@ -112,7 +112,7 @@ # 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 JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE 'test=arwdDxt' = ANY (defaclacl) AND nspname = 'public' and defaclobjtype = 'r')") + .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 @@ -222,7 +222,33 @@ # 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 JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE 'test=arwdDxt' = ANY (defaclacl) AND nspname = 'my_schema' and defaclobjtype = 'r')") + .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 defaclobjtype = 'r')") # rubocop:enable Layout/LineLength end end