mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-05-10 07:15:43 +02:00
Compare commits
3 Commits
c9ab0cd7cc
...
59e985eb3b
Author | SHA1 | Date | |
---|---|---|---|
59e985eb3b | |||
f27076a5cc | |||
250f26e03c |
@ -1,29 +1,57 @@
|
|||||||
# General
|
# General
|
||||||
pause_duration: "120" # Database delay to wait for the central database before continue tasks
|
pause_duration: "120" # Database delay to wait for the central database before continue tasks
|
||||||
|
|
||||||
timezone: "UTC"
|
timezone: "Etc/UTC"
|
||||||
locale: "en" # Some applications are case sensitive
|
locale: "en" # Some applications are case sensitive
|
||||||
|
|
||||||
# Deployment mode
|
# Deployment mode
|
||||||
deployment_mode: "single" # Use single, if you deploy on one server. Use cluster if you setup in cluster mode.
|
deployment_mode: "single" # Use single, if you deploy on one server. Use cluster if you setup in cluster mode.
|
||||||
|
|
||||||
|
web_protocol: "https" # Web protocol type. Use https or http. If you run local you need to change it to http
|
||||||
|
|
||||||
## Domain
|
## Domain
|
||||||
primary_domain_tld: "localhost" # Top Level Domain of the server
|
primary_domain_tld: "localhost" # Top Level Domain of the server
|
||||||
primary_domain_sld: "cymais" # Second Level Domain of the server
|
primary_domain_sld: "cymais" # Second Level Domain of the server
|
||||||
primary_domain: "{{primary_domain_sld}}.{{primary_domain_tld}}" # Primary Domain of the server
|
primary_domain: "{{primary_domain_sld}}.{{primary_domain_tld}}" # Primary Domain of the server
|
||||||
|
|
||||||
# Helper Variables
|
# Helper Variables
|
||||||
|
|
||||||
|
# Helper Variables for administrator
|
||||||
_users_administrator_username: "{{ users.administrator.username | default('administrator') }}"
|
_users_administrator_username: "{{ users.administrator.username | default('administrator') }}"
|
||||||
_users_administrator_email: "{{ users.administrator.email | default(_users_administrator_username ~ '@' ~ primary_domain) }}"
|
_users_administrator_email: "{{ users.administrator.email | default(_users_administrator_username ~ '@' ~ primary_domain) }}"
|
||||||
|
|
||||||
|
# Helper Variables for bouncer
|
||||||
|
_users_bouncer_username: "{{ users.bouncer.username | default('bouncer') }}"
|
||||||
|
_users_bouncer_email: "{{ users.bouncer.email | default(_users_bouncer_username ~ '@' ~ primary_domain) }}"
|
||||||
|
|
||||||
|
# Helper Variables for no-reply
|
||||||
|
_users_no_reply_username: "{{ users.no-reply.username | default('no-reply') }}"
|
||||||
|
_users_no_reply_email: "{{ users.no-reply.email | default(_users_no_reply_username ~ '@' ~ primary_domain) }}"
|
||||||
|
|
||||||
# Administrator
|
# Administrator
|
||||||
default_users:
|
default_users:
|
||||||
administrator:
|
administrator:
|
||||||
username: "{{_users_administrator_username}}" # Username of the administrator
|
username: "{{_users_administrator_username}}" # Username of the administrator
|
||||||
email: "{{_users_administrator_email}}" # Email of the administrator
|
email: "{{_users_administrator_email}}" # Email of the administrator
|
||||||
# initial_password: Null # Example initialisation password needs to be set in inventory file
|
password: "{{ansible_become_password}}" # Example initialisation password needs to be set in inventory file
|
||||||
uid: 1001 # Posix User ID
|
uid: 1001 # Posix User ID
|
||||||
gid: 1001 # Posix Group ID
|
gid: 1001 # Posix Group ID
|
||||||
|
is_admin: true # Define as admin user
|
||||||
|
|
||||||
|
bouncer:
|
||||||
|
username: "{{ _users_bouncer_username }}" # Bounce-handler account username
|
||||||
|
email: "{{ _users_bouncer_email }}" # Email address for handling bounces
|
||||||
|
password: "{{ansible_become_password}}" # Example initialisation password needs to be set in inventory file
|
||||||
|
uid: 1002 # Posix User ID for bouncer
|
||||||
|
gid: 1002 # Posix Group ID for bouncer
|
||||||
|
|
||||||
|
no-reply:
|
||||||
|
username: "{{ _users_no_reply_username }}" # No-reply account username
|
||||||
|
email: "{{ _users_no_reply_email }}" # Email address for outgoing no-reply mails
|
||||||
|
password: "{{ansible_become_password}}" # Example initialisation password needs to be set in inventory file
|
||||||
|
uid: 1003 # Posix User ID for no-reply
|
||||||
|
gid: 1003 # Posix Group ID for no-reply
|
||||||
|
|
||||||
|
|
||||||
# Test Email
|
# Test Email
|
||||||
test_email: "test@{{primary_domain}}"
|
test_email: "test@{{primary_domain}}"
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
## Helper Variables:
|
## Helper Variables:
|
||||||
_oidc_client_realm: "{{ oidc.client.realm if oidc.client is defined and oidc.client.realm is defined else primary_domain }}"
|
_oidc_client_realm: "{{ oidc.client.realm if oidc.client is defined and oidc.client.realm is defined else primary_domain }}"
|
||||||
_oidc_client_issuer_url: "https://{{domains.keycloak}}/realms/{{_oidc_client_realm}}"
|
_oidc_client_issuer_url: "{{ web_protocol }}://{{domains.keycloak}}/realms/{{_oidc_client_realm}}"
|
||||||
|
|
||||||
defaults_oidc:
|
defaults_oidc:
|
||||||
client:
|
client:
|
||||||
|
@ -28,4 +28,4 @@ defaults_service_provider:
|
|||||||
legal:
|
legal:
|
||||||
editorial_responsible: "Johannes Gutenberg"
|
editorial_responsible: "Johannes Gutenberg"
|
||||||
source_code: "https://github.com/kevinveenbirkenbach/cymais"
|
source_code: "https://github.com/kevinveenbirkenbach/cymais"
|
||||||
imprint: "https://{{domains.html_server}}/imprint.html"
|
imprint: "{{ web_protocol }}://{{domains.html_server}}/imprint.html"
|
@ -22,8 +22,8 @@ services:
|
|||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
# It doesn't compile yet with this parameters. @todo Fix it
|
# It doesn't compile yet with this parameters. @todo Fix it
|
||||||
args:
|
args:
|
||||||
REACT_APP_PDS_URL: "https://{{domains.bluesky_api}}" # URL des PDS
|
REACT_APP_PDS_URL: "{{ web_protocol }}://{{domains.bluesky_api}}" # URL des PDS
|
||||||
REACT_APP_API_URL: "https://{{domains.bluesky_api}}" # API-URL des PDS
|
REACT_APP_API_URL: "{{ web_protocol }}://{{domains.bluesky_api}}" # API-URL des PDS
|
||||||
REACT_APP_SITE_NAME: "{{primary_domain | upper}} - Bluesky"
|
REACT_APP_SITE_NAME: "{{primary_domain | upper}} - Bluesky"
|
||||||
REACT_APP_SITE_DESCRIPTION: "Decentral Social "
|
REACT_APP_SITE_DESCRIPTION: "Decentral Social "
|
||||||
ports:
|
ports:
|
||||||
|
@ -51,8 +51,8 @@ env:
|
|||||||
DISCOURSE_DEVELOPER_EMAILS: {{users.administrator.email}}
|
DISCOURSE_DEVELOPER_EMAILS: {{users.administrator.email}}
|
||||||
|
|
||||||
# Set Logo
|
# Set Logo
|
||||||
DISCOURSE_LOGO_URL: "{{service_provider.platform.logo}}"
|
DISCOURSE_LOGO_URL: "{{ service_provider.platform.logo }}"
|
||||||
DISCOURSE_LOGO_SMALL_URL: "{{service_provider.platform.logo}}"
|
DISCOURSE_LOGO_SMALL_URL: "{{ service_provider.platform.logo }}"
|
||||||
|
|
||||||
# SMTP ADDRESS, username, and password are required
|
# SMTP ADDRESS, username, and password are required
|
||||||
# WARNING the char '#' in SMTP password can cause problems!
|
# WARNING the char '#' in SMTP password can cause problems!
|
||||||
@ -124,7 +124,7 @@ run:
|
|||||||
- exec: rails r "SiteSetting.username_change_period = 0" # Deactivate changing of username
|
- exec: rails r "SiteSetting.username_change_period = 0" # Deactivate changing of username
|
||||||
|
|
||||||
# Activate Administrator User
|
# Activate Administrator User
|
||||||
#- exec: printf '{{users.administrator.email}}\n{{users.administrator.initial_password}}\n{{users.administrator.initial_password}}\nY\n' | rake admin:create
|
#- exec: printf '{{users.administrator.email}}\n{{users.administrator.password}}\n{{users.administrator.password}}\nY\n' | rake admin:create
|
||||||
#- exec: rails r "User.find_by_email('{{users.administrator.email}}').update(username: '{{users.administrator.username}}')"
|
#- exec: rails r "User.find_by_email('{{users.administrator.email}}').update(username: '{{users.administrator.username}}')"
|
||||||
|
|
||||||
# The following code is just an inspiration, how to connect with the oidc account. as long as this is not set the admini account needs to be manually connected with oidc
|
# The following code is just an inspiration, how to connect with the oidc account. as long as this is not set the admini account needs to be manually connected with oidc
|
||||||
|
@ -13,7 +13,7 @@ SSH_LISTEN_PORT=22
|
|||||||
DOMAIN={{domains[application_id]}}
|
DOMAIN={{domains[application_id]}}
|
||||||
SSH_DOMAIN={{domains[application_id]}}
|
SSH_DOMAIN={{domains[application_id]}}
|
||||||
RUN_MODE="{{run_mode}}"
|
RUN_MODE="{{run_mode}}"
|
||||||
ROOT_URL="https://{{domains[application_id]}}/"
|
ROOT_URL="{{ web_protocol }}://{{domains[application_id]}}/"
|
||||||
|
|
||||||
# Mail Configuration
|
# Mail Configuration
|
||||||
# @see https://docs.gitea.com/next/installation/install-with-docker#managing-deployments-with-environment-variables
|
# @see https://docs.gitea.com/next/installation/install-with-docker#managing-deployments-with-environment-variables
|
||||||
|
@ -19,4 +19,4 @@ KC_DB_PASSWORD= {{database_password}}
|
|||||||
|
|
||||||
# If the initial administrator already exists and the environment variables are still present at startup, an error message stating the failed creation of the initial administrator is shown in the logs. Keycloak ignores the values and starts up correctly.
|
# If the initial administrator already exists and the environment variables are still present at startup, an error message stating the failed creation of the initial administrator is shown in the logs. Keycloak ignores the values and starts up correctly.
|
||||||
KC_BOOTSTRAP_ADMIN_USERNAME= {{users.administrator.username}}
|
KC_BOOTSTRAP_ADMIN_USERNAME= {{users.administrator.username}}
|
||||||
KC_BOOTSTRAP_ADMIN_PASSWORD= {{users.administrator.initial_password}}
|
KC_BOOTSTRAP_ADMIN_PASSWORD= {{users.administrator.password}}
|
@ -517,7 +517,7 @@
|
|||||||
"/realms/{{realm}}/account/*"
|
"/realms/{{realm}}/account/*"
|
||||||
],
|
],
|
||||||
"webOrigins": [
|
"webOrigins": [
|
||||||
"https://{{domains.keycloak}}"
|
"{{ web_protocol }}://{{domains.keycloak}}"
|
||||||
],
|
],
|
||||||
"notBefore": 0,
|
"notBefore": 0,
|
||||||
"bearerOnly": false,
|
"bearerOnly": false,
|
||||||
@ -825,9 +825,9 @@
|
|||||||
"clientId": "{{realm}}",
|
"clientId": "{{realm}}",
|
||||||
"name": "",
|
"name": "",
|
||||||
"description": "",
|
"description": "",
|
||||||
"rootUrl": "https://{{realm}}/",
|
"rootUrl": "{{ web_protocol }}://{{realm}}/",
|
||||||
"adminUrl": "https://{{realm}}/",
|
"adminUrl": "{{ web_protocol }}://{{realm}}/",
|
||||||
"baseUrl": "https://{{realm}}/",
|
"baseUrl": "{{ web_protocol }}://{{realm}}/",
|
||||||
"surrogateAuthRequired": false,
|
"surrogateAuthRequired": false,
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"alwaysDisplayInConsole": false,
|
"alwaysDisplayInConsole": false,
|
||||||
@ -837,10 +837,10 @@
|
|||||||
{%- for application, domain in domains.items() %}
|
{%- for application, domain in domains.items() %}
|
||||||
{%- if applications[application] is defined and (applications | get_oauth2_enabled(application) or applications | get_oidc_enabled(application)) %}
|
{%- if applications[application] is defined and (applications | get_oauth2_enabled(application) or applications | get_oidc_enabled(application)) %}
|
||||||
{%- if domain is string %}
|
{%- if domain is string %}
|
||||||
{%- set _ = redirect_uris.append("https://{}/*".format(domain)) %}
|
{%- set _ = redirect_uris.append(web_protocol ~ '://' ~ domain ~ '/*') %}
|
||||||
{%- else %}
|
{%- else %}
|
||||||
{%- for d in domain %}
|
{%- for d in domain %}
|
||||||
{%- set _ = redirect_uris.append("https://{}/*".format(d)) %}
|
{%- set _ = redirect_uris.append(web_protocol ~ '://' ~ d ~ '/*') %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
@ -848,7 +848,7 @@
|
|||||||
|
|
||||||
"redirectUris": {{ redirect_uris | tojson }},
|
"redirectUris": {{ redirect_uris | tojson }},
|
||||||
"webOrigins": [
|
"webOrigins": [
|
||||||
"https://*.{{primary_domain}}"
|
"{{ web_protocol }}://*.{{primary_domain}}"
|
||||||
],
|
],
|
||||||
"notBefore": 0,
|
"notBefore": 0,
|
||||||
"bearerOnly": false,
|
"bearerOnly": false,
|
||||||
@ -865,7 +865,7 @@
|
|||||||
"oidc.ciba.grant.enabled": "false",
|
"oidc.ciba.grant.enabled": "false",
|
||||||
"client.secret.creation.time": "0",
|
"client.secret.creation.time": "0",
|
||||||
"backchannel.logout.session.required": "true",
|
"backchannel.logout.session.required": "true",
|
||||||
"post.logout.redirect.uris": "https://{{primary_domain}}/*##+",
|
"post.logout.redirect.uris": "{{ web_protocol }}://{{primary_domain}}/*##+",
|
||||||
"frontchannel.logout.session.required": "true",
|
"frontchannel.logout.session.required": "true",
|
||||||
"oauth2.device.authorization.grant.enabled": "false",
|
"oauth2.device.authorization.grant.enabled": "false",
|
||||||
"display.on.consent.screen": "false",
|
"display.on.consent.screen": "false",
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
{##
|
||||||
|
# Iterate over all users and create LDAP entries for each, then assign admin to application roles
|
||||||
|
# This template loops through a 'users' list variable where each user is a dict with keys:
|
||||||
|
# username, uid, gid, password (optional), sn (optional), cn (optional)
|
||||||
|
##}
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# Container for Application Roles (if not already created)
|
# Container for Application Roles (if not already created)
|
||||||
#######################################################################
|
#######################################################################
|
||||||
@ -6,36 +11,48 @@ objectClass: organizationalUnit
|
|||||||
ou: roles
|
ou: roles
|
||||||
description: Container for application access profiles
|
description: Container for application access profiles
|
||||||
|
|
||||||
|
{% for user in users %}
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# Create Admin User
|
# Create User {{ user.username }}
|
||||||
#######################################################################
|
#######################################################################
|
||||||
dn: {{ldap.attributes.user_id}}={{users.administrator.username}},{{ldap.dn.users}}
|
dn: {{ ldap.attributes.user_id }}={{ user.username }},{{ ldap.dn.users }}
|
||||||
objectClass: top
|
objectClass: top
|
||||||
objectClass: inetOrgPerson
|
objectClass: inetOrgPerson
|
||||||
objectClass: posixAccount
|
objectClass: posixAccount
|
||||||
{{ldap.attributes.user_id}}: {{users.administrator.username}}
|
{{ ldap.attributes.user_id }}: {{ user.username }}
|
||||||
sn: Administrator
|
sn: {{ user.username }}
|
||||||
cn: Administrator
|
cn: {{ user.username }}
|
||||||
userPassword: {SSHA}CHANGE_THIS_PASSWORD
|
userPassword: {{ user.password }}
|
||||||
loginShell: /bin/bash
|
loginShell: /bin/bash
|
||||||
homeDirectory: /home/admin
|
homeDirectory: /home/{{ user.username }}
|
||||||
uidNumber: {{users.administrator.uid}}
|
uidNumber: {{ user.uid }}
|
||||||
gidNumber: {{users.administrator.gid}}
|
gidNumber: {{ user.gid }}
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# Add Admin User to All Application Role Groups
|
# Assign {{ user.username }} to application user roles
|
||||||
#######################################################################
|
#######################################################################
|
||||||
{# Loop over each application defined in defaults_applications #}
|
|
||||||
{% for app, config in defaults_applications.items() %}
|
{% for app, config in defaults_applications.items() %}
|
||||||
|
dn: cn={{ app }}-user,{{ ldap.dn.application_roles }}
|
||||||
|
changetype: modify
|
||||||
|
add: roleOccupant
|
||||||
|
roleOccupant: {{ ldap.attributes.user_id }}={{ user.username }},{{ ldap.dn.users }}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
# Add Admin User to All Application Role Groups (unchanged)
|
||||||
|
#######################################################################
|
||||||
|
{% for app, config in defaults_applications.items() %}
|
||||||
dn: cn={{ app }}-administrator,{{ ldap.dn.application_roles }}
|
dn: cn={{ app }}-administrator,{{ ldap.dn.application_roles }}
|
||||||
changetype: modify
|
changetype: modify
|
||||||
add: roleOccupant
|
add: roleOccupant
|
||||||
roleOccupant: {{ldap.attributes.user_id}}={{users.administrator.username}},{{ldap.dn.users}}
|
roleOccupant: {{ ldap.attributes.user_id }}={{ users.administrator.username }},{{ ldap.dn.users }}
|
||||||
|
|
||||||
dn: cn={{ app }}-user,{{ ldap.dn.application_roles }}
|
dn: cn={{ app }}-user,{{ ldap.dn.application_roles }}
|
||||||
changetype: modify
|
changetype: modify
|
||||||
add: roleOccupant
|
add: roleOccupant
|
||||||
roleOccupant: {{ldap.attributes.user_id}}={{users.administrator.username}},{{ldap.dn.users}}
|
roleOccupant: {{ ldap.attributes.user_id }}={{ users.administrator.username }},{{ ldap.dn.users }}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
@ -19,4 +19,5 @@ galaxy_info:
|
|||||||
documentation: "https://s.veen.world/cymais"
|
documentation: "https://s.veen.world/cymais"
|
||||||
logo:
|
logo:
|
||||||
class: "fa-solid fa-list"
|
class: "fa-solid fa-list"
|
||||||
dependencies: []
|
dependencies:
|
||||||
|
- docker-mailu
|
@ -54,6 +54,7 @@
|
|||||||
shell: |
|
shell: |
|
||||||
docker exec -i {{ database_host }} psql \
|
docker exec -i {{ database_host }} psql \
|
||||||
-U {{ database_username }} \
|
-U {{ database_username }} \
|
||||||
|
-v ON_ERROR_STOP=1 \
|
||||||
-d {{ database_name }} << 'EOSQL'
|
-d {{ database_name }} << 'EOSQL'
|
||||||
UPDATE settings
|
UPDATE settings
|
||||||
SET value = '{{ item.value }}'::jsonb
|
SET value = '{{ item.value }}'::jsonb
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
TZ=Etc/UTC
|
TZ={{timezone}}
|
||||||
|
|
||||||
# Administrator setup
|
# Administrator setup
|
||||||
|
|
||||||
|
@ -4,7 +4,10 @@ database_type: "postgres"
|
|||||||
|
|
||||||
listmonk_settings:
|
listmonk_settings:
|
||||||
- key: "app.root_url"
|
- key: "app.root_url"
|
||||||
value: '"https://{{ domains[application_id] }}"'
|
value: '"{{ web_protocol }}://{{ domains[application_id] }}"'
|
||||||
|
|
||||||
|
- key: "app.notify_emails"
|
||||||
|
value: "{{ [ users.administrator.email ] | to_json }}"
|
||||||
|
|
||||||
# OIDC integration (conditional)
|
# OIDC integration (conditional)
|
||||||
- key: "security.oidc"
|
- key: "security.oidc"
|
||||||
@ -17,9 +20,178 @@ listmonk_settings:
|
|||||||
} | to_json }}
|
} | to_json }}
|
||||||
when: applications[application_id].features.oidc | bool
|
when: applications[application_id].features.oidc | bool
|
||||||
|
|
||||||
# hCaptcha toggles and credentials\ n - key: "security.enable_captcha"
|
# hCaptcha toggles and credentials
|
||||||
value: "true"
|
- key: "security.enable_captcha"
|
||||||
|
value: 'true'
|
||||||
|
|
||||||
- key: "security.captcha_key"
|
- key: "security.captcha_key"
|
||||||
value: '"{{ applications[application_id].credentials.hcaptcha.site_key }}"'
|
value: '"{{ applications[application_id].credentials.hcaptcha.site_key }}"'
|
||||||
|
|
||||||
- key: "security.captcha_secret"
|
- key: "security.captcha_secret"
|
||||||
value: '"{{ applications[application_id].credentials.hcaptcha.secret }}"'
|
value: '"{{ applications[application_id].credentials.hcaptcha.secret }}"'
|
||||||
|
|
||||||
|
# SMTP servers
|
||||||
|
- key: "smtp"
|
||||||
|
value: >-
|
||||||
|
{{ [
|
||||||
|
{
|
||||||
|
"host": system_email.host,
|
||||||
|
"port": system_email.port,
|
||||||
|
"enabled": system_email.smtp,
|
||||||
|
"username": system_email.username,
|
||||||
|
"password": system_email.password,
|
||||||
|
"tls_type": (
|
||||||
|
system_email.tls
|
||||||
|
| ternary("TLS",
|
||||||
|
system_email.start_tls
|
||||||
|
| ternary("STARTTLS","NONE")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"email_headers": [],
|
||||||
|
"hello_hostname": "",
|
||||||
|
"max_conns": 10,
|
||||||
|
"idle_timeout": "15s",
|
||||||
|
"wait_timeout": "5s",
|
||||||
|
"auth_protocol": "login",
|
||||||
|
"max_msg_retries": 2,
|
||||||
|
"tls_skip_verify": false
|
||||||
|
}
|
||||||
|
] | to_json }}
|
||||||
|
when: system_email.smtp | bool
|
||||||
|
|
||||||
|
|
||||||
|
- key: "app.lang"
|
||||||
|
value: '"{{ locale }}"'
|
||||||
|
|
||||||
|
# - key: "messengers"
|
||||||
|
# value: '[]'
|
||||||
|
|
||||||
|
- key: "app.logo_url"
|
||||||
|
value: '"{{ service_provider.platform.logo }}"'
|
||||||
|
|
||||||
|
- key: "app.site_name"
|
||||||
|
value: '"{{ service_provider.company.titel }} Mailing list"'
|
||||||
|
|
||||||
|
# - key: "bounce.enabled"
|
||||||
|
# value: 'false'
|
||||||
|
#
|
||||||
|
# - key: "upload.max_file_size"
|
||||||
|
# value: '5000'
|
||||||
|
#
|
||||||
|
# - key: "upload.s3.aws_secret_access_key"
|
||||||
|
# value: '""'
|
||||||
|
#
|
||||||
|
# - key: "app.batch_size"
|
||||||
|
# value: '1000'
|
||||||
|
|
||||||
|
- key: "app.from_email"
|
||||||
|
value: '"{{ service_provider.company.titel }} Newsletter <{{ system_email.from }}>"'
|
||||||
|
|
||||||
|
- key: "bounce.actions"
|
||||||
|
value: >-
|
||||||
|
{"hard": {"count": 1, "action": "blocklist"}, "soft": {"count": 2, "action": "none"}, "complaint": {"count": 1, "action": "blocklist"}}
|
||||||
|
|
||||||
|
- key: "app.concurrency"
|
||||||
|
value: '10'
|
||||||
|
|
||||||
|
- key: "app.favicon_url"
|
||||||
|
value: '"{{ service_provider.platform.favicon }}"'
|
||||||
|
|
||||||
|
# - key: "bounce.postmark"
|
||||||
|
# value: '{"enabled": false, "password": "", "username": ""}'
|
||||||
|
#
|
||||||
|
# - key: "upload.provider"
|
||||||
|
# value: '"filesystem"'
|
||||||
|
|
||||||
|
# - key: "app.message_rate"
|
||||||
|
# value: '10'
|
||||||
|
#
|
||||||
|
# - key: "bounce.mailboxes"
|
||||||
|
# value: >-
|
||||||
|
# [{"host": "pop.yoursite.com", "port": 995, "type": "pop", "uuid": "471fd0e9-8c33-4e4a-9183-c4679699faca", "enabled": false, "password": "password", "username": "username", "return_path": "bounce@listmonk.yoursite.com", "tls_enabled": true, "auth_protocol": "userpass", "scan_interval": "15m", "tls_skip_verify": false}]
|
||||||
|
|
||||||
|
# - key: "upload.s3.url"
|
||||||
|
# value: '"https://ap-south-1.s3.amazonaws.com"'
|
||||||
|
#
|
||||||
|
# - key: "upload.s3.bucket"
|
||||||
|
# value: '""'
|
||||||
|
#
|
||||||
|
# - key: "upload.s3.expiry"
|
||||||
|
# value: '"167h"'
|
||||||
|
|
||||||
|
- key: "app.check_updates"
|
||||||
|
value: 'true'
|
||||||
|
|
||||||
|
|
||||||
|
# - key: "upload.extensions"
|
||||||
|
# value: '["jpg", "jpeg", "png", "gif", "svg", "*"]'
|
||||||
|
#
|
||||||
|
# - key: "bounce.ses_enabled"
|
||||||
|
# value: 'false'
|
||||||
|
#
|
||||||
|
# - key: "privacy.allow_wipe"
|
||||||
|
# value: 'true'
|
||||||
|
#
|
||||||
|
# - key: "privacy.exportable"
|
||||||
|
# value: '["profile", "subscriptions", "campaign_views", "link_clicks"]'
|
||||||
|
#
|
||||||
|
# - key: "app.max_send_errors"
|
||||||
|
# value: '1000'
|
||||||
|
#
|
||||||
|
# - key: "bounce.forwardemail"
|
||||||
|
# value: '{"key": "", "enabled": false}'
|
||||||
|
#
|
||||||
|
# - key: "bounce.sendgrid_key"
|
||||||
|
# value: '""'
|
||||||
|
#
|
||||||
|
# - key: "privacy.allow_export"
|
||||||
|
# value: 'true'
|
||||||
|
#
|
||||||
|
# - key: "upload.s3.public_url"
|
||||||
|
# value: '""'
|
||||||
|
#
|
||||||
|
# - key: "upload.s3.bucket_path"
|
||||||
|
# value: '"/"'
|
||||||
|
#
|
||||||
|
# - key: "upload.s3.bucket_type"
|
||||||
|
# value: '"public"'
|
||||||
|
#
|
||||||
|
# - key: "app.cache_slow_queries"
|
||||||
|
# value: 'false'
|
||||||
|
#
|
||||||
|
# - key: "bounce.sendgrid_enabled"
|
||||||
|
# value: 'false'
|
||||||
|
#
|
||||||
|
# - key: "bounce.webhooks_enabled"
|
||||||
|
# value: 'false'
|
||||||
|
#
|
||||||
|
# - key: "privacy.domain_blocklist"
|
||||||
|
# value: '[]'
|
||||||
|
#
|
||||||
|
# - key: "privacy.allow_blocklist"
|
||||||
|
# value: 'true'
|
||||||
|
#
|
||||||
|
# - key: "privacy.record_optin_ip"
|
||||||
|
# value: 'false'
|
||||||
|
#
|
||||||
|
# - key: "app.enable_public_archive"
|
||||||
|
# value: 'true'
|
||||||
|
#
|
||||||
|
# - key: "privacy.allow_preferences"
|
||||||
|
# value: 'true'
|
||||||
|
#
|
||||||
|
# - key: "app.message_sliding_window"
|
||||||
|
# value: 'false'
|
||||||
|
#
|
||||||
|
# - key: "app.message_sliding_window_rate"
|
||||||
|
# value: '10000'
|
||||||
|
#
|
||||||
|
# - key: "app.enable_public_subscription_page"
|
||||||
|
# value: 'true'
|
||||||
|
#
|
||||||
|
# - key: "app.message_sliding_window_duration"
|
||||||
|
# value: '"1h"'
|
||||||
|
|
||||||
|
- key: "app.enable_public_archive_rss_content"
|
||||||
|
value: 'true'
|
||||||
|
|
||||||
|
2
roles/docker-mailu/tasks/TODO.md
Normal file
2
roles/docker-mailu/tasks/TODO.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Todo
|
||||||
|
- Implement create-mailu-user-and-token.yml for no-reply and bounce
|
72
roles/docker-mailu/tasks/create-mailu-user-and-token.yml
Normal file
72
roles/docker-mailu/tasks/create-mailu-user-and-token.yml
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
---
|
||||||
|
# tasks/create-mailu-user-and-token.yml
|
||||||
|
#
|
||||||
|
# Ensures a Mailu user exists and idempotently creates an API token for them,
|
||||||
|
# storing tokens in a dictionary for targeted access.
|
||||||
|
#
|
||||||
|
# Required variables:
|
||||||
|
# mailu_compose_dir: Path to your docker-compose.yml directory
|
||||||
|
# mailu_user: Local part of the user (e.g., "alice")
|
||||||
|
# mailu_domain: Domain for the user (e.g., "example.com")
|
||||||
|
# mailu_password: Password for the new user
|
||||||
|
# mailu_api_base_url: Base URL of the Mailu API (e.g., "https://mail.example.com/api/v1")
|
||||||
|
# mailu_global_api_token: Global API token (from API_TOKEN environment variable)
|
||||||
|
#
|
||||||
|
# Optional variable:
|
||||||
|
# mailu_user_tokens: Dictionary of existing tokens, e.g. { "alice": "secret" }
|
||||||
|
|
||||||
|
- name: "Ensure Mailu user {{ mailu_user }}@{{ mailu_domain }} exists"
|
||||||
|
command: >
|
||||||
|
docker compose exec admin flask mailu {{ mailu_action }} {{ mailu_user }} {{ mailu_domain }} '{{ mailu_password }}'
|
||||||
|
args:
|
||||||
|
chdir: "{{ mailu_compose_dir }}"
|
||||||
|
register: mailu_user_creation
|
||||||
|
failed_when: false
|
||||||
|
changed_when: mailu_user_creation.rc == 0 and 'User added' in mailu_user_creation.stdout
|
||||||
|
|
||||||
|
- name: "Fetch existing API tokens"
|
||||||
|
uri:
|
||||||
|
url: "{{ mailu_api_base_url }}/tokens"
|
||||||
|
method: GET
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {{ mailu_global_api_token }}"
|
||||||
|
return_content: yes
|
||||||
|
register: mailu_tokens_response
|
||||||
|
failed_when: mailu_tokens_response.status not in [200]
|
||||||
|
|
||||||
|
- name: "Extract existing token info for {{ mailu_user }}"
|
||||||
|
set_fact:
|
||||||
|
mailu_user_existing_token: >
|
||||||
|
{{ mailu_tokens_response.json
|
||||||
|
| selectattr('comment', 'equalto', mailu_user)
|
||||||
|
| list
|
||||||
|
| first }}
|
||||||
|
|
||||||
|
- name: "Create API token for {{ mailu_user }} if none exists"
|
||||||
|
uri:
|
||||||
|
url: "{{ mailu_api_base_url }}/tokens"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
Authorization: "Bearer {{ mailu_global_api_token }}"
|
||||||
|
Content-Type: "application/json"
|
||||||
|
body_format: json
|
||||||
|
body:
|
||||||
|
comment: "{{ mailu_user }}"
|
||||||
|
ip: "{{ mailu_token_ip }}"
|
||||||
|
status_code: 201
|
||||||
|
register: mailu_token_creation
|
||||||
|
when: mailu_user_existing_token is not defined
|
||||||
|
|
||||||
|
- name: "Set mailu_user_tokens dictionary"
|
||||||
|
set_fact:
|
||||||
|
mailu_user_tokens: >
|
||||||
|
{{ (mailu_user_tokens | default({}))
|
||||||
|
| combine({ mailu_user: ((mailu_token_creation is defined)
|
||||||
|
| ternary(mailu_token_creation.json.secret,
|
||||||
|
mailu_user_existing_token.secret)) }) }}
|
||||||
|
|
||||||
|
# Note:
|
||||||
|
# - GET /tokens returns only metadata (id, comment, ip, created), not the secret itself.
|
||||||
|
# - The secret is returned only by the POST request and must be captured when created.
|
||||||
|
# - Tokens are stored in the mailu_user_tokens dictionary for targeted access.
|
||||||
|
# - Persist mailu_user_tokens securely (e.g., in Ansible Vault) for future use.
|
@ -1,29 +1,48 @@
|
|||||||
---
|
---
|
||||||
- name: "include docker-central-database"
|
- name: "Include docker-central-database"
|
||||||
include_role:
|
include_role:
|
||||||
name: docker-central-database
|
name: docker-central-database
|
||||||
|
when: run_once_docker_mailu is not defined
|
||||||
|
|
||||||
- name: "include role nginx-domain-setup for {{application_id}}"
|
- name: "Include role nginx-domain-setup for {{ application_id }}"
|
||||||
include_role:
|
include_role:
|
||||||
name: nginx-domain-setup
|
name: nginx-domain-setup
|
||||||
vars:
|
vars:
|
||||||
domain: "{{ domains[application_id] }}"
|
domain: "{{ domains[application_id] }}"
|
||||||
http_port: "{{ ports.localhost.http[application_id] }}"
|
http_port: "{{ ports.localhost.http[application_id] }}"
|
||||||
vars:
|
|
||||||
nginx_docker_reverse_proxy_extra_configuration: "client_max_body_size 31M;"
|
nginx_docker_reverse_proxy_extra_configuration: "client_max_body_size 31M;"
|
||||||
|
when: run_once_docker_mailu is not defined
|
||||||
|
|
||||||
- name: "Include the nginx-docker-cert-deploy role"
|
- name: "Include the nginx-docker-cert-deploy role"
|
||||||
include_role:
|
include_role:
|
||||||
name: nginx-docker-cert-deploy
|
name: nginx-docker-cert-deploy
|
||||||
|
when: run_once_docker_mailu is not defined
|
||||||
|
|
||||||
- name: "copy docker-compose.yml and env file"
|
- name: "Copy docker-compose.yml and env file"
|
||||||
include_tasks: copy-docker-compose-and-env.yml
|
include_tasks: copy-docker-compose-and-env.yml
|
||||||
|
when: run_once_docker_mailu is not defined
|
||||||
|
|
||||||
- name: flush docker service
|
- name: Flush docker service handlers
|
||||||
meta: flush_handlers
|
meta: flush_handlers
|
||||||
|
when: run_once_docker_mailu is not defined
|
||||||
|
|
||||||
- name: create administrator account
|
- name: "Create Mailu accounts and API tokens"
|
||||||
command:
|
include_tasks: create-mailu-user-and-token.yml
|
||||||
cmd: "docker compose -p mailu exec admin flask mailu admin {{users.administrator.username}} {{primary_domain}} {{applications.mailu.initial_administrator_password}}"
|
vars:
|
||||||
chdir: "{{docker_compose.directories.instance}}"
|
mailu_compose_dir: "{{ docker_compose.directories.instance }}"
|
||||||
ignore_errors: true
|
mailu_domain: "{{ domain }}"
|
||||||
|
mailu_api_base_url: "{{ web_protocol }}://{{ domain }}/api/v1"
|
||||||
|
mailu_global_api_token: "{{ applications.mailu.credentials.api_token }}"
|
||||||
|
mailu_action: "{{ item.value.is_admin | default(false) | ternary('admin','user') }}"
|
||||||
|
mailu_user: "{{ item.key }}"
|
||||||
|
mailu_password: "{{ item.value.password }}"
|
||||||
|
mailu_token_ip: "{{ item.value.ip | default('') }}"
|
||||||
|
loop: "{{ users | dict2items }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: item
|
||||||
|
when: run_once_docker_mailu is not defined
|
||||||
|
|
||||||
|
- name: Run the docker_mailu tasks once
|
||||||
|
set_fact:
|
||||||
|
run_once_docker_mailu: true
|
||||||
|
when: run_once_docker_mailu is not defined
|
@ -182,7 +182,7 @@ OIDC_CHANGE_PASSWORD_REDIRECT_ENABLED=True
|
|||||||
# Redirect URL for password change. Defaults to provider issuer url appended by /.well-known/change-password
|
# Redirect URL for password change. Defaults to provider issuer url appended by /.well-known/change-password
|
||||||
OIDC_CHANGE_PASSWORD_REDIRECT_URL={{oidc.client.change_credentials}}
|
OIDC_CHANGE_PASSWORD_REDIRECT_URL={{oidc.client.change_credentials}}
|
||||||
|
|
||||||
{% if applications[application_id].features.oidc | bool %}
|
{% if applications[application_id].oidc.email_by_username | bool %}
|
||||||
|
|
||||||
# The OIDC claim used as the username. If the selected claim contains an email address, it will be used as is. If it is not an email (e.g., sub), the email address will be constructed as <OIDC_USERNAME_CLAIM>@<OIDC_USER_DOMAIN>. Defaults to email.
|
# The OIDC claim used as the username. If the selected claim contains an email address, it will be used as is. If it is not an email (e.g., sub), the email address will be constructed as <OIDC_USERNAME_CLAIM>@<OIDC_USER_DOMAIN>. Defaults to email.
|
||||||
OIDC_USERNAME_CLAIM={{oidc.attributes.username}}
|
OIDC_USERNAME_CLAIM={{oidc.attributes.username}}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"default_server_config": {
|
"default_server_config": {
|
||||||
"m.homeserver": {
|
"m.homeserver": {
|
||||||
"base_url": "https://{{domains.matrix_synapse}}",
|
"base_url": "{{ web_protocol }}://{{domains.matrix_synapse}}",
|
||||||
"server_name": "{{domains.matrix_synapse}}"
|
"server_name": "{{domains.matrix_synapse}}"
|
||||||
},
|
},
|
||||||
"m.identity_server": {
|
"m.identity_server": {
|
||||||
"base_url": "https://{{primary_domain}}"
|
"base_url": "{{ web_protocol }}://{{primary_domain}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"brand": "Element",
|
"brand": "Element",
|
||||||
|
@ -24,8 +24,8 @@ report_stats: true
|
|||||||
macaroon_secret_key: "{{matrix_macaroon_secret_key}}"
|
macaroon_secret_key: "{{matrix_macaroon_secret_key}}"
|
||||||
form_secret: "{{matrix_form_secret}}"
|
form_secret: "{{matrix_form_secret}}"
|
||||||
signing_key_path: "/data/{{domains.matrix_synapse}}.signing.key"
|
signing_key_path: "/data/{{domains.matrix_synapse}}.signing.key"
|
||||||
web_client_location: "https://{{domains.matrix_element}}"
|
web_client_location: "{{ web_protocol }}://{{domains.matrix_element}}"
|
||||||
public_baseurl: "https://{{domains.matrix_synapse}}"
|
public_baseurl: "{{ web_protocol }}://{{domains.matrix_synapse}}"
|
||||||
trusted_key_servers:
|
trusted_key_servers:
|
||||||
- server_name: "matrix.org"
|
- server_name: "matrix.org"
|
||||||
admin_contact: 'mailto:{{users.administrator.email}}'
|
admin_contact: 'mailto:{{users.administrator.email}}'
|
||||||
|
@ -25,14 +25,14 @@ MAIL_DOMAIN= "{{system_email.domain}}"
|
|||||||
|
|
||||||
# Initial Admin Data
|
# Initial Admin Data
|
||||||
NEXTCLOUD_ADMIN_USER= "{{applications[application_id].users.administrator.username}}"
|
NEXTCLOUD_ADMIN_USER= "{{applications[application_id].users.administrator.username}}"
|
||||||
NEXTCLOUD_ADMIN_PASSWORD= "{{applications[application_id].users.administrator.initial_password}}"
|
NEXTCLOUD_ADMIN_PASSWORD= "{{applications[application_id].users.administrator.password}}"
|
||||||
|
|
||||||
# Security
|
# Security
|
||||||
|
|
||||||
NEXTCLOUD_TRUSTED_DOMAINS= "{{domains[application_id]}}"
|
NEXTCLOUD_TRUSTED_DOMAINS= "{{domains[application_id]}}"
|
||||||
# Whitelist local docker gateway in Nextcloud to prevent brute-force throtteling
|
# Whitelist local docker gateway in Nextcloud to prevent brute-force throtteling
|
||||||
TRUSTED_PROXIES= "192.168.102.65"
|
TRUSTED_PROXIES= "192.168.102.65"
|
||||||
OVERWRITECLIURL= "https://{{domains[application_id]}}"
|
OVERWRITECLIURL= "{{ web_protocol }}://{{domains[application_id]}}"
|
||||||
OVERWRITEPROTOCOL= "https"
|
OVERWRITEPROTOCOL= "https"
|
||||||
|
|
||||||
# Redis Configuration
|
# Redis Configuration
|
||||||
|
@ -18,4 +18,4 @@ nextcloud_system_config:
|
|||||||
value: "{{domains[application_id]}}"
|
value: "{{domains[application_id]}}"
|
||||||
|
|
||||||
- parameter: "overwrite.cli.url"
|
- parameter: "overwrite.cli.url"
|
||||||
value: "https://{{domains[application_id]}}"
|
value: "{{ web_protocol }}://{{domains[application_id]}}"
|
@ -9,7 +9,7 @@ whitelist_domains = [".{{primary_domain}}"]
|
|||||||
# keycloak provider
|
# keycloak provider
|
||||||
client_secret = "{{oidc.client.secret}}"
|
client_secret = "{{oidc.client.secret}}"
|
||||||
client_id = "{{oidc.client.id}}"
|
client_id = "{{oidc.client.id}}"
|
||||||
redirect_url = "https://{{domain}}/oauth2/callback"
|
redirect_url = "{{ web_protocol }}://{{domain}}/oauth2/callback"
|
||||||
oidc_issuer_url = "{{oidc.client.issuer_url}}"
|
oidc_issuer_url = "{{oidc.client.issuer_url}}"
|
||||||
provider = "oidc"
|
provider = "oidc"
|
||||||
provider_display_name = "Keycloak"
|
provider_display_name = "Keycloak"
|
||||||
|
@ -26,7 +26,7 @@ accounts:
|
|||||||
description: Follow {{ 'our' if service_provider.type == 'legal' else 'my' }} updates on Mastodon.
|
description: Follow {{ 'our' if service_provider.type == 'legal' else 'my' }} updates on Mastodon.
|
||||||
icon:
|
icon:
|
||||||
class: fa-brands fa-mastodon
|
class: fa-brands fa-mastodon
|
||||||
url: "https://{{ service_provider.contact.mastodon.split('@')[2] }}/@{{ service_provider.contact.mastodon.split('@')[1] }}"
|
url: "{{ web_protocol }}://{{ service_provider.contact.mastodon.split('@')[2] }}/@{{ service_provider.contact.mastodon.split('@')[1] }}"
|
||||||
identifier: "{{service_provider.contact.mastodon}}"
|
identifier: "{{service_provider.contact.mastodon}}"
|
||||||
iframe: {{ applications | get_features_iframe('mastodon') }}
|
iframe: {{ applications | get_features_iframe('mastodon') }}
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ accounts:
|
|||||||
icon:
|
icon:
|
||||||
class: fa-solid fa-camera
|
class: fa-solid fa-camera
|
||||||
identifier: "{{service_provider.contact.pixelfed}}"
|
identifier: "{{service_provider.contact.pixelfed}}"
|
||||||
url: "https://{{ service_provider.contact.pixelfed.split('@')[2] }}/@{{ service_provider.contact.pixelfed.split('@')[1] }}"
|
url: "{{ web_protocol }}://{{ service_provider.contact.pixelfed.split('@')[2] }}/@{{ service_provider.contact.pixelfed.split('@')[1] }}"
|
||||||
iframe: {{ applications | get_features_iframe('pixelfed') }}
|
iframe: {{ applications | get_features_iframe('pixelfed') }}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -63,7 +63,7 @@ accounts:
|
|||||||
icon:
|
icon:
|
||||||
class: fa-solid fa-video
|
class: fa-solid fa-video
|
||||||
identifier: "{{service_provider.contact.peertube}}"
|
identifier: "{{service_provider.contact.peertube}}"
|
||||||
url: "https://{{ service_provider.contact.peertube.split('@')[2] }}/@{{ service_provider.contact.peertube.split('@')[1] }}"
|
url: "{{ web_protocol }}://{{ service_provider.contact.peertube.split('@')[2] }}/@{{ service_provider.contact.peertube.split('@')[1] }}"
|
||||||
iframe: {{ applications | get_features_iframe('peertube') }}
|
iframe: {{ applications | get_features_iframe('peertube') }}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -75,7 +75,7 @@ accounts:
|
|||||||
icon:
|
icon:
|
||||||
class: fa-solid fa-blog
|
class: fa-solid fa-blog
|
||||||
identifier: "{{service_provider.contact.wordpress}}"
|
identifier: "{{service_provider.contact.wordpress}}"
|
||||||
url: "https://{{ service_provider.contact.wordpress.split('@')[2] }}/@{{ service_provider.contact.wordpress.split('@')[1] }}"
|
url: "{{ web_protocol }}://{{ service_provider.contact.wordpress.split('@')[2] }}/@{{ service_provider.contact.wordpress.split('@')[1] }}"
|
||||||
iframe: {{ applications | get_features_iframe('wordpress') }}
|
iframe: {{ applications | get_features_iframe('wordpress') }}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -97,7 +97,7 @@ accounts:
|
|||||||
icon:
|
icon:
|
||||||
class: fas fa-network-wired
|
class: fas fa-network-wired
|
||||||
identifier: "{{service_provider.contact.friendica}}"
|
identifier: "{{service_provider.contact.friendica}}"
|
||||||
url: "https://{{ service_provider.contact.friendica.split('@')[2] }}/@{{ service_provider.contact.friendica.split('@')[1] }}"
|
url: "{{ web_protocol }}://{{ service_provider.contact.friendica.split('@')[2] }}/@{{ service_provider.contact.friendica.split('@')[1] }}"
|
||||||
iframe: {{ applications | get_features_iframe('friendica') }}
|
iframe: {{ applications | get_features_iframe('friendica') }}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
command: >
|
command: >
|
||||||
docker-compose exec -T -u www-data application
|
docker-compose exec -T -u www-data application
|
||||||
wp core install
|
wp core install
|
||||||
--url="https://{{ domains[application_id][0] }}"
|
--url="{{ web_protocol }}://{{ domains[application_id][0] }}"
|
||||||
--title="{{ applications[application_id].title }}"
|
--title="{{ applications[application_id].title }}"
|
||||||
--admin_user="{{ applications[application_id].credentials.administrator.username }}"
|
--admin_user="{{ applications[application_id].credentials.administrator.username }}"
|
||||||
--admin_password="{{ applications[application_id].credentials.administrator.password }}"
|
--admin_password="{{ applications[application_id].credentials.administrator.password }}"
|
||||||
|
@ -11,7 +11,7 @@ discourse_settings:
|
|||||||
|
|
||||||
- name: discourse_connect
|
- name: discourse_connect
|
||||||
key: url
|
key: url
|
||||||
value: "https://{{ domains.discourse }}"
|
value: "{{ web_protocol }}://{{ domains.discourse }}"
|
||||||
- name: discourse_connect
|
- name: discourse_connect
|
||||||
key: api-key
|
key: api-key
|
||||||
value: "{{ vault_discourse_api_key }}"
|
value: "{{ vault_discourse_api_key }}"
|
||||||
|
@ -2,6 +2,6 @@ YOURLS_DB_HOST: "{{database_host}}"
|
|||||||
YOURLS_DB_USER: "{{database_username}}"
|
YOURLS_DB_USER: "{{database_username}}"
|
||||||
YOURLS_DB_PASS: "{{database_password}}"
|
YOURLS_DB_PASS: "{{database_password}}"
|
||||||
YOURLS_DB_NAME: "{{database_name}}"
|
YOURLS_DB_NAME: "{{database_name}}"
|
||||||
YOURLS_SITE: "https://{{domains[application_id]}}"
|
YOURLS_SITE: "{{ web_protocol }}://{{domains[application_id]}}"
|
||||||
YOURLS_USER: "{{applications.yourls.users.administrator.username}}"
|
YOURLS_USER: "{{applications.yourls.users.administrator.username}}"
|
||||||
YOURLS_PASS: "{{yourls_administrator_password}}"
|
YOURLS_PASS: "{{yourls_administrator_password}}"
|
@ -20,7 +20,7 @@ for filename in os.listdir(config_path):
|
|||||||
parts = domain.split('.')
|
parts = domain.split('.')
|
||||||
|
|
||||||
# Prepare the URL and expected status codes
|
# Prepare the URL and expected status codes
|
||||||
url = f"https://{domain}"
|
url = f"{{ web_protocol }}://{domain}"
|
||||||
|
|
||||||
# Default: Expect status code 200 or 302 for a domain
|
# Default: Expect status code 200 or 302 for a domain
|
||||||
expected_statuses = [200,302]
|
expected_statuses = [200,302]
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
- name: Add site to Matomo and get ID if not exists
|
- name: Add site to Matomo and get ID if not exists
|
||||||
uri:
|
uri:
|
||||||
url: "https://{{ domains.matomo }}/index.php"
|
url: "{{ web_protocol }}://{{ domains.matomo }}/index.php"
|
||||||
method: POST
|
method: POST
|
||||||
body: "module=API&method=SitesManager.addSite&siteName={{ base_domain }}&urls=https://{{ base_domain }}&token_auth={{ applications.matomo.credentials.auth_token }}&format=json"
|
body: "module=API&method=SitesManager.addSite&siteName={{ base_domain }}&urls=https://{{ base_domain }}&token_auth={{ applications.matomo.credentials.auth_token }}&format=json"
|
||||||
body_format: form-urlencoded
|
body_format: form-urlencoded
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
base_domain: "{{ domain | regex_replace('^(?:.*\\.)?(.+\\..+)$', '\\1') }}"
|
base_domain: "{{ domain | regex_replace('^(?:.*\\.)?(.+\\..+)$', '\\1') }}"
|
||||||
verification_url: "https://{{domains.matomo}}/index.php?module=API&method=SitesManager.getSitesIdFromSiteUrl&url=https://{{base_domain}}&format=json&token_auth={{applications.matomo.credentials.auth_token}}"
|
verification_url: "{{ web_protocol }}://{{domains.matomo}}/index.php?module=API&method=SitesManager.getSitesIdFromSiteUrl&url=https://{{base_domain}}&format=json&token_auth={{applications.matomo.credentials.auth_token}}"
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="{{ locale }}">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
user:
|
user:
|
||||||
name: administrator
|
name: administrator
|
||||||
update_password: on_create
|
update_password: on_create
|
||||||
password: "{{ users.administrator.initial_password | password_hash('sha512') }}"
|
password: "{{ users.administrator.password | password_hash('sha512') }}"
|
||||||
create_home: yes
|
create_home: yes
|
||||||
generate_ssh_key: yes
|
generate_ssh_key: yes
|
||||||
ssh_key_type: rsa
|
ssh_key_type: rsa
|
||||||
|
3
templates/vars/Todo.md
Normal file
3
templates/vars/Todo.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Todo
|
||||||
|
- Implement Keycloak iframe so that mailu can be used in iframe
|
||||||
|
- Activate mailu in iframe
|
@ -34,7 +34,7 @@ defaults_applications:
|
|||||||
## Assets Server
|
## Assets Server
|
||||||
assets_server:
|
assets_server:
|
||||||
source_directory: "{{ playbook_dir }}/assets" # Directory from which the assets will be copied
|
source_directory: "{{ playbook_dir }}/assets" # Directory from which the assets will be copied
|
||||||
url: "https://{{domains.file_server}}/assets" # Public address of the assets directory
|
url: "{{ web_protocol }}://{{domains.file_server}}/assets" # Public address of the assets directory
|
||||||
## Attendize
|
## Attendize
|
||||||
attendize:
|
attendize:
|
||||||
version: "latest"
|
version: "latest"
|
||||||
@ -76,7 +76,7 @@ defaults_applications:
|
|||||||
# fsesl_password: # Needs to be defined in inventory file
|
# fsesl_password: # Needs to be defined in inventory file
|
||||||
# turn_secret: # Needs to be defined in inventory file
|
# turn_secret: # Needs to be defined in inventory file
|
||||||
urls:
|
urls:
|
||||||
api: "https://{{domains.bigbluebutton}}/bigbluebutton/" # API Address used by Nextcloud Integration
|
api: "{{ web_protocol }}://{{domains.bigbluebutton}}/bigbluebutton/" # API Address used by Nextcloud Integration
|
||||||
|
|
||||||
## Bluesky
|
## Bluesky
|
||||||
bluesky:
|
bluesky:
|
||||||
@ -231,7 +231,7 @@ defaults_applications:
|
|||||||
# LDAP Account Manager
|
# LDAP Account Manager
|
||||||
lam:
|
lam:
|
||||||
version: "latest"
|
version: "latest"
|
||||||
# administrator_password: "{{users.administrator.initial_password}}" # CHANGE for security reasons
|
# administrator_password: "{{users.administrator.password}}" # CHANGE for security reasons
|
||||||
oauth2_proxy:
|
oauth2_proxy:
|
||||||
application: application # Needs to be the same as webinterface
|
application: application # Needs to be the same as webinterface
|
||||||
port: 80 # application port
|
port: 80 # application port
|
||||||
@ -305,11 +305,12 @@ defaults_applications:
|
|||||||
{% endraw %}{{ features.render_features({
|
{% endraw %}{{ features.render_features({
|
||||||
'matomo': true,
|
'matomo': true,
|
||||||
'css': true,
|
'css': true,
|
||||||
'iframe': true,
|
'iframe': false,
|
||||||
'oidc': true,
|
'oidc': true,
|
||||||
'database': false
|
'database': false
|
||||||
}) }}{% raw %}
|
}) }}{% raw %}
|
||||||
# Deactivate central database for mailu, I don't know why the database deactivation is necessary
|
# Deactivate central database for mailu, I don't know why the database deactivation is necessary
|
||||||
|
# Deactivated mailu iframe loading until keycloak supports it
|
||||||
|
|
||||||
## MariaDB
|
## MariaDB
|
||||||
mariadb:
|
mariadb:
|
||||||
@ -427,7 +428,7 @@ defaults_applications:
|
|||||||
users:
|
users:
|
||||||
administrator:
|
administrator:
|
||||||
username: "{{users.administrator.username}}"
|
username: "{{users.administrator.username}}"
|
||||||
initial_password: "{{users.administrator.initial_password}}" # Keep in mind to change the password fast after creation and activate 2FA
|
password: "{{users.administrator.password}}" # Keep in mind to change the password fast after creation and activate 2FA
|
||||||
default_quota: '1000000000' # Quota to assign if no quota is specified in the OIDC response (bytes)
|
default_quota: '1000000000' # Quota to assign if no quota is specified in the OIDC response (bytes)
|
||||||
legacy_login_mask:
|
legacy_login_mask:
|
||||||
enabled: False # If true, then legacy login mask is shown. Otherwise just SSO
|
enabled: False # If true, then legacy login mask is shown. Otherwise just SSO
|
||||||
@ -633,7 +634,7 @@ defaults_applications:
|
|||||||
oauth2_proxy:
|
oauth2_proxy:
|
||||||
configuration_file: "oauth2-proxy-keycloak.cfg" # Needs to be set true in the roles which use it
|
configuration_file: "oauth2-proxy-keycloak.cfg" # Needs to be set true in the roles which use it
|
||||||
version: "latest" # Docker Image version
|
version: "latest" # Docker Image version
|
||||||
redirect_url: "https://{{domains.keycloak}}/auth/realms/{{primary_domain}}/protocol/openid-connect/auth" # The redirect URL for the OAuth2 flow. It should match the redirect URL configured in Keycloak.
|
redirect_url: "{{ web_protocol }}://{{domains.keycloak}}/auth/realms/{{primary_domain}}/protocol/openid-connect/auth" # The redirect URL for the OAuth2 flow. It should match the redirect URL configured in Keycloak.
|
||||||
allowed_roles: admin # Restrict it default to admin role. Use the vars/main.yml to open the specific role for other groups
|
allowed_roles: admin # Restrict it default to admin role. Use the vars/main.yml to open the specific role for other groups
|
||||||
{% endraw %}{{ features.render_features({
|
{% endraw %}{{ features.render_features({
|
||||||
'matomo': true,
|
'matomo': true,
|
||||||
@ -679,7 +680,7 @@ defaults_applications:
|
|||||||
users:
|
users:
|
||||||
administrator:
|
administrator:
|
||||||
email: "{{ users.administrator.email }}" # Initial login email address
|
email: "{{ users.administrator.email }}" # Initial login email address
|
||||||
password: "{{ users.administrator.initial_password }}" # Initial login password – should be overridden in inventory for security
|
password: "{{ users.administrator.password }}" # Initial login password – should be overridden in inventory for security
|
||||||
oauth2_proxy:
|
oauth2_proxy:
|
||||||
application: "application"
|
application: "application"
|
||||||
port: "80"
|
port: "80"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user