-
Notifications
You must be signed in to change notification settings - Fork 613
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parameter ensure
on postgresql::server::grant
and postgresql::server::database_grant
#891
Parameter ensure
on postgresql::server::grant
and postgresql::server::database_grant
#891
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat work! I went through it, but haven't had time for the very long query and tests. I can look at them later, if you like.
manifests/server/grant.pp
Outdated
} | ||
default: { | ||
fail("Unknown value for ensure '${ensure}'.") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unnecessary with the datatype.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just copied this structure from grant_role.pp
I suspect it pre-dates the introduction of strict typing.
I will remove the redundant code.
manifests/server/grant.pp
Outdated
default => "SELECT 1 WHERE ${unless_function}('${role}', | ||
'${_granted_object}', '${unless_privilege}')", | ||
default => "SELECT * FROM ${unless_function}('${role}', | ||
'${_granted_object}', '${unless_privilege}') WHERE ${unless_function} = ${unless_is}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SELECT 1 WHERE ${unless_function}('${role}', '${_granted_object}', '${unless_privilege}') = ${unless_is}
would be cleaner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll update the code
manifests/server/grant.pp
Outdated
AND privilege_type IN ('SELECT','UPDATE','INSERT','DELETE','TRIGGER','REFERENCES','TRUNCATE') | ||
GROUP BY table_name | ||
) AS P WHERE P.count >= 7 | ||
) AS TBLS HAVING TBLS.count=0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this query and the following unnecessarily complicated. First of all, the logic is reverse. It returns a row when there are no matching tables. We can use onlyif
instead of unless
and just return rows for tables.
We can use NOT EXISTS
instead of EXCEPT
with list of privileges. It would be cleaner and better optimised.
GROUP BY
on the inner most query is unnecessary. count(privilege_type)
could be just count(*)
.
I believe HAVING t.count
is an unusual syntax. The subquery could have SELECT count(*)
instead. Thank you for showing me this synax though. SQL still surprises me after many years.
Upper case alias is not good style.
In conclusion, I suggest this:
SELECT 1
FROM pg_catalog.pg_tables AS t,
(VALUES ('SELECT'), ('UPDATE'), ('INSERT'), ('DELETE'), ('TRIGGER'), ('REFERENCES'), ('TRUNCATE')) AS p(privilege_type)
WHERE t.schemaname = '${schema}'
AND NOT EXISTS (
SELECT 1
FROM information_schema.role_table_grants AS g
WHERE g.grantee = '${role}'
AND g.table_schema = t.schemaname
AND g.table_name = t.tablename
AND g.privilege_type = p.privilege_type
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would much rather use 'onlyif' instead of 'unless' for these queries, but for 2 things:
- The existing puppet code was written this way. It uses
$unless_function = 'custom'
plus this code to determine whether or not to apply the GRANT. Adding the logic for$onlyif_function = 'custom'
would makeALL TABLES IN SCHEMA
the exception to this approach - The variable
$onlyif_function
is currently only used to test for the existence of something - a table, a language. Re-using it for a different purpose adds complexity to this logic.
It's quite feasible to use onlyif
, but it's really just simplifying the SQL and making the puppet code more complex.
Let me know your thoughts on this trade-off. I'll change it if you ask.
On the rest of the SQL, the logic around GRANT ALL ON ALL TABLES IN SCHEMA
is quite complicated. I want to capture the case where, say one table has one privilege missing. So it is necessary to account for all privileges, not just any one. Hence the count(privilege_type)
.
This has to be done on a per-table basis, which is why the GROUP BY
is there.
count(*) would suffice, I just put privilege_type in there for readability, since that is what we are interested in.
I'm happy to substitute your version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the reason to keep the logic reversed. We can encapsulate whole query inside another NOT EXISTS
to keep it that way, so:
SELECT 1
WHERE NOT EXISTS (
SELECT 1
FROM pg_catalog.pg_tables AS t,
(VALUES
('SELECT'),
('UPDATE'),
('INSERT'),
('DELETE'),
('TRIGGER'),
('REFERENCES'),
('TRUNCATE')
) AS p(privilege_type)
WHERE t.schemaname = '${schema}'
AND NOT EXISTS (
SELECT 1
FROM information_schema.role_table_grants AS g
WHERE g.grantee = '${role}'
AND g.table_schema = t.schemaname
AND g.table_name = t.tablename
AND g.privilege_type = p.privilege_type
)
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the code use SELECT 1 WHERE NOT EXISTS
instead of HAVING count(*)=0
I think this makes it a bit more readable.
f3ae3a4
to
92f4842
Compare
I've updated the code to include the improvements you have suggested. |
I don't have rights on the repository. I am just doing reviews to keep it clean. I guess someone from Puppetlabs would pick this up. This is a useful feature in my opinion. |
Thanks, this would be very useful to have George, let us know if there's anything we can do to help get this merged @puppetlabs |
7d5fb57
to
d47d30d
Compare
Hi @hasegeli I've made one small change to this pull-request, which is to check that the role exits before revoking DB privileges, thus preventing this operation from failing This is desirable because a common usage pattern is the revoke all privileges prior to dropping a role. On the next run, after the role is gone, we don't want the ensure=>absent to fail. The Thanks for your time. |
baa21d5
to
34b266d
Compare
8f8205b
to
68d7bb0
Compare
I've updates this code to:
All tests are now passing, and there are no merge conflicts. |
👍 |
FYI - We logged a Puppet Enterprise support ticket to try and get some movement on getting @georgehansper's MRs actioned but they closed the support request as 'SOLVED' stating its a different @puppet team that supports the modules, it's in their backlog and they'll review it next sprint but that there's nothing else Puppet support can do. |
Issue is MODULES-5634 |
96e7415
to
aca9970
Compare
…tgresql into grant_ensure_absent_is_revoke
aca9970
to
70f15cf
Compare
Hi @willmeek I've fixed the merge-conflict on this branch, so the |
@hunner Could you take a look at this pr please? |
This has passed 7 months. Any progress? |
+1 from me. @hunner can you have a look, as a final sign off |
@hunner Per TP's request, could you look over this PR? |
fc03526
to
cc38605
Compare
@georgehansper This is currently failing the inbuilt Rubocop checks. In order for it to be merged it would first need to be updated to match the set standards. Some example rubocop commands are shown below: Run command: Flags: Disable Commands:
Disable rubocop for a single line:
|
@david22swan thanks for the pointers re rubocop. I've started looking at this, and I expect to have these issues resolved soon. |
cc38605
to
9a5ffdb
Compare
@david22swan @hunner I've resolved the merge conflicts and made rubocop happy again. |
Thanks all |
ensure
on postgresql::server::grant
and postgresql::server::database_grant
…t_is_revoke postgresql::server::grant with ensure => absent uses REVOKE instead of GRANT
This change updates the defined type postgresql::server::grant to introduce a new parameter:
ensure => present
-- or --
ensure => absent
ensure => present preserves the existing behaviour, using GRANT to add privileges
ensure => absent uses REVOKE to remove privileges
The SQL associated with the unless clause has been updated to work correctly, in general.