From 6d314df91bf2f73b895e096dde7eb882d4653904 Mon Sep 17 00:00:00 2001 From: Peter Palfrader Date: Sun, 29 Sep 2019 10:57:49 +0200 Subject: [PATCH] Start with pg cluster configuration --- modules/postgres/manifests/cluster.pp | 42 +++++++++++ .../postgres/manifests/cluster/hba_entry.pp | 74 +++++++++++++++++++ .../templates/cluster/pg_hba.conf-head.erb | 22 ++++++ 3 files changed, 138 insertions(+) create mode 100644 modules/postgres/manifests/cluster.pp create mode 100644 modules/postgres/manifests/cluster/hba_entry.pp create mode 100644 modules/postgres/templates/cluster/pg_hba.conf-head.erb diff --git a/modules/postgres/manifests/cluster.pp b/modules/postgres/manifests/cluster.pp new file mode 100644 index 000000000..a57f5433f --- /dev/null +++ b/modules/postgres/manifests/cluster.pp @@ -0,0 +1,42 @@ +# postgresql cluster configuration +# +# @param pg_version pg version of the cluster +# @param pg_cluster cluster name +# @param pg_port port of the postgres cluster +# @param manage_hba manage pg_hba +# @param confdir directory where the configuration resides +define postgres::cluster( + String $pg_version, + String $pg_cluster = 'main', + Integer $pg_port = 5432, + Boolean $manage_hba = false, + String $confdir = "/etc/postgresql/${pg_version}/${pg_cluster}", +) { + $reload = "postgresql ${pg_version}/${pg_cluster} reload" + exec { $reload: + command => "systemctl reload postgresql@${pg_version}-${pg_cluster}.service", + refreshonly => true, + } + + ferm::rule::simple { "postgres::cluster::hba_entry::${pg_version}::${pg_cluster}": + description => "check access to pg${pg_version}/${pg_cluster}", + port => $pg_port, + target => "pg-${pg_port}", + } + + if $manage_hba { + concat { "postgres::cluster::${pg_version}::${pg_cluster}::hba": + path => "${confdir}/pg_hba.conf", + mode => '0440', + group => 'postgres', + ensure_newline => true, + notify => Exec[$reload], + } + concat::fragment{ "postgres::cluster::pg_hba-head::${pg_version}::${pg_cluster}": + target => "postgres::cluster::${pg_version}::${pg_cluster}::hba", + order => '00', + content => template('postgres/cluster/pg_hba.conf-head.erb'), + } + Concat::Fragment <| tag == "postgres::cluster::${pg_version}::${pg_cluster}::hba" |> + } +} diff --git a/modules/postgres/manifests/cluster/hba_entry.pp b/modules/postgres/manifests/cluster/hba_entry.pp new file mode 100644 index 000000000..e909a3cc5 --- /dev/null +++ b/modules/postgres/manifests/cluster/hba_entry.pp @@ -0,0 +1,74 @@ +# An entry in pg_hba and the corresponding firewall rule if necessary +# +# This currently only supports a limited number of entry types. Only +# what we need at the moment. +# +# See the upstream documentation at https://www.postgresql.org/docs/11/auth-pg-hba-conf.html +# for details. +# +# @param pg_port port of the postgres cluster +# @param pg_cluster cluster name +# @param pg_version pg version of the cluster +# @param connection_type connection type +# @param database database (or all, sameuser, replication, etc.) +# @param user user (or all, etc.) +# @param address hosts that match +# @param method auth method +# @param order ordering of this entry in pg_hba.conf +define postgres::cluster::hba_entry ( + Integer $pg_port, + String $pg_cluster, + String $pg_version, + Enum['local', 'hostssl'] $connection_type = 'hostssl', + Variant[String,Array[String]] $database = 'sameuser', + Variant[String,Array[String]] $user = 'all', + Optional[Variant[Stdlib::IP::Address, Array[Stdlib::IP::Address]]] $address = undef, + Enum['md5', 'trust'] $method = 'md5', + String $order = '50', +) { + $address_methods = ['md5'] + if $method in $address_methods { + if !$address { + fail("Authentication method ${method} needs an address") + } + } else { + if !($method in $address_methods) { + fail("Authentication method ${method} needs no address") + } + } + + if ($address) { + ferm::rule::simple { "postgres::cluster::hba_entry::${pg_version}::${pg_cluster}::${name}": + description => "allow access to pg${pg_version}/${pg_cluster}: ${name}", + saddr => $address, + chain => "pg-${pg_port}", + } + } + + $real_database = Array($database, true).sort().join(',') + $real_user = Array($user, true).sort().join(',') + $real_address = $address ? { + undef => [''], + default => Array($address, true).map |$a| { + if $a =~ Stdlib::IP::Address::V4::CIDR { $a } + elsif $a =~ Stdlib::IP::Address::V4::Nosubnet { "${a}/32" } + elsif $a =~ Stdlib::IP::Address::V6::CIDR { $a } + elsif $a =~ Stdlib::IP::Address::V6::Nosubnet { "${a}/128" } + else { fail("Do not know address type for ${a}") } + } + } + + @concat::fragment { "postgres::cluster::pg_hba::${pg_version}::${pg_cluster}::${name}": + tag => "postgres::cluster::${pg_version}::${pg_cluster}::hba", + target => "postgres::cluster::${pg_version}::${pg_cluster}::hba", + order => $order, + content => inline_template( @(EOF) ), + # + # rule <%= @name %> + <% @real_address.each do |addr| -%> + <%= [@connection_type, @real_database, @real_user, addr, @method].join(' ') %> + <% end -%> + # + | EOF + } +} diff --git a/modules/postgres/templates/cluster/pg_hba.conf-head.erb b/modules/postgres/templates/cluster/pg_hba.conf-head.erb new file mode 100644 index 000000000..f899cf1da --- /dev/null +++ b/modules/postgres/templates/cluster/pg_hba.conf-head.erb @@ -0,0 +1,22 @@ +# PostgreSQL Client Authentication Configuration File +# =================================================== +# maintained via puppet + +# default entries allows local access: +###################################### +# Database administrative login by Unix domain socket +local all postgres peer + +# "local" is for Unix domain socket connections only +local all all peer +# IPv4 local connections: +host all all 127.0.0.1/32 md5 +# IPv6 local connections: +host all all ::1/128 md5 +# Allow replication connections from localhost, by a user with the +# replication privilege. +local replication all peer +host replication all 127.0.0.1/32 md5 +host replication all ::1/128 md5 +###################################### + -- 2.20.1