Support granting permission on sequences.

add spec test for sequence grant and document postgresql::server::grant.
This commit is contained in:
qha 2015-05-08 16:33:26 +02:00 committed by Bryan Jen
parent 6f44abea6b
commit c9ffadd31b
3 changed files with 138 additions and 9 deletions

View file

@ -618,6 +618,39 @@ If provided, this will install the given package prior to activating the extensi
####`package_ensure`
By default, the package specified with `package_name` will be installed when the extension is activated, and removed when the extension is deactivated. You can override this behavior by setting the `ensure` value for the package.
###Resource: postgresql::server::grant
This defined type manages grant based access privileges for roles. Consult the PostgreSQL documentation for `grant` for more information.
####`namevar`
Used to uniquely identify this resource, but functionality not used during grant.
####`db`
Database of object which you are granting access on.
####`role`
Role or user whom you are granting access for.
####`privilege`
The privilege you are granting. Can be `ALL`, `ALL PRIVILEGES` or
`object_type` dependent string.
####`object_type`
The type of object you are granting privileges on. Can be `DATABASE`,
`SCHEMA`, `SEQUENCE`, `ALL SEQUENCES IN SCHEMA`, `TABLE` or `ALL
TABLES IN SCHEMA`.
####`object_name`
Object of type `object_type` on which to grant access.
####`psql_db`
Database to execute the grant against. This should not ordinarily be changed from the default, which is `postgres`.
####`psql_user`
OS user for running `psql`. Defaults to the default user for the module, usually `postgres`.
####`port`
Port to use when connecting. Default to 'undef' which generally defaults to 5432 depending on your PostgreSQL packaging.
###Resource: postgresql::server::pg\_hba\_rule
This defined type allows you to create an access rule for `pg_hba.conf`. For more details see the [PostgreSQL documentation](http://www.postgresql.org/docs/8.2/static/auth-pg-hba-conf.html).

View file

@ -31,13 +31,15 @@ define postgresql::server::grant (
#'FUNCTION',
#'PROCEDURAL LANGUAGE',
'SCHEMA',
#'SEQUENCE',
'SEQUENCE',
'ALL SEQUENCES IN SCHEMA',
'TABLE',
'ALL TABLES IN SCHEMA',
#'TABLESPACE',
#'VIEW',
)
# You can use ALL TABLES IN SCHEMA by passing schema_name to object_name
# You can use ALL SEQUENCES IN SCHEMA by passing schema_name to object_name
## Validate that the object type's privilege is acceptable
# TODO: this is a terrible hack; if they pass "ALL" as the desired privilege,
@ -70,6 +72,53 @@ define postgresql::server::grant (
$unless_function = 'has_schema_privilege'
$on_db = $db
}
'SEQUENCE': {
$unless_privilege = $_privilege ? {
'ALL' => 'USAGE',
default => $_privilege,
}
validate_string($unless_privilege,'USAGE','ALL','ALL PRIVILEGES')
$unless_function = 'has_sequence_privilege'
$on_db = $db
}
'ALL SEQUENCES IN SCHEMA': {
validate_string($_privilege,'USAGE','ALL','ALL PRIVILEGES')
$unless_function = 'custom'
$on_db = $db
$schema = $object_name
$custom_privilege = $_privilege ? {
'ALL' => 'USAGE',
'ALL PRIVILEGES' => 'USAGE',
default => $_privilege,
}
# This checks if there is a difference between the sequences in the
# specified schema and the sequences 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 sequences 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 sequence for which
# the role does not have the specified privilege, making it necessary to
# execute the GRANT statement.
$custom_unless = "SELECT 1 FROM (
SELECT sequence_name
FROM information_schema.sequences
WHERE sequence_schema='${schema}'
EXCEPT DISTINCT
SELECT object_name as sequence_name
FROM information_schema.role_usage_grants
WHERE object_type='SEQUENCE'
AND grantee='${role}'
AND object_schema='${schema}'
AND privilege_type='${custom_privilege}'
) P
HAVING count(P.sequence_name) = 0"
}
'TABLE': {
$unless_privilege = $_privilege ? {
'ALL' => 'INSERT',

View file

@ -17,16 +17,63 @@ describe 'postgresql::server::grant', :type => :define do
'test'
end
let :params do
{
:db => 'test',
:role => 'test',
}
context 'plain' do
let :params do
{
:db => 'test',
:role => 'test',
}
end
let :pre_condition do
"class {'postgresql::server':}"
end
it { is_expected.to contain_postgresql__server__grant('test') }
end
let :pre_condition do
"class {'postgresql::server':}"
context 'sequence' do
let :params do
{
:db => 'test',
:role => 'test',
:privilege => 'usage',
:object_type => 'sequence',
}
end
let :pre_condition do
"class {'postgresql::server':}"
end
it { is_expected.to contain_postgresql__server__grant('test') }
it { is_expected.to contain_postgresql_psql('grant:test').with(
{
'command' => "GRANT USAGE ON SEQUENCE \"test\" TO\n \"test\"",
'unless' => "SELECT 1 WHERE has_sequence_privilege('test',\n 'test', 'USAGE')",
}) }
end
it { is_expected.to contain_postgresql__server__grant('test') }
context 'all sequences' do
let :params do
{
:db => 'test',
:role => 'test',
:privilege => 'usage',
:object_type => 'all sequences in schema',
:object_name => 'public',
}
end
let :pre_condition do
"class {'postgresql::server':}"
end
it { is_expected.to contain_postgresql__server__grant('test') }
it { is_expected.to contain_postgresql_psql('grant:test').with(
{
'command' => "GRANT USAGE ON ALL SEQUENCES IN SCHEMA \"public\" TO\n \"test\"",
'unless' => "SELECT 1 FROM (\n SELECT sequence_name\n FROM information_schema.sequences\n WHERE sequence_schema='public'\n EXCEPT DISTINCT\n SELECT object_name as sequence_name\n FROM information_schema.role_usage_grants\n WHERE object_type='SEQUENCE'\n AND grantee='test'\n AND object_schema='public'\n AND privilege_type='USAGE'\n ) P\n HAVING count(P.sequence_name) = 0",
}) }
end
end