Skip to content

Commit 45055d3

Browse files
committed
Bring database, database_user, and database_grant into alignment with mysql module
Renamed a few files and made some tweaks to try to get database_grant, database_user, and database types into a state where they work very similarly to the ones in the mysql module. Also introduced a "postgresql_password" function that can be used to generate an md5 password hash for a postgres user.
1 parent ba80247 commit 45055d3

11 files changed

+189
-57
lines changed

Diff for: lib/puppet/parser/functions/postgresql_password.rb

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# hash a string as mysql's "PASSWORD()" function would do it
2+
require 'digest/md5'
3+
4+
module Puppet::Parser::Functions
5+
newfunction(:postgresql_password, :type => :rvalue, :doc => <<-EOS
6+
Returns the postgresql password hash from the clear text username / password.
7+
EOS
8+
) do |args|
9+
10+
raise(Puppet::ParseError, "postgresql_password(): Wrong number of arguments " +
11+
"given (#{args.size} for 2)") if args.size != 2
12+
13+
username = args[0]
14+
password = args[1]
15+
16+
'md5' + Digest::MD5.hexdigest(password + username)
17+
end
18+
end

Diff for: manifests/db.pp renamed to manifests/database.pp

+10-7
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,18 @@
1616
# See the License for the specific language governing permissions and
1717
# limitations under the License.
1818

