mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-07-22 08:11:09 +02:00
Adapted discourse version to new code after the big refactoring
This commit is contained in:
parent
1b9775ccb5
commit
d86ca6cc0e
@ -13,6 +13,12 @@ class FilterModule(object):
|
|||||||
seen_domains = {}
|
seen_domains = {}
|
||||||
|
|
||||||
for app_id, cfg in apps.items():
|
for app_id, cfg in apps.items():
|
||||||
|
if not isinstance(cfg, dict):
|
||||||
|
raise AnsibleFilterError(
|
||||||
|
f"Invalid configuration for application '{app_id}': "
|
||||||
|
f"expected a dict, got {cfg!r}"
|
||||||
|
)
|
||||||
|
|
||||||
domains_cfg = cfg.get('domains')
|
domains_cfg = cfg.get('domains')
|
||||||
if not domains_cfg or 'canonical' not in domains_cfg:
|
if not domains_cfg or 'canonical' not in domains_cfg:
|
||||||
self._add_default_domain(app_id, primary_domain, seen_domains, result)
|
self._add_default_domain(app_id, primary_domain, seen_domains, result)
|
||||||
|
@ -2,6 +2,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
import yaml
|
import yaml
|
||||||
from ansible.errors import AnsibleFilterError
|
from ansible.errors import AnsibleFilterError
|
||||||
|
from collections.abc import Mapping
|
||||||
|
|
||||||
from ansible.errors import AnsibleUndefinedVariable
|
from ansible.errors import AnsibleUndefinedVariable
|
||||||
try:
|
try:
|
||||||
@ -62,12 +63,15 @@ def get_app_conf(applications, application_id, config_path, strict=True, default
|
|||||||
return default if default is not None else False
|
return default if default is not None else False
|
||||||
raise AppConfigKeyError(
|
raise AppConfigKeyError(
|
||||||
f"Key '{k}' is undefined at '{'.'.join(path_trace)}'\n"
|
f"Key '{k}' is undefined at '{'.'.join(path_trace)}'\n"
|
||||||
|
f" actual type: {type(obj).__name__}\n"
|
||||||
|
f" repr(obj): {obj!r}\n"
|
||||||
|
f" repr(applications): {applications!r}\n"
|
||||||
f"application_id: {application_id}\n"
|
f"application_id: {application_id}\n"
|
||||||
f"config_path: {config_path}"
|
f"config_path: {config_path}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Access dict key
|
# Access dict key
|
||||||
if isinstance(obj, dict):
|
if isinstance(obj, Mapping):
|
||||||
if k not in obj:
|
if k not in obj:
|
||||||
# Non-strict mode: always return default on missing key
|
# Non-strict mode: always return default on missing key
|
||||||
if not strict:
|
if not strict:
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
# Todo
|
# Todo
|
||||||
- Finish LDAP implementation
|
- Finish LDAP implementation
|
||||||
|
- Check if this current network setting makes sense. Seems a bit unneccessary complicated. Could be that a more straight foreword approach makes more sense.
|
@ -32,3 +32,16 @@ docker:
|
|||||||
volumes:
|
volumes:
|
||||||
data: discourse_data
|
data: discourse_data
|
||||||
network: discourse
|
network: discourse
|
||||||
|
plugins:
|
||||||
|
docker_manager:
|
||||||
|
enabled: true
|
||||||
|
discourse-activity-pub:
|
||||||
|
enabled: true
|
||||||
|
discourse-akismet:
|
||||||
|
enabled: true
|
||||||
|
discourse-cakeday:
|
||||||
|
enabled: true
|
||||||
|
discourse-solved:
|
||||||
|
enabled: true
|
||||||
|
discourse-voting:
|
||||||
|
enabled: true
|
@ -7,7 +7,7 @@
|
|||||||
failed_when: container_action.failed and 'No such container' not in container_action.msg
|
failed_when: container_action.failed and 'No such container' not in container_action.msg
|
||||||
listen: recreate discourse
|
listen: recreate discourse
|
||||||
|
|
||||||
- name: "add central database temporary to {{ discourse_network }}"
|
- name: "add central database temporary to discourse network"
|
||||||
command: "docker network connect {{ discourse_network }} {{ database_host }}"
|
command: "docker network connect {{ discourse_network }} {{ database_host }}"
|
||||||
failed_when: >
|
failed_when: >
|
||||||
result.rc != 0 and
|
result.rc != 0 and
|
||||||
|
@ -35,9 +35,10 @@
|
|||||||
template:
|
template:
|
||||||
src: config.yml.j2
|
src: config.yml.j2
|
||||||
dest: "{{ discourse_application_yml_destination }}"
|
dest: "{{ discourse_application_yml_destination }}"
|
||||||
|
mode: '0640'
|
||||||
notify: recreate discourse
|
notify: recreate discourse
|
||||||
|
|
||||||
- name: "Verify that {{ discourse_container }} is running"
|
- name: "Verify that '{{ discourse_container }}' is running"
|
||||||
command: docker compose ps --filter status=running --format '{{"{{"}}.Name{{"}}"}}' | grep -x {{ discourse_container }}
|
command: docker compose ps --filter status=running --format '{{"{{"}}.Name{{"}}"}}' | grep -x {{ discourse_container }}
|
||||||
register: docker_ps
|
register: docker_ps
|
||||||
changed_when: docker_ps.rc == 1
|
changed_when: docker_ps.rc == 1
|
||||||
@ -62,13 +63,17 @@
|
|||||||
when:
|
when:
|
||||||
- applications | get_app_conf(application_id, 'features.central_database', False)
|
- applications | get_app_conf(application_id, 'features.central_database', False)
|
||||||
|
|
||||||
|
- name: Set error string for network not connected
|
||||||
|
set_fact:
|
||||||
|
docker_discourse_not_connected: 'is not connected to network {{ discourse_network }}'
|
||||||
|
|
||||||
- name: "Remove {{ discourse_network }} from {{ database_host }}"
|
- name: "Remove {{ discourse_network }} from {{ database_host }}"
|
||||||
command: >
|
command: >
|
||||||
docker network disconnect {{ discourse_network }} {{ database_host }}
|
docker network disconnect {{ discourse_network }} {{ database_host }}
|
||||||
register: network_disconnect
|
register: network_disconnect
|
||||||
failed_when: >
|
failed_when: >
|
||||||
network_disconnect.rc != 0 and
|
network_disconnect.rc != 0 and
|
||||||
'is not connected to network {{ discourse_network }}' not in network_disconnect.stderr
|
docker_discourse_not_connected not in network_disconnect.stderr
|
||||||
changed_when: network_disconnect.rc == 0
|
changed_when: network_disconnect.rc == 0
|
||||||
when:
|
when:
|
||||||
- applications | get_app_conf(application_id, 'features.central_database', False)
|
- applications | get_app_conf(application_id, 'features.central_database', False)
|
||||||
|
@ -74,7 +74,7 @@ env:
|
|||||||
DISCOURSE_DB_NAME: {{ database_name }}
|
DISCOURSE_DB_NAME: {{ database_name }}
|
||||||
|
|
||||||
# Redis Configuration
|
# Redis Configuration
|
||||||
DISCOURSE_REDIS_HOST: {{application_id}}-redis
|
DISCOURSE_REDIS_HOST: {{ discourse_redis_host }}
|
||||||
|
|
||||||
## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
|
## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
|
||||||
#LETSENCRYPT_ACCOUNT_EMAIL: administrator@veen.world
|
#LETSENCRYPT_ACCOUNT_EMAIL: administrator@veen.world
|
||||||
@ -103,18 +103,11 @@ hooks:
|
|||||||
- exec:
|
- exec:
|
||||||
cd: $home/plugins
|
cd: $home/plugins
|
||||||
cmd:
|
cmd:
|
||||||
- git clone --depth=1 https://github.com/discourse/docker_manager.git
|
{% for plugin_name, plugin_config in discourse_plugins.items() %}
|
||||||
- git clone --depth=1 https://github.com/discourse/discourse-activity-pub.git
|
{% if plugin_config.enabled %}
|
||||||
- git clone --depth=1 https://github.com/discourse/discourse-calendar.git
|
- git clone --depth=1 https://github.com/discourse/{{ plugin_name }}.git
|
||||||
- git clone --depth=1 https://github.com/discourse/discourse-akismet.git
|
|
||||||
- git clone --depth=1 https://github.com/discourse/discourse-cakeday.git
|
|
||||||
- git clone --depth=1 https://github.com/discourse/discourse-solved.git
|
|
||||||
- git clone --depth=1 https://github.com/discourse/discourse-voting.git
|
|
||||||
- git clone --depth=1 https://github.com/discourse/discourse-oauth2-basic.git
|
|
||||||
|
|
||||||
{% if applications | get_app_conf(application_id, 'features.oidc', False) %}
|
|
||||||
- git clone --depth=1 https://github.com/discourse/discourse-openid-connect.git
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
{% if applications | get_app_conf(application_id, 'features.ldap', False) %}
|
{% if applications | get_app_conf(application_id, 'features.ldap', False) %}
|
||||||
- git clone --depth=1 https://github.com/jonmbake/discourse-ldap-auth.git
|
- git clone --depth=1 https://github.com/jonmbake/discourse-ldap-auth.git
|
||||||
@ -177,5 +170,5 @@ run:
|
|||||||
- exec: echo "End of custom commands"
|
- exec: echo "End of custom commands"
|
||||||
|
|
||||||
docker_args:
|
docker_args:
|
||||||
- --network={{application_id}}_default
|
- --network={{ discourse_network }}
|
||||||
- --name={{ discourse_container }}
|
- --name={{ discourse_container }}
|
||||||
|
@ -4,5 +4,5 @@
|
|||||||
redis:
|
redis:
|
||||||
|
|
||||||
{% include 'roles/docker-compose/templates/networks.yml.j2' %}
|
{% include 'roles/docker-compose/templates/networks.yml.j2' %}
|
||||||
discourse_default:
|
{{ discourse_network }}:
|
||||||
external: true
|
external: true
|
@ -6,10 +6,12 @@ database_type: "postgres"
|
|||||||
|
|
||||||
# Discourse
|
# Discourse
|
||||||
discourse_container: "{{ applications | get_app_conf(application_id, 'docker.services.discourse.name') }}"
|
discourse_container: "{{ applications | get_app_conf(application_id, 'docker.services.discourse.name') }}"
|
||||||
discourse_application_yml_destination: "{{ docker_repository_directory }}containers/{{ discourse_container }}.yml"
|
|
||||||
discourse_network: "{{ applications | get_app_conf(application_id, 'docker.network') }}"
|
discourse_network: "{{ applications | get_app_conf(application_id, 'docker.network') }}"
|
||||||
discourse_volume: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
|
discourse_volume: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
|
||||||
|
discourse_plugins: "{{ applications | get_app_conf(application_id, 'plugins') }}"
|
||||||
discourse_pg_network: "{{ applications | get_app_conf('svc-db-postgres', 'docker.network' ) }}"
|
discourse_pg_network: "{{ applications | get_app_conf('svc-db-postgres', 'docker.network' ) }}"
|
||||||
|
discourse_application_yml_destination: "{{ docker_repository_directory }}containers/{{ discourse_container }}.yml"
|
||||||
|
discourse_redis_host: "{{ application_id |get_entity_name }}-redis"
|
||||||
|
|
||||||
# General Docker Configuration
|
# General Docker Configuration
|
||||||
docker_repository_directory : "{{ docker_compose.directories.services}}{{applications | get_app_conf( application_id, 'repository') }}/"
|
docker_repository_directory : "{{ docker_compose.directories.services}}{{applications | get_app_conf( application_id, 'repository') }}/"
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
- name: Merge application definitions
|
- name: Merge application definitions
|
||||||
set_fact:
|
set_fact:
|
||||||
applications: "{{ defaults_applications | combine(applications | default({}, true), recursive=True) }}"
|
applications: "{{ defaults_applications | merge_with_defaults(applications | default({}, true)) }}"
|
||||||
|
|
||||||
- name: Merge current play applications
|
- name: Merge current play applications
|
||||||
set_fact:
|
set_fact:
|
||||||
|
36
tests/integration/test_handlers_no_vars_in_name.py
Normal file
36
tests/integration/test_handlers_no_vars_in_name.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import unittest
|
||||||
|
import yaml
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
class HandlerNameIntegrationTest(unittest.TestCase):
|
||||||
|
"""
|
||||||
|
Integration test to ensure that handler definitions in Ansible roles
|
||||||
|
do not include Jinja variable interpolations in their 'name' attribute.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_handlers_have_no_variables_in_name(self):
|
||||||
|
# Locate all handler YAML files under roles/*/handlers/
|
||||||
|
handler_files = Path('roles').glob('*/handlers/*.yml')
|
||||||
|
for handler_file in handler_files:
|
||||||
|
with self.subTest(handler_file=str(handler_file)):
|
||||||
|
content = handler_file.read_text(encoding='utf-8')
|
||||||
|
# Load all documents in the YAML file
|
||||||
|
documents = list(yaml.safe_load_all(content))
|
||||||
|
for index, doc in enumerate(documents):
|
||||||
|
if not isinstance(doc, dict):
|
||||||
|
continue
|
||||||
|
# Only consider entries that are handlers (they have a 'listen' key)
|
||||||
|
if 'listen' in doc:
|
||||||
|
name = doc.get('name', '')
|
||||||
|
# Assert that no Jinja interpolation is present in the name
|
||||||
|
self.assertNotRegex(
|
||||||
|
name,
|
||||||
|
r"{{.*}}",
|
||||||
|
msg=(
|
||||||
|
f"Handler 'name' in file {handler_file} document #{index} "
|
||||||
|
f"contains a Jinja variable: {name}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user