From e7f5d588b5951697b9fd03adad1617aa401251a1 Mon Sep 17 00:00:00 2001
From: Andrea Dell'Amico <adellam@sevenseas.org>
Date: Tue, 21 Jun 2016 19:58:26 +0200
Subject: [PATCH] library/roles/postgresql: Manage SSL and install the
 letsencrypt acme hook if needed.

---
 postgresql/defaults/main.yml                  | 10 +++++-
 .../files/postgresql-letsencrypt-acme.sh      | 35 +++++++++++++++++++
 postgresql/tasks/main.yml                     |  7 +++-
 .../tasks/postgresql-letsencrypt-acmetool.yml | 15 ++++++++
 postgresql/tasks/postgresql-ssl-config.yml    |  8 +++++
 5 files changed, 73 insertions(+), 2 deletions(-)
 create mode 100644 postgresql/files/postgresql-letsencrypt-acme.sh
 create mode 100644 postgresql/tasks/postgresql-letsencrypt-acmetool.yml
 create mode 100644 postgresql/tasks/postgresql-ssl-config.yml

diff --git a/postgresql/defaults/main.yml b/postgresql/defaults/main.yml
index 79c831f2..1b0eb9d5 100644
--- a/postgresql/defaults/main.yml
+++ b/postgresql/defaults/main.yml
@@ -23,7 +23,6 @@ psql_data_dir: '/var/lib/postgresql/{{ psql_version }}'
 psql_log_dir: /var/log/postgresql
 psql_conf_parameters:
   - { name: 'max_connections', value: '100', set: 'False' }
-  - { name: 'ssl', value: 'true', set: 'False' }
   - { name: 'shared_buffers', value: '24MB', set: 'False' }
   - { name: 'temp_buffers', value: '8MB', set: 'False' }
   - { name: 'work_mem', value: '1MB', set: 'False' }
@@ -32,6 +31,15 @@ psql_conf_parameters:
   - { name: 'checkpoint_segments', value: '3', set: 'False' }
   - { name: 'max_files_per_process', value: '1000', set: 'False' }
 
+# SSL as a special case
+psql_enable_ssl: False
+postgresql_letsencrypt_managed: True
+psql_conf_ssl_parameters:
+  - { name: 'ssl', value: 'true' 
+  - { name: 'ssl_cert_file', value: '/var/lib/acme/live/{{ ansible_fqdn }}/cert' }
+  - { name: 'ssl_key_file', value: '/etc/pki/postgresql/postgresql.key' }
+  - { name: 'ssl_ca_file', value: '/var/lib/acme/live/{{ ansible_fqdn }}/chain' }
+
 psql_set_shared_memory: False
 psql_sysctl_file: 30-postgresql-shm.conf
 psql_sysctl_kernel_sharedmem_parameters:
diff --git a/postgresql/files/postgresql-letsencrypt-acme.sh b/postgresql/files/postgresql-letsencrypt-acme.sh
new file mode 100644
index 00000000..7ff0d353
--- /dev/null
+++ b/postgresql/files/postgresql-letsencrypt-acme.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+LE_SERVICES_SCRIPT_DIR=/usr/lib/acme/hooks
+LE_CERTS_DIR=/var/lib/acme/live/$HOSTNAME
+LE_LOG_DIR=/var/log/letsencrypt
+POSTGRESQL_CERTDIR=/etc/pki/postgresql
+POSTGRESQL_KEYFILE=$POSTGRESQL_CERTDIR/postgresql.key
+DATE=$( date )
+
+[ ! -d $POSTGRESQL_CERTDIR ] && mkdir -p $POSTGRESQL_CERTDIR
+[ ! -d $LE_LOG_DIR ] && mkdir $LE_LOG_DIR
+echo "$DATE" >> $LE_LOG_DIR/postgresql.log
+
+if [ -f /etc/default/letsencrypt ] ; then
+    . /etc/default/letsencrypt
+else
+    echo "No letsencrypt default file" >> $LE_LOG_DIR/postgresql.log
+fi
+
+echo "Copy the key file" >> $LE_LOG_DIR/postgresql.log
+cp ${LE_CERTS_DIR}/privkey  ${POSTGRESQL_KEYFILE}
+chmod 440 ${POSTGRESQL_KEYFILE}
+chgrp postgres ${POSTGRESQL_KEYFILE}
+
+echo "Reload the postgresql service" >> $LE_LOG_DIR/postgresql.log
+if [ -x /bin/systemctl ] ; then
+    systemctl reload postgresql >> $LE_LOG_DIR/postgresql.log 2>&1
+else
+    service postgresql reload >> $LE_LOG_DIR/postgresql.log 2>&1
+fi
+
+echo "Done." >> $LE_LOG_DIR/postgresql.log
+
+exit 0
+
diff --git a/postgresql/tasks/main.yml b/postgresql/tasks/main.yml
index f41b8e14..115e215e 100644
--- a/postgresql/tasks/main.yml
+++ b/postgresql/tasks/main.yml
@@ -9,6 +9,8 @@
   when: psql_pgpool_install
 - include: postgresql-config.yml
   when: psql_postgresql_install
+- include: postgresql-ssl-config.yml
+  when: psql_postgresql_install
 - include: psql-kernel-sharedmem.yml
   when:
     - psql_postgresql_install 
@@ -27,6 +29,9 @@
     - psql_db_data is defined
 - include: pgpool-ii.yml
   when: psql_pgpool_service_install
-
+- include: postgresql-letsencrypt-acmetool.yml
+  when:
+    - postgresql_letsencrypt_managed
+    - letsencrypt_acme_install is defined
 
 
diff --git a/postgresql/tasks/postgresql-letsencrypt-acmetool.yml b/postgresql/tasks/postgresql-letsencrypt-acmetool.yml
new file mode 100644
index 00000000..70aff0fc
--- /dev/null
+++ b/postgresql/tasks/postgresql-letsencrypt-acmetool.yml
@@ -0,0 +1,15 @@
+---
+- name: Create the acme hooks directory if it does not yet exist
+  file: dest={{ letsencrypt_acme_services_scripts_dir }} state=directory owner=root group=root
+  when:
+    - postgresql_letsencrypt_managed
+    - letsencrypt_acme_install
+  tags: [ 'postgresql', 'postgres', 'letsencrypt' ]
+
+- name: Install a script that fix the letsencrypt certificate for postgresql and then reload the service
+  copy: src=postgresql-letsencrypt-acme.sh dest={{ letsencrypt_acme_services_scripts_dir }}/postgresql owner=root group=root mode=4555
+  when:
+    - postgresql_letsencrypt_managed
+    - letsencrypt_acme_install
+  tags: [ 'postgresql', 'postgres', 'letsencrypt' ]
+
diff --git a/postgresql/tasks/postgresql-ssl-config.yml b/postgresql/tasks/postgresql-ssl-config.yml
new file mode 100644
index 00000000..9c76f060
--- /dev/null
+++ b/postgresql/tasks/postgresql-ssl-config.yml
@@ -0,0 +1,8 @@
+---
+- name: Setup ssl in the postgresql configuration
+  action: configfile path=/etc/postgresql/{{ psql_version }}/main/postgresql.conf key={{ item.name }} value="{{ item.value }}"
+  with_items: '{{ psql_conf_ssl_parameters }}'
+  when: psql_enable_ssl
+  notify: Restart postgresql
+  tags: [ 'postgresql', 'postgres', 'pg_conf' ]
+