Skip to content

Commit c6532b0

Browse files
committed
Merge pull request puppetlabs#120 from kbarber/ticket/master/pg_hba_template
Provide new defined resources for managing pg_hba.conf
2 parents 8dba376 + b9db279 commit c6532b0

20 files changed

+624
-151
lines changed

.fixtures.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ fixtures:
33
apt: "git://github.com/puppetlabs/puppetlabs-apt.git"
44
stdlib: "git://github.com/puppetlabs/puppetlabs-stdlib.git"
55
firewall: "git://github.com/puppetlabs/puppetlabs-firewall.git"
6+
concat: "git://github.com/ripienaar/puppet-concat.git"
67
symlinks:
78
postgresql: "#{source_dir}"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
# This is a library, so don't pin
44
Gemfile.lock
55
/metadata.json
6+
spec/fixtures

Modulefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ project_page 'https://github.com/puppetlabs/puppet-postgresql'
1010
dependency 'puppetlabs/stdlib', '>=3.2.0 <4.0.0'
1111
dependency 'puppetlabs/firewall', '>= 0.0.4'
1212
dependency 'puppetlabs/apt', '>=1.1.0 <2.0.0'
13+
dependency 'ripienaar/concat', '=~ 0.2.0'

README.md

Lines changed: 85 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@ postgresql
66
2. [Module Description - What does the module do?](#module-description)
77
3. [Setup - The basics of getting started with PostgreSQL module](#setup)
88
4. [Usage - The classes and parameters available for configuration](#usage)
9-
5. [Implementation - An under-the-hood peek at what the module is doing](#implementation)
10-
6. [Limitations - OS compatibility, etc.](#limitations)
11-
7. [Development - Guide for contributing to the module](#development)
12-
8. [Disclaimer - Licensing information](#disclaimer)
13-
9. [Transfer Notice - Notice of authorship change](#transfer-notice)
14-
10. [Contributors - List of module contributors](#contributors)
15-
11. [Release Notes - Notes on the most recent updates to the module](#release-notes)
9+
5. [Limitations - OS compatibility, etc.](#limitations)
10+
6. [Development - Guide for contributing to the module](#development)
11+
7. [Disclaimer - Licensing information](#disclaimer)
12+
8. [Transfer Notice - Notice of authorship change](#transfer-notice)
13+
9. [Contributors - List of module contributors](#contributors)
14+
10. [Release Notes - Notes on the most recent updates to the module](#release-notes)
1615

1716

1817
Overview
@@ -105,7 +104,10 @@ Usage
105104

106105
The postgresql module comes with many options for configuring the server. While you are unlikely to use all of the below settings, they allow you a decent amount of control over your security settings.
107106

108-
###postgresql::server
107+
###Class: postgresql
108+
This class is used to configure the cross-domain settings for this module.
109+
110+
###Class: postgresql::server
109111
Here are the options that you can set in the `config_hash` parameter of `postgresql::server`:
110112

111113
####`postgres_password`
@@ -140,7 +142,7 @@ List of strings for access control for connection method, users, databases, IPv4
140142
List of strings for access control for connection method, users, databases, IPv6
141143
addresses; see [postgresql documentation](http://www.postgresql.org/docs/9.2/static/auth-pg-hba-conf.html) about pg_hba.conf for information (please note that the link will take you to documentation for the most recent version of Postgres, however links for earlier versions can be found on that page).
142144

143-
###postgresql::client
145+
###Class: postgresql::client
144146

145147
This class installs postgresql client software. Alter the following parameters if you have a custom version you would like to install (Note: don't forget to make sure to add any necessary yum or apt repositories if specifying a custom version):
146148

@@ -150,7 +152,7 @@ The name of the postgresql client package.
150152
####`package_ensure`
151153
The ensure parameter passed on to postgresql client package resource.
152154

153-
###postgresql::java
155+
###Class: postgresql::java
154156
This class installs postgresql bindings for Java (JDBC). Alter the following parameters if you have a custom version you would like to install (Note: don't forget to make sure to add any necessary yum or apt repositories if specifying a custom version):
155157

156158
####`package_name`
@@ -159,63 +161,80 @@ The name of the postgresql java package.
159161
####`package_ensure`
160162
The ensure parameter passed on to postgresql java package resource.
161163

162-
### Custom Functions
164+
###Resource: postgresql::database
165+
This defined type can be used to create a database with no users and no permissions, which is a rare use case.
163166

164-
If you need to generate a postgres encrypted password, use `postgresql_password`. You can call it from your production manifests if you don’t mind them containing the clear text versions of your passwords, or you can call it from the command line and then copy and paste the encrypted password into your manifest:
167+
###Resource: postgresql::tablespace
168+
This defined type can be used to create a tablespace.
165169

166-
$ puppet apply --execute 'notify { "test": message => postgresql_password("username", "password") }'
170+
###Resource: postgresql::pg_hba_rule
171+
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).
167172

168-
### Tests
173+
For example:
169174

170-
There are two types of tests distributed with the module. The first set is the “traditional” Puppet manifest-style smoke tests. You can use these to experiment with the module on a virtual machine or other test environment, via `puppet apply`. You should see the following files in the `tests` directory.
175+
postgresql::pg_hba_rule { 'allow application network to access app database':
176+
description => "Open up postgresql for access from 200.1.2.0/24",
177+
type => 'host',
178+
database => 'app',
179+
user => 'app',
180+
address => '200.1.2.0/24',
181+
auth_method => 'md5',
182+
}
171183

172-
In addition to these manifest-based smoke tests, there are some ruby rspec tests in the spec directory. These tests run against a VirtualBox VM, so they are actually testing the live application of the module on a real, running system. To do this, you must install and setup an [RVM](http://beginrescueend.com/) with [vagrant](http://vagrantup.com/), [sahara](https://github.com/jedi4ever/sahara), and [rspec](http://rspec.info/):
184+
This would create a ruleset in `pg_hba.conf` similar to:
173185

174-
$ curl -L get.rvm.io | bash -s stable
175-
$ rvm install 1.9.3
176-
$ rvm use --create 1.9.3@puppet-postgresql
177-
$ bundle install
186+
# Rule Name: allow application network to access app database
187+
# Description: Open up postgresql for access from 200.1.2.0/24
188+
# Order: 150
189+
host app app 200.1.2.0/24 md5
178190

179-
Run the system tests:
191+
####`namevar`
192+
A unique identifier or short description for this rule. The namevar doesn't provide any functional usage, but it is stored in the comments of the produced pg_hba.conf so the originating resource can be identified.
180193

181-
$ rake spec:system
194+
####`description`
195+
A longer description for this rule if required. Defaults to `none`. This description is placed in the comments above the rule in `pg_hba.conf`.
182196

183-
The system test suite will snapshot the VM and rollback between each test.
184-
185-
We also have some unit tests that utilize rspec-puppet for faster iteration if required:
197+
####`type`
198+
The type of rule, this is usually one of: local, host, hostssl or hostnossl.
186199

187-
$ rake spec
200+
####`database`
201+
A comma separated list of databases that this rule matches.
188202

189-
The unit tests are ran in Travis-CI as well, if you want to see the results of your own tests regsiter the service hook through Travis-CI via the accounts section for your Github clone of this project.
203+
####`user`
204+
A comma separated list of database users that this rule matches.
190205

191-
Implementation
192-
---------------
206+
####`address`
207+
If the type is not 'local' you can provide a CIDR based address here for rule matching.
193208

194-
### Resource Overview
209+
####`auth_method`
210+
The auth_method is described further in the pg_hba.conf documentation, but it provides the method that is used for authentication for the connection that this rule matches.
195211

196-
**postgresql**
212+
####`auth_option`
213+
For certain auth_methods there are extra options that can be passed. Consult the PostgreSQL `pg_hba.conf` documentation for further details.
197214

198-
This class is used to manage the basic postgresql client packages (which include the psql command line tool and other utilities).
215+
####`order`
216+
An order for placing the rule in pg_hba.conf. Defaults to `150`.
199217

200-
**postgresql::database**
218+
####`target`
219+
This provides the target for the rule, and is generally an internal only property. Use with caution.
201220

202-
This defined type can be used to create a database with no users and no permissions, which is a rare use case.
221+
###Resource: postgresql_psql**
203222

204-
**postgresql::tablespace**
223+
This type manages the command line tool for the postgresql module.
205224

206-
This defined type can be used to create a tablespace.
207-
208-
**postgresql_psql**
225+
###Function: postgresql_password
226+
If you need to generate a postgres encrypted password, use `postgresql_password`. You can call it from your production manifests if you don’t mind them containing the clear text versions of your passwords, or you can call it from the command line and then copy and paste the encrypted password into your manifest:
209227

210-
This defined type manages the command line tool for the postgresql module.
228+
$ puppet apply --execute 'notify { "test": message => postgresql_password("username", "password") }'
211229

212-
213-
### Custom Facts
230+
###Function: postgresql_acls_to_resources_hash(acl_array, id, order_offset)
231+
This internal function converts a list of pg_hba.conf based acls (passed in as an array of strings) to a format compatible with the `postgresql::pg_hba_rule` resource.
214232

215-
**postgres\_default\_version**
233+
**This function should only be used internally by the module**.
216234

235+
###Fact: postgres_default_version
217236
The module provides a Facter fact that can be used to determine what the default version of postgres is for your operating system/distribution. Depending on the distribution, it might be 8.1, 8.4, 9.1, or possibly another version. This can be useful in a few cases, like when building path strings for the postgres directories.
218-
237+
219238
Limitations
220239
------------
221240

@@ -230,6 +249,29 @@ We want to keep it as easy as possible to contribute changes so that our modules
230249

231250
You can read the complete module contribution guide [on the Puppet Labs wiki.](http://projects.puppetlabs.com/projects/module-site/wiki/Module_contributing)
232251

252+
### Tests
253+
254+
There are two types of tests distributed with the module. The first set is the “traditional” Puppet manifest-style smoke tests. You can use these to experiment with the module on a virtual machine or other test environment, via `puppet apply`. You should see the following files in the `tests` directory.
255+
256+
In addition to these manifest-based smoke tests, there are some ruby rspec tests in the spec directory. These tests run against a VirtualBox VM, so they are actually testing the live application of the module on a real, running system. To do this, you must install and setup an [RVM](http://beginrescueend.com/) with [vagrant](http://vagrantup.com/), [sahara](https://github.com/jedi4ever/sahara), and [rspec](http://rspec.info/):
257+
258+
$ curl -L get.rvm.io | bash -s stable
259+
$ rvm install 1.9.3
260+
$ rvm use --create 1.9.3@puppet-postgresql
261+
$ bundle install
262+
263+
Run the system tests:
264+
265+
$ rake spec:system
266+
267+
The system test suite will snapshot the VM and rollback between each test.
268+
269+
We also have some unit tests that utilize rspec-puppet for faster iteration if required:
270+
271+
$ rake spec
272+
273+
The unit tests are ran in Travis-CI as well, if you want to see the results of your own tests regsiter the service hook through Travis-CI via the accounts section for your Github clone of this project.
274+
233275
Disclaimer
234276
-----------
235277

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
module Puppet::Parser::Functions
2+
newfunction(:postgresql_acls_to_resources_hash, :type => :rvalue, :doc => <<-EOS
3+
This internal function translates the ipv(4|6)acls format into a resource
4+
suitable for create_resources. It is not intended to be used outside of the
5+
postgresql internal classes/defined resources.
6+
7+
This function accepts an array of strings that are pg_hba.conf rules. It
8+
will return a hash that can be fed into create_resources to create multiple
9+
individual pg_hba_rule resources.
10+
11+
The second parameter is an identifier that will be included in the namevar
12+
to provide uniqueness. It must be a string.
13+
14+
The third parameter is an order offset, so you can start the order at an
15+
arbitrary starting point.
16+
EOS
17+
) do |args|
18+
func_name = "postgresql_acls_to_resources_hash()"
19+
20+
raise(Puppet::ParseError, "#{func_name}: Wrong number of arguments " +
21+
"given (#{args.size} for 3)") if args.size != 3
22+
23+
acls = args[0]
24+
raise(Puppet::ParseError, "#{func_name}: first argument must be an array") \
25+
unless acls.instance_of? Array
26+
27+
id = args[1]
28+
raise(Puppet::ParseError, "#{func_name}: second argument must be a string") \
29+
unless id.instance_of? String
30+
31+
offset = args[2].to_i
32+
raise(Puppet::ParseError, "#{func_name}: third argument must be a number") \
33+
unless offset.instance_of? Fixnum
34+
35+
resources = {}
36+
acls.each do |acl|
37+
index = acls.index(acl)
38+
39+
parts = acl.split
40+
41+
raise(Puppet::ParseError, "#{func_name}: acl line #{index} does not " +
42+
"have enough parts") unless parts.length >= 4
43+
44+
resource = {
45+
'type' => parts[0],
46+
'database' => parts[1],
47+
'user' => parts[2],
48+
'order' => format('%03d', offset + index),
49+
}
50+
if parts[0] == 'local' then
51+
resource['auth_method'] = parts[3]
52+
if parts.length > 4 then
53+
resource['auth_option'] = parts.last(parts.length - 4).join(" ")
54+
end
55+
else
56+
if parts[4] =~ /^\d/
57+
resource['address'] = parts[3] + ' ' + parts[4]
58+
resource['auth_method'] = parts[5]
59+
60+
if parts.length > 6 then
61+
resource['auth_option'] = parts.last(parts.length - 6).join(" ")
62+
end
63+
else
64+
resource['address'] = parts[3]
65+
resource['auth_method'] = parts[4]
66+
67+
if parts.length > 5 then
68+
resource['auth_option'] = parts.last(parts.length - 5).join(" ")
69+
end
70+
end
71+
end
72+
resources["postgresql class generated rule #{id} #{index}"] = resource
73+
end
74+
resources
75+
end
76+
end

manifests/config/afterservice.pp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
if ($postgres_password != undef) {
2525
# NOTE: this password-setting logic relies on the pg_hba.conf being configured
2626
# to allow the postgres system user to connect via psql without specifying
27-
# a password ('ident', 'peer', or 'trust' security). This is the default
27+
# a password ('ident' or 'trust' security). This is the default
2828
# for pg_hba.conf.
2929
exec { 'set_postgres_postgrespw':
3030
# This command works w/no password because we run it as postgres system user

manifests/config/beforeservice.pp

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,66 @@
5050
group => $postgresql::params::group,
5151
}
5252

53-
# We use a templated version of pg_hba.conf. Our main needs are to
54-
# make sure that md5 authentication can be made available for
55-
# remote hosts.
56-
file { 'pg_hba.conf':
57-
ensure => file,
58-
path => $pg_hba_conf_path,
59-
content => template('postgresql/pg_hba.conf.erb'),
60-
notify => Exec['reload_postgresql'],
53+
# Create the main pg_hba resource
54+
postgresql::pg_hba { 'main':
55+
notify => Exec['reload_postgresql'],
6156
}
6257

58+
Postgresql::Pg_hba_rule {
59+
database => 'all',
60+
user => 'all',
61+
}
62+
63+
# Lets setup the base rules
64+
postgresql::pg_hba_rule { 'local access as postgres user':
65+
type => 'local',
66+
auth_method => 'ident',
67+
auth_option => $postgresql::params::version ? {
68+
'8.1' => 'sameuser',
69+
default => undef,
70+
},
71+
order => '001',
72+
}
73+
postgresql::pg_hba_rule { 'local access to database with same name':
74+
type => 'local',
75+
auth_method => 'ident',
76+
auth_option => $postgresql::params::version ? {
77+
'8.1' => 'sameuser',
78+
default => undef,
79+
},
80+
order => '002',
81+
}
82+
postgresql::pg_hba_rule { 'deny access to postgresql user':
83+
type => 'host',
84+
user => 'postgres',
85+
address => $ip_mask_deny_postgres_user,
86+
auth_method => 'reject',
87+
order => '003',
88+
}
89+
90+
# ipv4acls are passed as an array of rule strings, here we transform them into
91+
# a resources hash, and pass the result to create_resources
92+
$ipv4acl_resources = postgresql_acls_to_resources_hash($ipv4acls, 'ipv4acls', 10)
93+
create_resources('postgresql::pg_hba_rule', $ipv4acl_resources)
94+
95+
postgresql::pg_hba_rule { 'allow access to all users':
96+
type => 'host',
97+
address => $ip_mask_allow_all_users,
98+
auth_method => 'md5',
99+
order => '100',
100+
}
101+
postgresql::pg_hba_rule { 'allow access to ipv6 localhost':
102+
type => 'host',
103+
address => '::1/128',
104+
auth_method => 'md5',
105+
order => '101',
106+
}
107+
108+
# ipv6acls are passed as an array of rule strings, here we transform them into
109+
# a resources hash, and pass the result to create_resources
110+
$ipv6acl_resources = postgresql_acls_to_resources_hash($ipv6acls, 'ipv6acls', 102)
111+
create_resources('postgresql::pg_hba_rule', $ipv6acl_resources)
112+
63113
# We must set a "listen_addresses" line in the postgresql.conf if we
64114
# want to allow any connections from remote hosts.
65115
file_line { 'postgresql.conf#listen_addresses':

manifests/pg_hba.pp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# This resource manages a pg_hba file, collecting fragments of pg_hba_rules
2+
# to build up the final file.
3+
define postgresql::pg_hba(
4+
$target = $postgresql::params::pg_hba_conf_path,
5+
$owner = 0,
6+
$group = $postgresql::params::group
7+
) {
8+
include postgresql::params
9+
10+
# Collect file from fragments
11+
concat { $target:
12+
owner => $owner,
13+
group => $group,
14+
mode => '0640',
15+
warn => true,
16+
}
17+
18+
}

0 commit comments

Comments
 (0)