Skip to content

Commit f8e2568

Browse files
authored
Merge pull request #1319 from fraenki/pg_dump
(MODULES-11251) Add support for backup provider "pg_dump"
2 parents 10a541f + 37e5bea commit f8e2568

File tree

7 files changed

+358
-0
lines changed

7 files changed

+358
-0
lines changed

.fixtures.yml

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ fixtures:
55
repo: "https://github.com/puppetlabs/puppetlabs-augeas_core.git"
66
puppet_version: ">= 6.0.0"
77
concat: "https://github.com/puppetlabs/puppetlabs-concat.git"
8+
cron_core: "https://github.com/puppetlabs/puppetlabs-cron_core.git"
89
facts: 'https://github.com/puppetlabs/puppetlabs-facts.git'
910
firewall: "https://github.com/puppetlabs/puppetlabs-firewall.git"
1011
provision: "https://github.com/puppetlabs/provision.git"

README.md

+21
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* [Create an access rule for pg_hba.conf](#create-an-access-rule-for-pg_hbaconf)
1616
* [Create user name maps for pg_ident.conf](#create-user-name-maps-for-pg_identconf)
1717
* [Validate connectivity](#validate-connectivity)
18+
* [Backups](#backups)
1819
4. [Reference - An under-the-hood peek at what the module is doing and how](#reference)
1920
5. [Limitations - OS compatibility, etc.](#limitations)
2021
6. [Development - Guide for contributing to the module](#development)
@@ -328,6 +329,26 @@ postgresql_conn_validator { 'validate my postgres connection':
328329
}
329330
```
330331

332+
### Backups
333+
334+
This example demonstrates how to configure PostgreSQL backups with "pg_dump". This sets up a daily cron job to perform a full backup. Each backup will create a new directory. A cleanup job will automatically remove backups that are older than 15 days.
335+
336+
```
337+
class { 'postgresql::server':
338+
backup_enable => true,
339+
backup_provider => 'pg_dump',
340+
backup_options => {
341+
db_user => 'backupuser',
342+
db_password => 'secret',
343+
manage_user => true,
344+
rotate => 15,
345+
},
346+
...
347+
}
348+
```
349+
350+
It is possible to set parameter `$ensure` to `absent` in order to remove the backup job, user/role, backup script and password file. However, the actual backup files and directories will remain untouched.
351+
331352
## Reference
332353

333354
For information on the classes and types, see the [REFERENCE.md](https://github.com/puppetlabs/puppetlabs-postgresql/blob/main/REFERENCE.md)

manifests/backup/pg_dump.pp

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# @summary
2+
# "Provider" for pg_dump backup
3+
#
4+
# @api private
5+
#
6+
# @param compress
7+
# Whether or not to compress the backup. Support for compression also depends on other backup parameters.
8+
# @param databases
9+
# Databases to backup. By default `[]` will back up all databases.
10+
# @param db_user
11+
# PostgreSQL user to create with superuser privileges.
12+
# @param db_password
13+
# Password to create for `$db_user`.
14+
# @param dir
15+
# Directory to store backup.
16+
# @param dir_mode
17+
# Permissions applied to the backup directory. This parameter is passed directly to the file resource.
18+
# @param dir_owner
19+
# Owner for the backup directory. This parameter is passed directly to the file resource.
20+
# @param dir_group
21+
# Group owner for the backup directory. This parameter is passed directly to the file resource.
22+
# @param format
23+
# Backup format to use, must be supported by pg_dump or pg_dumpall. The choice will affect other options, i.e. compression.
24+
# @param install_cron
25+
# Manage installation of cron package.
26+
# @param manage_user
27+
# Manage creation of the backup user.
28+
# @param optional_args
29+
# Specifies an array of optional arguments which should be passed through to the backup tool. These options are not validated, unsupported options may break the backup.
30+
# @param postscript
31+
# One or more scripts that are executed when the backup is finished. This could be used to sync the backup to a central store.
32+
# @param prescript
33+
# One or more scripts that are executed before the backup begins.
34+
# @param rotate
35+
# Backup rotation interval in 24 hour periods.
36+
# @param success_file_path
37+
# Specify a path where upon successful backup a file should be created for checking purposes.
38+
# @param time
39+
# An array of two elements to set the backup time. Allows `['23', '5']` (i.e., 23:05) or `['3', '45']` (i.e., 03:45) for HH:MM times.
40+
# @param weekday
41+
# Weekdays on which the backup job should run. Defaults to `*`. This parameter is passed directly to the cron resource.
42+
#
43+
class postgresql::backup::pg_dump (
44+
Boolean $compress = true,
45+
Array $databases = [],
46+
Boolean $delete_before_dump = false,
47+
String[1] $dir,
48+
String[1] $dir_group = '0',
49+
String[1] $dir_mode = '0700',
50+
String[1] $dir_owner = 'root',
51+
Enum['present','absent'] $ensure = 'present',
52+
Enum['plain','custom','directory','tar'] $format = 'plain',
53+
Boolean $install_cron = true,
54+
Boolean $manage_user = false,
55+
Array $optional_args = [],
56+
Stdlib::Absolutepath $pgpass_path = '/root/.pgpass',
57+
Integer $rotate = 30,
58+
Stdlib::Absolutepath $script_path = '/usr/local/sbin/pg_dump.sh',
59+
Stdlib::Absolutepath $success_file_path = '/tmp/pgbackup_success',
60+
String[1] $template = 'postgresql/pg_dump.sh.epp',
61+
Array $time = ['23', '5'],
62+
String[1] $weekday = '*',
63+
Optional[Variant[String, Sensitive[String]]] $db_password = undef,
64+
Optional[String[1]] $db_user = undef,
65+
Optional[String[1]] $package_name = undef,
66+
Optional[String[1]] $post_script = undef,
67+
Optional[String[1]] $pre_script = undef,
68+
) {
69+
# Install required packages
70+
if $package_name {
71+
ensure_packages($package_name)
72+
}
73+
if $install_cron {
74+
if $facts['os']['family'] == 'RedHat' {
75+
ensure_packages('cronie')
76+
} elsif $facts['os']['family'] != 'FreeBSD' {
77+
ensure_packages('cron')
78+
}
79+
}
80+
81+
# Setup db user with required permissions
82+
if $manage_user and $db_user and $db_password {
83+
# Create user with superuser privileges
84+
postgresql::server::role { $db_user:
85+
ensure => $ensure,
86+
password_hash => postgresql::postgresql_password($db_user, $db_password),
87+
superuser => true,
88+
}
89+
90+
# Allow authentication from localhost
91+
postgresql::server::pg_hba_rule { 'local access as backup user':
92+
type => 'local',
93+
database => 'all',
94+
user => $db_user,
95+
auth_method => 'md5',
96+
order => 1,
97+
}
98+
}
99+
100+
# Create backup directory
101+
file { $dir:
102+
ensure => 'directory',
103+
mode => $dir_mode,
104+
owner => $dir_owner,
105+
group => $dir_group,
106+
}
107+
108+
# Create backup script
109+
file { $script_path:
110+
ensure => $ensure,
111+
mode => '0700',
112+
owner => 'root',
113+
group => '0', # Use GID for compat with Linux and BSD.
114+
content => epp($template, {
115+
compress => $compress,
116+
databases => $databases,
117+
db_user => $db_user,
118+
delete_before_dump => $delete_before_dump,
119+
dir => $dir,
120+
format => $format,
121+
optional_args => $optional_args,
122+
post_script => $post_script,
123+
pre_script => $pre_script,
124+
rotate => $rotate,
125+
success_file_path => $success_file_path,
126+
}),
127+
}
128+
129+
# Create password file for pg_dump
130+
file { $pgpass_path:
131+
ensure => $ensure,
132+
mode => '0600',
133+
owner => 'root',
134+
group => '0', # Use GID for compat with Linux and BSD.
135+
content => inline_epp('*:*:*:<%= $db_user %>:<%= $db_password %>',{
136+
db_password => $db_password,
137+
db_user => $db_user,
138+
}),
139+
show_diff => false,
140+
}
141+
142+
# Create cron job
143+
cron { 'pg_dump backup job':
144+
ensure => $ensure,
145+
command => $script_path,
146+
user => 'root',
147+
hour => $time[0],
148+
minute => $time[1],
149+
weekday => $weekday,
150+
}
151+
}

manifests/params.pp

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
$manage_logdir = true
3232
$manage_xlogdir = true
3333

34+
$backup_enable = false
35+
$backup_provider = 'pg_dump'
36+
3437
# Amazon Linux's OS Family is 'Linux', operating system 'Amazon'.
3538
case $facts['os']['family'] {
3639
'RedHat', 'Linux': {

manifests/server.pp

+21
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@
7777
# @param roles Specifies a hash from which to generate postgresql::server::role resources.
7878
# @param config_entries Specifies a hash from which to generate postgresql::server::config_entry resources.
7979
# @param pg_hba_rules Specifies a hash from which to generate postgresql::server::pg_hba_rule resources.
80+
81+
# @param backup_enable Whether a backup job should be enabled.
82+
# @param backup_options A hash of options that should be passed through to the backup provider.
83+
# @param backup_provider Specifies the backup provider to use.
8084
#
8185
# @param version Deprecated. Use postgresql::globals instead. Sets PostgreSQL version
8286
#
@@ -152,6 +156,10 @@
152156
Hash[String, Any] $config_entries = {},
153157
Hash[String, Hash] $pg_hba_rules = {},
154158

159+
Boolean $backup_enable = $postgresql::params::backup_enable,
160+
Hash $backup_options = {},
161+
Enum['pg_dump'] $backup_provider = $postgresql::params::backup_provider,
162+
155163
#Deprecated
156164
$version = undef,
157165
) inherits postgresql::params {
@@ -201,4 +209,17 @@
201209
* => $rule,
202210
}
203211
}
212+
213+
if $backup_enable {
214+
case $backup_provider {
215+
'pg_dump': {
216+
class { 'postgresql::backup::pg_dump':
217+
* => $backup_options,
218+
}
219+
}
220+
default: {
221+
fail("Unsupported backup provider '${backup_provider}'.")
222+
}
223+
}
224+
}
204225
}

spec/classes/server_spec.rb

+58
Original file line numberDiff line numberDiff line change
@@ -256,4 +256,62 @@ class { 'postgresql::globals':
256256
.with_address('192.0.2.100')
257257
end
258258
end
259+
260+
describe 'backup_enable => false' do
261+
let(:params) { { backup_enable: false } }
262+
263+
it { is_expected.to contain_class('postgresql::server') }
264+
it { is_expected.not_to contain_class('postgresql::backup::pg_dump') }
265+
it { is_expected.not_to contain_file('/root/.pgpass') }
266+
it { is_expected.not_to contain_file('/usr/local/sbin/pg_dump.sh') }
267+
it { is_expected.not_to contain_cron('pg_dump backup job') }
268+
end
269+
270+
describe 'backup_enable => true' do
271+
let(:params) do
272+
{
273+
backup_enable: true,
274+
backup_provider: 'pg_dump',
275+
backup_options: {
276+
db_user: 'backupuser',
277+
db_password: 'backuppass',
278+
dir: '/tmp/backuptest',
279+
manage_user: true,
280+
},
281+
}
282+
end
283+
284+
it { is_expected.to contain_class('postgresql::server') }
285+
it { is_expected.to contain_class('postgresql::backup::pg_dump') }
286+
it {
287+
is_expected.to contain_postgresql__server__role('backupuser')
288+
.with_superuser(true)
289+
}
290+
it {
291+
is_expected.to contain_postgresql__server__pg_hba_rule('local access as backup user')
292+
.with_type('local')
293+
.with_database('all')
294+
.with_user('backupuser')
295+
.with_auth_method('md5')
296+
}
297+
it {
298+
is_expected.to contain_file('/root/.pgpass')
299+
.with_content(%r{.*:backupuser:.*})
300+
}
301+
it {
302+
is_expected.to contain_file('/usr/local/sbin/pg_dump.sh')
303+
.with_content(%r{.*pg_dumpall \$_pg_args --file=\$\{FILE\} \$@.*})
304+
}
305+
it {
306+
is_expected.to contain_cron('pg_dump backup job')
307+
.with(
308+
ensure: 'present',
309+
command: '/usr/local/sbin/pg_dump.sh',
310+
user: 'root',
311+
hour: '23',
312+
minute: '5',
313+
weekday: '*',
314+
)
315+
}
316+
end
259317
end

0 commit comments

Comments
 (0)