mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-26 21:45:20 +02:00
Add custom Ansible filter plugin get_category_entries
This commit introduces a new Ansible filter plugin named 'get_category_entries', which returns all role names under the roles/ directory that start with a given prefix. Additionally, unit tests (unittest framework) have been added under tests/unit/filterplugins/ to ensure correct behavior, including: - Returns empty list when roles/ directory is missing - Correctly filters and sorts by prefix - Ignores non-directory entries - Supports custom roles_path argument - Returns all roles when prefix is empty Reference: https://chatgpt.com/share/68a2f1ab-1fe8-800f-b22a-28c1c95802c2
This commit is contained in:
parent
a5941763ff
commit
29f50da226
31
filter_plugins/get_category_entries.py
Normal file
31
filter_plugins/get_category_entries.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Custom Ansible filter to get all role names under "roles/" with a given prefix.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
def get_category_entries(prefix, roles_path="roles"):
|
||||||
|
"""
|
||||||
|
Returns a list of role names under the given roles_path
|
||||||
|
that start with the specified prefix.
|
||||||
|
|
||||||
|
:param prefix: String prefix to match role names.
|
||||||
|
:param roles_path: Path to the roles directory (default: 'roles').
|
||||||
|
:return: List of matching role names.
|
||||||
|
"""
|
||||||
|
if not os.path.isdir(roles_path):
|
||||||
|
return []
|
||||||
|
|
||||||
|
roles = []
|
||||||
|
for entry in os.listdir(roles_path):
|
||||||
|
full_path = os.path.join(roles_path, entry)
|
||||||
|
if os.path.isdir(full_path) and entry.startswith(prefix):
|
||||||
|
roles.append(entry)
|
||||||
|
|
||||||
|
return sorted(roles)
|
||||||
|
|
||||||
|
class FilterModule(object):
|
||||||
|
""" Custom filters for Ansible """
|
||||||
|
|
||||||
|
def filters(self):
|
||||||
|
return {
|
||||||
|
"get_category_entries": get_category_entries
|
||||||
|
}
|
85
tests/unit/filter_plugins/test_get_category_entries.py
Normal file
85
tests/unit/filter_plugins/test_get_category_entries.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
# Unit tests for the get_category_entries Ansible filter plugin (unittest version).
|
||||||
|
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
import tempfile
|
||||||
|
import shutil
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from filter_plugins.get_category_entries import get_category_entries
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetCategoryEntries(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
# Create an isolated temp directory for each test
|
||||||
|
self._tmpdir = tempfile.TemporaryDirectory()
|
||||||
|
self.tmp = Path(self._tmpdir.name)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# Clean up the temp directory
|
||||||
|
self._tmpdir.cleanup()
|
||||||
|
|
||||||
|
def test_returns_empty_when_roles_dir_missing(self):
|
||||||
|
"""If the roles directory does not exist, the filter must return an empty list."""
|
||||||
|
missing_dir = self.tmp / "no_such_roles_dir"
|
||||||
|
self.assertFalse(missing_dir.exists())
|
||||||
|
self.assertEqual(get_category_entries("docker-", roles_path=str(missing_dir)), [])
|
||||||
|
|
||||||
|
def test_matches_prefix_and_sorts(self):
|
||||||
|
"""
|
||||||
|
The filter should return only directory names starting with the prefix,
|
||||||
|
and the result must be sorted.
|
||||||
|
"""
|
||||||
|
roles_dir = self.tmp / "roles"
|
||||||
|
roles_dir.mkdir()
|
||||||
|
|
||||||
|
# Create role directories
|
||||||
|
(roles_dir / "docker-nginx").mkdir()
|
||||||
|
(roles_dir / "docker-postgres").mkdir()
|
||||||
|
(roles_dir / "web-app-keycloak").mkdir()
|
||||||
|
(roles_dir / "docker-redis").mkdir()
|
||||||
|
|
||||||
|
# A file that should be ignored
|
||||||
|
(roles_dir / "docker-file").write_text("not a directory")
|
||||||
|
|
||||||
|
result = get_category_entries("docker-", roles_path=str(roles_dir))
|
||||||
|
self.assertEqual(result, ["docker-nginx", "docker-postgres", "docker-redis"])
|
||||||
|
|
||||||
|
def test_ignores_non_directories(self):
|
||||||
|
"""Non-directory entries under roles/ must be ignored."""
|
||||||
|
roles_dir = self.tmp / "roles"
|
||||||
|
roles_dir.mkdir()
|
||||||
|
|
||||||
|
(roles_dir / "docker-engine").mkdir()
|
||||||
|
(roles_dir / "docker-engine.txt").write_text("file, should be ignored")
|
||||||
|
|
||||||
|
result = get_category_entries("docker-", roles_path=str(roles_dir))
|
||||||
|
self.assertEqual(result, ["docker-engine"])
|
||||||
|
|
||||||
|
def test_respects_custom_roles_path(self):
|
||||||
|
"""When roles_path is provided, the filter should use it instead of 'roles'."""
|
||||||
|
custom_roles = self.tmp / "custom" / "rolesdir"
|
||||||
|
custom_roles.mkdir(parents=True)
|
||||||
|
|
||||||
|
(custom_roles / "docker-a").mkdir()
|
||||||
|
(custom_roles / "docker-b").mkdir()
|
||||||
|
(custom_roles / "other-c").mkdir()
|
||||||
|
|
||||||
|
result = get_category_entries("docker-", roles_path=str(custom_roles))
|
||||||
|
self.assertEqual(result, ["docker-a", "docker-b"])
|
||||||
|
|
||||||
|
def test_empty_prefix_returns_all_roles_sorted(self):
|
||||||
|
"""If an empty prefix is passed, the filter should return all role directories (sorted)."""
|
||||||
|
roles_dir = self.tmp / "roles"
|
||||||
|
roles_dir.mkdir()
|
||||||
|
|
||||||
|
(roles_dir / "a-role").mkdir()
|
||||||
|
(roles_dir / "c-role").mkdir()
|
||||||
|
(roles_dir / "b-role").mkdir()
|
||||||
|
|
||||||
|
result = get_category_entries("", roles_path=str(roles_dir))
|
||||||
|
self.assertEqual(result, ["a-role", "b-role", "c-role"])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user