Provide new defined resources for managing pg_hba.conf

This patch provides a more advanced way of managing pg_hba rules, by providing a
defined resource to manage a pg_hba file, and a defined resource for managing
rules within such a file (pg_hba_rule).

These new resources are wrappers around ripinaar-concat, and utilise file
assemblies instead of a template to compose the pg_hba.conf file.

I've provided a function that interprets the old ip4|6acl arrays and converts
them to this new format for backwards compatibility as well.

I slightly reformatted our documentation to allow for better documentation of
defined resources in 'Usage' as well, and provided examples of how to use this
new resource.

This hopefully should go a long way to solving the PR's related to lack of full
functionality for pg_hba.conf.

Signed-off-by: Ken Barber <ken@bob.sh>
This commit is contained in:
Ken Barber 2013-02-10 00:36:12 +00:00
parent 8dba376aff
commit 86a0453f2f
19 changed files with 640 additions and 165 deletions

View file

@ -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
.gitignore vendored
View file

@ -3,3 +3,4 @@
# This is a library, so don't pin
Gemfile.lock
/metadata.json
spec/fixtures

View file

@ -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'

160
README.md
View file

@ -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
@ -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`
@ -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):
@ -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`
@ -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
If you need to generate a postgres encrypted password, use `postgresql_password`. You can call it from your production manifests if you dont 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:
$ puppet apply --execute 'notify { "test": message => postgresql_password("username", "password") }'
### 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.
Implementation
---------------
### Resource Overview
**postgresql**
This class is used to manage the basic postgresql client packages (which include the psql command line tool and other utilities).
**postgresql::database**
This defined type can be used to create a database with no users and no permissions, which is a rare use case.
**postgresql::tablespace**
###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.
###Resource: postgresql::tablespace
This defined type can be used to create a tablespace.
**postgresql_psql**
###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).
This defined type manages the command line tool for the postgresql module.
For example:
### Custom Facts
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',
}
**postgres\_default\_version**
This would create a ruleset in `pg_hba.conf` similar to:
# 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
####`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.
####`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`.
####`type`
The type of rule, this is usually one of: local, host, hostssl or hostnossl.
####`database`
A comma separated list of databases that this rule matches.
####`user`
A comma separated list of database users that this rule matches.
####`address`
If the type is not 'local' you can provide a CIDR based address here for rule matching.
####`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.
####`auth_option`
For certain auth_methods there are extra options that can be passed. Consult the PostgreSQL `pg_hba.conf` documentation for further details.
####`order`
An order for placing the rule in pg_hba.conf. Defaults to `150`.
####`target`
This provides the target for the rule, and is generally an internal only property. Use with caution.
###Resource: postgresql_psql**
This type manages the command line tool for the postgresql module.
###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 dont 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:
$ puppet apply --execute 'notify { "test": message => postgresql_password("username", "password") }'
###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.
**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
------------
@ -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
-----------

View file

@ -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

View file

@ -24,7 +24,7 @@ class postgresql::config::afterservice(
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

View file

@ -50,16 +50,66 @@ class postgresql::config::beforeservice(
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':

18
manifests/pg_hba.pp Normal file
View file

@ -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,
}
}

41
manifests/pg_hba_rule.pp Normal file
View file

@ -0,0 +1,41 @@
# This resource manages an individual rule that applies to the file defined in
# $target.
define postgresql::pg_hba_rule(
$type,
$database,
$user,
$auth_method,
$address = undef,
$description = 'none',
$auth_option = undef,
$target = $postgresql::params::pg_hba_conf_path,
$order = '150',
) {
include postgresql::params
validate_re($type, ['^local$', '^host$', '^hostssl$', '^hostnossl$'],
"The type you specified [${type}] must be one of: local, host, hostssl, hostnosssl")
validate_re($auth_method, '^(trust|reject|md5|crypt|password|gss|sspi|krb5|ident|peer|ldap|radius|cert|pam)$',
"The auth_method you specified [${auth_method}] must be one of: trust, reject, md5, crypt, password, krb5, ident, ldap, pam")
if($type =~ /^host/ and $address == undef) {
fail('You must specify an address property when type is host based')
}
# This is required to make sure concat::setup is initialized first. This
# probably points to a bug inside ripienaar-concat.
include concat::setup
# Create a rule fragment
$fragname = "pg_hba_rule_${name}"
concat::fragment { $fragname:
target => $target,
content => template('postgresql/pg_hba_rule.conf'),
order => $order,
owner => $::id,
mode => '0600',
}
Class['concat::setup']->
Concat::Fragment[$fragname]
}

View file

