Refactor systemctl services and categories due to alarm bugs

This commit restructures systemctl service definitions and category mappings.

Motivation: Alarm-related bugs revealed inconsistencies in service and role handling.

Preparation step: lays the groundwork for fixing the alarm issues by aligning categories, roles, and service templates.
This commit is contained in:
2025-08-18 13:35:43 +02:00
parent 29f50da226
commit 3a839cfe37
289 changed files with 975 additions and 948 deletions

View File

@@ -0,0 +1,61 @@
import unittest
import os
import sys
# Add the path to roles/sys-ctl-bkp-docker-2-loc/filter_plugins
CURRENT_DIR = os.path.dirname(__file__)
FILTER_PLUGIN_DIR = os.path.abspath(
os.path.join(CURRENT_DIR, '../../../../../roles/sys-ctl-bkp-docker-2-loc/filter_plugins')
)
sys.path.insert(0, FILTER_PLUGIN_DIR)
from dict_to_cli_args import dict_to_cli_args
class TestDictToCliArgs(unittest.TestCase):
def test_simple_string_args(self):
data = {"backup-dir": "/mnt/backups", "version-suffix": "-nightly"}
expected = "--backup-dir=/mnt/backups --version-suffix=-nightly"
self.assertEqual(dict_to_cli_args(data), expected)
def test_boolean_true(self):
data = {"shutdown": True, "everything": True}
expected = "--shutdown --everything"
self.assertEqual(dict_to_cli_args(data), expected)
def test_boolean_false(self):
data = {"shutdown": False, "everything": True}
expected = "--everything"
self.assertEqual(dict_to_cli_args(data), expected)
def test_list_argument(self):
data = {"ignore-volumes": ["redis", "memcached"]}
expected = '--ignore-volumes="redis memcached"'
self.assertEqual(dict_to_cli_args(data), expected)
def test_mixed_arguments(self):
data = {
"backup-dir": "/mnt/backups",
"shutdown": True,
"ignore-volumes": ["redis", "memcached"]
}
result = dict_to_cli_args(data)
self.assertIn("--backup-dir=/mnt/backups", result)
self.assertIn("--shutdown", result)
self.assertIn('--ignore-volumes="redis memcached"', result)
def test_empty_dict(self):
self.assertEqual(dict_to_cli_args({}), "")
def test_none_value(self):
data = {"some-value": None, "other": "yes"}
expected = "--other=yes"
self.assertEqual(dict_to_cli_args(data), expected)
def test_invalid_type(self):
with self.assertRaises(TypeError):
dict_to_cli_args(["not", "a", "dict"])
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,140 @@
import unittest
import importlib.util
import os
TEST_DIR = os.path.dirname(__file__)
PLUGIN_PATH = os.path.abspath(os.path.join(
TEST_DIR,
'../../../../../roles/sys-ctl-bkp-docker-2-loc/filter_plugins/find_dock_val_by_bkp_entr.py'
))
spec = importlib.util.spec_from_file_location("find_dock_val_by_bkp_entr", PLUGIN_PATH)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
find_dock_val_by_bkp_entr = mod.find_dock_val_by_bkp_entr
class TestFindDockValByBkpEntr(unittest.TestCase):
def setUp(self):
self.applications = {
'app1': {
'docker': {
'services': {
'svc1': {
'name': 'svc1',
'image': 'nginx:latest',
'custom_field': 'foo',
'backup': {
'enabled': True,
'mode': 'full'
}
},
'svc2': {
'name': 'svc2',
'image': 'redis:alpine',
'custom_field': 'bar',
'backup': {
'enabled': False,
}
},
'svc3': {
'name': 'svc3',
'image': 'postgres:alpine'
}
}
}
},
'app2': {
'docker': {
'services': {
'svcA': {
'name': 'svcA',
'image': 'alpine:latest',
'backup': {
'enabled': 1,
'mode': 'diff'
}
},
'svcB': {
'name': 'svcB',
'image': 'ubuntu:latest',
'backup': {
'something_else': True,
}
}
}
}
},
'app_no_docker': {
'meta': 'should be skipped'
}
}
def test_finds_services_with_enabled_backup_name(self):
# Sucht alle service-namen, wo backup.enabled truthy ist
result = find_dock_val_by_bkp_entr(self.applications, 'enabled', 'name')
self.assertIn('svc1', result)
self.assertIn('svcA', result)
self.assertNotIn('svc2', result)
self.assertNotIn('svc3', result)
self.assertEqual(set(result), {'svc1', 'svcA'})
def test_finds_services_with_enabled_backup_image(self):
# Sucht alle image, wo backup.enabled truthy ist
result = find_dock_val_by_bkp_entr(self.applications, 'enabled', 'image')
self.assertIn('nginx:latest', result)
self.assertIn('alpine:latest', result)
self.assertNotIn('redis:alpine', result)
self.assertNotIn('postgres:alpine', result)
self.assertEqual(set(result), {'nginx:latest', 'alpine:latest'})
def test_finds_services_with_enabled_backup_custom_field(self):
# Sucht alle custom_field, wo backup.enabled truthy ist
result = find_dock_val_by_bkp_entr(self.applications, 'enabled', 'custom_field')
self.assertIn('foo', result)
# svcA hat kein custom_field -> sollte nicht im Resultat sein
self.assertEqual(result, ['foo'])
def test_finds_other_backup_keys(self):
# Sucht nach services, wo backup.mode gesetzt ist
result = find_dock_val_by_bkp_entr(self.applications, 'mode', 'name')
self.assertIn('svc1', result)
self.assertIn('svcA', result)
self.assertEqual(set(result), {'svc1', 'svcA'})
def test_returns_empty_list_when_no_match(self):
# Sucht nach services, wo backup.xyz nicht gesetzt ist
result = find_dock_val_by_bkp_entr(self.applications, 'doesnotexist', 'name')
self.assertEqual(result, [])
def test_returns_empty_list_on_empty_input(self):
result = find_dock_val_by_bkp_entr({}, 'enabled', 'name')
self.assertEqual(result, [])
def test_raises_on_non_dict_input(self):
with self.assertRaises(Exception):
find_dock_val_by_bkp_entr(None, 'enabled', 'name')
with self.assertRaises(Exception):
find_dock_val_by_bkp_entr([], 'enabled', 'name')
def test_works_with_missing_field(self):
# mapped_entry fehlt -> kein Eintrag im Ergebnis
apps = {
'a': {'docker': {'services': {'x': {'backup': {'enabled': True}}}}}
}
result = find_dock_val_by_bkp_entr(apps, 'enabled', 'foo')
self.assertEqual(result, [])
def test_works_with_multiple_matches(self):
# Zwei Treffer, beide mit enabled, mit custom Rückgabefeld
apps = {
'a': {'docker': {'services': {
'x': {'backup': {'enabled': True}, 'any': 'n1'},
'y': {'backup': {'enabled': True}, 'any': 'n2'}
}}}
}
result = find_dock_val_by_bkp_entr(apps, 'enabled', 'any')
self.assertEqual(set(result), {'n1', 'n2'})
if __name__ == '__main__':
unittest.main()