Skip to content

Commit 40061ba

Browse files
committed
Merge pull request puppetlabs#603 from dacrome/ticket/1761-provide_recovery_conf
(MODULES-1761) Provide defined resource for managing recovery.conf
2 parents c8d12ae + 81b4778 commit 40061ba

File tree

8 files changed

+286
-0
lines changed

8 files changed

+286
-0
lines changed

README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ Resources:
147147
* [postgresql::server::extension](#resource-postgresqlserverextension)
148148
* [postgresql::server::pg_hba_rule](#resource-postgresqlserverpg_hba_rule)
149149
* [postgresql::server::pg_ident_rule](#resource-postgresqlserverpg_ident_rule)
150+
* [postgresql::server::recovery](#resource-postgresqlserverrecovery)
150151
* [postgresql::server::role](#resource-postgresqlserverrole)
151152
* [postgresql::server::schema](#resource-postgresqlserverschema)
152153
* [postgresql::server::table_grant](#resource-postgresqlservertable_grant)
@@ -246,6 +247,9 @@ Path to your `pg\_ident.conf` file.
246247
####`postgresql_conf_path`
247248
Path to your `postgresql.conf` file.
248249

250+
####`recovery_conf_path`
251+
Path to your `recovery.conf` file.
252+
249253
####`pg_hba_conf_defaults`
250254
If false, disables the defaults supplied with the module for `pg\_hba.conf`. This is useful if you disagree with the defaults and wish to override them yourself. Be sure that your changes of course align with the rest of the module, as some access is required to perform basic `psql` operations for example.
251255

@@ -365,6 +369,9 @@ Path to your `pg\_ident.conf` file.
365369
####`postgresql_conf_path`
366370
Path to your `postgresql.conf` file.
367371

372+
####`recovery_conf_path`
373+
Path to your `recovery.conf` file.
374+
368375
####`pg_hba_conf_defaults`
369376
If false, disables the defaults supplied with the module for `pg\_hba.conf`. This is useful if you di
370377
sagree with the defaults and wish to override them yourself. Be sure that your changes of course alig
@@ -396,6 +403,9 @@ This value defaults to `true`. Whether or not manage the pg_hba.conf. If set to
396403
####`manage_pg_ident_conf`
397404
This value defaults to `true`. Whether or not manage the pg_ident.conf. If set to `true`, puppet will overwrite this file. If set to `false`, puppet will not modify the file.
398405

406+
####`manage_recovery_conf`
407+
This value defaults to `false`. Whether or not manage the recovery.conf. If set to `true`, puppet will overwrite this file. If set to `false`, puppet will not create the file.
408+
399409
###Class: postgresql::client
400410

401411
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):
@@ -696,6 +706,65 @@ An order for placing the mapping in pg_ident.conf. Defaults to 150.
696706
####`target`
697707
This provides the target for the rule, and is generally an internal only property. Use with caution.
698708

709+
###Resource: postgresql::server::recovery
710+
This defined type allows you to create the content for `recovery.conf`. For more details see the [PostgreSQL documentation](http://www.postgresql.org/docs/9.4/static/recovery-config.html).
711+
712+
For example:
713+
714+
postgresql::server::recovery( 'Create a recovery.conf file with the following defined parameters':
715+
restore_command => 'cp /mnt/server/archivedir/%f %p',
716+
archive_cleanup_command => undef,
717+
recovery_end_command => undef,
718+
recovery_target_name => 'daily backup 2015-01-26',
719+
recovery_target_time => '2015-02-08 22:39:00 EST',
720+
recovery_target_xid => undef,
721+
recovery_target_inclusive => true,
722+
recovery_target => 'immediate',
723+
recovery_target_timeline => 'latest',
724+
pause_at_recovery_target => true,
725+
standby_mode => 'on',
726+
primary_conninfo => 'host=localhost port=5432',
727+
primary_slot_name => undef,
728+
trigger_file => undef,
729+
recovery_min_apply_delay => 0,
730+
}
731+
732+
This would create a `recovery.conf` config file, similar to this:
733+
734+
restore_command = 'cp /mnt/server/archivedir/%f %p'
735+
recovery_target_name = 'daily backup 2015-01-26'
736+
recovery_target_time = '2015-02-08 22:39:00 EST'
737+
recovery_target_inclusive = true
738+
recovery_target = 'immediate'
739+
recovery_target_timeline = 'latest'
740+
pause_at_recovery_target = true
741+
standby_mode = on
742+
primary_conninfo = 'host=localhost port=5432'
743+
recovery_min_apply_delay = 0
744+
745+
746+
Only the specified parameters will be recognize in the template! The `recovery.conf` will be only create if at least one parameter set and [manage_recovery_conf](#manage_recovery_conf) set to true.
747+
748+
Every param value is a String set in the template with inverted comma except `recovery_target_inclusive`, `pause_at_recovery_target`, `standby_mode` and `recovery_min_apply_delay`.
749+
`standby_mode` is special, String ('on'/'off') and Boolean (true/false) is allowed, but the postgres documentation says it's a Boolean.
750+
751+
A detailed description of all above listed parameters can be found in the [PostgreSQL documentation](http://www.postgresql.org/docs/9.4/static/recovery-config.html).
752+
753+
The parameters are grouped into these three sections:
754+
755+
756+
#### [`Archive Recovery Parameters`](http://www.postgresql.org/docs/9.4/static/archive-recovery-settings.html)
757+
In this section the `restore_command`, `archive_cleanup_command` and `recovery_end_command` parameters are listed.
758+
759+
#### [`Recovery Target Settings`](http://www.postgresql.org/docs/9.4/static/recovery-target-settings.html)
760+
In this section the `recovery_target_name`, `recovery_target_time`, `recovery_target_xid`, `recovery_target_inclusive`, `recovery_target`, `recovery_target_timeline` and `pause_at_recovery_target` parameters are listed.
761+
762+
#### [`Standby Server Settings`](http://www.postgresql.org/docs/9.4/static/standby-settings.html)
763+
In this section the `standby_mode`, `primary_conninfo`, `primary_slot_name`, `trigger_file` and `recovery_min_apply_delay` parameters are listed.
764+
765+
####`target`
766+
This provides the target for the rule, and is generally an internal only property. Use with caution.
767+
699768

700769
###Resource: postgresql::server::role
701770
This resource creates a role or user in PostgreSQL.

manifests/globals.pp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
$pg_hba_conf_path = undef,
2323
$pg_ident_conf_path = undef,
2424
$postgresql_conf_path = undef,
25+
$recovery_conf_path = undef,
2526

2627
$pg_hba_conf_defaults = undef,
2728

@@ -44,6 +45,7 @@
4445

4546
$manage_pg_hba_conf = undef,
4647
$manage_pg_ident_conf = undef,
48+
$manage_recovery_conf = undef,
4749

4850
$manage_package_repo = undef
4951
) {

manifests/params.pp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
$service_provider = $service_provider
1717
$manage_pg_hba_conf = pick($manage_pg_hba_conf, true)
1818
$manage_pg_ident_conf = pick($manage_pg_ident_conf, true)
19+
$manage_recovery_conf = pick($manage_recovery_conf, false)
1920
$package_ensure = 'present'
2021

2122
# Amazon Linux's OS Family is 'Linux', operating system 'Amazon'.
@@ -250,5 +251,6 @@
250251
$pg_hba_conf_defaults = pick($pg_hba_conf_defaults, true)
251252
$pg_ident_conf_path = pick($pg_ident_conf_path, "${confdir}/pg_ident.conf")
252253
$postgresql_conf_path = pick($postgresql_conf_path, "${confdir}/postgresql.conf")
254+
$recovery_conf_path = pick($recovery_conf_path, "${datadir}/recovery.conf")
253255
$default_database = pick($default_database, 'postgres')
254256
}

manifests/server.pp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
$pg_hba_conf_path = $postgresql::params::pg_hba_conf_path,
3131
$pg_ident_conf_path = $postgresql::params::pg_ident_conf_path,
3232
$postgresql_conf_path = $postgresql::params::postgresql_conf_path,
33+
$recovery_conf_path = $postgresql::params::recovery_conf_path,
3334

3435
$datadir = $postgresql::params::datadir,
3536
$xlogdir = $postgresql::params::xlogdir,
@@ -47,6 +48,7 @@
4748

4849
$manage_pg_hba_conf = $postgresql::params::manage_pg_hba_conf,
4950
$manage_pg_ident_conf = $postgresql::params::manage_pg_ident_conf,
51+
$manage_recovery_conf = $postgresql::params::manage_recovery_conf,
5052

5153
#Deprecated
5254
$version = undef,

manifests/server/config.pp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
$pg_hba_conf_path = $postgresql::server::pg_hba_conf_path
1010
$pg_ident_conf_path = $postgresql::server::pg_ident_conf_path
1111
$postgresql_conf_path = $postgresql::server::postgresql_conf_path
12+
$recovery_conf_path = $postgresql::server::recovery_conf_path
1213
$pg_hba_conf_defaults = $postgresql::server::pg_hba_conf_defaults
1314
$user = $postgresql::server::user
1415
$group = $postgresql::server::group
1516
$version = $postgresql::server::_version
1617
$manage_pg_hba_conf = $postgresql::server::manage_pg_hba_conf
1718
$manage_pg_ident_conf = $postgresql::server::manage_pg_ident_conf
19+
$manage_recovery_conf = $postgresql::server::manage_recovery_conf
1820
$datadir = $postgresql::server::datadir
1921
$logdir = $postgresql::server::logdir
2022

@@ -144,6 +146,17 @@
144146
}
145147
}
146148

149+
if ($manage_recovery_conf == true) {
150+
concat { $recovery_conf_path:
151+
owner => $user,
152+
group => $group,
153+
force => true, # do not crash if there is no recovery conf file
154+
mode => '0640',
155+
warn => true,
156+
notify => Class['postgresql::server::reload'],
157+
}
158+
}
159+
147160
if $::osfamily == 'RedHat' {
148161
if $::operatingsystemrelease =~ /^7/ or $::operatingsystem == 'Fedora' {
149162
file { 'systemd-override':

manifests/server/recovery.pp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# This resource manages the parameters that applies to the recovery.conf template. See README.md for more details.
2+
define postgresql::server::recovery(
3+
$restore_command = undef,
4+
$archive_cleanup_command = undef,
5+
$recovery_end_command = undef,
6+
$recovery_target_name = undef,
7+
$recovery_target_time = undef,
8+
$recovery_target_xid = undef,
9+
$recovery_target_inclusive = undef,
10+
$recovery_target = undef,
11+
$recovery_target_timeline = undef,
12+
$pause_at_recovery_target = undef,
13+
$standby_mode = undef,
14+
$primary_conninfo = undef,
15+
$primary_slot_name = undef,
16+
$trigger_file = undef,
17+
$recovery_min_apply_delay = undef,
18+
$target = $postgresql::server::recovery_conf_path
19+
) {
20+
21+
if $postgresql::server::manage_recovery_conf == false {
22+
fail('postgresql::server::manage_recovery_conf has been disabled, so this resource is now unused and redundant, either enable that option or remove this resource from your manifests')
23+
} else {
24+
if($restore_command == undef and $archive_cleanup_command == undef and $recovery_end_command == undef
25+
and $recovery_target_name == undef and $recovery_target_time == undef and $recovery_target_xid == undef
26+
and $recovery_target_inclusive == undef and $recovery_target == undef and $recovery_target_timeline == undef
27+
and $pause_at_recovery_target == undef and $standby_mode == undef and $primary_conninfo == undef
28+
and $primary_slot_name == undef and $trigger_file == undef and $recovery_min_apply_delay == undef) {
29+
fail('postgresql::server::recovery use this resource but do not pass a parameter will avoid creating the recovery.conf, because it makes no sense.')
30+
}
31+
32+
# Create the recovery.conf content
33+
concat::fragment { 'recovery.conf':
34+
target => $target,
35+
content => template('postgresql/recovery.conf'),
36+
}
37+
}
38+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
require 'spec_helper'
2+
3+
describe 'postgresql::server::recovery', :type => :define do
4+
let :facts do
5+
{
6+
:osfamily => 'Debian',
7+
:operatingsystem => 'Debian',
8+
:operatingsystemrelease => '6.0',
9+
:kernel => 'Linux',
10+
:concat_basedir => tmpfilename('recovery'),
11+
:id => 'root',
12+
:path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
13+
}
14+
end
15+
let :title do
16+
'test'
17+
end
18+
let :target do
19+
tmpfilename('recovery')
20+
end
21+
22+
context 'managing recovery' do
23+
let :pre_condition do
24+
<<-EOS
25+
class { 'postgresql::globals':
26+
manage_recovery_conf => true,
27+
}
28+
class { 'postgresql::server': }
29+
EOS
30+
end
31+
32+
let :params do
33+
{
34+
:restore_command => 'restore_command',
35+
:recovery_target_timeline => 'recovery_target_timeline',
36+
}
37+
end
38+
it do
39+
is_expected.to contain_concat__fragment('recovery.conf').with({
40+
:content => /restore_command = 'restore_command'[\n]+recovery_target_timeline = 'recovery_target_timeline'/
41+
})
42+
end
43+
end
44+
context 'not managing recovery' do
45+
let :pre_condition do
46+
<<-EOS
47+
class { 'postgresql::globals':
48+
manage_recovery_conf => false,
49+
}
50+
class { 'postgresql::server': }
51+
EOS
52+
end
53+
let :params do
54+
{
55+
:restore_command => '',
56+
}
57+
end
58+
it 'should fail because $manage_recovery_conf is false' do
59+
expect { catalogue }.to raise_error(Puppet::Error,
60+
/postgresql::server::manage_recovery_conf has been disabled/)
61+
end
62+
end
63+
context 'not managing recovery, missing param' do
64+
let :pre_condition do
65+
<<-EOS
66+
class { 'postgresql::globals':
67+
manage_recovery_conf => true,
68+
}
69+
class { 'postgresql::server': }
70+
EOS
71+
end
72+
it 'should fail because no param set' do
73+
expect { catalogue }.to raise_error(Puppet::Error,
74+
/postgresql::server::recovery use this resource but do not pass a parameter will avoid creating the recovery.conf, because it makes no sense./)
75+
end
76+
end
77+
78+
context 'managing recovery with all params' do
79+
let :pre_condition do
80+
<<-EOS
81+
class { 'postgresql::globals':
82+
manage_recovery_conf => true,
83+
}
84+
class { 'postgresql::server': }
85+
EOS
86+
end
87+
88+
let :params do
89+
{
90+
:restore_command => 'restore_command',
91+
:archive_cleanup_command => 'archive_cleanup_command',
92+
:recovery_end_command => 'recovery_end_command',
93+
:recovery_target_name => 'recovery_target_name',
94+
:recovery_target_time => 'recovery_target_time',
95+
:recovery_target_xid => 'recovery_target_xid',
96+
:recovery_target_inclusive => true,
97+
:recovery_target => 'recovery_target',
98+
:recovery_target_timeline => 'recovery_target_timeline',
99+
:pause_at_recovery_target => true,
100+
:standby_mode => 'on',
101+
:primary_conninfo => 'primary_conninfo',
102+
:primary_slot_name => 'primary_slot_name',
103+
:trigger_file => 'trigger_file',
104+
:recovery_min_apply_delay => 0,
105+
}
106+
end
107+
it do
108+
is_expected.to contain_concat__fragment('recovery.conf').with({
109+
:content => /restore_command = 'restore_command'[\n]+archive_cleanup_command = 'archive_cleanup_command'[\n]+recovery_end_command = 'recovery_end_command'[\n]+recovery_target_name = 'recovery_target_name'[\n]+recovery_target_time = 'recovery_target_time'[\n]+recovery_target_xid = 'recovery_target_xid'[\n]+recovery_target_inclusive = true[\n]+recovery_target = 'recovery_target'[\n]+recovery_target_timeline = 'recovery_target_timeline'[\n]+pause_at_recovery_target = true[\n]+standby_mode = on[\n]+primary_conninfo = 'primary_conninfo'[\n]+primary_slot_name = 'primary_slot_name'[\n]+trigger_file = 'trigger_file'[\n]+recovery_min_apply_delay = 0[\n]+/
110+
})
111+
end
112+
end
113+
end

templates/recovery.conf

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<% if @restore_command %>
2+
restore_command = '<%= @restore_command %>'
3+
<% end %>
4+
<% if @archive_cleanup_command %>
5+
archive_cleanup_command = '<%= @archive_cleanup_command %>'
6+
<% end %>
7+
<% if @recovery_end_command %>
8+
recovery_end_command = '<%= @recovery_end_command %>'
9+
<% end %>
10+
11+
<% if @recovery_target_name %>
12+
recovery_target_name = '<%= @recovery_target_name %>'
13+
<% end %>
14+
<% if @recovery_target_time %>
15+
recovery_target_time = '<%= @recovery_target_time %>'
16+
<% end %>
17+
<% if @recovery_target_xid %>
18+
recovery_target_xid = '<%= @recovery_target_xid %>'
19+
<% end %>
20+
<% if @recovery_target_inclusive %>
21+
recovery_target_inclusive = <%= @recovery_target_inclusive %>
22+
<% end %>
23+
<% if @recovery_target %>
24+
recovery_target = '<%= @recovery_target %>'
25+
<% end %>
26+
<% if @recovery_target_timeline %>
27+
recovery_target_timeline = '<%= @recovery_target_timeline %>'
28+
<% end %>
29+
<% if @pause_at_recovery_target %>
30+
pause_at_recovery_target = <%= @pause_at_recovery_target %>
31+
<% end %>
32+
33+
<% if @standby_mode %>
34+
standby_mode = <%= @standby_mode %>
35+
<% end %>
36+
<% if @primary_conninfo %>
37+
primary_conninfo = '<%= @primary_conninfo %>'
38+
<% end %>
39+
<% if @primary_slot_name %>
40+
primary_slot_name = '<%= @primary_slot_name %>'
41+
<% end %>
42+
<% if @trigger_file %>
43+
trigger_file = '<%= @trigger_file %>'
44+
<% end %>
45+
<% if @recovery_min_apply_delay %>
46+
recovery_min_apply_delay = <%= @recovery_min_apply_delay %>
47+
<% end %>

0 commit comments

Comments
 (0)