Skip to content

Commit c9ffadd

Browse files
qhabmjen
authored andcommitted
Support granting permission on sequences.
add spec test for sequence grant and document postgresql::server::grant.
1 parent 6f44abe commit c9ffadd

File tree

3 files changed

+138
-9
lines changed

3 files changed

+138
-9
lines changed

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,39 @@ If provided, this will install the given package prior to activating the extensi
618618
####`package_ensure`
619619
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.
620620

621+
###Resource: postgresql::server::grant
622+
This defined type manages grant based access privileges for roles. Consult the PostgreSQL documentation for `grant` for more information.
623+
624+
####`namevar`
625+
Used to uniquely identify this resource, but functionality not used during grant.
626+
627+
####`db`
628+
Database of object which you are granting access on.
629+
630+
####`role`
631+
Role or user whom you are granting access for.
632+
633+
####`privilege`
634+
The privilege you are granting. Can be `ALL`, `ALL PRIVILEGES` or
635+
`object_type` dependent string.
636+
637+
####`object_type`
638+
The type of object you are granting privileges on. Can be `DATABASE`,
639+
`SCHEMA`, `SEQUENCE`, `ALL SEQUENCES IN SCHEMA`, `TABLE` or `ALL
640+
TABLES IN SCHEMA`.
641+
642+
####`object_name`
643+
Object of type `object_type` on which to grant access.
644+
645+
####`psql_db`
646+
Database to execute the grant against. This should not ordinarily be changed from the default, which is `postgres`.
647+
648+
####`psql_user`
649+
OS user for running `psql`. Defaults to the default user for the module, usually `postgres`.
650+
651+
####`port`
652+
Port to use when connecting. Default to 'undef' which generally defaults to 5432 depending on your PostgreSQL packaging.
653+
621654
###Resource: postgresql::server::pg\_hba\_rule
622655
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).
623656

manifests/server/grant.pp

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@
3131
#'FUNCTION',
3232
#'PROCEDURAL LANGUAGE',
3333
'SCHEMA',
34-
#'SEQUENCE',
34+
'SEQUENCE',
35+
'ALL SEQUENCES IN SCHEMA',
3536
'TABLE',
3637
'ALL TABLES IN SCHEMA',
3738
#'TABLESPACE',
3839
#'VIEW',
3940
)
4041
# You can use ALL TABLES IN SCHEMA by passing schema_name to object_name
42+
# You can use ALL SEQUENCES IN SCHEMA by passing schema_name to object_name
4143

4244
## Validate that the object type's privilege is acceptable
4345
# TODO: this is a terrible hack; if they pass "ALL" as the desired privilege,
@@ -70,6 +72,53 @@
7072
$unless_function = 'has_schema_privilege'
7173
$on_db = $db
7274
}
75+
'SEQUENCE': {
76+
$unless_privilege = $_privilege ? {
77+
'ALL' => 'USAGE',
78+
default => $_privilege,
79+
}
80+
validate_string($unless_privilege,'USAGE','ALL','ALL PRIVILEGES')
81+
$unless_function = 'has_sequence_privilege'
82+
$on_db = $db
83+
}
84+
'ALL SEQUENCES IN SCHEMA': {
85+
validate_string($_privilege,'USAGE','ALL','ALL PRIVILEGES')
86+
$unless_function = 'custom'
87+
$on_db = $db
88+
89+
$schema = $object_name
90+
91+
$custom_privilege = $_privilege ? {
92+
'ALL' => 'USAGE',
93+
'ALL PRIVILEGES' => 'USAGE',
94+
default => $_privilege,
95+
}
96+
97+
# This checks if there is a difference between the sequences in the
98+
# specified schema and the sequences for which the role has the specified
99+
# privilege. It uses the EXCEPT clause which computes the set of rows
100+
# that are in the result of the first SELECT statement but not in the
101+
# result of the second one. It then counts the number of rows from this
102+
# operation. If this number is zero then the role has the specified
103+
# privilege for all sequences in the schema and the whole query returns a
104+
# single row, which satisfies the `unless` parameter of Postgresql_psql.
105+
# If this number is not zero then there is at least one sequence for which
106+
# the role does not have the specified privilege, making it necessary to
107+
# execute the GRANT statement.
108+
$custom_unless = "SELECT 1 FROM (
109+
SELECT sequence_name
110+
FROM information_schema.sequences
111+
WHERE sequence_schema='${schema}'
112+
EXCEPT DISTINCT
113+
SELECT object_name as sequence_name
114+
FROM information_schema.role_usage_grants
115+
WHERE object_type='SEQUENCE'
116+
AND grantee='${role}'
117+
AND object_schema='${schema}'
118+
AND privilege_type='${custom_privilege}'
119+
) P
120+
HAVING count(P.sequence_name) = 0"
121+
}
73122
'TABLE': {
74123
$unless_privilege = $_privilege ? {
75124
'ALL' => 'INSERT',

spec/unit/defines/server/grant_spec.rb

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,63 @@
1717
'test'
1818
end
1919

20-
let :params do
21-
{
22-
:db => 'test',
23-
:role => 'test',
24-
}
20+
context 'plain' do
21+
let :params do
22+
{
23+
:db => 'test',
24+
:role => 'test',
25+
}
26+
end
27+
28+
let :pre_condition do
29+
"class {'postgresql::server':}"
30+
end
31+
32+
it { is_expected.to contain_postgresql__server__grant('test') }
2533
end
2634

27-
let :pre_condition do
28-
"class {'postgresql::server':}"
35+
context 'sequence' do
36+
let :params do
37+
{
38+
:db => 'test',
39+
:role => 'test',
40+
:privilege => 'usage',
41+
:object_type => 'sequence',
42+
}
43+
end
44+
45+
let :pre_condition do
46+
"class {'postgresql::server':}"
47+
end
48+
49+
it { is_expected.to contain_postgresql__server__grant('test') }
50+
it { is_expected.to contain_postgresql_psql('grant:test').with(
51+
{
52+
'command' => "GRANT USAGE ON SEQUENCE \"test\" TO\n \"test\"",
53+
'unless' => "SELECT 1 WHERE has_sequence_privilege('test',\n 'test', 'USAGE')",
54+
}) }
2955
end
3056

31-
it { is_expected.to contain_postgresql__server__grant('test') }
57+
context 'all sequences' do
58+
let :params do
59+
{
60+
:db => 'test',
61+
:role => 'test',
62+
:privilege => 'usage',
63+
:object_type => 'all sequences in schema',
64+
:object_name => 'public',
65+
}
66+
end
67+
68+
let :pre_condition do
69+
"class {'postgresql::server':}"
70+
end
71+
72+
it { is_expected.to contain_postgresql__server__grant('test') }
73+
it { is_expected.to contain_postgresql_psql('grant:test').with(
74+
{
75+
'command' => "GRANT USAGE ON ALL SEQUENCES IN SCHEMA \"public\" TO\n \"test\"",
76+
'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",
77+
}) }
78+
end
3279
end

0 commit comments

Comments
 (0)