@ -1,7 +1,9 @@
require 'puppetlabs_spec_helper/module_spec_helper'
RSpec.configure do |config|
config.before :each do
RSpec.configure do |c|
c.include PuppetlabsSpec::Files
c.before :each do
# Ensure that we don't accidentally cache facts and environment
# between test cases.
Facter::Util::Loader.any_instance.stubs(:load_all)
@ -12,4 +14,14 @@ RSpec.configure do |config|
@old_env = {}
ENV.each_key {|k| @old_env[k] = ENV[k]}
end
c.after :each do
PuppetlabsSpec::Files.cleanup
end
end
# Convenience helper for returning parameters for a type from the
# catalogue.
def param(type, title, param)
param_value(catalogue, type, title, param)
end

View file

@ -63,7 +63,7 @@ shared_examples :system_default_postgres do
sudo_and_log(vm, "puppet apply -e '#{manifest}'")
# Some basic tests here to check if the db indeed was created with the
#rr correct locale.
# correct locale.
sudo_and_log(vm, 'su postgres -c \'psql -c "show lc_ctype" test1\'')
sudo_and_log(vm, 'su postgres -c \'psql -c "show lc_ctype" test1\' | grep en_NG')
sudo_and_log(vm, 'su postgres -c \'psql -c "show lc_collate" test1\' | grep en_NG')
@ -170,6 +170,47 @@ shared_examples :system_default_postgres do
end
end
describe 'postgresql::pg_hba_rule' do
it 'should create a ruleset in pg_hba.conf' do
manifest = <<-EOS
include postgresql::server
postgresql::pg_hba_rule { "allow application network to access app database":
type => "host",
database => "app",
user => "app",
address => "200.1.2.0/24",
auth_method => md5,
}
EOS
sudo_and_log(vm, "puppet apply -e '#{manifest}'")
sudo_and_log(vm, "grep '200.1.2.0/24' /etc/postgresql/*/*/pg_hba.conf || grep '200.1.2.0/24' /var/lib/pgsql/data/pg_hba.conf")
end
it 'should create a ruleset in pg_hba.conf that denies db access to db test1' do
manifest = <<-EOS
include postgresql::server
postgresql::db { "test1":
user => "test1",
password => "test1",
grant => "all",
}
postgresql::pg_hba_rule { "allow anyone to have access to db test1":
type => "local",
database => "test1",
user => "test1",
auth_method => reject,
order => '001',
}
user { "test1":
shell => "/bin/bash",
managehome => true,
}
EOS
sudo_and_log(vm, "puppet apply -e '#{manifest}'")
sudo_and_log(vm, 'su - test1 -c \'psql -U test1 -c "\q" test1\'; [ $? == 2 ]')
end
end
describe 'postgresql.conf include' do
it "should support an 'include' directive at the end of postgresql.conf" do
test_class = 'class {"postgresql_tests::system_default::test_pgconf_include": }'

View file

@ -6,6 +6,7 @@ def apply_common_vagrant_config(config)
# TODO: it would be better to install this via the puppet module tool
config.vm.share_folder "puppetlabs-stdlib-module", "/usr/share/puppet/modules/stdlib", "../../../../../puppetlabs-stdlib"
config.vm.share_folder "puppetlabs-apt-module", "/usr/share/puppet/modules/apt", "../../../../../puppetlabs-apt"
config.vm.share_folder "ripienaar-concat-module", "/usr/share/puppet/modules/concat", "../../../../../puppet-concat"
# Share the postgressql module
config.vm.share_folder "puppet-postgresql-module", "/usr/share/puppet/modules/postgresql", "../../../.."

View file

@ -5,6 +5,7 @@ describe 'postgresql::server', :type => :class do
{
:postgres_default_version => '8.4',
:osfamily => 'Debian',
:concat_basedir => tmpfilename('server'),
}
end
it { should include_class("postgresql::server") }

View file

@ -0,0 +1,104 @@
require 'spec_helper'
describe 'postgresql::pg_hba_rule', :type => :define do
let :facts do
{
:postgres_default_version => '8.4',
:osfamily => 'Debian',
:concat_basedir => tmpfilename('pg_hba'),
}
end
let :title do
'test'
end
let :target do
tmpfilename('pg_hba_rule')
end
context 'test template 1' do
let :params do
{
:type => 'host',
:database => 'all',
:user => 'all',
:address => '1.1.1.1/24',
:auth_method => 'md5',
:target => target,
}
end
it do
content = param('concat::fragment', 'pg_hba_rule_test', 'content')
content.should =~ /host\s+all\s+all\s+1\.1\.1\.1\/24\s+md5/
end
end
context 'test template 2' do
let :params do
{
:type => 'local',
:database => 'all',
:user => 'all',
:auth_method => 'ident',
:target => target,
}
end
it do
content = param('concat::fragment', 'pg_hba_rule_test', 'content')
content.should =~ /local\s+all\s+all\s+ident/
end
end
context 'test template 3' do
let :params do
{
:type => 'host',
:database => 'all',
:user => 'all',
:address => '0.0.0.0/0',
:auth_method => 'ldap',
:auth_option => 'foo=bar',
:target => target,
}
end
it do
content = param('concat::fragment', 'pg_hba_rule_test', 'content')
content.should =~ /host\s+all\s+all\s+0\.0\.0\.0\/0\s+ldap\s+foo=bar/
end
end
context 'validation' do
context 'validate type test 1' do
let :params do
{
:type => 'invalid',
:database => 'all',
:user => 'all',
:address => '0.0.0.0/0',
:auth_method => 'ldap',
:target => target,
}
end
it 'should fail parsing when type is not valid' do
expect {subject}.to raise_error(Puppet::Error,
/The type you specified \[invalid\] must be one of/)
end
end
context 'validate auth_method' do
let :params do
{
:type => 'local',
:database => 'all',
:user => 'all',
:address => '0.0.0.0/0',
:auth_method => 'invalid',
:target => target,
}
end
it 'should fail parsing when auth_method is not valid' do
expect {subject}.to raise_error(Puppet::Error,
/The auth_method you specified \[invalid\] must be one of/)
end
end
end
end

