mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-07-18 06:24:25 +02:00
Task include tests implemented, nginx restart, etc.
This commit is contained in:
parent
46cf65f296
commit
a026681553
@ -2,12 +2,30 @@
|
|||||||
include_role:
|
include_role:
|
||||||
name: srv-web-composer
|
name: srv-web-composer
|
||||||
|
|
||||||
- name: "copy nginx domain configuration to {{ configuration_destination }}"
|
- name: "Copy nginx config to {{ configuration_destination }}"
|
||||||
template:
|
template:
|
||||||
src: "{{ vhost_template_src }}"
|
src: "{{ vhost_template_src }}"
|
||||||
dest: "{{ configuration_destination }}"
|
dest: "{{ configuration_destination }}"
|
||||||
|
register: nginx_conf
|
||||||
notify: restart nginx
|
notify: restart nginx
|
||||||
|
|
||||||
|
- name: "Check if {{ domains | get_domain(application_id) }} is reachable (only if config unchanged)"
|
||||||
|
uri:
|
||||||
|
url: "{{ domains | get_url(application_id, web_protocol) }}"
|
||||||
|
register: site_check
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
when: not nginx_conf.changed
|
||||||
|
|
||||||
|
- name: Restart nginx if site is down
|
||||||
|
command:
|
||||||
|
cmd: "true"
|
||||||
|
notify: restart nginx
|
||||||
|
when:
|
||||||
|
- not nginx_conf.changed
|
||||||
|
- site_check.status is defined
|
||||||
|
- not site_check.status in [200,301,302]
|
||||||
|
|
||||||
- name: "set oauth2_proxy_application_id (Needed due to lazzy loading issue)"
|
- name: "set oauth2_proxy_application_id (Needed due to lazzy loading issue)"
|
||||||
set_fact:
|
set_fact:
|
||||||
oauth2_proxy_application_id: "{{ application_id }}"
|
oauth2_proxy_application_id: "{{ application_id }}"
|
||||||
|
@ -11,5 +11,5 @@
|
|||||||
http_port: "{{ ports.localhost.http[application_id] }}"
|
http_port: "{{ ports.localhost.http[application_id] }}"
|
||||||
|
|
||||||
- name: "configure pgadmin servers"
|
- name: "configure pgadmin servers"
|
||||||
include_tasks: config/main.yml
|
include_tasks: configuration.yml
|
||||||
when: applications[application_id].server_mode | bool
|
when: applications[application_id].server_mode | bool
|
102
tests/integration/test_include_import_tasks_existence.py
Normal file
102
tests/integration/test_include_import_tasks_existence.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import unittest
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import yaml
|
||||||
|
import re
|
||||||
|
|
||||||
|
class TestIncludeImportTasksExistence(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
# Determine project root, roles directory and list of YAML files to scan
|
||||||
|
tests_dir = os.path.dirname(__file__) # .../tests/integration
|
||||||
|
project_root = os.path.abspath(os.path.join(tests_dir, os.pardir, os.pardir))
|
||||||
|
self.project_root = project_root
|
||||||
|
self.roles_dir = os.path.join(project_root, 'roles')
|
||||||
|
|
||||||
|
self.files_to_scan = []
|
||||||
|
for filepath in glob.glob(os.path.join(project_root, '**', '*.yml'), recursive=True):
|
||||||
|
# Skip .git and tests directories
|
||||||
|
if '/.git/' in filepath or '/tests/' in filepath:
|
||||||
|
continue
|
||||||
|
self.files_to_scan.append(filepath)
|
||||||
|
|
||||||
|
def _collect_task_includes(self, data):
|
||||||
|
"""
|
||||||
|
Recursively collect all file references from include_tasks and import_tasks.
|
||||||
|
Supports scalar syntax, block syntax ({ file: ... }), and block-list syntax.
|
||||||
|
"""
|
||||||
|
task_files = []
|
||||||
|
if isinstance(data, dict):
|
||||||
|
for key, val in data.items():
|
||||||
|
if key in ('include_tasks', 'import_tasks'):
|
||||||
|
# Scalar syntax: include_tasks: tasks.yml
|
||||||
|
if isinstance(val, str):
|
||||||
|
task_files.append(val)
|
||||||
|
# Block syntax: include_tasks: { file: tasks.yml }
|
||||||
|
elif isinstance(val, dict) and 'file' in val:
|
||||||
|
task_files.append(val['file'])
|
||||||
|
# Block-list syntax:
|
||||||
|
elif isinstance(val, list):
|
||||||
|
for item in val:
|
||||||
|
if isinstance(item, dict) and 'file' in item:
|
||||||
|
task_files.append(item['file'])
|
||||||
|
else:
|
||||||
|
task_files.extend(self._collect_task_includes(val))
|
||||||
|
elif isinstance(data, list):
|
||||||
|
for item in data:
|
||||||
|
task_files.extend(self._collect_task_includes(item))
|
||||||
|
return task_files
|
||||||
|
|
||||||
|
def test_include_import_tasks_exist(self):
|
||||||
|
missing = []
|
||||||
|
for file_path in self.files_to_scan:
|
||||||
|
with open(file_path) as f:
|
||||||
|
try:
|
||||||
|
documents = list(yaml.safe_load_all(f))
|
||||||
|
except yaml.YAMLError:
|
||||||
|
self.fail(f"Failed to parse YAML in {file_path}")
|
||||||
|
|
||||||
|
file_dir = os.path.dirname(file_path)
|
||||||
|
# Determine the role context if under roles/
|
||||||
|
role_name = None
|
||||||
|
if self.roles_dir in file_dir:
|
||||||
|
parts = file_dir.split(os.sep)
|
||||||
|
idx = parts.index('roles')
|
||||||
|
if idx + 1 < len(parts):
|
||||||
|
role_name = parts[idx + 1]
|
||||||
|
role_path_dir = os.path.join(self.roles_dir, role_name)
|
||||||
|
|
||||||
|
for doc in documents:
|
||||||
|
for task_ref in self._collect_task_includes(doc):
|
||||||
|
# Handle special Jinja2 vars
|
||||||
|
pattern_ref = task_ref
|
||||||
|
if '{{ role_path }}' in pattern_ref and role_name:
|
||||||
|
pattern_ref = pattern_ref.replace('{{ role_path }}', role_path_dir)
|
||||||
|
if '{{ playbook_dir }}' in pattern_ref:
|
||||||
|
pattern_ref = pattern_ref.replace('{{ playbook_dir }}', self.project_root)
|
||||||
|
# Replace other Jinja2 expressions with wildcard
|
||||||
|
pattern_ref = re.sub(r"\{\{.*?\}\}", '*', pattern_ref)
|
||||||
|
# If no extension, assume .yml
|
||||||
|
if not os.path.splitext(pattern_ref)[1]:
|
||||||
|
pattern_ref += '.yml'
|
||||||
|
|
||||||
|
# Prepare search globs
|
||||||
|
local_glob = os.path.join(file_dir, pattern_ref)
|
||||||
|
global_glob = os.path.join(self.project_root, pattern_ref)
|
||||||
|
tasks_dir_glob = os.path.join(self.project_root, 'tasks', pattern_ref)
|
||||||
|
matches = []
|
||||||
|
matches += [p for p in glob.glob(local_glob) if os.path.isfile(p)]
|
||||||
|
matches += [p for p in glob.glob(global_glob) if os.path.isfile(p)]
|
||||||
|
matches += [p for p in glob.glob(tasks_dir_glob) if os.path.isfile(p)]
|
||||||
|
|
||||||
|
if not matches:
|
||||||
|
missing.append((file_path, task_ref))
|
||||||
|
|
||||||
|
if missing:
|
||||||
|
messages = [
|
||||||
|
f"File '{fp}' references missing task file '{tr}'"
|
||||||
|
for fp, tr in missing
|
||||||
|
]
|
||||||
|
self.fail("\n".join(messages))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user