__init__.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. """
  2. Health checks for OpenShift clusters.
  3. """
  4. import os
  5. from abc import ABCMeta, abstractmethod, abstractproperty
  6. from importlib import import_module
  7. import operator
  8. import six
  9. from six.moves import reduce
  10. class OpenShiftCheckException(Exception):
  11. """Raised when a check cannot proceed."""
  12. pass
  13. @six.add_metaclass(ABCMeta)
  14. class OpenShiftCheck(object):
  15. """A base class for defining checks for an OpenShift cluster environment."""
  16. def __init__(self, module_executor):
  17. self.module_executor = module_executor
  18. @abstractproperty
  19. def name(self):
  20. """The name of this check, usually derived from the class name."""
  21. return "openshift_check"
  22. @property
  23. def tags(self):
  24. """A list of tags that this check satisfy.
  25. Tags are used to reference multiple checks with a single '@tagname'
  26. special check name.
  27. """
  28. return []
  29. @classmethod
  30. def is_active(cls, task_vars): # pylint: disable=unused-argument
  31. """Returns true if this check applies to the ansible-playbook run."""
  32. return True
  33. @abstractmethod
  34. def run(self, tmp, task_vars):
  35. """Executes a check, normally implemented as a module."""
  36. return {}
  37. @classmethod
  38. def subclasses(cls):
  39. """Returns a generator of subclasses of this class and its subclasses."""
  40. for subclass in cls.__subclasses__(): # pylint: disable=no-member
  41. yield subclass
  42. for subclass in subclass.subclasses():
  43. yield subclass
  44. def get_var(task_vars, *keys, **kwargs):
  45. """Helper function to get deeply nested values from task_vars.
  46. Ansible task_vars structures are Python dicts, often mapping strings to
  47. other dicts. This helper makes it easier to get a nested value, raising
  48. OpenShiftCheckException when a key is not found.
  49. """
  50. try:
  51. value = reduce(operator.getitem, keys, task_vars)
  52. except (KeyError, TypeError):
  53. if "default" in kwargs:
  54. return kwargs["default"]
  55. raise OpenShiftCheckException("'{}' is undefined".format(".".join(map(str, keys))))
  56. return value
  57. # Dynamically import all submodules for the side effect of loading checks.
  58. EXCLUDES = (
  59. "__init__.py",
  60. "mixins.py",
  61. )
  62. for name in os.listdir(os.path.dirname(__file__)):
  63. if name.endswith(".py") and name not in EXCLUDES:
  64. import_module(__package__ + "." + name[:-3])