From 4f5a8b95da64e7b4aa87f4b0628e3683015aff26 Mon Sep 17 00:00:00 2001
From: Jean <popi+github@nomagic.fr>
Date: Thu, 6 Feb 2020 09:36:39 +0100
Subject: [PATCH] Add possibility to handle remote managed postgresql setup

---
 defaults/main.yml | 15 ++++++++++++-
 tasks/db.yml      | 57 +++++++++++++++++++++++++++++------------------
 tasks/main.yml    | 10 +++++++++
 templates/env.j2  |  2 +-
 4 files changed, 60 insertions(+), 24 deletions(-)

diff --git a/defaults/main.yml b/defaults/main.yml
index 8e7f4d2..8d288a7 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -8,10 +8,23 @@ funkwhale_config_path: /srv/funkwhale/config
 funkwhale_external_storage_enabled: false
 funkwhale_disable_django_admin: false
 funkwhale_username: funkwhale
-funkwhale_database_managed: true
 funkwhale_frontend_managed: true
+
+funkwhale_database_managed: true
+funkwhale_database_local: true
 funkwhale_database_name: funkwhale
 funkwhale_database_user: funkwhale
+# the DB host as per your ansible inventory
+funkwhale_database_host_ansible: localhost
+# the DB FQDN or IP for funkwhale connector configuration (ex: pg01.local)
+funkwhale_database_host_app: localhost
+funkwhale_database_port: 5432
+
+# ↓ Only needed if 'funkwhale_database_managed' == false
+# ↓ This is also assuming DB and user have already been set up, outside of the playbook.
+# ↓ Considering the playbook handles both local and remote PostGreSQL server types, this should typically not be required.
+#funkwhale_database_url: postgresql://{{ funkwhale_database_user }}[:{{ funkwhale_database_password }}]@[{{ funkwhale_database_host_app }}]:{{ funkwhale_database_port | default(5432) }}/{{ funkwhale_database_name }}
+
 funkwhale_nginx_managed: true
 funkwhale_nginx_max_body_size: 100M
 funkwhale_redis_managed: true
diff --git a/tasks/db.yml b/tasks/db.yml
index b7ec289..230bad9 100644
--- a/tasks/db.yml
+++ b/tasks/db.yml
@@ -1,47 +1,60 @@
 ---
 - name: "Install postgresql"
   become: true
-  when: funkwhale_database_managed
+  when: funkwhale_database_managed and funkwhale_database_local
   package:
     name:
       - postgresql
       - python3-psycopg2
 
 - name: "Start Postgresql"
-  when: funkwhale_database_managed
+  when: funkwhale_database_managed and funkwhale_database_local
   service:
     name: postgresql
     state: started
 
-- name: "Create {{ funkwhale_database_name }} database"
+- name: "Create {{ funkwhale_database_user }} database user on {{ funkwhale_database_host_ansible }} (local / passwordless)"
   become: true
   become_user: postgres
-  when: funkwhale_database_managed
-  postgresql_db:
-    name: "{{ funkwhale_database_name }}"
-    encoding: UTF-8
-    template: template0
+  when: funkwhale_database_managed and funkwhale_database_host_ansible == 'localhost'
+  postgresql_user:
+    name: "{{ funkwhale_database_user }}"
+    login_user: postgres
+  delegate_to: "{{ funkwhale_database_host_ansible }}"
 
-- name: "Create {{ funkwhale_database_user }} database user"
+- name: "Create {{ funkwhale_database_user }} database user on {{ funkwhale_database_host_ansible }} (remote / with password)"
   become: true
   become_user: postgres
-  when: funkwhale_database_managed
+  when: funkwhale_database_managed and funkwhale_database_host_ansible != 'localhost'
   postgresql_user:
-    db: "{{ funkwhale_database_name }}"
     name: "{{ funkwhale_database_user }}"
+    password: "{{ funkwhale_database_password }}"
+    login_user: postgres
+  delegate_to: "{{ funkwhale_database_host_ansible }}"
 
-- name: "Grant privileges on database {{ funkwhale_database_name }} to {{ funkwhale_database_user }} user"
-  when: funkwhale_database_managed
+- name: "Create {{ funkwhale_database_name }} database on {{ funkwhale_database_host_ansible }}"
   become: true
   become_user: postgres
-  command: psql -c "GRANT ALL PRIVILEGES ON DATABASE {{ funkwhale_database_name }} TO {{ funkwhale_database_user }}"
-
-
-- name: "Create db extensions"
   when: funkwhale_database_managed
-  become: true
+  postgresql_db:
+    name: "{{ funkwhale_database_name }}"
+    login_user: postgres
+    owner: "{{ funkwhale_database_user }}"
+    encoding: UTF-8
+    template: template0
+  delegate_to: "{{ funkwhale_database_host_ansible }}"
+
+- name: set up pgsql extensions
+  become: yes
   become_user: postgres
-  command: psql {{ funkwhale_database_name }} -c "CREATE EXTENSION IF NOT EXISTS {{ item }}"
-  with_items:
-    - unaccent
-    - citext
+  when: funkwhale_database_managed
+  postgresql_ext:
+    db: "{{ funkwhale_database_name }}"
+    name: "{{ myext }}"
+    login_user: postgres
+  loop: ['unaccent', 'citext']
+  loop_control:
+    loop_var: myext
+  delegate_to: "{{ funkwhale_database_host_ansible }}"
+
+...
diff --git a/tasks/main.yml b/tasks/main.yml
index 9ee4c7b..4858288 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -1,4 +1,14 @@
 ---
+- name: set a password for postgresql DB (remote psql server only)
+  tags: [ db ]
+  set_fact:
+    # Look up for the key 'vault_funkwhale_database_password' (for you to create, ideally in a vault).
+    # If no key is found,it will search inside ./pgsql_funkwhale.credentials.txt.
+    # If ./pgsql_funkwhale.credentials.txt does not exist, it  generates a random password and write it there.
+    funkwhale_database_password: "{{ vault_funkwhale_database_password | default(lookup('password', './%s.credentials.txt chars=ascii_letters,digits length=20' % 'pgsql_funkwhale')) }}"
+  # If 'funkwhale_database_local:' == true, funkwhale will connect via unix socket (no password needed).
+  when: not funkwhale_database_local
+
 - name: "Set frontend path"
   when: funkwhale_frontend_managed
   tags: [funkwhale, nginx]
diff --git a/templates/env.j2 b/templates/env.j2
index b3654f9..b3eeb5f 100644
--- a/templates/env.j2
+++ b/templates/env.j2
@@ -10,7 +10,7 @@ FUNKWHALE_WEB_WORKERS={{ funkwhale_web_workers }}
 REVERSE_PROXY_TYPE=nginx
 
 {% if funkwhale_database_managed %}
-DATABASE_URL=postgresql://{{ funkwhale_database_user }}@:5432/{{ funkwhale_database_name }}
+DATABASE_URL=postgresql://{{ funkwhale_database_user }}{%- if funkwhale_database_password is defined -%}:{{ funkwhale_database_password }}{%- endif -%}@{%- if funkwhale_database_host_app != 'localhost' -%}{{ funkwhale_database_host_app }}{%- endif -%}:{{ funkwhale_database_port }}/{{ funkwhale_database_name }}
 {% else %}
 DATABASE_URL={{ funkwhale_database_url }}
 {% endif %}
-- 
GitLab