From cfb073980e8d304076ee29a6806aec34f586732f Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Sun, 2 May 2021 18:42:30 +0200 Subject: Added borg validate action plugin --- action_plugins/borg_validate.py | 81 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 action_plugins/borg_validate.py (limited to 'action_plugins/borg_validate.py') diff --git a/action_plugins/borg_validate.py b/action_plugins/borg_validate.py new file mode 100644 index 0000000..16d97ec --- /dev/null +++ b/action_plugins/borg_validate.py @@ -0,0 +1,81 @@ +from ansible.plugins.action import ActionBase + +import re + +class ActionModule(ActionBase): + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + result['changed'] = False + result['failed'] = False + + error_msgs = [] + + ### host_vars validations ############################################ + if 'borg_server' in task_vars: + # a borg server must exist + if not isinstance(task_vars['borg_server'], str): + error_msgs.append(f"The borg_server variable must be of type string for host {task_vars['ansible_host']}") + elif not task_vars['borg_server'] in task_vars['hostvars'].keys(): + error_msgs.append(f"The borg_server {task_vars['borg_server']} configured for host {task_vars['ansible_host']} does not exist") + else: + # a borg client needs a list of jobs + if 'borg_jobs' not in task_vars: + error_msgs.append(f"No borg_jobs defined for host {task_vars['ansible_host']} while it has a borg_server configured") + elif not isinstance(task_vars['borg_jobs'], list): + error_msgs.append(f"The borg_jobs variable must be of type list for host {task_vars['ansible_host']}") + else: + for job in task_vars['borg_jobs']: + # a job is a dict with specific keys + if not isinstance(job, dict): + error_msgs.append(f"The borg_jobs list elements must be of type dict for host {task_vars['ansible_host']}") + continue + for key in job.keys(): + if not key in ['name', 'path', 'command_to_pipe', 'pre_command', 'post_command', 'exclude']: + error_msgs.append(f"Invalid key {key} in a job for host {task_vars['ansible_host']}") + # a job name is a mandatory string + if not 'name' in job.keys(): + error_msgs.append(f"Invalid job for host {task_vars['ansible_host']} : no name defined") + elif not isinstance(job['name'], str): + error_msgs.append(f"Invalid job name for host {task_vars['ansible_host']} : name must be of type string") + elif not re.match(r'^[a-zA-Z0-9_]+$', job['name']): + error_msgs.append(f"Invalid job name for host {task_vars['ansible_host']} : name must match ^[a-zA-Z0-9_]+$") + # path and command_to_pipe are mutually exclusive + if 'path' in job.keys() and 'command_to_pipe' in job.keys(): + error_msgs.append(f"Invalid job for host {task_vars['ansible_host']} : it needs either a path or a command_to_pipe, not both") + elif 'path' not in job.keys() and 'command_to_pipe' not in job.keys(): + error_msgs.append(f"Invalid job for host {task_vars['ansible_host']} : it needs either a path or a command_to_pipe") + elif 'path' in job.keys(): + if not isinstance(job['path'], str): + error_msgs.append(f"Invalid job for host {task_vars['ansible_host']} : path must be of type string") + elif not isinstance(job['command_to_pipe'], str): + error_msgs.append(f"Invalid job for host {task_vars['ansible_host']} : command_to_pipe must be of type string") + # a pre_command is an optional string + if 'pre_command' in job.keys(): + if not isinstance(job['pre_command'], str): + error_msgs.append(f"Invalid job for host {task_vars['ansible_host']} : pre_command must be of type string") + # a post_command is an optional string + if 'post_command' in job.keys(): + if not isinstance(job['post_command'], str): + error_msgs.append(f"Invalid job for host {task_vars['ansible_host']} : post_command must be of type string") + # exclude is an optional list of paths + if 'exclude' in job.keys(): + if not isinstance(job['exclude'], list): + error_msgs.append(f"Invalid job for host {task_vars['ansible_host']} : exclude must be of type list") + else: + for path in job['exclude']: + if not isinstance(path, str): + error_msgs.append(f"Invalid job for host {task_vars['ansible_host']} : exclude must be a list of strings") + # a borg client needs prune arguments + if not 'borg_prune_arguments' in task_vars: + error_msgs.append(f"No borg_jobs defined for host {task_vars['ansible_host']} while it has a borg_server configured") + elif not isinstance(task_vars['borg_prune_arguments'], str): + error_msgs.append(f"The borg_prune_arguments variable must be of type string for host {task_vars['ansible_host']}") + + ### Results compilation ############################################## + if error_msgs != []: + result['msg'] = ' ; '.join(error_msgs) + result['failed'] = True + + return result -- cgit v1.2.3