From f9f00d1919d6f42c54c4d40f1e3bb566f1a2738b Mon Sep 17 00:00:00 2001
From: transcaffeine <transcaffeine@finally.coffee>
Date: Sat, 19 Apr 2025 16:21:22 +0200
Subject: [PATCH] feat(postgresql): add playbooks to provision users,
 databases, hba entries and entire client(s)

---
 playbooks/postgresql_client.yml               | 24 +++++++++++++++++
 playbooks/postgresql_clients.yml              |  4 +++
 playbooks/postgresql_database.yml             | 26 +++++++++++++++++++
 .../postgresql_host_based_authentication.yml  | 23 ++++++++++++++++
 playbooks/postgresql_user.yml                 | 24 +++++++++++++++++
 5 files changed, 101 insertions(+)
 create mode 100644 playbooks/postgresql_client.yml
 create mode 100644 playbooks/postgresql_clients.yml
 create mode 100644 playbooks/postgresql_database.yml
 create mode 100644 playbooks/postgresql_host_based_authentication.yml
 create mode 100644 playbooks/postgresql_user.yml

diff --git a/playbooks/postgresql_client.yml b/playbooks/postgresql_client.yml
new file mode 100644
index 0000000..402d8e6
--- /dev/null
+++ b/playbooks/postgresql_client.yml
@@ -0,0 +1,24 @@
+---
+- import_playbook: finallycoffee.databases.postgresql_user
+  vars:
+    postgresql_users:
+      - name: "{{ postgresql_client_username }}"
+        password: "{{ postgresql_client_password }}"
+- import_playbook: finallycoffee.databases.postgresql_database
+  vars:
+    postgresql_databases:
+      - name: "{{ postgresql_client_database }}"
+        owner: "{{ postgresql_client_username }}"
+        encoding: "{{ postgresql_client_database_encoding | default('UTF8', true) }}"
+        lc_ctype: "{{ postgresql_client_database_lc_ctype | default('en_US.UTF-8', true) }}"
+        lc_collate: "{{ postgresql_client_database_lc_collate | default('en_US.UTF-8', true) }}"
+- import_playbook: finallycoffee.databases.postgresql_host_based_authentication
+  vars:
+    postgresql_authentications:
+      - users: "{{ postgresql_client_username }}"
+        databases: "{{ postgresql_client_database }}"
+        contype: "{{ postgresql_client_database_contype | default('local') }}"
+        method: "{{ postgresql_client_database_auth_method | default('md5') }}"
+        options: "{{ postgresql_client_options | default(false, true) }}"
+        address: "{{ postgresql_client_address | default(false, true) }}"
+        netmask: "{{ postgresql_client_netmask | default(false, true) }}"
diff --git a/playbooks/postgresql_clients.yml b/playbooks/postgresql_clients.yml
new file mode 100644
index 0000000..e75505d
--- /dev/null
+++ b/playbooks/postgresql_clients.yml
@@ -0,0 +1,4 @@
+---
+- import_playbook: finallycoffee.databases.postgresql_user
+- import_playbook: finallycoffee.databases.postgresql_database
+- import_playbook: finallycoffee.databases.postgresql_host_based_authentication
diff --git a/playbooks/postgresql_database.yml b/playbooks/postgresql_database.yml
new file mode 100644
index 0000000..e0a7336
--- /dev/null
+++ b/playbooks/postgresql_database.yml
@@ -0,0 +1,26 @@
+---
+- name: Configure postgresql databases
+  hosts: "{{ postgresql_hosts | default('postgresql', true) }}"
+  become: "{{ postgresql_become | default(false, true) }}"
+  gather_facts: "{{ postgresql_gather_facts | default(false, true) }}"
+  tasks:
+    - name: Configure individual postgresql database
+      community.postgresql.postgresql_db:
+        name: "{{ postgresql_database.name }}"
+        owner: "{{ postgresql_database.owner | default(omit) }}"
+        state: "{{ postgresql_database_state }}"
+        template: "{{ postgresql_database.template | default(omit, true) }}"
+        encoding: "{{ postgresql_database.encoding | default(omit, true) }}"
+        lc_ctype: "{{ postgresql_database.lc_ctype | default(omit, true) }}"
+        lc_collate: "{{ postgresql_database.lc_collate | default(omit, true) }}"
+        login_host: "{{ postgresql_connection_host | default(omit, true) }}"
+        login_port: "{{ postgresql_connection_port | default(omit, true) }}"
+        login_unix_socket: "{{ postgresql_connection_unix_socket | default(omit, true) }}"
+        login_user: "{{ postgresql_connection_user | default(omit, true) }}"
+        login_password: "{{ postgresql_connection_password | default(omit, true) }}"
+      vars:
+        postgresql_database_state: "{{ postgresql_database.state | default('present', true) }}"
+      loop: "{{ postgresql_databases | default([]) }}"
+      loop_control:
+        loop_var: postgresql_database
+        label: "{{ postgresql_database.name }}"
diff --git a/playbooks/postgresql_host_based_authentication.yml b/playbooks/postgresql_host_based_authentication.yml
new file mode 100644
index 0000000..36cb3a6
--- /dev/null
+++ b/playbooks/postgresql_host_based_authentication.yml
@@ -0,0 +1,23 @@
+---
+- name: Configure postgresql host based authentications
+  hosts: "{{ postgresql_hosts | default('postgresql', true) }}"
+  become: "{{ postgresql_become | default(false, true) }}"
+  gather_facts: "{{ postgresql_gather_facts | default(false, true) }}"
+  tasks:
+    - name: Configure individual postgresql host based authentication
+      community.postgresql.postgresql_pg_hba:
+        dest: "{{ postgresql_pg_hba_conf_file }}"
+        users: "{{ postgresql_auth.users | default(omit) }}"
+        databases: "{{ postgresql_auth.databases | default(omit) }}"
+        contype: "{{ postgresql_auth.contype }}"
+        state: "{{ postgresql_auth_state }}"
+        method: "{{ postgresql_auth.method | default(omit, true) }}"
+        options: "{{ postgresql_auth.options | default(omit, true) }}"
+        address: "{{ postgresql_auth.address | default(omit, true) }}"
+        netmask: "{{ postgresql_auth.netmask | default(omit, true) }}"
+      vars:
+        postgresql_auth_state: "{{ postgresql_auth.state | default('present', true) }}"
+      loop: "{{ postgresql_authentications | default([]) }}"
+      loop_control:
+        loop_var: postgresql_auth
+        label: "{{ postgresql_auth.users }}@{{ postgresql_auth.databases }}"
diff --git a/playbooks/postgresql_user.yml b/playbooks/postgresql_user.yml
new file mode 100644
index 0000000..236b8fa
--- /dev/null
+++ b/playbooks/postgresql_user.yml
@@ -0,0 +1,24 @@
+---
+- name: Configure postgresql users
+  hosts: "{{ postgresql_hosts | default('postgresql', true) }}"
+  become: "{{ postgresql_become | default(false, true) }}"
+  gather_facts: "{{ postgresql_gather_facts | default(false, true) }}"
+  tasks:
+    - name: Configure individual postgresql user
+      community.postgresql.postgresql_user:
+        name: "{{ postgresql_user.name }}"
+        state: "{{ postgresql_user_state }}"
+        password: "{{ postgresql_user_password }}"
+        login_host: "{{ postgresql_connection_host | default(omit, true) }}"
+        login_port: "{{ postgresql_connection_port | default(omit, true) }}"
+        login_unix_socket: "{{ postgresql_connection_unix_socket | default(omit, true) }}"
+        login_user: "{{ postgresql_connection_user | default(omit, true) }}"
+        login_password: "{{ postgresql_connection_password | default(omit, true) }}"
+      vars:
+        postgresql_user_state: "{{ postgresql_user.state | default('present', true) }}"
+        postgresql_user_password: >-2
+          {{ (postgresql_user_state != 'absent') | ternary(postgresql_user.password, omit) }}
+      loop: "{{ postgresql_users | default([]) }}"
+      loop_control:
+        loop_var: postgresql_user
+        label: "{{ postgresql_user.name }}"