View file

@ -0,0 +1,20 @@
require 'spec_helper'
describe 'postgresql::pg_hba', :type => :define do
let :facts do
{
:postgres_default_version => '8.4',
:osfamily => 'Debian',
:concat_basedir => tmpfilename('pg_hba'),
}
end
let :title do
'test'
end
let :params do
{
:target => tmpfilename('pg_hba_target'),
}
end
it { should include_class("postgresql::params") }
end

View file

@ -0,0 +1,137 @@
require 'spec_helper'
describe 'postgresql_acls_to_resources_hash', :type => :puppet_function do
context 'individual transform tests' do
it do
input = 'local all postgres ident'
result = {
"postgresql class generated rule test 0"=>{
"type"=>"local",
"database"=>"all",
"user"=>"postgres",
"auth_method"=>"ident",
"order"=>"100",
},
}
should run.with_params([input], 'test', 100).and_return(result)
end
it do
input = 'local all root ident'
result = {
"postgresql class generated rule test 0"=>{
"type"=>"local",
"database"=>"all",
"user"=>"root",
"auth_method"=>"ident",
"order"=>"100",
},
}
should run.with_params([input], 'test', 100).and_return(result)
end
it do
input_array = [
'local all all ident',
]
result = {
"postgresql class generated rule test 0"=>{
"type"=>"local",
"database"=>"all",
"user"=>"all",
"auth_method"=>"ident",
"order"=>"100",
},
}
should run.with_params(input_array, 'test', 100).and_return(result)
end
it do
input = 'host all all 127.0.0.1/32 md5'
result = {
"postgresql class generated rule test 0"=>{
"type"=>"host",
"database"=>"all",
"user"=>"all",
"address"=>"127.0.0.1/32",
"auth_method"=>"md5",
"order"=>"100",
},
}
should run.with_params([input], 'test', 100).and_return(result)
end
it do
input = 'host all all 0.0.0.0/0 md5'
result = {
"postgresql class generated rule test 0"=>{
"type"=>"host",
"database"=>"all",
"user"=>"all",
"address"=>"0.0.0.0/0",
"auth_method"=>"md5",
"order"=>"100",
},
}
should run.with_params([input], 'test', 100).and_return(result)
end
it do
input = 'host all all ::1/128 md5'
result = {
"postgresql class generated rule test 0"=>{
"type"=>"host",
"database"=>"all",
"user"=>"all",
"address"=>"::1/128",
"auth_method"=>"md5",
"order"=>"100",
},
}
should run.with_params([input], 'test', 100).and_return(result)
end
it do
input = 'host all all 1.1.1.1 255.255.255.0 md5'
result = {
"postgresql class generated rule test 0"=>{
"type"=>"host",
"database"=>"all",
"user"=>"all",
"address"=>"1.1.1.1 255.255.255.0",
"auth_method"=>"md5",
"order"=>"100",
},
}
should run.with_params([input], 'test', 100).and_return(result)
end
it do
input = 'host all all 1.1.1.1 255.255.255.0 ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"'
result = {
"postgresql class generated rule test 0"=>{
"type"=>"host",
"database"=>"all",
"user"=>"all",
"address"=>"1.1.1.1 255.255.255.0",
"auth_method"=>"ldap",
"auth_option"=>"ldapserver=ldap.example.net ldapprefix=\"cn=\" ldapsuffix=\", dc=example, dc=net\"",
"order"=>"100",
},
}
should run.with_params([input], 'test', 100).and_return(result)
end
end
it 'should return an empty hash when input is empty array' do
should run.with_params([], 'test', 100).and_return({})
end
end

View file

