mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-06-25 11:45:32 +02:00
Compare commits
7 Commits
c492c824b7
...
f06ad0af18
Author | SHA1 | Date | |
---|---|---|---|
f06ad0af18 | |||
76aef5949b | |||
9c65c320f9 | |||
2302cbfeb4 | |||
9c45d070b4 | |||
2478e4013f | |||
2aac8b5f80 |
27
Makefile
27
Makefile
@ -1,17 +1,26 @@
|
||||
ROLES_DIR=./roles
|
||||
OUTPUT=./group_vars/all/11_applications.yml
|
||||
SCRIPT=./cli/generate_defaults_applications.py
|
||||
ROLES_DIR := ./roles
|
||||
APPLICATIONS_OUT := ./group_vars/all/11_applications.yml
|
||||
APPLICATIONS_SCRIPT := ./cli/generate_defaults_applications.py
|
||||
INCLUDES_OUT := ./tasks/include-docker-roles.yml
|
||||
INCLUDES_SCRIPT := ./cli/generate_role_includes.py
|
||||
|
||||
.PHONY: build install test
|
||||
|
||||
build:
|
||||
@echo "🔧 Generating $(OUTPUT) from roles in $(ROLES_DIR)..."
|
||||
@mkdir -p $(dir $(OUTPUT))
|
||||
python3 $(SCRIPT) --roles-dir $(ROLES_DIR) --output-file $(OUTPUT)
|
||||
@echo "✅ Output written to $(OUTPUT)"
|
||||
@echo "🔧 Generating applications defaults → $(APPLICATIONS_OUT) from roles in $(ROLES_DIR)…"
|
||||
@mkdir -p $(dir $(APPLICATIONS_OUT))
|
||||
python3 $(APPLICATIONS_SCRIPT) --roles-dir $(ROLES_DIR) --output-file $(APPLICATIONS_OUT)
|
||||
@echo "✅ Applications defaults written to $(APPLICATIONS_OUT)\n"
|
||||
@echo "🔧 Generating Docker role includes → $(INCLUDES_OUT)…"
|
||||
@mkdir -p $(dir $(INCLUDES_OUT))
|
||||
python3 $(INCLUDES_SCRIPT) $(ROLES_DIR) -o $(INCLUDES_OUT) -p docker-
|
||||
@echo "✅ Docker role includes written to $(INCLUDES_OUT)"
|
||||
|
||||
install: build
|
||||
@echo "⚙️ Install complete."
|
||||
|
||||
test:
|
||||
@echo "Executing Unit Tests:"
|
||||
@echo "🧪 Running Unit Tests..."
|
||||
python -m unittest discover -s tests/unit
|
||||
@echo "Executing Integration Tests:"
|
||||
@echo "🔬 Running Integration Tests..."
|
||||
python -m unittest discover -s tests/integration
|
79
cli/generate_role_includes.py
Normal file
79
cli/generate_role_includes.py
Normal file
@ -0,0 +1,79 @@
|
||||
import os
|
||||
import argparse
|
||||
import yaml
|
||||
|
||||
def find_roles(roles_dir, prefix=None):
|
||||
"""
|
||||
Yield absolute paths of role directories under roles_dir.
|
||||
Only include roles whose directory name starts with prefix (if given) and contain vars/main.yml.
|
||||
"""
|
||||
for entry in os.listdir(roles_dir):
|
||||
if prefix and not entry.startswith(prefix):
|
||||
continue
|
||||
path = os.path.join(roles_dir, entry)
|
||||
vars_file = os.path.join(path, 'vars', 'main.yml')
|
||||
if os.path.isdir(path) and os.path.isfile(vars_file):
|
||||
yield path, vars_file
|
||||
|
||||
|
||||
def load_application_id(vars_file):
|
||||
"""
|
||||
Load the vars/main.yml and return the value of application_id key.
|
||||
Returns None if not found.
|
||||
"""
|
||||
with open(vars_file, 'r') as f:
|
||||
data = yaml.safe_load(f) or {}
|
||||
return data.get('application_id')
|
||||
|
||||
|
||||
def generate_playbook_entries(roles_dir, prefix=None):
|
||||
entries = []
|
||||
for role_path, vars_file in find_roles(roles_dir, prefix):
|
||||
app_id = load_application_id(vars_file)
|
||||
if not app_id:
|
||||
continue
|
||||
# Derive role name from directory name
|
||||
role_name = os.path.basename(role_path)
|
||||
# entry text
|
||||
entry = (
|
||||
f"- name: setup {app_id}\n"
|
||||
f" when: (\"{app_id}\" in group_names)\n"
|
||||
f" include_role:\n"
|
||||
f" name: {role_name}\n"
|
||||
)
|
||||
entries.append(entry)
|
||||
return entries
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Generate an Ansible playbook include file from Docker roles and application_ids.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'roles_dir',
|
||||
help='Path to directory containing role folders'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-p', '--prefix',
|
||||
help='Only include roles whose names start with this prefix (e.g. docker-, client-)',
|
||||
default=None
|
||||
)
|
||||
parser.add_argument(
|
||||
'-o', '--output',
|
||||
help='Output file path (default: stdout)',
|
||||
default=None
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
entries = generate_playbook_entries(args.roles_dir, args.prefix)
|
||||
output = ''.join(entries)
|
||||
|
||||
if args.output:
|
||||
with open(args.output, 'w') as f:
|
||||
f.write(output)
|
||||
print(f"Playbook entries written to {args.output}")
|
||||
else:
|
||||
print(output)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -21,7 +21,7 @@ defaults_applications:
|
||||
features: # Version of the service
|
||||
matomo: true # Enable Matomo tracking for analytics
|
||||
css: true # Enable or disable global CSS styling
|
||||
iframe: false # Allow embedding the landing page in an iframe (if true)
|
||||
portfolio_iframe: false # Allow embedding the landing page in an iframe (if true)
|
||||
database: true # Enable central database integration
|
||||
ldap: true # Enable ldap integration
|
||||
oauth2: true # Enable oauth2 proxy
|
||||
|
@ -0,0 +1,2 @@
|
||||
from pkgutil import extend_path
|
||||
__path__ = extend_path(__path__, __name__)
|
@ -113,6 +113,13 @@ class FilterModule(object):
|
||||
if matomo_domain:
|
||||
tokens.append(f"{web_protocol}://{matomo_domain}")
|
||||
|
||||
# ReCaptcha integration: allow loading scripts from Google if feature enabled
|
||||
if (
|
||||
self.is_feature_enabled(applications, 'recaptcha', application_id)
|
||||
and directive == 'script-src'
|
||||
):
|
||||
tokens.append('https://www.google.com')
|
||||
|
||||
# whitelist
|
||||
tokens += self.get_csp_whitelist(applications, application_id, directive)
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
CYMAIS_ENVIRONMENT: "production"
|
||||
|
||||
HOST_CURRENCY: "EUR"
|
||||
HOST_TIMEZONE: "UTC"
|
||||
|
5
main.py
5
main.py
@ -3,6 +3,7 @@
|
||||
import argparse
|
||||
import subprocess
|
||||
import os
|
||||
import datetime
|
||||
|
||||
def run_ansible_vault(action, filename, password_file):
|
||||
"""Execute an ansible-vault command with the specified action on a file."""
|
||||
@ -10,6 +11,8 @@ def run_ansible_vault(action, filename, password_file):
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
def run_ansible_playbook(inventory: str, playbook: str, modes: dict, limit: str = None, password_file: str = None, verbose: int = 0, skip_tests: bool = False):
|
||||
start_time = datetime.datetime.now().isoformat()
|
||||
print(f"\n▶️ Script started at: {start_time}\n")
|
||||
print("\n🛠️ Building project (make build)...\n")
|
||||
subprocess.run(["make", "build"], check=True)
|
||||
|
||||
@ -39,6 +42,8 @@ def run_ansible_playbook(inventory: str, playbook: str, modes: dict, limit: str
|
||||
print("\n🚀 Launching Ansible Playbook...\n")
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
end_time = datetime.datetime.now().isoformat()
|
||||
print(f"\n✅ Script ended at: {end_time}\n")
|
||||
def main():
|
||||
# Change to script dir to execute all folders relative to their
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
@ -5,7 +5,7 @@ setup_admin_email: "{{users.administrator.email}}"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
central_database: true
|
||||
credentials:
|
||||
# database_password: Needs to be defined in inventory file
|
||||
|
@ -5,5 +5,5 @@ credentials:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
central_database: true
|
||||
|
@ -2,5 +2,5 @@ version: "latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
||||
central_database: true
|
@ -15,7 +15,7 @@ urls:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
ldap: false
|
||||
oidc: true
|
||||
central_database: false
|
@ -10,5 +10,5 @@ credentials:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
||||
central_database: true
|
@ -5,7 +5,7 @@ credentials:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
oidc: true
|
||||
central_database: true
|
||||
csp:
|
||||
|
@ -8,7 +8,7 @@ credentials:
|
||||
features:
|
||||
matomo: true
|
||||
css: false
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
ldap: false
|
||||
oidc: true
|
||||
central_database: true
|
||||
|
@ -2,6 +2,6 @@ version: "latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
||||
oidc: true
|
||||
central_database: true
|
@ -2,7 +2,7 @@ version: "1.4.0"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
||||
ldap: true
|
||||
central_database: true
|
||||
credentials:
|
||||
|
@ -12,7 +12,7 @@ SSH_PORT={{ports.public.ssh[application_id]}}
|
||||
SSH_LISTEN_PORT=22
|
||||
DOMAIN={{domains[application_id]}}
|
||||
SSH_DOMAIN={{domains[application_id]}}
|
||||
RUN_MODE="{{run_mode}}"
|
||||
RUN_MODE="{{ 'dev' if (CYMAIS_ENVIRONMENT | lower) == 'development' else 'prod' }}"
|
||||
ROOT_URL="{{ web_protocol }}://{{domains[application_id]}}/"
|
||||
|
||||
# Mail Configuration
|
||||
|
@ -7,7 +7,7 @@ configuration:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
||||
central_database: true
|
||||
csp:
|
||||
flags:
|
||||
|
@ -2,5 +2,5 @@ version: "latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
||||
central_database: true
|
@ -2,4 +2,4 @@ version: "latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
@ -4,12 +4,16 @@ users:
|
||||
username: "{{users.administrator.username}}" # Administrator Username for Keycloak
|
||||
import_realm: True # If True realm will be imported. If false skip.
|
||||
credentials:
|
||||
# database_password: # Needs to be defined in inventory file
|
||||
# administrator_password: # Needs to be defined in inventory file
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
||||
ldap: true
|
||||
central_database: true
|
||||
recaptcha: true
|
||||
csp:
|
||||
flags:
|
||||
script-src:
|
||||
unsafe-inline: true
|
||||
style-src:
|
||||
unsafe-inline: true
|
@ -1,4 +1,4 @@
|
||||
application_id: "keycloak"
|
||||
application_id: "keycloak"
|
||||
database_type: "postgres"
|
||||
container_name: "{{application_id}}_application"
|
||||
realm: "{{primary_domain}}" # This is the name of the default realm which is used by the applications
|
||||
|
@ -8,7 +8,7 @@ credentials:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
||||
ldap: true
|
||||
central_database: false
|
||||
oauth2: false
|
||||
|
@ -6,6 +6,6 @@ version: "latest" # Docker Image
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
||||
central_database: true
|
||||
oidc: true
|
@ -15,6 +15,6 @@ credentials:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false # Deactivated mailu iframe loading until keycloak supports it
|
||||
portfolio_iframe: false # Deactivated mailu iframe loading until keycloak supports it
|
||||
oidc: true
|
||||
central_database: false # Deactivate central database for mailu, I don't know why the database deactivation is necessary
|
@ -14,6 +14,6 @@ credentials:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
oidc: true
|
||||
central_database: true
|
||||
|
@ -2,7 +2,7 @@ version: "latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: false
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
central_database: true
|
||||
oauth2: false
|
||||
csp:
|
||||
|
5
roles/docker-matrix/Todo.md
Normal file
5
roles/docker-matrix/Todo.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Todo
|
||||
- Enable Whatsapp by default
|
||||
- Enable Telegram by default
|
||||
- Enable Slack by default
|
||||
- Enable ChatGPT by default
|
2
roles/docker-matrix/filter_plugins/__init__.py
Normal file
2
roles/docker-matrix/filter_plugins/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
from pkgutil import extend_path
|
||||
__path__ = extend_path(__path__, __name__)
|
13
roles/docker-matrix/filter_plugins/bridge_filters.py
Normal file
13
roles/docker-matrix/filter_plugins/bridge_filters.py
Normal file
@ -0,0 +1,13 @@
|
||||
def filter_enabled_bridges(bridges, plugins):
|
||||
"""
|
||||
Return only those bridge definitions whose 'bridge_name' is set to True in plugins.
|
||||
:param bridges: list of dicts, each with a 'bridge_name' key
|
||||
:param plugins: dict mapping bridge_name to a boolean
|
||||
"""
|
||||
return [b for b in bridges if plugins.get(b['bridge_name'], False)]
|
||||
|
||||
class FilterModule(object):
|
||||
def filters(self):
|
||||
return {
|
||||
'filter_enabled_bridges': filter_enabled_bridges,
|
||||
}
|
@ -1,4 +1,13 @@
|
||||
---
|
||||
- name: Load bridges configuration
|
||||
include_vars:
|
||||
file: "bridges.yml"
|
||||
|
||||
- name: Filter enabled bridges and register as fact
|
||||
set_fact:
|
||||
bridges: "{{ bridges_configuration | filter_enabled_bridges(applications[application_id].plugins) }}"
|
||||
changed_when: false
|
||||
|
||||
- name: "include docker-central-database"
|
||||
include_role:
|
||||
name: docker-central-database
|
||||
|
@ -25,7 +25,11 @@ services:
|
||||
interval: 1m
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
{% if bridges | bool %}
|
||||
{% include 'templates/docker/container/depends-on-also-database.yml.j2' %}
|
||||
{% else %}
|
||||
{% include 'templates/docker/container/depends-on-just-database.yml.j2' %}
|
||||
{% endif %}
|
||||
{% for item in bridges %}
|
||||
mautrix-{{item.bridge_name}}:
|
||||
condition: service_healthy
|
||||
@ -61,47 +65,47 @@ services:
|
||||
retries: 3
|
||||
{% include 'templates/docker/container/networks.yml.j2' %}
|
||||
{% endfor %}
|
||||
# Deactivated chatgpt.
|
||||
# @todo needs to be reactivated as soon as bug is found
|
||||
# matrix-chatgpt-bot:
|
||||
# restart: {{docker_restart_policy}}
|
||||
# container_name: matrix-chatgpt
|
||||
# image: ghcr.io/matrixgpt/matrix-chatgpt-bot:latest
|
||||
# volumes:
|
||||
# - chatgpt_data:/storage
|
||||
# environment:
|
||||
# OPENAI_API_KEY: '{{applications[application_id].credentials.chatgpt_bridge_openai_api_key}}'
|
||||
# # Uncomment the next two lines if you are using Azure OpenAI API
|
||||
# # OPENAI_AZURE: 'false'
|
||||
# # CHATGPT_REVERSE_PROXY: 'your-completion-endpoint-here'
|
||||
# CHATGPT_CONTEXT: 'thread'
|
||||
# CHATGPT_API_MODEL: 'gpt-3.5-turbo'
|
||||
# # Uncomment and edit the next line if needed
|
||||
# # CHATGPT_PROMPT_PREFIX: 'Instructions:\nYou are ChatGPT, a large language model trained by OpenAI.'
|
||||
# # CHATGPT_IGNORE_MEDIA: 'false'
|
||||
# CHATGPT_REVERSE_PROXY: 'https://api.openai.com/v1/chat/completions'
|
||||
# # Uncomment and edit the next line if needed
|
||||
# # CHATGPT_TEMPERATURE: '0.8'
|
||||
# # Uncomment and edit the next line if needed
|
||||
# #CHATGPT_MAX_CONTEXT_TOKENS: '4097'
|
||||
# CHATGPT_MAX_PROMPT_TOKENS: '3000'
|
||||
# KEYV_BACKEND: 'file'
|
||||
# KEYV_URL: ''
|
||||
# KEYV_BOT_ENCRYPTION: 'false'
|
||||
# KEYV_BOT_STORAGE: 'true'
|
||||
# MATRIX_HOMESERVER_URL: 'https://{{domains.synapse}}'
|
||||
# MATRIX_BOT_USERNAME: '@chatgptbot:{{applications.matrix.server_name}}'
|
||||
# MATRIX_ACCESS_TOKEN: '{{ applications[application_id].credentials.chatgpt_bridge_access_token | default('') }}'
|
||||
# MATRIX_BOT_PASSWORD: '{{applications[application_id].credentials.chatgpt_bridge_user_password}}'
|
||||
# MATRIX_DEFAULT_PREFIX: '!chatgpt'
|
||||
# MATRIX_DEFAULT_PREFIX_REPLY: 'false'
|
||||
# #MATRIX_BLACKLIST: ''
|
||||
# MATRIX_WHITELIST: ':{{applications.matrix.server_name}}'
|
||||
# MATRIX_AUTOJOIN: 'true'
|
||||
# MATRIX_ENCRYPTION: 'true'
|
||||
# MATRIX_THREADS: 'true'
|
||||
# MATRIX_PREFIX_DM: 'false'
|
||||
# MATRIX_RICH_TEXT: 'true'
|
||||
{% if applications[application_id] | bool %}
|
||||
matrix-chatgpt-bot:
|
||||
restart: {{docker_restart_policy}}
|
||||
container_name: matrix-chatgpt
|
||||
image: ghcr.io/matrixgpt/matrix-chatgpt-bot:latest
|
||||
volumes:
|
||||
- chatgpt_data:/storage
|
||||
environment:
|
||||
OPENAI_API_KEY: '{{applications[application_id].credentials.chatgpt_bridge_openai_api_key}}'
|
||||
# Uncomment the next two lines if you are using Azure OpenAI API
|
||||
# OPENAI_AZURE: 'false'
|
||||
# CHATGPT_REVERSE_PROXY: 'your-completion-endpoint-here'
|
||||
CHATGPT_CONTEXT: 'thread'
|
||||
CHATGPT_API_MODEL: 'gpt-3.5-turbo'
|
||||
# Uncomment and edit the next line if needed
|
||||
# CHATGPT_PROMPT_PREFIX: 'Instructions:\nYou are ChatGPT, a large language model trained by OpenAI.'
|
||||
# CHATGPT_IGNORE_MEDIA: 'false'
|
||||
CHATGPT_REVERSE_PROXY: 'https://api.openai.com/v1/chat/completions'
|
||||
# Uncomment and edit the next line if needed
|
||||
# CHATGPT_TEMPERATURE: '0.8'
|
||||
# Uncomment and edit the next line if needed
|
||||
#CHATGPT_MAX_CONTEXT_TOKENS: '4097'
|
||||
CHATGPT_MAX_PROMPT_TOKENS: '3000'
|
||||
KEYV_BACKEND: 'file'
|
||||
KEYV_URL: ''
|
||||
KEYV_BOT_ENCRYPTION: 'false'
|
||||
KEYV_BOT_STORAGE: 'true'
|
||||
MATRIX_HOMESERVER_URL: 'https://{{domains.synapse}}'
|
||||
MATRIX_BOT_USERNAME: '@chatgptbot:{{applications.matrix.server_name}}'
|
||||
MATRIX_ACCESS_TOKEN: '{{ applications[application_id].credentials.chatgpt_bridge_access_token | default('') }}'
|
||||
MATRIX_BOT_PASSWORD: '{{applications[application_id].credentials.chatgpt_bridge_user_password}}'
|
||||
MATRIX_DEFAULT_PREFIX: '!chatgpt'
|
||||
MATRIX_DEFAULT_PREFIX_REPLY: 'false'
|
||||
#MATRIX_BLACKLIST: ''
|
||||
MATRIX_WHITELIST: ':{{applications.matrix.server_name}}'
|
||||
MATRIX_AUTOJOIN: 'true'
|
||||
MATRIX_ENCRYPTION: 'true'
|
||||
MATRIX_THREADS: 'true'
|
||||
MATRIX_PREFIX_DM: 'false'
|
||||
MATRIX_RICH_TEXT: 'true'
|
||||
{% endif %}
|
||||
|
||||
{% include 'templates/docker/compose/volumes.yml.j2' %}
|
||||
synapse_data:
|
||||
|
@ -45,7 +45,7 @@ email:
|
||||
client_base_url: "{{domains.synapse}}"
|
||||
validation_token_lifetime: 15m
|
||||
|
||||
{% if applications[application_id].features.oidc | bool %}
|
||||
{% if applications | is_feature_enabled('oidc',application_id) %}
|
||||
# @See https://matrix-org.github.io/synapse/latest/openid.html
|
||||
oidc_providers:
|
||||
- idp_id: keycloak
|
||||
@ -61,7 +61,9 @@ oidc_providers:
|
||||
backchannel_logout_enabled: true
|
||||
{% endif %}
|
||||
|
||||
{% if bridges | bool %}
|
||||
app_service_config_files:
|
||||
{% for item in bridges %}
|
||||
- {{registration_file_folder}}{{item.bridge_name}}.registration.yaml
|
||||
{% endfor %}
|
||||
{% endif %}
|
30
roles/docker-matrix/vars/bridges.yml
Normal file
30
roles/docker-matrix/vars/bridges.yml
Normal file
@ -0,0 +1,30 @@
|
||||
bridges_configuration:
|
||||
- database_password: "{{ applications[application_id].credentials.mautrix_whatsapp_bridge_database_password }}"
|
||||
database_username: "mautrix_whatsapp_bridge"
|
||||
database_name: "mautrix_whatsapp_bridge"
|
||||
bridge_name: "whatsapp"
|
||||
|
||||
- database_password: "{{ applications[application_id].credentials.mautrix_telegram_bridge_database_password }}"
|
||||
database_username: "mautrix_telegram_bridge"
|
||||
database_name: "mautrix_telegram_bridge"
|
||||
bridge_name: "telegram"
|
||||
|
||||
- database_password: "{{ applications[application_id].credentials.mautrix_signal_bridge_database_password }}"
|
||||
database_username: "mautrix_signal_bridge"
|
||||
database_name: "mautrix_signal_bridge"
|
||||
bridge_name: "signal"
|
||||
|
||||
- database_password: "{{ applications[application_id].credentials.mautrix_slack_bridge_database_password }}"
|
||||
database_username: "mautrix_slack_bridge"
|
||||
database_name: "mautrix_slack_bridge"
|
||||
bridge_name: "slack"
|
||||
|
||||
- database_password: "{{ applications[application_id].credentials.mautrix_facebook_bridge_database_password }}"
|
||||
database_username: "mautrix_facebook_bridge"
|
||||
database_name: "mautrix_facebook_bridge"
|
||||
bridge_name: "facebook"
|
||||
|
||||
- database_password: "{{ applications[application_id].credentials.mautrix_instagram_bridge_database_password }}"
|
||||
database_username: "mautrix_instagram_bridge"
|
||||
database_name: "mautrix_instagram_bridge"
|
||||
bridge_name: "instagram"
|
@ -3,7 +3,6 @@ users:
|
||||
administrator:
|
||||
username: "{{users.administrator.username}}" # Accountname of the matrix admin
|
||||
playbook_tags: "setup-all,start" # For the initial update use: install-all,ensure-matrix-users-created,start
|
||||
role: "compose" # Role to setup Matrix. Valid values: ansible, compose
|
||||
server_name: "{{primary_domain}}" # Adress for the account names etc.
|
||||
synapse:
|
||||
version: "latest"
|
||||
@ -13,8 +12,8 @@ setup: false # Set true in inventory
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
oidc: false # Deactivated OIDC due to this issue https://github.com/matrix-org/synapse/issues/10492
|
||||
portfolio_iframe: false
|
||||
oidc: true # Deactivated OIDC due to this issue https://github.com/matrix-org/synapse/issues/10492
|
||||
central_database: true
|
||||
csp:
|
||||
flags:
|
||||
@ -30,3 +29,14 @@ csp:
|
||||
script-src:
|
||||
- "{{ domains.synapse }}"
|
||||
- "https://cdn.jsdelivr.net"
|
||||
plugins:
|
||||
# You need to enable them in the inventory file
|
||||
chatgpt: false
|
||||
facebook: false
|
||||
immesage: false
|
||||
instagram: false
|
||||
signal: false
|
||||
slack: false
|
||||
telegram: false
|
||||
whatsapp: false
|
||||
|
||||
|
@ -1,38 +1,5 @@
|
||||
---
|
||||
application_id: "matrix"
|
||||
application_id: "matrix"
|
||||
database_type: "postgres"
|
||||
registration_file_folder: "/data/"
|
||||
well_known_directory: "{{nginx.directories.data.well_known}}/matrix/"
|
||||
|
||||
bridges:
|
||||
- database_password: "{{ applications[application_id].credentials.mautrix_whatsapp_bridge_database_password }}"
|
||||
database_username: "mautrix_whatsapp_bridge"
|
||||
database_name: "mautrix_whatsapp_bridge"
|
||||
bridge_name: "whatsapp"
|
||||
|
||||
- database_password: "{{ applications[application_id].credentials.mautrix_telegram_bridge_database_password }}"
|
||||
database_username: "mautrix_telegram_bridge"
|
||||
database_name: "mautrix_telegram_bridge"
|
||||
bridge_name: "telegram"
|
||||
|
||||
- database_password: "{{ applications[application_id].credentials.mautrix_signal_bridge_database_password }}"
|
||||
database_username: "mautrix_signal_bridge"
|
||||
database_name: "mautrix_signal_bridge"
|
||||
bridge_name: "signal"
|
||||
|
||||
# Deactivated temporary, due to bug which is hard to find
|
||||
# @todo Reactivate
|
||||
# - database_password: "{{ applications[application_id].credentials.mautrix_slack_bridge_database_password }}"
|
||||
# database_username: "mautrix_slack_bridge"
|
||||
# database_name: "mautrix_slack_bridge"
|
||||
# bridge_name: "slack"
|
||||
|
||||
- database_password: "{{ applications[application_id].credentials.mautrix_facebook_bridge_database_password }}"
|
||||
database_username: "mautrix_facebook_bridge"
|
||||
database_name: "mautrix_facebook_bridge"
|
||||
bridge_name: "facebook"
|
||||
|
||||
- database_password: "{{ applications[application_id].credentials.mautrix_instagram_bridge_database_password }}"
|
||||
database_username: "mautrix_instagram_bridge"
|
||||
database_name: "mautrix_instagram_bridge"
|
||||
bridge_name: "instagram"
|
@ -1,23 +1,24 @@
|
||||
site_titel: "Global Learning Academy on {{primary_domain}}"
|
||||
site_titel: "Global Learning Academy on {{primary_domain}}"
|
||||
users:
|
||||
administrator:
|
||||
username: "{{users.administrator.username}}"
|
||||
email: "{{users.administrator.email}}"
|
||||
version: "latest"
|
||||
username: "{{users.administrator.username}}"
|
||||
email: "{{users.administrator.email}}"
|
||||
version: "latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
css: false
|
||||
portfolio_iframe: false
|
||||
central_database: true
|
||||
csp:
|
||||
flags:
|
||||
script-src:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
style-src:
|
||||
unsafe-inline: true
|
||||
unsafe-inline: true
|
||||
whitelist:
|
||||
font-src:
|
||||
- "data:"
|
||||
- "blob:"
|
||||
script-src:
|
||||
- "https://cdn.jsdelivr.net"
|
@ -3,5 +3,5 @@ version: "latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
central_database: true
|
||||
|
@ -23,7 +23,7 @@ credentials:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
ldap: true
|
||||
oidc: true
|
||||
central_database: true
|
||||
|
@ -5,4 +5,4 @@ allowed_roles: admin
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
@ -96,7 +96,7 @@
|
||||
shell: >
|
||||
docker compose exec web bash -c "
|
||||
cd /app &&
|
||||
RAILS_ENV=production bundle exec rails runner \"
|
||||
RAILS_ENV={{ CYMAIS_ENVIRONMENT | lower }} bundle exec rails runner \"
|
||||
user = User.find_by(mail: '{{ users.administrator.email }}');
|
||||
if user.nil?;
|
||||
puts 'User with email {{ users.administrator.email }} not found.';
|
||||
|
@ -49,7 +49,7 @@
|
||||
- name: Set settings in OpenProject
|
||||
shell: >
|
||||
docker compose exec web bash -c "cd /app &&
|
||||
RAILS_ENV=production bundle exec rails runner \"Setting[:{{ item.key }}] = '{{ item.value }}'\""
|
||||
RAILS_ENV={{ CYMAIS_ENVIRONMENT | lower }} bundle exec rails runner \"Setting[:{{ item.key }}] = '{{ item.value }}'\""
|
||||
args:
|
||||
chdir: "{{ docker_compose.directories.instance }}"
|
||||
loop: "{{ openproject_rails_settings | dict2items }}"
|
||||
|
@ -9,7 +9,7 @@ ldap:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
ldap: true
|
||||
central_database: true
|
||||
oauth2: true
|
||||
|
@ -2,7 +2,7 @@ version: "bookworm"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
central_database: true
|
||||
csp:
|
||||
flags:
|
||||
|
@ -10,6 +10,6 @@ oauth2_proxy:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
central_database: true
|
||||
oauth2: true
|
@ -5,6 +5,6 @@ oauth2_proxy:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
ldap: true
|
||||
oauth2: true
|
@ -6,7 +6,7 @@ oauth2_proxy:
|
||||
features:
|
||||
matomo: true
|
||||
css: false
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
central_database: true
|
||||
oauth2: true
|
||||
hostname: central-mariadb
|
@ -3,7 +3,7 @@ version: "latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
central_database: true
|
||||
csp:
|
||||
flags:
|
||||
|
@ -28,7 +28,7 @@ accounts:
|
||||
class: fa-brands fa-mastodon
|
||||
url: "{{ web_protocol }}://{{ service_provider.contact.mastodon.split('@')[2] }}/@{{ service_provider.contact.mastodon.split('@')[1] }}"
|
||||
identifier: "{{service_provider.contact.mastodon}}"
|
||||
iframe: {{ applications | is_feature_enabled('landing_page_iframe','mastodon') }}
|
||||
iframe: {{ applications | is_feature_enabled('portfolio_iframe','mastodon') }}
|
||||
|
||||
{% endif %}
|
||||
{% if service_provider.contact.bluesky is defined and service_provider.contact.bluesky != "" %}
|
||||
@ -52,7 +52,7 @@ accounts:
|
||||
class: fa-solid fa-camera
|
||||
identifier: "{{service_provider.contact.pixelfed}}"
|
||||
url: "{{ web_protocol }}://{{ service_provider.contact.pixelfed.split('@')[2] }}/@{{ service_provider.contact.pixelfed.split('@')[1] }}"
|
||||
iframe: {{ applications | is_feature_enabled('landing_page_iframe','pixelfed') }}
|
||||
iframe: {{ applications | is_feature_enabled('portfolio_iframe','pixelfed') }}
|
||||
|
||||
{% endif %}
|
||||
{% if service_provider.contact.peertube is defined and service_provider.contact.peertube != "" %}
|
||||
@ -64,7 +64,7 @@ accounts:
|
||||
class: fa-solid fa-video
|
||||
identifier: "{{service_provider.contact.peertube}}"
|
||||
url: "{{ web_protocol }}://{{ service_provider.contact.peertube.split('@')[2] }}/@{{ service_provider.contact.peertube.split('@')[1] }}"
|
||||
iframe: {{ applications | is_feature_enabled('landing_page_iframe','peertube') }}
|
||||
iframe: {{ applications | is_feature_enabled('portfolio_iframe','peertube') }}
|
||||
|
||||
{% endif %}
|
||||
{% if service_provider.contact.wordpress is defined and service_provider.contact.wordpress != "" %}
|
||||
@ -76,7 +76,7 @@ accounts:
|
||||
class: fa-solid fa-blog
|
||||
identifier: "{{service_provider.contact.wordpress}}"
|
||||
url: "{{ web_protocol }}://{{ service_provider.contact.wordpress.split('@')[2] }}/@{{ service_provider.contact.wordpress.split('@')[1] }}"
|
||||
iframe: {{ applications | is_feature_enabled('landing_page_iframe','wordpress') }}
|
||||
iframe: {{ applications | is_feature_enabled('portfolio_iframe','wordpress') }}
|
||||
|
||||
{% endif %}
|
||||
{% if service_provider.contact.source_code is defined and service_provider.contact.source_code != "" %}
|
||||
@ -98,7 +98,7 @@ accounts:
|
||||
class: fas fa-network-wired
|
||||
identifier: "{{service_provider.contact.friendica}}"
|
||||
url: "{{ web_protocol }}://{{ service_provider.contact.friendica.split('@')[2] }}/@{{ service_provider.contact.friendica.split('@')[1] }}"
|
||||
iframe: {{ applications | is_feature_enabled('landing_page_iframe','friendica') }}
|
||||
iframe: {{ applications | is_feature_enabled('portfolio_iframe','friendica') }}
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
@ -37,13 +37,13 @@
|
||||
icon:
|
||||
class: fa-solid fa-shield-halved
|
||||
url: https://{{domains.keycloak}}/admin
|
||||
iframe: {{ applications | is_feature_enabled('landing_page_iframe','keycloak') }}
|
||||
iframe: {{ applications | is_feature_enabled('portfolio_iframe','keycloak') }}
|
||||
- name: Profile
|
||||
description: Update your personal admin settings
|
||||
icon:
|
||||
class: fa-solid fa-user-gear
|
||||
url: https://{{ domains.keycloak }}/realms/{{oidc.client.id}}/account
|
||||
iframe: {{ applications | is_feature_enabled('landing_page_iframe','keycloak') }}
|
||||
iframe: {{ applications | is_feature_enabled('portfolio_iframe','keycloak') }}
|
||||
- name: Logout
|
||||
description: End your admin session securely
|
||||
icon:
|
||||
@ -113,7 +113,7 @@
|
||||
icon:
|
||||
class: fas fa-book
|
||||
url: https://{{domains.sphinx}}
|
||||
iframe: {{ applications | is_feature_enabled('landing_page_iframe','sphinx') }}
|
||||
iframe: {{ applications | is_feature_enabled('portfolio_iframe','sphinx') }}
|
||||
|
||||
{% endif %}
|
||||
|
||||
@ -124,7 +124,7 @@
|
||||
icon:
|
||||
class: "fas fa-chalkboard-teacher"
|
||||
url: https://{{domains.presentation}}
|
||||
iframe: {{ applications | is_feature_enabled('landing_page_iframe','presentation') }}
|
||||
iframe: {{ applications | is_feature_enabled('portfolio_iframe','presentation') }}
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
csp:
|
||||
whitelist:
|
||||
script-src:
|
||||
|
@ -1,7 +1,7 @@
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
||||
|
||||
csp:
|
||||
whitelist:
|
||||
|
@ -2,5 +2,5 @@ version: "latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
central_database: true
|
@ -1,7 +1,7 @@
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
csp:
|
||||
flags:
|
||||
script-src:
|
||||
|
@ -9,7 +9,7 @@ flavor: 'taigaio' # Potential flavors: robrotheram, taigaio
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
oidc: false
|
||||
central_database: true
|
||||
|
||||
|
@ -13,7 +13,7 @@ plugins:
|
||||
features:
|
||||
matomo: true
|
||||
css: false
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
oidc: true
|
||||
central_database: true
|
||||
csp:
|
||||
@ -28,10 +28,9 @@ csp:
|
||||
- "blob:"
|
||||
font-src:
|
||||
- "data:"
|
||||
- "https://fonts.bunny.net"
|
||||
script-src:
|
||||
- "https://cdn.gtranslate.net"
|
||||
- "{{ domains.wordpress[0] }}"
|
||||
frame-src:
|
||||
- "{{ domains.peertube }}"
|
||||
style-src:
|
||||
- "https://fonts.bunny.net"
|
@ -9,6 +9,6 @@ oauth2_proxy:
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
||||
central_database: true
|
||||
oauth2: true
|
@ -1,4 +1,4 @@
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: true
|
||||
portfolio_iframe: true
|
@ -1,4 +1,4 @@
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
landingpage_iframe: false
|
||||
portfolio_iframe: false
|
@ -149,7 +149,7 @@ def update_mastodon():
|
||||
Runs the database migration for Mastodon to ensure all required tables are up to date.
|
||||
"""
|
||||
print("Starting Mastodon database migration.")
|
||||
run_command("docker compose exec -T web bash -c 'RAILS_ENV=production bin/rails db:migrate'")
|
||||
run_command("docker compose exec -T web bash -c 'RAILS_ENV={{ CYMAIS_ENVIRONMENT | lower }} bin/rails db:migrate'")
|
||||
print("Mastodon database migration complete.")
|
||||
|
||||
def upgrade_listmonk():
|
||||
|
1
tasks/.gitignore
vendored
Normal file
1
tasks/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
include-docker-roles.yml
|
211
tasks/server.yml
211
tasks/server.yml
@ -11,215 +11,8 @@
|
||||
- health-btrfs
|
||||
- system-btrfs-auto-balancer
|
||||
|
||||
#########################################################################
|
||||
### Docker Roles ###
|
||||
#########################################################################
|
||||
|
||||
- name: "setup matomo"
|
||||
when: ("matomo" in group_names)
|
||||
include_role:
|
||||
name: docker-matomo
|
||||
|
||||
- name: setup ldap
|
||||
when: ("ldap" in group_names)
|
||||
include_role:
|
||||
name: docker-ldap
|
||||
|
||||
- name: setup keycloak
|
||||
when: ("keycloak" in group_names)
|
||||
include_role:
|
||||
name: docker-keycloak
|
||||
|
||||
- name: setup lam
|
||||
when: ("lam" in group_names)
|
||||
include_role:
|
||||
name: docker-lam
|
||||
|
||||
- name: setup phpldapadmin
|
||||
when: ("phpldapadmin" in group_names)
|
||||
include_role:
|
||||
name: docker-phpldapadmin
|
||||
|
||||
- name: setup nextcloud hosts
|
||||
when: ("nextcloud" in group_names)
|
||||
include_role:
|
||||
name: docker-nextcloud
|
||||
|
||||
- name: setup gitea hosts
|
||||
when: ("gitea" in group_names)
|
||||
include_role:
|
||||
name: docker-gitea
|
||||
vars:
|
||||
run_mode: prod
|
||||
|
||||
- name: setup wordpress hosts
|
||||
when: ("wordpress" in group_names)
|
||||
include_role:
|
||||
name: docker-wordpress
|
||||
|
||||
- name: setup mediawiki hosts
|
||||
when: ("mediawiki" in group_names)
|
||||
include_role:
|
||||
name: docker-mediawiki
|
||||
|
||||
- name: setup mybb hosts
|
||||
when: ("mybb" in group_names)
|
||||
include_role:
|
||||
name: docker-mybb
|
||||
vars:
|
||||
mybb_domains: "{{domains.mybb}}"
|
||||
|
||||
- name: setup yourls hosts
|
||||
when: ("yourls" in group_names)
|
||||
include_role:
|
||||
name: docker-yourls
|
||||
|
||||
- name: setup mailu hosts
|
||||
when: ("mailu" in group_names)
|
||||
include_role:
|
||||
name: docker-mailu
|
||||
|
||||
- name: setup elk hosts
|
||||
when: ("elk" in group_names)
|
||||
include_role:
|
||||
name: docker-elk
|
||||
|
||||
- name: setup mastodon hosts
|
||||
when: ("mastodon" in group_names)
|
||||
include_role:
|
||||
name: docker-mastodon
|
||||
|
||||
- name: setup pixelfed hosts
|
||||
when: ("pixelfed" in group_names)
|
||||
include_role:
|
||||
name: docker-pixelfed
|
||||
|
||||
- name: setup peertube hosts
|
||||
when: ("peertube" in group_names)
|
||||
include_role:
|
||||
name: docker-peertube
|
||||
|
||||
- name: setup bigbluebutton hosts
|
||||
when: ("bigbluebutton" in group_names)
|
||||
include_role:
|
||||
name: docker-bigbluebutton
|
||||
vars:
|
||||
domain: "{{domains.bigbluebutton}}"
|
||||
|
||||
- name: setup funkwhale hosts
|
||||
when: ("funkwhale" in group_names)
|
||||
include_role:
|
||||
name: docker-funkwhale
|
||||
|
||||
- name: setup roulette-wheel hosts
|
||||
when: ("roulette-wheel" in group_names)
|
||||
include_role:
|
||||
name: docker-roulette-wheel
|
||||
|
||||
- name: setup joomla hosts
|
||||
when: ("joomla" in group_names)
|
||||
include_role:
|
||||
name: docker-joomla
|
||||
|
||||
- name: setup attendize
|
||||
when: ("attendize" in group_names)
|
||||
include_role:
|
||||
name: docker-attendize
|
||||
|
||||
- name: setup baserow hosts
|
||||
when: ("baserow" in group_names)
|
||||
include_role:
|
||||
name: docker-baserow
|
||||
|
||||
- name: setup listmonk
|
||||
when: ("listmonk" in group_names)
|
||||
include_role:
|
||||
name: docker-listmonk
|
||||
|
||||
- name: setup discourse
|
||||
when: ("discourse" in group_names)
|
||||
include_role:
|
||||
name: docker-discourse
|
||||
|
||||
- name: setup matrix with flavor 'ansible'
|
||||
include_role:
|
||||
name: docker-matrix-ansible
|
||||
when: applications.matrix.role == 'ansible' and ("matrix" in group_names)
|
||||
|
||||
- name: setup matrix with flavor 'compose'
|
||||
include_role:
|
||||
name: docker-matrix
|
||||
when: applications.matrix.role == 'compose' and ("matrix" in group_names)
|
||||
|
||||
- name: setup open project instances
|
||||
when: ("openproject" in group_names)
|
||||
include_role:
|
||||
name: docker-openproject
|
||||
|
||||
- name: setup gitlab hosts
|
||||
when: ("gitlab" in group_names)
|
||||
include_role:
|
||||
name: docker-gitlab
|
||||
|
||||
- name: setup akaunting hosts
|
||||
when: ("akaunting" in group_names)
|
||||
include_role:
|
||||
name: docker-akaunting
|
||||
|
||||
- name: setup moodle instance
|
||||
when: ("moodle" in group_names)
|
||||
include_role:
|
||||
name: docker-moodle
|
||||
|
||||
- name: setup taiga instance
|
||||
when: ("taiga" in group_names)
|
||||
include_role:
|
||||
name: docker-taiga
|
||||
|
||||
- name: setup friendica hosts
|
||||
when: ("friendica" in group_names)
|
||||
include_role:
|
||||
name: docker-friendica
|
||||
|
||||
- name: setup portfolio
|
||||
when: ("portfolio" in group_names)
|
||||
include_role:
|
||||
name: docker-portfolio
|
||||
|
||||
- name: setup bluesky
|
||||
when: ("bluesky" in group_names)
|
||||
include_role:
|
||||
name: docker-bluesky
|
||||
|
||||
- name: setup PHPMyAdmin
|
||||
when: ("phpmyadmin" in group_names)
|
||||
include_role:
|
||||
name: docker-phpmyadmin
|
||||
|
||||
- name: setup SNIPE-IT
|
||||
when: ("snipe_it" in group_names)
|
||||
include_role:
|
||||
name: docker-snipe_it
|
||||
|
||||
- name: setup sphinx
|
||||
when: ("sphinx" in group_names)
|
||||
include_role:
|
||||
name: docker-sphinx
|
||||
|
||||
- name: setup pgadmin
|
||||
when: ("pgadmin" in group_names)
|
||||
include_role:
|
||||
name: docker-pgadmin
|
||||
|
||||
- name: setup presentation
|
||||
when: ("presentation" in group_names)
|
||||
include_role:
|
||||
name: docker-presentation
|
||||
|
||||
- name: setup espocrm hosts
|
||||
when: ("espocrm" in group_names)
|
||||
include_role:
|
||||
name: docker-espocrm
|
||||
- name: "Integrate Docker Role includes"
|
||||
include_tasks: "include-docker-roles.yml"
|
||||
|
||||
# Native Webserver Roles
|
||||
- name: setup nginx-serve-htmls
|
||||
|
64
tests/unit/test_bridge_filters.py
Normal file
64
tests/unit/test_bridge_filters.py
Normal file
@ -0,0 +1,64 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
# Add the filter_plugins directory from the docker-matrix role to the import path
|
||||
sys.path.insert(
|
||||
0,
|
||||
os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), "../../roles/docker-matrix")
|
||||
),
|
||||
)
|
||||
|
||||
from filter_plugins.bridge_filters import filter_enabled_bridges
|
||||
|
||||
|
||||
class TestBridgeFilters(unittest.TestCase):
|
||||
def test_no_bridges_returns_empty_list(self):
|
||||
# When there are no bridges defined, result should be an empty list
|
||||
self.assertEqual(filter_enabled_bridges([], {}), [])
|
||||
|
||||
def test_all_bridges_disabled(self):
|
||||
# Define two bridges, but plugins dict has them disabled or missing
|
||||
bridges = [
|
||||
{'bridge_name': 'whatsapp', 'config': {}},
|
||||
{'bridge_name': 'telegram', 'config': {}},
|
||||
]
|
||||
plugins = {
|
||||
'whatsapp': False,
|
||||
'telegram': False,
|
||||
}
|
||||
result = filter_enabled_bridges(bridges, plugins)
|
||||
self.assertEqual(result, [])
|
||||
|
||||
def test_some_bridges_enabled(self):
|
||||
# Only bridges with True in plugins should be returned
|
||||
bridges = [
|
||||
{'bridge_name': 'whatsapp', 'version': '1.0'},
|
||||
{'bridge_name': 'telegram', 'version': '1.0'},
|
||||
{'bridge_name': 'signal', 'version': '1.0'},
|
||||
]
|
||||
plugins = {
|
||||
'whatsapp': True,
|
||||
'telegram': False,
|
||||
'signal': True,
|
||||
}
|
||||
result = filter_enabled_bridges(bridges, plugins)
|
||||
expected = [
|
||||
{'bridge_name': 'whatsapp', 'version': '1.0'},
|
||||
{'bridge_name': 'signal', 'version': '1.0'},
|
||||
]
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_bridge_without_plugin_entry_defaults_to_disabled(self):
|
||||
# If a bridge_name is not present in plugins, it should be treated as disabled
|
||||
bridges = [
|
||||
{'bridge_name': 'facebook', 'enabled': True},
|
||||
]
|
||||
plugins = {} # no entries
|
||||
result = filter_enabled_bridges(bridges, plugins)
|
||||
self.assertEqual(result, [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
@ -1,6 +1,16 @@
|
||||
# tests/unit/test_configuration_filters.py
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
import os
|
||||
|
||||
sys.path.insert(
|
||||
0,
|
||||
os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), "../../")
|
||||
),
|
||||
)
|
||||
|
||||
from filter_plugins.configuration_filters import (
|
||||
is_feature_enabled,
|
||||
)
|
||||
|
@ -1,6 +1,16 @@
|
||||
import unittest
|
||||
import hashlib
|
||||
import base64
|
||||
import sys
|
||||
import os
|
||||
|
||||
sys.path.insert(
|
||||
0,
|
||||
os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), "../../")
|
||||
),
|
||||
)
|
||||
|
||||
from filter_plugins.csp_filters import FilterModule, AnsibleFilterError
|
||||
|
||||
class TestCspFilters(unittest.TestCase):
|
||||
@ -137,5 +147,25 @@ class TestCspFilters(unittest.TestCase):
|
||||
style_hash = self.filter.get_csp_hash("body { background: #fff; }")
|
||||
self.assertNotIn(style_hash, header)
|
||||
|
||||
|
||||
def test_build_csp_header_recaptcha_toggle(self):
|
||||
"""
|
||||
When the 'recaptcha' feature is enabled, 'https://www.google.com'
|
||||
must be included in script-src; when disabled, it must not be.
|
||||
"""
|
||||
# enabled case
|
||||
self.apps['app1']['features']['recaptcha'] = True
|
||||
header_enabled = self.filter.build_csp_header(
|
||||
self.apps, 'app1', self.domains, web_protocol='https'
|
||||
)
|
||||
self.assertIn("https://www.google.com", header_enabled)
|
||||
|
||||
# disabled case
|
||||
self.apps['app1']['features']['recaptcha'] = False
|
||||
header_disabled = self.filter.build_csp_header(
|
||||
self.apps, 'app1', self.domains, web_protocol='https'
|
||||
)
|
||||
self.assertNotIn("https://www.google.com", header_disabled)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -2,8 +2,12 @@ import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../.."))
|
||||
sys.path.insert(0, PROJECT_ROOT)
|
||||
sys.path.insert(
|
||||
0,
|
||||
os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), "../../")
|
||||
),
|
||||
)
|
||||
|
||||
from filter_plugins.redirect_filters import FilterModule
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user