summaryrefslogtreecommitdiffstats
path: root/roles/openshift_health_checker/action_plugins/openshift_health_check.py
diff options
context:
space:
mode:
Diffstat (limited to 'roles/openshift_health_checker/action_plugins/openshift_health_check.py')
-rw-r--r--roles/openshift_health_checker/action_plugins/openshift_health_check.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/roles/openshift_health_checker/action_plugins/openshift_health_check.py b/roles/openshift_health_checker/action_plugins/openshift_health_check.py
new file mode 100644
index 000000000..0411797b1
--- /dev/null
+++ b/roles/openshift_health_checker/action_plugins/openshift_health_check.py
@@ -0,0 +1,116 @@
+"""
+Ansible action plugin to execute health checks in OpenShift clusters.
+"""
+# pylint: disable=wrong-import-position,missing-docstring,invalid-name
+import sys
+import os
+
+try:
+ from __main__ import display
+except ImportError:
+ from ansible.utils.display import Display
+ display = Display()
+
+from ansible.plugins.action import ActionBase
+
+# Augment sys.path so that we can import checks from a directory relative to
+# this callback plugin.
+sys.path.insert(1, os.path.dirname(os.path.dirname(__file__)))
+
+from openshift_checks import OpenShiftCheck, OpenShiftCheckException # noqa: E402
+
+
+class ActionModule(ActionBase):
+
+ def run(self, tmp=None, task_vars=None):
+ result = super(ActionModule, self).run(tmp, task_vars)
+
+ if task_vars is None:
+ task_vars = {}
+
+ if "openshift" not in task_vars:
+ result["failed"] = True
+ result["msg"] = "'openshift' is undefined, did 'openshift_facts' run?"
+ return result
+
+ try:
+ known_checks = self.load_known_checks()
+ except OpenShiftCheckException as e:
+ result["failed"] = True
+ result["msg"] = str(e)
+ return result
+
+ args = self._task.args
+ requested_checks = resolve_checks(args.get("checks", []), known_checks.values())
+
+ unknown_checks = requested_checks - set(known_checks)
+ if unknown_checks:
+ result["failed"] = True
+ result["msg"] = (
+ "One or more checks are unknown: {}. "
+ "Make sure there is no typo in the playbook and no files are missing."
+ ).format(", ".join(unknown_checks))
+ return result
+
+ result["checks"] = check_results = {}
+
+ for check_name in requested_checks & set(known_checks):
+ display.banner("CHECK [{} : {}]".format(check_name, task_vars["ansible_host"]))
+ check = known_checks[check_name]
+
+ if check.is_active(task_vars):
+ try:
+ r = check.run(tmp, task_vars)
+ except OpenShiftCheckException as e:
+ r = {}
+ r["failed"] = True
+ r["msg"] = str(e)
+ else:
+ r = {"skipped": True}
+
+ check_results[check_name] = r
+
+ if r.get("failed", False):
+ result["failed"] = True
+ result["msg"] = "One or more checks failed"
+
+ return result
+
+ def load_known_checks(self):
+ known_checks = {}
+
+ known_check_classes = set(cls for cls in OpenShiftCheck.subclasses())
+
+ for cls in known_check_classes:
+ check_name = cls.name
+ if check_name in known_checks:
+ other_cls = known_checks[check_name].__class__
+ raise OpenShiftCheckException(
+ "non-unique check name '{}' in: '{}.{}' and '{}.{}'".format(
+ check_name,
+ cls.__module__, cls.__name__,
+ other_cls.__module__, other_cls.__name__))
+ known_checks[check_name] = cls(module_executor=self._execute_module)
+
+ return known_checks
+
+
+def resolve_checks(names, all_checks):
+ """Returns a set of resolved check names.
+
+ Resolving a check name involves expanding tag references (e.g., '@tag') with
+ all the checks that contain the given tag.
+
+ names should be a sequence of strings.
+
+ all_checks should be a sequence of check classes/instances.
+ """
+ resolved = set()
+ for name in names:
+ if name.startswith("@"):
+ for check in all_checks:
+ if name[1:] in check.tags:
+ resolved.add(check.name)
+ else:
+ resolved.add(name)
+ return resolved