Merge pull request #564 from antaflos/idempotency_for_grant_all_tables

Make granting on ALL TABLES IN SCHEMA idempotent
This commit is contained in:
Hunter Haugen 2015-03-12 10:28:34 -07:00
commit 9e9aa9da85

View file

@ -81,10 +81,45 @@ define postgresql::server::grant (
$on_db = $db
}
'ALL TABLES IN SCHEMA': {
validate_string($_privilege, 'SELECT', 'INSERT', 'UPDATE', 'REFERENCES',
'ALL', 'ALL PRIVILEGES')
$unless_function = false # There is no way to test it simply
validate_string($_privilege,'SELECT','INSERT','UPDATE','DELETE',
'TRUNCATE','REFERENCES','TRIGGER','ALL','ALL PRIVILEGES')
$unless_function = 'custom'
$on_db = $db
$schema = $object_name
# Again there seems to be no easy way in plain SQL to check if ALL
# PRIVILEGES are granted on a table. By convention we use INSERT
# here to represent ALL PRIVILEGES (truly terrible).
$custom_privilege = $_privilege ? {
'ALL' => 'INSERT',
'ALL PRIVILEGES' => 'INSERT',
default => $_privilege,
}
# This checks if there is a difference between the tables in the
# specified schema and the tables for which the role has the specified
# privilege. It uses the EXCEPT clause which computes the set of rows
# that are in the result of the first SELECT statement but not in the
# result of the second one. It then counts the number of rows from this
# operation. If this number is zero then the role has the specified
# privilege for all tables in the schema and the whole query returns a
# single row, which satisfies the `unless` parameter of Postgresql_psql.
# If this number is not zero then there is at least one table for which
# the role does not have the specified privilege, making it necessary to
# execute the GRANT statement.
$custom_unless = "SELECT 1 FROM (
SELECT table_name
FROM information_schema.tables
WHERE table_schema='${schema}'
EXCEPT DISTINCT
SELECT table_name
FROM information_schema.role_table_grants
WHERE grantee='${role}'
AND table_schema='${schema}'
AND privilege_type='${custom_privilege}'
) P
HAVING count(P.table_name) = 0"
}
default: {
fail("Missing privilege validation for object type ${_object_type}")
@ -109,8 +144,9 @@ define postgresql::server::grant (
}
$_unless = $unless_function ? {
false => undef,
default => "SELECT 1 WHERE ${unless_function}('${role}',
false => undef,
'custom' => $custom_unless,
default => "SELECT 1 WHERE ${unless_function}('${role}',
'${_granted_object}', '${unless_privilege}')",
}