define profiles::sql::postgres::grant ( String $username, Enum['SCHEMA', 'DATABASE'] $type = 'DATABASE', Optional[String] $dbname = undef, Optional[String] $schema = undef, String $privilege = 'ALL PRIVILEGES', ) { # Validate parameters based on type if $type == 'DATABASE' and $dbname == undef { fail('The dbname parameter must be provided when type is DATABASE') } if $type == 'SCHEMA' and ($dbname == undef or $schema == undef) { fail('Both dbname and schema parameters must be provided when type is SCHEMA') } # Determine the appropriate SQL command and unless condition $command = $type ? { 'DATABASE' => "GRANT ${privilege} ON DATABASE ${dbname} TO ${username}", 'SCHEMA' => "GRANT ${privilege} ON SCHEMA ${schema} TO ${username}", } $unless = $type ? { 'DATABASE' => "SELECT 1 FROM pg_roles r WHERE r.rolname='${username}' AND has_database_privilege('${username}', '${dbname}', 'CONNECT')", # lint:ignore:140chars 'SCHEMA' => "SELECT 1 FROM pg_namespace n JOIN pg_roles r ON r.oid = n.nspowner WHERE nspname = '${schema}' AND r.rolname = '${username}'", # lint:ignore:140chars } # Ensure the db parameter is set correctly when type is SCHEMA $effective_dbname = $type ? { 'SCHEMA' => $dbname, 'DATABASE' => $dbname, } postgresql_psql { "grant_${privilege}_on_${type}_${effective_dbname}_${schema}_to_${username}": command => $command, unless => $unless, db => $effective_dbname, } }