Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .fixtures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ fixtures:
apt: "git://github.com/puppetlabs/puppetlabs-apt.git"
stdlib: "git://github.com/puppetlabs/puppetlabs-stdlib.git"
firewall: "git://github.com/puppetlabs/puppetlabs-firewall.git"
concat: "git://github.com/ripienaar/puppet-concat.git"
symlinks:
postgresql: "#{source_dir}"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
# This is a library, so don't pin
Gemfile.lock
/metadata.json
spec/fixtures
1 change: 1 addition & 0 deletions Modulefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ project_page 'https://github.com/puppetlabs/puppet-postgresql'
dependency 'puppetlabs/stdlib', '>=3.2.0 <4.0.0'
dependency 'puppetlabs/firewall', '>= 0.0.4'
dependency 'puppetlabs/apt', '>=1.1.0 <2.0.0'
dependency 'ripienaar/concat', '=~ 0.2.0'
128 changes: 85 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ postgresql
2. [Module Description - What does the module do?](#module-description)
3. [Setup - The basics of getting started with PostgreSQL module](#setup)
4. [Usage - The classes and parameters available for configuration](#usage)
5. [Implementation - An under-the-hood peek at what the module is doing](#implementation)
6. [Limitations - OS compatibility, etc.](#limitations)
7. [Development - Guide for contributing to the module](#development)
8. [Disclaimer - Licensing information](#disclaimer)
9. [Transfer Notice - Notice of authorship change](#transfer-notice)
10. [Contributors - List of module contributors](#contributors)
11. [Release Notes - Notes on the most recent updates to the module](#release-notes)
5. [Limitations - OS compatibility, etc.](#limitations)
6. [Development - Guide for contributing to the module](#development)
7. [Disclaimer - Licensing information](#disclaimer)
8. [Transfer Notice - Notice of authorship change](#transfer-notice)
9. [Contributors - List of module contributors](#contributors)
10. [Release Notes - Notes on the most recent updates to the module](#release-notes)


Overview
Expand Down Expand Up @@ -105,7 +104,10 @@ Usage

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.

###postgresql::server
###Class: postgresql
This class is used to configure the cross-domain settings for this module.

###Class: postgresql::server
Here are the options that you can set in the `config_hash` parameter of `postgresql::server`:

####`postgres_password`
Expand Down Expand Up @@ -140,7 +142,7 @@ List of strings for access control for connection method, users, databases, IPv4
List of strings for access control for connection method, users, databases, IPv6
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).

###postgresql::client
###Class: postgresql::client

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):

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

###postgresql::java
###Class: postgresql::java
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):

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

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

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:
###Resource: postgresql::tablespace
This defined type can be used to create a tablespace.

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

### Tests
For example:

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.
postgresql::pg_hba_rule { 'allow application network to access app database':
description => "Open up postgresql for access from 200.1.2.0/24",
type => 'host',
database => 'app',
user => 'app',
address => '200.1.2.0/24',
auth_method => 'md5',
}

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/):
This would create a ruleset in `pg_hba.conf` similar to:

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

Run the system tests:
####`namevar`
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.

$ rake spec:system
####`description`
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`.

The system test suite will snapshot the VM and rollback between each test.

We also have some unit tests that utilize rspec-puppet for faster iteration if required:
####`type`
The type of rule, this is usually one of: local, host, hostssl or hostnossl.

$ rake spec
####`database`
A comma separated list of databases that this rule matches.

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.
####`user`
A comma separated list of database users that this rule matches.

Implementation
---------------
####`address`
If the type is not 'local' you can provide a CIDR based address here for rule matching.

### Resource Overview
####`auth_method`
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.

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

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

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

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

**postgresql::tablespace**
This type manages the command line tool for the postgresql module.

This defined type can be used to create a tablespace.

**postgresql_psql**
###Function: postgresql_password
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:

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

### Custom Facts
###Function: postgresql_acls_to_resources_hash(acl_array, id, order_offset)
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.

**postgres\_default\_version**
**This function should only be used internally by the module**.

###Fact: postgres_default_version
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.

Limitations
------------

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

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

### Tests

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.

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/):

$ curl -L get.rvm.io | bash -s stable
$ rvm install 1.9.3
$ rvm use --create 1.9.3@puppet-postgresql
$ bundle install

Run the system tests:

$ rake spec:system

The system test suite will snapshot the VM and rollback between each test.

We also have some unit tests that utilize rspec-puppet for faster iteration if required:

$ rake spec

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.

Disclaimer
-----------

Expand Down
76 changes: 76 additions & 0 deletions lib/puppet/parser/functions/postgresql_acls_to_resources_hash.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
module Puppet::Parser::Functions
newfunction(:postgresql_acls_to_resources_hash, :type => :rvalue, :doc => <<-EOS
This internal function translates the ipv(4|6)acls format into a resource
suitable for create_resources. It is not intended to be used outside of the
postgresql internal classes/defined resources.

This function accepts an array of strings that are pg_hba.conf rules. It
will return a hash that can be fed into create_resources to create multiple
individual pg_hba_rule resources.

The second parameter is an identifier that will be included in the namevar
to provide uniqueness. It must be a string.

The third parameter is an order offset, so you can start the order at an
arbitrary starting point.
EOS
) do |args|
func_name = "postgresql_acls_to_resources_hash()"

raise(Puppet::ParseError, "#{func_name}: Wrong number of arguments " +
"given (#{args.size} for 3)") if args.size != 3

acls = args[0]
raise(Puppet::ParseError, "#{func_name}: first argument must be an array") \
unless acls.instance_of? Array

id = args[1]
raise(Puppet::ParseError, "#{func_name}: second argument must be a string") \
unless id.instance_of? String

offset = args[2].to_i
raise(Puppet::ParseError, "#{func_name}: third argument must be a number") \
unless offset.instance_of? Fixnum

resources = {}
acls.each do |acl|
index = acls.index(acl)

parts = acl.split

raise(Puppet::ParseError, "#{func_name}: acl line #{index} does not " +
"have enough parts") unless parts.length >= 4

resource = {
'type' => parts[0],
'database' => parts[1],
'user' => parts[2],
'order' => format('%03d', offset + index),
}
if parts[0] == 'local' then
resource['auth_method'] = parts[3]
if parts.length > 4 then
resource['auth_option'] = parts.last(parts.length - 4).join(" ")
end
else
if parts[4] =~ /^\d/
resource['address'] = parts[3] + ' ' + parts[4]
resource['auth_method'] = parts[5]

if parts.length > 6 then
resource['auth_option'] = parts.last(parts.length - 6).join(" ")
end
else
resource['address'] = parts[3]
resource['auth_method'] = parts[4]

if parts.length > 5 then
resource['auth_option'] = parts.last(parts.length - 5).join(" ")
end
end
end
resources["postgresql class generated rule #{id} #{index}"] = resource
end
resources
end
end
2 changes: 1 addition & 1 deletion manifests/config/afterservice.pp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
if ($postgres_password != undef) {
# NOTE: this password-setting logic relies on the pg_hba.conf being configured
# to allow the postgres system user to connect via psql without specifying
# a password ('ident', 'peer', or 'trust' security). This is the default
# a password ('ident' or 'trust' security). This is the default
# for pg_hba.conf.
exec { 'set_postgres_postgrespw':
# This command works w/no password because we run it as postgres system user
Expand Down
66 changes: 58 additions & 8 deletions manifests/config/beforeservice.pp
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,66 @@
group => $postgresql::params::group,
}

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

Postgresql::Pg_hba_rule {
database => 'all',
user => 'all',
}

# Lets setup the base rules
postgresql::pg_hba_rule { 'local access as postgres user':
type => 'local',
auth_method => 'ident',
auth_option => $postgresql::params::version ? {
'8.1' => 'sameuser',
default => undef,
},
order => '001',
}
postgresql::pg_hba_rule { 'local access to database with same name':
type => 'local',
auth_method => 'ident',
auth_option => $postgresql::params::version ? {
'8.1' => 'sameuser',
default => undef,
},
order => '002',
}
postgresql::pg_hba_rule { 'deny access to postgresql user':
type => 'host',
user => 'postgres',
address => $ip_mask_deny_postgres_user,
auth_method => 'reject',
order => '003',
}

# ipv4acls are passed as an array of rule strings, here we transform them into
# a resources hash, and pass the result to create_resources
$ipv4acl_resources = postgresql_acls_to_resources_hash($ipv4acls, 'ipv4acls', 10)
create_resources('postgresql::pg_hba_rule', $ipv4acl_resources)

postgresql::pg_hba_rule { 'allow access to all users':
type => 'host',
address => $ip_mask_allow_all_users,
auth_method => 'md5',
order => '100',
}
postgresql::pg_hba_rule { 'allow access to ipv6 localhost':
type => 'host',
address => '::1/128',
auth_method => 'md5',
order => '101',
}

# ipv6acls are passed as an array of rule strings, here we transform them into
# a resources hash, and pass the result to create_resources
$ipv6acl_resources = postgresql_acls_to_resources_hash($ipv6acls, 'ipv6acls', 102)
create_resources('postgresql::pg_hba_rule', $ipv6acl_resources)

# We must set a "listen_addresses" line in the postgresql.conf if we
# want to allow any connections from remote hosts.
file_line { 'postgresql.conf#listen_addresses':
Expand Down
18 changes: 18 additions & 0 deletions manifests/pg_hba.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# This resource manages a pg_hba file, collecting fragments of pg_hba_rules
# to build up the final file.
define postgresql::pg_hba(
$target = $postgresql::params::pg_hba_conf_path,
$owner = 0,
$group = $postgresql::params::group
) {
include postgresql::params

# Collect file from fragments
concat { $target:
owner => $owner,
group => $group,
mode => '0640',
warn => true,
}

}
Loading