mirror of
				https://github.com/kevinveenbirkenbach/computer-playbook.git
				synced 2025-10-31 10:19:09 +00:00 
			
		
		
		
	Adapted discourse version to new code after the big refactoring
This commit is contained in:
		| @@ -13,6 +13,12 @@ class FilterModule(object): | ||||
|         seen_domains = {} | ||||
|  | ||||
|         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') | ||||
|             if not domains_cfg or 'canonical' not in domains_cfg: | ||||
|                 self._add_default_domain(app_id, primary_domain, seen_domains, result) | ||||
|   | ||||
| @@ -2,6 +2,7 @@ import os | ||||
| import re | ||||
| import yaml | ||||
| from ansible.errors import AnsibleFilterError | ||||
| from collections.abc import Mapping | ||||
|  | ||||
| from ansible.errors import AnsibleUndefinedVariable | ||||
| 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 | ||||
|             raise AppConfigKeyError( | ||||
|                 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"config_path: {config_path}" | ||||
|             ) | ||||
|  | ||||
|         # Access dict key | ||||
|         if isinstance(obj, dict): | ||||
|         if isinstance(obj, Mapping): | ||||
|             if k not in obj: | ||||
|                 # Non-strict mode: always return default on missing key | ||||
|                 if not strict: | ||||
|   | ||||
| @@ -1,2 +1,3 @@ | ||||
| # 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:  | ||||
|     data:   discourse_data | ||||
|   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 | ||||
|   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 }}" | ||||
|   failed_when: > | ||||
|     result.rc != 0 and | ||||
|   | ||||
| @@ -35,9 +35,10 @@ | ||||
|     template:  | ||||
|       src: config.yml.j2 | ||||
|       dest: "{{ discourse_application_yml_destination }}" | ||||
|       mode: '0640' | ||||
|     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 }} | ||||
|     register:     docker_ps | ||||
|     changed_when: docker_ps.rc == 1 | ||||
| @@ -62,13 +63,17 @@ | ||||
|     when: | ||||
|       - 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 }}" | ||||
|     command: > | ||||
|       docker network disconnect {{ discourse_network }} {{ database_host }} | ||||
|     register: network_disconnect | ||||
|     failed_when: > | ||||
|       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 | ||||
|     when: | ||||
|       - applications | get_app_conf(application_id, 'features.central_database', False) | ||||
|   | ||||
| @@ -74,7 +74,7 @@ env: | ||||
|   DISCOURSE_DB_NAME:     {{ database_name }} | ||||
|  | ||||
|   # 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 | ||||
|   #LETSENCRYPT_ACCOUNT_EMAIL: administrator@veen.world | ||||
| @@ -103,18 +103,11 @@ hooks: | ||||
|     - exec: | ||||
|         cd: $home/plugins | ||||
|         cmd: | ||||
|           - git clone --depth=1 https://github.com/discourse/docker_manager.git | ||||
|           - git clone --depth=1 https://github.com/discourse/discourse-activity-pub.git | ||||
|           - git clone --depth=1 https://github.com/discourse/discourse-calendar.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 | ||||
| {% for plugin_name, plugin_config in discourse_plugins.items() %} | ||||
| {% if plugin_config.enabled %} | ||||
|           - git clone --depth=1 https://github.com/discourse/{{ plugin_name }}.git | ||||
| {% endif %} | ||||
| {% endfor %}      | ||||
|  | ||||
| {% if applications | get_app_conf(application_id, 'features.ldap', False) %} | ||||
|           - git clone --depth=1 https://github.com/jonmbake/discourse-ldap-auth.git | ||||
| @@ -177,5 +170,5 @@ run: | ||||
|   - exec: echo "End of custom commands" | ||||
|  | ||||
| docker_args: | ||||
|   - --network={{application_id}}_default | ||||
|   - --network={{ discourse_network }} | ||||
|   - --name={{ discourse_container }} | ||||
|   | ||||
| @@ -4,5 +4,5 @@ | ||||
|   redis: | ||||
|  | ||||
| {% include 'roles/docker-compose/templates/networks.yml.j2' %} | ||||
|   discourse_default: | ||||
|   {{ discourse_network }}: | ||||
|     external: true | ||||
| @@ -6,10 +6,12 @@ database_type:                          "postgres" | ||||
|  | ||||
| # Discourse | ||||
| 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_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_application_yml_destination:  "{{ docker_repository_directory }}containers/{{ discourse_container }}.yml" | ||||
| discourse_redis_host:                   "{{ application_id |get_entity_name }}-redis" | ||||
|  | ||||
| # General Docker Configuration | ||||
| docker_repository_directory :           "{{ docker_compose.directories.services}}{{applications | get_app_conf( application_id, 'repository') }}/" | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  | ||||
|   - name: Merge application definitions | ||||
|     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 | ||||
|     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() | ||||
		Reference in New Issue
	
	Block a user