I want to implement a plugin manager class that is able to register multiple check-functions running checks on virtual machine related data in a dict to verify if the specific conditions (defined in the check-functions) were met. A check-function itself returns either True (checked conditions met) or False. Which checks are getting registered to the manager class is defined by the user selecting the checks to run.
My problem:
The check-functions require different arguments (except the vm_data argument) - e.g. they sometimes require API connection objects to be passed in for checking conditions.
How do I make sure that the functions get registered with the arguments they need as the checks to run are selectable by the user? Is there any other way to get this done except maintaining a bunch of conditionals, which is not the best idea? In the end I simply want to add/remove check-functions without having to deal with a block of conditionals, which is not maintainable. Maybe there is another way to dynamically prepare the arguments the checks require.
# just for simplicity - user input is a list
user_activated_checks = ['check_min_ram', 'check_vm_overrides']
manager = CheckManager()
if 'check_min_ram' in user_activated_checks:
min_ram = 1024
manager.register_check(check_min_ram, min_ram)
if 'check_vm_overrides' ...
def check_min_ram(vm_data, min_ram):
"""Check if VM has minimum of configured RAM"""
# check-specific code
def check_vm_overrides(vm_data, cluster):
"""Check for VM configured cluster overrides."""
# check-specifc code
class CheckManager:
"""Check plugin manager"""
def __init__(self):
self.registered_checks = []
def _check_names(self):
check_names = []
for check in self.registered_checks:
check_names.append(check[0].__name__)
return check_names
def register_check(self, func, *args, **kwargs):
if func.__name__ not in self._check_names():
self.registered_checks.append((func, args, kwargs))
def run_checks(self):
"""
Run all checks.
Return True if one check is True.
"""
if not self.registered_checks:
return False
for check in self.registered_checks:
for func, args, kwargs in check:
if func(*args, **kwargs):
return True