-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
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
services.postgresql: Allow configuration of user roles in ensureUser #200724
services.postgresql: Allow configuration of user roles in ensureUser #200724
Conversation
default = [ ]; | ||
description = lib.mdDoc '' | ||
A list of roles to grant to the user. Under the hood this uses the | ||
[ALTER USER syntax](https://www.postgresql.org/docs/current/sql-alteruser.html) for each role in the list: |
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.
Double space in "each role in". (Hehe, it seems github removes double space in these comments.)
Note that there is some uncertainty whether the database modules should have |
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 have a couple of suggestions, and this should be tested. You could extend nixos/tests/postgresql.nix
for this purpose.
@@ -168,6 +168,18 @@ in | |||
} | |||
''; | |||
}; | |||
ensureRoles = mkOption { |
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.
Roles and Users are synonymous in PostgreSQL.
The linked page calls them options. This page calls them clauses. That seems like an even better name.
description = lib.mdDoc '' | ||
A list of roles to grant to the user. Under the hood this uses the | ||
[ALTER USER syntax](https://www.postgresql.org/docs/current/sql-alteruser.html) for each role in the list: | ||
`ALTER USER user.name WITH role` |
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.
Can clauses be removed? We don't seem to have enough knowledge to remove unmentioned roles.
The linked page lists negatives as well: NOSUPERUSER
, etc. Could those be used for this purpose?
A better option representation would be types.attrsOf types.bool
. (or even individual options, to restrict it to known-valid attribute names; not sure if that's better)
With this infrastructure in place, we can also provide an option (off by default, not to break configs) for fully declarative user permissions; a matter of conditionally assigning some lib.mkDefault
defaults to those options, so that they cover all possible clauses.
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.
Great suggestion. I will try to find some time this weekend to do this, as well as adding tests.
nixos/tests/postgresql.nix
Outdated
assert clauses['rolreplication'], 'expected user with clauses to have replication clause' | ||
assert clauses['rolbypassrls'], 'expected user with clauses to have bypassrls clause' | ||
|
||
with subtest("All user permissions default to false when ensureClauses is not provided"): |
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 the default for NixOS admins who are unaware of this new feature, so it'd be a breaking change to remove all clauses. I think the bool
types need to be nullOr bool
, to represent "leave as is" with null
.
Then change the defaults to null
, or perhaps add a new option so the defaults can be if config.services.postgresql.declarativeRoleClauses then false else null
?
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.
Oh yeah, great point. I will try to get to this next week when I have some time. Thanks for all the direction on this.
Thinking about it a bit more, maybe it would be better to move all these ensure options into a separate module (accessible under e.g. |
Sounds ok to me, though I wouldn't rush it because it seems that we need to solve some declarativeness problems that need interface changes. It'd be nicer for users to do one migration than to do a rename and then a migration. Also if we rename options first, then options with the old semantics may collide with the names we want to use after making things more declarative.
Moving it to a separate module isn't trivial, because it needs to run as part of |
|
||
clauseSqlStatements = attrValues (mapAttrs (n: v: if v then n else "no${n}") filteredClauses); | ||
|
||
alterClause = role: ''$PSQL -tAc 'ALTER USER "${user.name}" WITH ${role}' ''; |
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.
Is it possible to set all clauses in one $PSQL
invocation?
It seems that that would save some latency, especially when you have multiple users and the connection isn't local and uses TLS.
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.
Good catch, just pushed a fix.
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.
Some nitpicks. Otherwise LGTM
|
||
More information on postgres roles can be found [here](https://www.postgresql.org/docs/current/role-attributes.html) | ||
''; | ||
default = null; |
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.
null
was underdocumented. Could you do the following? And maybe create a let binding for it, so you don't have to copy paste.
defaultText = lib.literalMD ''
`null`: do not set. For newly created roles, use PostgreSQL's default. For existing roles, do not touch this clause.
'';
I don't know. This might be a bit out of place if we don't make the other things more declarative. Can be done in a follow up PR if desired. The PR contains many commits, which should be squashed. I doesn't look like there's an intermediate change that would warrant having more than one commit. @JonathanLorimer could you squash them? |
remove trailing whitespace switch docs to markdown use mdDoc remove trailing whitespace get rid of double space add tests and update options to use submodule remove whitespace remove whitespace use mdDoc remove whitespace make default a no-op make ALTER ROLE a single sql statement document null case
67e3912
to
193aa6f
Compare
Co-authored-by: Robert Hensing <[email protected]>
There might be features conflicts with #203474 ? |
@ofborg test postgresql |
LGTM. |
I think we could make what I have work with that PR. |
2 weeks have passed, or 10 maintainer*weeks, without any response. Still LGTM. |
Probably the maintainers are only interested in the package. Next time I'll cc them but not ask for anything. |
Description of changes
This adds an attribute to the
ensureUsers
option on theservices.postgresql
module. The attribute allows you to set a list of roles that you want to applied to the user when the postgresql service starts up.Things done
sandbox = true
set innix.conf
? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)nixos/doc/manual/md-to-db.sh
to update generated release notes