19-
define postgresql::db(
19+
# TODO: in order to match up more closely with the mysql module, this probably
20+
# needs to be moved over to ruby, and add support for ensurable.
21+
22+
define postgresql::database(
2023
$dbname = $title,
21-
$version = '9.1',
22-
$encoding = 'UTF8',
23-
$options='' )
24+
$charset = 'UTF8')
2425
{
25-
# TODO: This should be found based on the operating system; currently hardcoded to Ubuntu's path choice
26-
exec {"/usr/lib/postgresql/${version}/bin/createdb --encoding '$encoding' '$dbname'":
27-
unless => "/usr/lib/postgresql/${version}/bin/psql --command=\"SELECT datname FROM pg_database WHERE datname=\'$dbname\' \" --pset=tuples_only | grep -q $dbname",
26+
require postgresql::params
27+
28+
29+
exec {"${postgresql::params::createdb_path} --template=template0 --encoding '$charset' --locale=C '$dbname'":
30+
unless => "${postgresql::params::psql_path} --command=\"SELECT datname FROM pg_database WHERE datname=\'$dbname\' \" --pset=tuples_only | grep -q $dbname",
2831
user => 'postgres',
2932
}
3033
}

Diff for: manifests/database_grant.pp

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# puppet-postgresql
2+
# For all details and documentation:
3+
# http://github.com/inkling/puppet-postgresql
4+
#
5+
# Copyright 2012- Inkling Systems, Inc.
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
# TODO: in mysql module, the grant resource name might look like this: 'user@host/dbname';
20+
# I think that the API for the resource type should split these up, because it's
21+
# easier / safer to recombine them for mysql than it is to parse them for other
22+
# databases. Also, in the mysql module, the hostname portion of that string
23+
# affects the user's ability to connect from remote hosts. In postgres this is
24+
# managed via pg_hba.conf; not sure if we want to try to reconcile that difference
25+
# in the modules or not.
26+
27+
define postgresql::database_grant(
28+
# TODO: mysql supports an array of privileges here. We should do that if we
29+
# port this to ruby.
30+
$privilege,
31+
$db,
32+
$role,
33+
$psql_db = 'postgres',
34+
$psql_user='postgres',
35+
) {
36+
37+
# TODO: FIXME: only works on databases, due to using has_database_privilege
38+
39+
# TODO: this is a terrible hack; if they pass "ALL" as the desired privilege,
40+
# we need a way to test for it--and has_database_privilege does not recognize
41+
# 'ALL' as a valid privelege name. So we probably need to hard-code a mapping
42+
# between 'ALL' and the list of actual privileges that it entails, and loop
43+
# over them to check them. That sort of thing will probably need to wait until
44+
# we port this over to ruby, so, for now, we're just going to assume that if
45+
# they have "CREATE" privileges on a database, then they have "ALL". (I told
46+
# you that it was terrible!)
47+
$unless_privilege = $privilege ? {
48+
'ALL' => 'CREATE',
49+
default => $privilege,
50+
}
51+
52+
postgresql::psql {"GRANT $privilege ON database $db TO $role":
53+
db => $psql_db,
54+
user => $psql_user,
55+
unless => "SELECT 1 WHERE has_database_privilege('$role', '$db', '$unless_privilege')",
56+
}
57+
}
58+

Diff for: manifests/user.pp renamed to manifests/database_user.pp

+14-8
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,20 @@
1616
# See the License for the specific language governing permissions and
1717
# limitations under the License.
1818

19-
define postgresql::user($username=$title, $password, $version='9.1', $db = 'postgres', $createdb=false, $superuser=false, $createrole=false) {
19+
define postgresql::database_user(
20+
$username=$title,
21+
$password_hash,
22+
$db = 'postgres',
23+
$createdb=false,
24+
$superuser=false,
25+
$createrole=false
26+
) {
2027
postgresql::role {$username:
21-
db => $db,
22-
password => $password,
23-
version => $version,
24-
login => true,
25-
createdb => $createdb,
26-
superuser => $superuser,
27-
createrole => $createrole,
28+
db => $db,
29+
password_hash => $password_hash,
30+
login => true,
31+
createdb => $createdb,
32+
superuser => $superuser,
33+
createrole => $createrole,
2834
}
2935
}

Diff for: manifests/grant.pp

-30
This file was deleted.

Diff for: manifests/params.pp

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
# Sample Usage:
1212
#
1313
class postgresql::params {
14-
15-
1614
$user = 'postgres'
1715
$group = 'postgres'
1816
$ip_mask_postgres_user = '127.0.0.1/32'
@@ -37,6 +35,8 @@
3735
$server_package_name = 'postgresql-server'
3836
$needs_initdb = true
3937
$initdb_path = '/usr/bin/initdb'
38+
$createdb_path = '/usr/bin/createdb'
39+
$psql_path = '/usr/bin/psql'
4040
$datadir = '/var/lib/pgsql/data/'
4141
$pg_hba_conf_path = '/var/lib/pgsql/data/pg_hba.conf'
4242
$postgresql_conf_path = '/var/lib/pgsql/data/postgresql.conf'
@@ -50,6 +50,8 @@
5050
$server_package_name = 'postgresql'
5151
$needs_initdb = false
5252
$initdb_path = "/usr/lib/postgresql/${::postgres_default_version}/bin/initdb"
53+
$createdb_path = "/usr/lib/postgresql/${::postgres_default_version}/bin/createdb"
54+
$psql_path = "/usr/lib/postgresql/${::postgres_default_version}/bin/psql"
5355
$datadir = "/var/lib/postgresql/${::postgres_default_version}/main"
5456
$pg_hba_conf_path = "/etc/postgresql/${::postgres_default_version}/main/pg_hba.conf"
5557
$postgresql_conf_path = "/etc/postgresql/${::postgres_default_version}/main/postgresql.conf"

Diff for: manifests/psql.pp

+10-6
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,23 @@
1616
# See the License for the specific language governing permissions and
1717
# limitations under the License.
1818

19-
define postgresql::psql($command = $title, $unless, $db, $user = 'postgres', $version='9.1') {
19+
define postgresql::psql($command = $title, $unless, $db, $user = 'postgres') {
2020

21-
# FIXME: shellquote does not work, and this regex works for trivial things but not nested escaping.
21+
require postgresql::params
22+
23+
# TODO: FIXME: shellquote does not work, and this regex works for trivial things but not nested escaping.
2224
# Need a lexer, preferably a ruby SQL parser to catch errors at catalog time
2325
# Possibly https://github.com/omghax/sql ?
2426

25-
$psql = "/usr/lib/postgresql/$version/bin/psql --no-password --tuples-only --quiet --dbname $db"
27+
$psql = "${postgresql::params::psql_path} --no-password --tuples-only --quiet --dbname $db"
2628
$quoted_command = regsubst($command, '"', '\\"')
2729
$quoted_unless = regsubst($unless, '"', '\\"')
2830

29-
exec {"/bin/echo \"$quoted_command\" | $psql":
30-
unless => "/bin/echo \"$quoted_$unless\" | $psql | egrep -v -q '^$'",
31-
user => $user,
31+
exec {"/bin/echo \"$quoted_command\" | $psql |egrep -v -q '^$'":
32+
cwd => '/tmp',
33+
user => $user,
34+
returns => 1,
35+
unless => "/bin/echo \"$quoted_$unless\" | $psql | egrep -v -q '^$'",
3236
}
3337
}
3438

Diff for: manifests/role.pp

+11-4
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,23 @@
1616
# See the License for the specific language governing permissions and
1717
# limitations under the License.
1818

19-
define postgresql::role($username=$title, $password, $db='postgres', $version='9.1', $login=false, $createrole=false, $createdb=false, $superuser=false) {
19+
define postgresql::role(
20+
$username=$title,
21+
$password_hash,
22+
$db='postgres',
23+
$login=false,
24+
$createrole=false,
25+
$createdb=false,
26+
$superuser=false
27+
) {
2028

2129
$login_sql = $login ? { true => 'LOGIN' , false => 'NOLOGIN' }
2230
$createrole_sql = $createrole ? { true => 'CREATEROLE', false => 'NOCREATEROLE' }
2331
$createdb_sql = $createdb ? { true => 'CREATEDB' , false => 'NOCREATEDB' }
2432
$superuser_sql = $superuser ? { true => 'SUPERUSER' , false => 'NOSUPERUSER' }
2533

26-
# FIXME: Will not correct the superuser / createdb / createrole / login status of a role that already exists
27-
postgresql::psql {"CREATE ROLE ${username} ENCRYPTED PASSWORD '${password}' $login_sql $createrole_sql $createdb_sql $superuser_sql":
28-
version => $version,
34+
# TODO: FIXME: Will not correct the superuser / createdb / createrole / login status of a role that already exists
35+
postgresql::psql {"CREATE ROLE ${username} ENCRYPTED PASSWORD '${password_hash}' $login_sql $createrole_sql $createdb_sql $superuser_sql":
2936
db => $db,
3037
user => 'postgres',
3138
unless => "SELECT rolname FROM pg_roles WHERE rolname='$username'",

Diff for: tests/postgresql_database.pp

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class { 'postgresql::server':
2+
config_hash => {
3+
'ip_mask_postgres_user' => '0.0.0.0/0',
4+
'ip_mask_all_users' => '0.0.0.0/0',
5+
'listen_addresses' => '*',
6+
'manage_redhat_firewall' => true,
7+
'postgres_password' => 'postgres',
8+
},
9+
}
10+
11+
postgresql::database{ ['test1', 'test2', 'test3']:
12+
# TODO: ensure not yet supported
13+
#ensure => present,
14+
charset => 'utf8',
15+
require => Class['postgresql::server'],
16+
}
17+
postgresql::database{ 'test4':
18+
# TODO: ensure not yet supported
19+
#ensure => present,
20+
charset => 'latin1',
21+
require => Class['postgresql::server'],
22+
}

Diff for: tests/postgresql_grant.pp

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# TODO: in mysql module, the grant resource name might look like this: 'user@host/dbname';
2+
# I think that the API for the resource type should split these up, because it's
3+
# easier / safer to recombine them for mysql than it is to parse them for other
4+
# databases. Also, in the mysql module, the hostname portion of that string
5+
# affects the user's ability to connect from remote hosts. In postgres this is
6+
# managed via pg_hba.conf; not sure if we want to try to reconcile that difference
7+
# in the modules or not.
8+
postgresql::database_grant{'test1':
9+
# TODO: mysql supports an array of privileges here. We should do that if we
10+
# port this to ruby.
11+
privilege => 'ALL',
12+
db => 'test1',
13+
role => 'dan',
14+
}

Diff for: tests/postgresql_user.pp

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class { 'postgresql::server':
2+
config_hash => {
3+
'ip_mask_postgres_user' => '0.0.0.0/0',
4+
'ip_mask_all_users' => '0.0.0.0/0',
5+
'listen_addresses' => '*',
6+
'manage_redhat_firewall' => true,
7+
'postgres_password' => 'postgres',
8+
},
9+
}
10+
11+
# TODO: in mysql module, the username includes, e.g., '@%' or '@localhost', which
12+
# affects the user's ability to connect from remote hosts. In postgres this is
13+
# managed via pg_hba.conf; not sure if we want to try to reconcile that difference
14+
# in the modules or not.
15+
postgresql::database_user{ 'redmine':
16+
# TODO: ensure is not yet supported
17+
#ensure => present,
18+
password_hash => postgresql_password('redmine', 'redmine'),
19+
require => Class['postgresql::server'],
20+
}
21+
22+
postgresql::database_user{ 'dan':
23+
# TODO: ensure is not yet supported
24+
#ensure => present,
25+
password_hash => postgresql_password('dan', 'blah'),
26+
require => Class['postgresql::server'],
27+
}
28+

0 commit comments

Comments
 (0)