@ -1,94 +0,0 @@
# PostgreSQL Client Authentication Configuration File
# ===================================================
#
# Refer to the "Client Authentication" section in the
# PostgreSQL documentation for a complete description
# of this file. A short synopsis follows.
#
# This file controls: which hosts are allowed to connect, how clients
# are authenticated, which PostgreSQL user names they can use, which
# databases they can access. Records take one of these forms:
#
# local DATABASE USER METHOD [OPTIONS]
# host DATABASE USER CIDR-ADDRESS METHOD [OPTIONS]
# hostssl DATABASE USER CIDR-ADDRESS METHOD [OPTIONS]
# hostnossl DATABASE USER CIDR-ADDRESS METHOD [OPTIONS]
#
# (The uppercase items must be replaced by actual values.)
#
# The first field is the connection type: "local" is a Unix-domain socket,
# "host" is either a plain or SSL-encrypted TCP/IP socket, "hostssl" is an
# SSL-encrypted TCP/IP socket, and "hostnossl" is a plain TCP/IP socket.
#
# DATABASE can be "all", "sameuser", "samerole", a database name, or
# a comma-separated list thereof.
#
# USER can be "all", a user name, a group name prefixed with "+", or
# a comma-separated list thereof. In both the DATABASE and USER fields
# you can also write a file name prefixed with "@" to include names from
# a separate file.
#
# CIDR-ADDRESS specifies the set of hosts the record matches.
# It is made up of an IP address and a CIDR mask that is an integer
# (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that specifies
# the number of significant bits in the mask. Alternatively, you can write
# an IP address and netmask in separate columns to specify the set of hosts.
#
# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi", "krb5",
# "ident", "pam", "ldap" or "cert". Note that "password" sends passwords
# in clear text; "md5" is preferred since it sends encrypted passwords.
#
# OPTIONS are a set of options for the authentication in the format
# NAME=VALUE. The available options depend on the different authentication
# methods - refer to the "Client Authentication" section in the documentation
# for a list of which options are available for which authentication methods.
#
# Database and user names containing spaces, commas, quotes and other special
# characters must be quoted. Quoting one of the keywords "all", "sameuser" or
# "samerole" makes the name lose its special character, and just match a
# database or username with that name.
#
# This file is read on server startup and when the postmaster receives
# a SIGHUP signal. If you edit the file on a running system, you have
# to SIGHUP the postmaster for the changes to take effect. You can use
# "pg_ctl reload" to do that.
# Put your actual configuration here
# ----------------------------------
#
# If you want to allow non-local connections, you need to add more
# "host" records. In that case you will also need to make PostgreSQL listen
# on a non-local interface via the listen_addresses configuration parameter,
# or via the -i or -h command line switches.
#
# DO NOT DISABLE!
# If you change this first entry you will need to make sure that the
# database
# super user can access the database using some other method.
# Noninteractive
# access to all databases is required during automatic maintenance
# (custom daily cronjobs, replication, and similar tasks).
#
# Database administrative login by UNIX sockets
local all postgres ident <%= "sameuser" if scope.lookupvar('postgresql::params::version') == "8.1" %>
# TYPE DATABASE USER CIDR-ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all ident <%= "sameuser" if scope.lookupvar('postgresql::params::version') == "8.1" %>
# IPv4 local connections:
host all postgres <%= @ip_mask_deny_postgres_user + "\t" %> reject
<% @ipv4acls.each do |acl|; parts = acl.split -%>
<%= parts[0] + "\t" + parts[1] + "\t" + parts[2] + "\t\t" + parts[3] + "\t\t" + parts[4] + "\t" + parts.last(parts.length - 5).join(" ") %>
<% end -%>
host all all <%= @ip_mask_allow_all_users + "\t" %> md5
# IPv6 local connections:
host all all ::1/128 md5
<% @ipv6acls.each do |acl|; parts = acl.split -%>
<%= parts[0] + "\t" + parts[1] + "\t" + parts[2] + "\t\t" + parts[3] + "\t\t" + parts[4] + "\t" + parts.last(parts.length - 5).join(" ") %>
<% end -%>

View file

@ -0,0 +1,5 @@
# Rule Name: <%=@name%>
# Description: <%=@description%>
# Order: <%=@order%>
<%=@type%> <%=@database%> <%=@user%> <%=@address%> <%=@auth_method%> <%=@auth_option%>

View file

@ -0,0 +1,18 @@
# Basic remote access
postgresql::pg_hba_rule{ 'allow access to db foo from 2.2.2.0/24 for user foo':
type => 'host',
database => 'foo',
user => 'foo',
address => '2.2.2.0/24',
auth_method => 'md5',
}
# LDAP Integration
postgresql::pg_hba_rule{ 'allow ldap access to db foo from 10.1.1.0/24 for all':
type => 'host',
database => 'foo',
user => 'all',
address => '10.1.1.0/24',
auth_method => 'ldap',
auth_option => 'ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"',
}