Skip to content

Commit 4563a6f

Browse files
authored
Merge pull request #6 from Yelp/y-trobinso_add_group_and_deduped_user_support
Add disambiguation for multiple users with the same name in a cluster, update documentation, add group stub in preparation of full functionality
2 parents 8f099a6 + 767453e commit 4563a6f

File tree

4 files changed

+126
-27
lines changed

4 files changed

+126
-27
lines changed

README.md

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ The postgresql module comes with many options for configuring the server. While
325325
* [postgresql::server::extension](#postgresqlserverextension)
326326
* [postgresql::server::grant](#postgresqlservergrant)
327327
* [postgresql::server::grant_role](#postgresqlservergrant_role)
328+
* [postgresql::server::group](#postgresqlservergroup)
328329
* [postgresql::server::pg_hba_rule](#postgresqlserverpg_hba_rule)
329330
* [postgresql::server::pg_ident_rule](#postgresqlserverpg_ident_rule)
330331
* [postgresql::server::recovery](#postgresqlserverrecovery)
@@ -448,6 +449,12 @@ Overrides the default PostgreSQL devel package name.
448449

449450
Default value: OS dependent.
450451

452+
##### `dialect`
453+
454+
Sets the dialect for all databases managed with this module. Select 'postgres' for managing vanilla postgres databases, or 'redshift' for Amazon Redshift databases. Note: local database software is only installable using the 'postgres' dialect.
455+
456+
Default value: 'postgres'
457+
451458
##### `docs_package_name`
452459

453460
Optional.
@@ -742,6 +749,12 @@ Specifies the name of the default database to connect with. On most systems this
742749

743750
Specifies a hash of environment variables used when connecting to a remote server. Becomes the default for other defined-types. i.e. `postgresql::server::role`
744751

752+
##### `dialect`
753+
754+
Sets the dialect for all databases managed with this module. Select 'postgres' for managing vanilla postgres databases, or 'redshift' for Amazon Redshift databases. Note: local database software is only installable using the 'postgres' dialect.
755+
756+
Default value: value set in `postgresql::params` or `postgresql::globals`
757+
745758
##### `encoding`
746759

747760
Sets the default encoding for all databases created with this module. On certain operating systems this is also used during the `template1` initialization, so it becomes a default outside of the module as well.
@@ -945,6 +958,12 @@ Overrides the default status check command for your PostgreSQL service.
945958

946959
Default value: OS dependent.
947960

961+
##### `skip_install`
962+
963+
Overrides the installation of a local PostgreSQL instance, such as when performing tests or when an instance is managed remotely.
964+
965+
Default value: `false`.
966+
948967
##### `user`
949968

950969
Overrides the default PostgreSQL super user and owner of PostgreSQL related files in the file system.
@@ -1281,6 +1300,42 @@ Specifies a hash of environment variables used when connecting to a remote serve
12811300

12821301
Default value: Connects to the local Postgres instance.
12831302

1303+
#### postgresql::server::group
1304+
1305+
Creates a Postgres group.
1306+
1307+
##### `connect_settings`
1308+
Required.
1309+
1310+
Specifies a hash of environment variables used when connecting to a remote server.
1311+
1312+
Default value: `undef`, because groups only currently make sense in remotely-managed Redshift clusters.
1313+
1314+
##### `db`
1315+
Required.
1316+
1317+
Specifies which database psql will use to perform certain checks, such as what settings exist for the current group prior to applying changes.
1318+
1319+
##### `dialect`
1320+
Reserved for future use. Currently both the 'postgres' and 'redshift' dialects are identical in operation.
1321+
1322+
Default value: inherit from server settings.
1323+
1324+
##### `groupname`
1325+
Defines the name of the group to create.
1326+
1327+
Default value: the namevar.
1328+
1329+
##### `groupmembers`
1330+
Defines the users that are part of the current group, if any.
1331+
1332+
Default value: `undef`, which specifies an empty members list.
1333+
1334+
##### `port`
1335+
Optional port override for connecting to postgres when applying this group.
1336+
1337+
Default value: inherit from `$connect_settings` or `postgresql::server::port`
1338+
12841339
#### postgresql::server::pg_hba_rule
12851340

12861341
Allows you to create an access rule for `pg_hba.conf`. For more details see the [usage example](#create-an-access-rule-for-pghba.conf) and the [PostgreSQL documentation](http://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html).
@@ -1410,7 +1465,7 @@ Provides the target for the rule, and is generally an internal only property.
14101465
**Use with caution.**
14111466

14121467
#### postgresql::server::role
1413-
Creates a role or user in PostgreSQL.
1468+
Creates a role or user in PostgreSQL. In the Redshift dialect, this creates a new redshift user (see `postgresql::server::group` for groups).
14141469

14151470
##### `connection_limit`
14161471
Specifies how many concurrent connections the role can make.
@@ -1432,6 +1487,16 @@ Specifies whether to grant the ability to create new roles with this role.
14321487

14331488
Default value: `false`.
14341489

1490+
##### `db`
1491+
Required.
1492+
1493+
Specifies which database psql will use to perform certain checks, such as what settings exist for the current role prior to applying changes.
1494+
1495+
##### `dialect`
1496+
Determines whether to use postgres or redshift's definition of a user. Also determines the tables to query for user metadata.
1497+
1498+
Default value: inherit from server settings.
1499+
14351500
##### `inherit`
14361501
Specifies whether to grant inherit capability for the new role.
14371502

@@ -1451,6 +1516,11 @@ password_hash => postgresql_password('myusername', 'mypassword'),
14511516
}
14521517
```
14531518

1519+
##### `port`
1520+
Optional port override for connecting to postgres when applying this role.
1521+
1522+
Default value: inherit from `$connect_settings` or `postgresql::server::port`
1523+
14541524
##### `replication`
14551525

14561526
Provides provides replication capabilities for this role if set to `true`.

manifests/server/group.pp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Define for creating a redshift group. See README.md for more information
2+
define postgresql::server::group(
3+
$db = $postgresql::server::default_database,
4+
$port = undef,
5+
$groupmembers = undef,
6+
$groupname = $title,
7+
$dialect = $postgresql::server::dialect,
8+
$connect_settings = undef,
9+
) {
10+
$psql_user = $postgresql::server::user
11+
$psql_group = $postgresql::server::group
12+
$psql_path = $postgresql::server::psql_path
13+
$module_workdir = $postgresql::server::module_workdir
14+
15+
# TODO: complete this functionality
16+
$groupmembers_list = []
17+
$groupmembers_sql = ''
18+
19+
postgresql_psql { "${title}: CREATE GROUP ${groupname}":
20+
command => "CREATE GROUP ${groupname}",
21+
unless => "SELECT 1 FROM pg_group WHERE groname = '${groupname}'",
22+
environment => $environment,
23+
require => Class['Postgresql::Server'],
24+
}
25+
26+
postgresql_psql {"${title}: ALTER GROUP \"${group}\" ${groupmembers_sql}":
27+
unless => "SELECT 1 FROM pg_group WHERE groname = '${groupname}' AND grolist = ${groupmembers_list}",
28+
}
29+
}

manifests/server/role.pp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
connect_settings => $connect_settings,
9494
cwd => $module_workdir,
9595
require => [
96-
Postgresql_psql["CREATE ${role_keyword} ${username} ENCRYPTED PASSWORD ****"],
96+
Postgresql_psql["${title}: CREATE ${role_keyword} ${username} ENCRYPTED PASSWORD ****"],
9797
Class['postgresql::server'],
9898
],
9999
}
@@ -104,54 +104,54 @@
104104
$options_sql = "${createrole_sql} ${createdb_sql}"
105105
}
106106

107-
postgresql_psql { "CREATE ${role_keyword} ${username} ENCRYPTED PASSWORD ****":
107+
postgresql_psql { "${title}: CREATE ${role_keyword} ${username} ENCRYPTED PASSWORD ****":
108108
command => "CREATE ${role_keyword} \"${username}\" ${password_sql} ${options_sql} CONNECTION LIMIT ${role_connection_limit}",
109109
unless => "SELECT 1 FROM ${role_table} WHERE ${role_column_prefix}name = '${username}'",
110110
environment => $environment,
111111
require => Class['Postgresql::Server'],
112112
}
113113

114-
postgresql_psql {"ALTER ${role_keyword} \"${username}\" ${createdb_sql}":
114+
postgresql_psql {"${title}: ALTER ${role_keyword} \"${username}\" ${createdb_sql}":
115115
unless => "SELECT 1 FROM ${role_table} WHERE ${role_column_prefix}name = '${username}' AND ${role_column_prefix}createdb = ${createdb}",
116116
}
117117

118118
if ($dialect == 'postgres') {
119-
postgresql_psql {"ALTER ${role_keyword} \"${username}\" ${createrole_sql}":
119+
postgresql_psql {"${title}: ALTER ${role_keyword} \"${username}\" ${createrole_sql}":
120120
unless => "SELECT 1 FROM ${role_table} WHERE ${role_column_prefix}name = '${username}' AND rolcreaterole = ${createrole}",
121121
}
122122

123-
postgresql_psql {"ALTER ${role_keyword} \"${username}\" ${superuser_sql}":
123+
postgresql_psql {"${title}: ALTER ${role_keyword} \"${username}\" ${superuser_sql}":
124124
unless => "SELECT 1 FROM ${role_table} WHERE rolname = '${username}' AND rolsuper = ${superuser}",
125125
}
126126

127-
postgresql_psql {"ALTER ${role_keyword} \"${username}\" ${login_sql}":
127+
postgresql_psql {"${title}: ALTER ${role_keyword} \"${username}\" ${login_sql}":
128128
unless => "SELECT 1 FROM ${role_table} WHERE rolname = '${username}' AND rolcanlogin = ${login}",
129129
}
130130

131-
postgresql_psql {"ALTER ${role_keyword} \"${username}\" ${inherit_sql}":
131+
postgresql_psql {"${title}: ALTER ${role_keyword} \"${username}\" ${inherit_sql}":
132132
unless => "SELECT 1 FROM ${role_table} WHERE rolname = '${username}' AND rolinherit = ${inherit}",
133133
}
134134

135135
if(versioncmp($version, '9.1') >= 0) {
136136
if $replication_sql == '' {
137-
postgresql_psql {"ALTER ${role_keyword} \"${username}\" NOREPLICATION":
137+
postgresql_psql {"${title}: ALTER ${role_keyword} \"${username}\" NOREPLICATION":
138138
unless => "SELECT 1 FROM ${role_table} WHERE rolname = '${username}' AND rolreplication = ${replication}",
139139
}
140140
} else {
141-
postgresql_psql {"ALTER ${role_keyword} \"${username}\" ${replication_sql}":
141+
postgresql_psql {"${title}: ALTER ${role_keyword} \"${username}\" ${replication_sql}":
142142
unless => "SELECT 1 FROM ${role_table} WHERE rolname = '${username}' AND rolreplication = ${replication}",
143143
}
144144
}
145145
}
146146
} elsif ($dialect == 'redshift') {
147147

148148
# CREATEUSER actually defines superuser privileges in Redshift: http://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_USER.html
149-
postgresql_psql {"ALTER ${role_keyword} \"${username}\" ${createrole_sql}":
149+
postgresql_psql {"${title}: ALTER ${role_keyword} \"${username}\" ${createrole_sql}":
150150
unless => "SELECT 1 FROM ${role_table} WHERE usename = '${username}' AND usesuper = ${createrole}",
151151
}
152152
}
153153

154-
postgresql_psql {"ALTER ${role_keyword} \"${username}\" CONNECTION LIMIT ${role_connection_limit}":
154+
postgresql_psql {"${title}: ALTER ${role_keyword} \"${username}\" CONNECTION LIMIT ${role_connection_limit}":
155155
unless => "SELECT 1 FROM ${role_table} WHERE ${role_column_prefix}name = '${username}' AND ${role_column_prefix}connlimit = '${role_connection_limit}'",
156156
}
157157

@@ -162,7 +162,7 @@
162162
$pwd_md5 = md5("${password_hash}${username}")
163163
$pwd_hash_sql = "md5${pwd_md5}"
164164
}
165-
postgresql_psql { "ALTER ${role_keyword} ${username} ENCRYPTED PASSWORD ****":
165+
postgresql_psql { "${title}: ALTER ${role_keyword} ${username} ENCRYPTED PASSWORD ****":
166166
command => "ALTER ${role_keyword} \"${username}\" ${password_sql}",
167167
unless => "SELECT 1 FROM ${password_table} WHERE usename = '${username}' AND passwd = '${pwd_hash_sql}'",
168168
environment => $environment,

spec/unit/defines/server/role_spec.rb

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@
3232

3333
it { is_expected.to contain_postgresql__server__role('test') }
3434
it 'should have create role for "test" user with password as ****' do
35-
is_expected.to contain_postgresql_psql('CREATE ROLE test ENCRYPTED PASSWORD ****').with({
35+
is_expected.to contain_postgresql_psql('test: CREATE ROLE test ENCRYPTED PASSWORD ****').with({
3636
'command' => "CREATE ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD' NOCREATEROLE NOCREATEDB LOGIN NOSUPERUSER CONNECTION LIMIT -1",
3737
'environment' => "NEWPGPASSWD=new-pa$s",
3838
'unless' => "SELECT 1 FROM pg_roles WHERE rolname = 'test'",
3939
'port' => "5432",
4040
})
4141
end
4242
it 'should have alter role for "test" user with password as ****' do
43-
is_expected.to contain_postgresql_psql('ALTER ROLE test ENCRYPTED PASSWORD ****').with({
43+
is_expected.to contain_postgresql_psql('test: ALTER ROLE test ENCRYPTED PASSWORD ****').with({
4444
'command' => "ALTER ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD'",
4545
'environment' => "NEWPGPASSWD=new-pa$s",
4646
'unless' => "SELECT 1 FROM pg_shadow WHERE usename = 'test' AND passwd = 'md5b6f7fcbbabb4befde4588a26c1cfd2fa'",
@@ -61,7 +61,7 @@
6161

6262
it { is_expected.to contain_postgresql__server__role('test') }
6363
it 'should have create role for "test" user with password as ****' do
64-
is_expected.to contain_postgresql_psql('CREATE ROLE test ENCRYPTED PASSWORD ****').with({
64+
is_expected.to contain_postgresql_psql('test: CREATE ROLE test ENCRYPTED PASSWORD ****').with({
6565
'command' => "CREATE ROLE \"test\" NOCREATEROLE NOCREATEDB LOGIN NOSUPERUSER CONNECTION LIMIT -1",
6666
'environment' => [],
6767
'unless' => "SELECT 1 FROM pg_roles WHERE rolname = 'test'",
@@ -87,7 +87,7 @@
8787

8888
it { is_expected.to contain_postgresql__server__role('test') }
8989
it 'should have create role for "test" user with password as ****' do
90-
is_expected.to contain_postgresql_psql('CREATE ROLE test ENCRYPTED PASSWORD ****').with({
90+
is_expected.to contain_postgresql_psql('test: CREATE ROLE test ENCRYPTED PASSWORD ****').with({
9191
'command' => "CREATE ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD' NOCREATEROLE NOCREATEDB LOGIN NOSUPERUSER CONNECTION LIMIT -1",
9292
'environment' => "NEWPGPASSWD=new-pa$s",
9393
'unless' => "SELECT 1 FROM pg_roles WHERE rolname = 'test'",
@@ -100,7 +100,7 @@
100100
})
101101
end
102102
it 'should have alter role for "test" user with password as ****' do
103-
is_expected.to contain_postgresql_psql('ALTER ROLE test ENCRYPTED PASSWORD ****').with({
103+
is_expected.to contain_postgresql_psql('test: ALTER ROLE test ENCRYPTED PASSWORD ****').with({
104104
'command' => "ALTER ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD'",
105105
'environment' => "NEWPGPASSWD=new-pa$s",
106106
'unless' => "SELECT 1 FROM pg_shadow WHERE usename = 'test' AND passwd = 'md5b6f7fcbbabb4befde4588a26c1cfd2fa'",
@@ -132,7 +132,7 @@
132132

133133
it { is_expected.to contain_postgresql__server__role('test') }
134134
it 'should have create role for "test" user with password as ****' do
135-
is_expected.to contain_postgresql_psql('CREATE ROLE test ENCRYPTED PASSWORD ****').with({
135+
is_expected.to contain_postgresql_psql('test: CREATE ROLE test ENCRYPTED PASSWORD ****').with({
136136
'command' => "CREATE ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD' NOCREATEROLE NOCREATEDB LOGIN NOSUPERUSER CONNECTION LIMIT -1",
137137
'environment' => "NEWPGPASSWD=new-pa$s",
138138
'unless' => "SELECT 1 FROM pg_roles WHERE rolname = 'test'",
@@ -144,7 +144,7 @@
144144
})
145145
end
146146
it 'should have alter role for "test" user with password as ****' do
147-
is_expected.to contain_postgresql_psql('ALTER ROLE test ENCRYPTED PASSWORD ****').with({
147+
is_expected.to contain_postgresql_psql('test: ALTER ROLE test ENCRYPTED PASSWORD ****').with({
148148
'command' => "ALTER ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD'",
149149
'environment' => "NEWPGPASSWD=new-pa$s",
150150
'unless' => "SELECT 1 FROM pg_shadow WHERE usename = 'test' AND passwd = 'md5b6f7fcbbabb4befde4588a26c1cfd2fa'",
@@ -171,15 +171,15 @@
171171

172172
it { is_expected.to contain_postgresql__server__role('test') }
173173
it 'should have create role for "test" user with password as ****' do
174-
is_expected.to contain_postgresql_psql('CREATE USER test ENCRYPTED PASSWORD ****').with({
174+
is_expected.to contain_postgresql_psql('test: CREATE USER test ENCRYPTED PASSWORD ****').with({
175175
'command' => "CREATE USER \"test\" PASSWORD '$NEWPGPASSWD' NOCREATEUSER NOCREATEDB CONNECTION LIMIT UNLIMITED",
176176
'environment' => "NEWPGPASSWD=new-pa$s",
177177
'unless' => "SELECT 1 FROM pg_user_info WHERE usename = 'test'",
178178
'port' => "5432",
179179
})
180180
end
181181
it 'should have alter role for "test" user with password as ****' do
182-
is_expected.to contain_postgresql_psql('ALTER USER test ENCRYPTED PASSWORD ****').with({
182+
is_expected.to contain_postgresql_psql('test: ALTER USER test ENCRYPTED PASSWORD ****').with({
183183
'command' => "ALTER USER \"test\" PASSWORD '$NEWPGPASSWD'",
184184
'environment' => "NEWPGPASSWD=new-pa$s",
185185
'unless' => "SELECT 1 FROM pg_user WHERE usename = 'test' AND passwd = 'md5b6f7fcbbabb4befde4588a26c1cfd2fa'",
@@ -200,7 +200,7 @@
200200

201201
it { is_expected.to contain_postgresql__server__role('test') }
202202
it 'should have create role for "test" user with password as ****' do
203-
is_expected.to contain_postgresql_psql('CREATE USER test ENCRYPTED PASSWORD ****').with({
203+
is_expected.to contain_postgresql_psql('test: CREATE USER test ENCRYPTED PASSWORD ****').with({
204204
'command' => "CREATE USER \"test\" PASSWORD DISABLE NOCREATEUSER NOCREATEDB CONNECTION LIMIT UNLIMITED",
205205
'environment' => [],
206206
'unless' => "SELECT 1 FROM pg_user_info WHERE usename = 'test'",
@@ -226,7 +226,7 @@
226226

227227
it { is_expected.to contain_postgresql__server__role('test') }
228228
it 'should have create role for "test" user with password as ****' do
229-
is_expected.to contain_postgresql_psql('CREATE USER test ENCRYPTED PASSWORD ****').with({
229+
is_expected.to contain_postgresql_psql('test: CREATE USER test ENCRYPTED PASSWORD ****').with({
230230
'command' => "CREATE USER \"test\" PASSWORD '$NEWPGPASSWD' NOCREATEUSER NOCREATEDB CONNECTION LIMIT UNLIMITED",
231231
'environment' => "NEWPGPASSWD=new-pa$s",
232232
'unless' => "SELECT 1 FROM pg_user_info WHERE usename = 'test'",
@@ -239,7 +239,7 @@
239239
})
240240
end
241241
it 'should have alter role for "test" user with password as ****' do
242-
is_expected.to contain_postgresql_psql('ALTER USER test ENCRYPTED PASSWORD ****').with({
242+
is_expected.to contain_postgresql_psql('test: ALTER USER test ENCRYPTED PASSWORD ****').with({
243243
'command' => "ALTER USER \"test\" PASSWORD '$NEWPGPASSWD'",
244244
'environment' => "NEWPGPASSWD=new-pa$s",
245245
'unless' => "SELECT 1 FROM pg_user WHERE usename = 'test' AND passwd = 'md5b6f7fcbbabb4befde4588a26c1cfd2fa'",
@@ -271,7 +271,7 @@
271271

272272
it { is_expected.to contain_postgresql__server__role('test') }
273273
it 'should have create role for "test" user with password as ****' do
274-
is_expected.to contain_postgresql_psql('CREATE USER test ENCRYPTED PASSWORD ****').with({
274+
is_expected.to contain_postgresql_psql('test: CREATE USER test ENCRYPTED PASSWORD ****').with({
275275
'command' => "CREATE USER \"test\" PASSWORD '$NEWPGPASSWD' NOCREATEUSER NOCREATEDB CONNECTION LIMIT UNLIMITED",
276276
'environment' => "NEWPGPASSWD=new-pa$s",
277277
'unless' => "SELECT 1 FROM pg_user_info WHERE usename = 'test'",
@@ -283,7 +283,7 @@
283283
})
284284
end
285285
it 'should have alter role for "test" user with password as ****' do
286-
is_expected.to contain_postgresql_psql('ALTER USER test ENCRYPTED PASSWORD ****').with({
286+
is_expected.to contain_postgresql_psql('test: ALTER USER test ENCRYPTED PASSWORD ****').with({
287287
'command' => "ALTER USER \"test\" PASSWORD '$NEWPGPASSWD'",
288288
'environment' => "NEWPGPASSWD=new-pa$s",
289289
'unless' => "SELECT 1 FROM pg_user WHERE usename = 'test' AND passwd = 'md5b6f7fcbbabb4befde4588a26c1cfd2fa'",

0 commit comments

Comments
 (0)