Puppet Plan: peadm::subplans::db_populate

Defined in:
plans/subplans/db_populate.pp

Summary

Destructively (re)populates a new or existing database with the contents or a known good source

Overview

This plan is in development and currently considered experimental.

Parameters:

  • source_host (Peadm::SingleTargetSpec)

    _ The hostname of the database containing data

  • targets (Peadm::SingleTargetSpec)


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'plans/subplans/db_populate.pp', line 7

plan peadm::subplans::db_populate(
  Peadm::SingleTargetSpec $targets,
  Peadm::SingleTargetSpec $source_host,
) {
  $source_target      = peadm::get_targets($source_host, 1)
  $destination_target = peadm::get_targets($targets, 1)

  # Always ensure Puppet is stopped or it'll remove rules that allow replication
  run_command('systemctl stop puppet.service', peadm::flatten_compact([
        $source_target,
        $destination_target,
  ]))

  # Retrieve source's PSQL version
  $psql_version = run_task('peadm::get_psql_version', $source_target).first.value['version']

  # Determine clientcert setting
  $clientcert = $psql_version ? {
    '14'    => 'verify-full',
    default => 1
  }

  # Add the following two lines to /opt/puppetlabs/server/data/postgresql/${psql_version}/data/pg_ident.conf
  #
  # These lines allow connections from destination by pg_basebackup to replicate
  # content
  apply($source_target) {
    file_line { 'replication-pe-ha-replication-map':
      path => "/opt/puppetlabs/server/data/postgresql/${psql_version}/data/pg_ident.conf",
      line => "replication-pe-ha-replication-map ${destination_target.peadm::certname()} pe-ha-replication",
    }
    file_line { 'replication-pe-ha-replication-ipv4':
      path => "/opt/puppetlabs/server/data/postgresql/${psql_version}/data/pg_hba.conf",
      line => "hostssl replication    pe-ha-replication 0.0.0.0/0  cert  map=replication-pe-ha-replication-map  clientcert=${clientcert}",
    }
    file_line { 'replication-pe-ha-replication-ipv6':
      path => "/opt/puppetlabs/server/data/postgresql/${psql_version}/data/pg_hba.conf",
      line => "hostssl replication    pe-ha-replication ::/0       cert  map=replication-pe-ha-replication-map  clientcert=${clientcert}",
    }
  }

  # Reload pe-postgresql to activate replication rules
  run_command('systemctl reload pe-postgresql.service', $source_target)

  # Save existing certificates to use for authentication to source. Can not use
  # certs stored in /etc/puppetlabs/puppet/ssl because we will run pg_basebackup
  # as pe-postgres user, which lacks access
  run_command("mv /opt/puppetlabs/server/data/postgresql/${psql_version}/data/certs /opt/puppetlabs/server/data/pg_certs", $destination_target)# lint:ignore:140chars

  # pg_basebackup requires an entirely empty data directory
  run_command('rm -rf /opt/puppetlabs/server/data/postgresql/*', $destination_target)
  $pg_basebackup = @("PGBASE")
    runuser -u pe-postgres -- \
      /opt/puppetlabs/server/bin/pg_basebackup \
        -D /opt/puppetlabs/server/data/postgresql/${psql_version}/data \
        -d "host=${source_host}
            user=pe-ha-replication
            sslmode=verify-full
            sslcert=/opt/puppetlabs/server/data/pg_certs/_local.cert.pem
            sslkey=/opt/puppetlabs/server/data/pg_certs/_local.private_key.pem
            sslrootcert=/etc/puppetlabs/puppet/ssl/certs/ca.pem"
    | - PGBASE
  run_command($pg_basebackup, $destination_target)

  # Delete the saved certs, they'll be properly re-populated by an agent run
  run_command('rm -rf /opt/puppetlabs/server/data/pg_certs', $destination_target)

  # Start pe-postgresql.service
  run_command('systemctl start pe-postgresql.service', $destination_target)

  # Delete the previously add replication rules to prevent Puppet restarting
  # thing later
  apply($source_target) {
    file_line { 'replication-pe-ha-replication-map':
      ensure => absent,
      path   => "/opt/puppetlabs/server/data/postgresql/${psql_version}/data/pg_ident.conf",
      line   => "replication-pe-ha-replication-map ${destination_target.peadm::certname()} pe-ha-replication",
    }
    file_line { 'replication-pe-ha-replication-ipv4':
      ensure => absent,
      path   => "/opt/puppetlabs/server/data/postgresql/${psql_version}/data/pg_hba.conf",
      line   => "hostssl replication    pe-ha-replication 0.0.0.0/0  cert  map=replication-pe-ha-replication-map  clientcert=${clientcert}",
    }
    file_line { 'replication-pe-ha-replication-ipv6':
      ensure => absent,
      path   => "/opt/puppetlabs/server/data/postgresql/${psql_version}/data/pg_hba.conf",
      line   => "hostssl replication    pe-ha-replication ::/0       cert  map=replication-pe-ha-replication-map  clientcert=${clientcert}",
    }
  }

  # Reload pe-postgresql to revoke replication rules
  run_command('systemctl reload pe-postgresql.service', $source_target)

  return("Population of ${$destination_target.peadm::certname()} with data from s${$source_target.peadm::certname()} succeeded.")
}