mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-07-17 22:14:25 +02:00
Implemented filter functions to get roles by application_id
This commit is contained in:
parent
c9c73cbdb2
commit
f3939661e4
@ -49,7 +49,7 @@ More informations about the features you will find [here](docs/overview/Features
|
|||||||
|
|
||||||
### Use it online 🌐
|
### Use it online 🌐
|
||||||
|
|
||||||
Give CyMaIS a spin at cymais.cloud – sign up in seconds, click around, and see how easy infra magic can be! 🚀🔧✨
|
Give CyMaIS a spin at [CyMaIS.cloud](httpy://cymais.cloud) – sign up in seconds, click around, and see how easy infra magic can be! 🚀🔧✨
|
||||||
|
|
||||||
### Install locally 💻
|
### Install locally 💻
|
||||||
1. **Install CyMaIS** via [Kevin's Package Manager](https://github.com/kevinveenbirkenbach/package-manager)
|
1. **Install CyMaIS** via [Kevin's Package Manager](https://github.com/kevinveenbirkenbach/package-manager)
|
||||||
|
88
filter_plugins/role_path_by_app_id.py
Normal file
88
filter_plugins/role_path_by_app_id.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# filter_plugins/role_path_by_app_id.py
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import yaml
|
||||||
|
from ansible.errors import AnsibleFilterError
|
||||||
|
|
||||||
|
|
||||||
|
def abs_role_path_by_application_id(application_id):
|
||||||
|
"""
|
||||||
|
Searches all roles/*/vars/main.yml for application_id and returns
|
||||||
|
the absolute path of the role that matches. Raises an error if
|
||||||
|
zero or more than one match is found.
|
||||||
|
"""
|
||||||
|
base_dir = os.getcwd()
|
||||||
|
pattern = os.path.join(base_dir, 'roles', '*', 'vars', 'main.yml')
|
||||||
|
matches = []
|
||||||
|
|
||||||
|
for filepath in glob.glob(pattern):
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r') as f:
|
||||||
|
data = yaml.safe_load(f) or {}
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if data.get('application_id') == application_id:
|
||||||
|
role_dir = os.path.dirname(os.path.dirname(filepath))
|
||||||
|
abs_path = os.path.abspath(role_dir)
|
||||||
|
matches.append(abs_path)
|
||||||
|
|
||||||
|
if len(matches) > 1:
|
||||||
|
raise AnsibleFilterError(
|
||||||
|
f"Multiple roles found with application_id='{application_id}': {matches}. "
|
||||||
|
"The application_id must be unique."
|
||||||
|
)
|
||||||
|
if not matches:
|
||||||
|
raise AnsibleFilterError(
|
||||||
|
f"No role found with application_id='{application_id}'."
|
||||||
|
)
|
||||||
|
|
||||||
|
return matches[0]
|
||||||
|
|
||||||
|
|
||||||
|
def rel_role_path_by_application_id(application_id):
|
||||||
|
"""
|
||||||
|
Searches all roles/*/vars/main.yml for application_id and returns
|
||||||
|
the relative path (from the project root) of the role that matches.
|
||||||
|
Raises an error if zero or more than one match is found.
|
||||||
|
"""
|
||||||
|
base_dir = os.getcwd()
|
||||||
|
pattern = os.path.join(base_dir, 'roles', '*', 'vars', 'main.yml')
|
||||||
|
matches = []
|
||||||
|
|
||||||
|
for filepath in glob.glob(pattern):
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r') as f:
|
||||||
|
data = yaml.safe_load(f) or {}
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if data.get('application_id') == application_id:
|
||||||
|
role_dir = os.path.dirname(os.path.dirname(filepath))
|
||||||
|
rel_path = os.path.relpath(role_dir, base_dir)
|
||||||
|
matches.append(rel_path)
|
||||||
|
|
||||||
|
if len(matches) > 1:
|
||||||
|
raise AnsibleFilterError(
|
||||||
|
f"Multiple roles found with application_id='{application_id}': {matches}. "
|
||||||
|
"The application_id must be unique."
|
||||||
|
)
|
||||||
|
if not matches:
|
||||||
|
raise AnsibleFilterError(
|
||||||
|
f"No role found with application_id='{application_id}'."
|
||||||
|
)
|
||||||
|
|
||||||
|
return matches[0]
|
||||||
|
|
||||||
|
|
||||||
|
class FilterModule(object):
|
||||||
|
"""
|
||||||
|
Provides the filters `abs_role_path_by_application_id` and
|
||||||
|
`rel_role_path_by_application_id`.
|
||||||
|
"""
|
||||||
|
def filters(self):
|
||||||
|
return {
|
||||||
|
'abs_role_path_by_application_id': abs_role_path_by_application_id,
|
||||||
|
'rel_role_path_by_application_id': rel_role_path_by_application_id,
|
||||||
|
}
|
@ -3,8 +3,8 @@
|
|||||||
src: "{{ item }}"
|
src: "{{ item }}"
|
||||||
dest: "{{ docker_compose.files.dockerfile }}"
|
dest: "{{ docker_compose.files.dockerfile }}"
|
||||||
loop:
|
loop:
|
||||||
- "{{ playbook_dir }}/roles/web-app-{{ application_id }}/templates/Dockerfile.j2"
|
- "{{ application_id | abs_role_path_by_application_id }}/templates/Dockerfile.j2"
|
||||||
- "{{ playbook_dir }}/roles/web-app-{{ application_id }}/files/Dockerfile"
|
- "{{ application_id | abs_role_path_by_application_id }}/files/Dockerfile"
|
||||||
notify: docker compose up
|
notify: docker compose up
|
||||||
register: create_dockerfile_result
|
register: create_dockerfile_result
|
||||||
failed_when:
|
failed_when:
|
||||||
@ -20,8 +20,8 @@
|
|||||||
notify: docker compose up
|
notify: docker compose up
|
||||||
register: env_template
|
register: env_template
|
||||||
loop:
|
loop:
|
||||||
- "{{ playbook_dir }}/roles/web-app-{{ application_id }}/templates/env.j2"
|
- "{{ application_id | abs_role_path_by_application_id }}/templates/env.j2"
|
||||||
- "{{ playbook_dir }}/roles/web-app-{{ application_id }}/files/env"
|
- "{{ application_id | abs_role_path_by_application_id }}/files/env"
|
||||||
failed_when:
|
failed_when:
|
||||||
- env_template is failed
|
- env_template is failed
|
||||||
- "'Could not find or access' not in env_template.msg"
|
- "'Could not find or access' not in env_template.msg"
|
||||||
|
@ -1 +1 @@
|
|||||||
modifier_javascript_template_file: "{{ playbook_dir }}/roles/web-app-{{ application_id }}/templates/javascript.js.j2"
|
modifier_javascript_template_file: "{{ application_id | abs_role_path_by_application_id }}/templates/javascript.js.j2"
|
@ -15,7 +15,7 @@ function getExportName(slug) {
|
|||||||
|
|
||||||
// Root: redirect to your documentation
|
// Root: redirect to your documentation
|
||||||
app.get('/', (req, res) => {
|
app.get('/', (req, res) => {
|
||||||
res.redirect('{{ domains | get_url('sphinx', web_protocol) }}/roles/web-app-{{ application_id }}/README.html');
|
res.redirect('{{ domains | get_url('sphinx', web_protocol) }}/{{ application_id | rel_role_path_by_application_id}}/README.html');
|
||||||
});
|
});
|
||||||
|
|
||||||
// GET /:slug.svg
|
// GET /:slug.svg
|
||||||
|
80
tests/unit/filter_plugins/test_role_path_by_app_id.py
Normal file
80
tests/unit/filter_plugins/test_role_path_by_app_id.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
import shutil
|
||||||
|
import yaml
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from ansible.errors import AnsibleFilterError
|
||||||
|
from filter_plugins.role_path_by_app_id import (
|
||||||
|
abs_role_path_by_application_id,
|
||||||
|
rel_role_path_by_application_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def write_vars_file(base_dir, role_name, app_id):
|
||||||
|
"""
|
||||||
|
Helper to create roles/<role_name>/vars/main.yml with application_id
|
||||||
|
"""
|
||||||
|
role_vars_dir = os.path.join(base_dir, 'roles', role_name, 'vars')
|
||||||
|
os.makedirs(role_vars_dir, exist_ok=True)
|
||||||
|
file_path = os.path.join(role_vars_dir, 'main.yml')
|
||||||
|
with open(file_path, 'w') as f:
|
||||||
|
yaml.safe_dump({'application_id': app_id}, f)
|
||||||
|
return file_path
|
||||||
|
|
||||||
|
|
||||||
|
class TestRolePathByApplicationId(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
# Create temporary directory for each test and switch cwd
|
||||||
|
self.tmp_dir = tempfile.mkdtemp()
|
||||||
|
self.prev_cwd = os.getcwd()
|
||||||
|
os.chdir(self.tmp_dir)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# Restore cwd and clean up
|
||||||
|
os.chdir(self.prev_cwd)
|
||||||
|
shutil.rmtree(self.tmp_dir)
|
||||||
|
|
||||||
|
def test_abs_single_match(self):
|
||||||
|
write_vars_file(self.tmp_dir, 'role_one', 'app123')
|
||||||
|
write_vars_file(self.tmp_dir, 'role_two', 'other_id')
|
||||||
|
result = abs_role_path_by_application_id('app123')
|
||||||
|
expected = os.path.abspath(os.path.join(self.tmp_dir, 'roles', 'role_one'))
|
||||||
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
|
def test_rel_single_match(self):
|
||||||
|
write_vars_file(self.tmp_dir, 'role_one', 'app123')
|
||||||
|
write_vars_file(self.tmp_dir, 'role_two', 'other_id')
|
||||||
|
result = rel_role_path_by_application_id('app123')
|
||||||
|
expected = os.path.relpath(os.path.join(self.tmp_dir, 'roles', 'role_one'), self.tmp_dir)
|
||||||
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
|
def test_abs_no_match(self):
|
||||||
|
write_vars_file(self.tmp_dir, 'role_one', 'app123')
|
||||||
|
with self.assertRaises(AnsibleFilterError) as cm:
|
||||||
|
abs_role_path_by_application_id('nonexistent')
|
||||||
|
self.assertIn("No role found with application_id='nonexistent'", str(cm.exception))
|
||||||
|
|
||||||
|
def test_rel_no_match(self):
|
||||||
|
write_vars_file(self.tmp_dir, 'role_one', 'app123')
|
||||||
|
with self.assertRaises(AnsibleFilterError) as cm:
|
||||||
|
rel_role_path_by_application_id('nonexistent')
|
||||||
|
self.assertIn("No role found with application_id='nonexistent'", str(cm.exception))
|
||||||
|
|
||||||
|
def test_abs_multiple_match(self):
|
||||||
|
write_vars_file(self.tmp_dir, 'role_one', 'dup_id')
|
||||||
|
write_vars_file(self.tmp_dir, 'role_two', 'dup_id')
|
||||||
|
with self.assertRaises(AnsibleFilterError) as cm:
|
||||||
|
abs_role_path_by_application_id('dup_id')
|
||||||
|
self.assertIn("Multiple roles found with application_id='dup_id'", str(cm.exception))
|
||||||
|
|
||||||
|
def test_rel_multiple_match(self):
|
||||||
|
write_vars_file(self.tmp_dir, 'role_one', 'dup_id')
|
||||||
|
write_vars_file(self.tmp_dir, 'role_two', 'dup_id')
|
||||||
|
with self.assertRaises(AnsibleFilterError) as cm:
|
||||||
|
rel_role_path_by_application_id('dup_id')
|
||||||
|
self.assertIn("Multiple roles found with application_id='dup_id'", str(cm.exception))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user