Catppuccin Mocha campaign template (default) and archive variant, kept in sync in the database; system e-mail header/footer overridden via --static-dir from a ConfigMap. PNG logo for mail clients. Tested in Mailpit (desktop, phone width; 87% CSS support, rest inlined). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
139 lines
5.0 KiB
YAML
139 lines
5.0 KiB
YAML
# SPDX-License-Identifier: MIT-0
|
|
---
|
|
- name: Validate required secrets
|
|
ansible.builtin.assert:
|
|
that:
|
|
- listmonk_db_password | length >= 16
|
|
- listmonk_admin_password | length >= 8
|
|
- listmonk_smtp_password | length > 0
|
|
- not listmonk_oidc_enabled | bool or listmonk_oidc_client_secret | length > 0
|
|
fail_msg: >-
|
|
Set listmonk_db_password (16+ chars), listmonk_admin_password (8+),
|
|
listmonk_smtp_password and listmonk_oidc_client_secret in Vault.
|
|
quiet: true
|
|
|
|
- name: Create namespace
|
|
kubernetes.core.k8s:
|
|
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
|
|
context: "{{ listmonk_kube_context | default(omit, true) }}"
|
|
state: present
|
|
definition:
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: "{{ listmonk_namespace }}"
|
|
when: listmonk_create_namespace | bool
|
|
|
|
- name: Store credentials
|
|
kubernetes.core.k8s:
|
|
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
|
|
context: "{{ listmonk_kube_context | default(omit, true) }}"
|
|
state: present
|
|
apply: true
|
|
definition: "{{ lookup('ansible.builtin.template', 'secret.yml.j2') | from_yaml }}"
|
|
no_log: true
|
|
|
|
- name: Deploy PostgreSQL
|
|
kubernetes.core.k8s:
|
|
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
|
|
context: "{{ listmonk_kube_context | default(omit, true) }}"
|
|
state: present
|
|
apply: true
|
|
definition: "{{ lookup('ansible.builtin.template', 'postgres.yml.j2') | from_yaml_all | list }}"
|
|
wait: true
|
|
wait_timeout: "{{ listmonk_wait_timeout }}"
|
|
|
|
- name: Store the system e-mail templates
|
|
kubernetes.core.k8s:
|
|
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
|
|
context: "{{ listmonk_kube_context | default(omit, true) }}"
|
|
state: present
|
|
apply: true
|
|
definition: "{{ lookup('ansible.builtin.template', 'email-configmap.yml.j2') | from_yaml }}"
|
|
|
|
- name: Deploy listmonk
|
|
kubernetes.core.k8s:
|
|
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
|
|
context: "{{ listmonk_kube_context | default(omit, true) }}"
|
|
state: present
|
|
apply: true
|
|
definition: "{{ lookup('ansible.builtin.template', 'listmonk.yml.j2') | from_yaml_all | list }}"
|
|
wait: true
|
|
wait_timeout: "{{ listmonk_wait_timeout }}"
|
|
|
|
- name: Read the newsletter automation credentials
|
|
kubernetes.core.k8s_info:
|
|
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
|
|
context: "{{ listmonk_kube_context | default(omit, true) }}"
|
|
kind: Secret
|
|
namespace: "{{ listmonk_namespace }}"
|
|
name: "{{ listmonk_name }}-newsletter-api"
|
|
register: _listmonk_newsletter_secret
|
|
no_log: true
|
|
when: listmonk_newsletter_api_enabled | bool
|
|
|
|
# Generated once, then reused; delete the Secret to rotate the token.
|
|
- name: Use or generate the newsletter automation token
|
|
ansible.builtin.set_fact:
|
|
listmonk_newsletter_api_token: >-
|
|
{{ (_listmonk_newsletter_secret.resources[0].data.token | b64decode)
|
|
if _listmonk_newsletter_secret.resources | length > 0
|
|
else lookup('ansible.builtin.password', '/dev/null', chars=['ascii_letters', 'digits'], length=48) }}
|
|
no_log: true
|
|
when: listmonk_newsletter_api_enabled | bool
|
|
|
|
- name: Store the newsletter automation credentials
|
|
kubernetes.core.k8s:
|
|
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
|
|
context: "{{ listmonk_kube_context | default(omit, true) }}"
|
|
state: present
|
|
definition:
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: "{{ listmonk_name }}-newsletter-api"
|
|
namespace: "{{ listmonk_namespace }}"
|
|
type: Opaque
|
|
stringData:
|
|
url: "{{ listmonk_root_url }}"
|
|
username: "{{ listmonk_newsletter_api_user }}"
|
|
token: "{{ listmonk_newsletter_api_token }}"
|
|
no_log: true
|
|
when: listmonk_newsletter_api_enabled | bool
|
|
|
|
# Settings, Dex admins and lists live in listmonk's database, not its config.
|
|
- name: Converge database-held configuration
|
|
kubernetes.core.k8s_exec:
|
|
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
|
|
context: "{{ listmonk_kube_context | default(omit, true) }}"
|
|
namespace: "{{ listmonk_namespace }}"
|
|
pod: "{{ listmonk_name }}-db-0"
|
|
container: postgres
|
|
command: >-
|
|
sh -c 'echo {{ lookup('ansible.builtin.template', 'configure.sql.j2') | b64encode }}
|
|
| base64 -d | psql -U listmonk -d listmonk -qtA'
|
|
register: listmonk_configure
|
|
changed_when: listmonk_configure.stdout_lines | map('int') | sum > 0
|
|
no_log: true
|
|
|
|
- name: Restart listmonk to load the new settings
|
|
kubernetes.core.k8s:
|
|
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
|
|
context: "{{ listmonk_kube_context | default(omit, true) }}"
|
|
state: patched
|
|
kind: Deployment
|
|
namespace: "{{ listmonk_namespace }}"
|
|
name: "{{ listmonk_name }}"
|
|
definition:
|
|
spec:
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
kubectl.kubernetes.io/restartedAt: "{{ now(utc=true).isoformat() }}"
|
|
wait: true
|
|
wait_condition:
|
|
type: Available
|
|
status: "True"
|
|
wait_timeout: "{{ listmonk_wait_timeout }}"
|
|
when: listmonk_configure is changed
|