logging.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. """
  2. Util functions for performing checks on an Elasticsearch, Fluentd, and Kibana stack
  3. """
  4. import json
  5. import os
  6. from openshift_checks import OpenShiftCheck, OpenShiftCheckException
  7. class LoggingCheck(OpenShiftCheck):
  8. """Base class for OpenShift aggregated logging component checks"""
  9. name = "logging"
  10. logging_namespace = "logging"
  11. def is_active(self):
  12. logging_deployed = self.get_var("openshift_hosted_logging_deploy", default=False)
  13. return logging_deployed and super(LoggingCheck, self).is_active() and self.is_first_master()
  14. def is_first_master(self):
  15. """Determine if running on first master. Returns: bool"""
  16. # Note: It would be nice to use membership in oo_first_master group, however for now it
  17. # seems best to avoid requiring that setup and just check this is the first master.
  18. hostname = self.get_var("ansible_ssh_host") or [None]
  19. masters = self.get_var("groups", "masters", default=None) or [None]
  20. return masters[0] == hostname
  21. def run(self):
  22. pass
  23. def get_pods_for_component(self, namespace, logging_component):
  24. """Get all pods for a given component. Returns: list of pods for component, error string"""
  25. pod_output = self.exec_oc(
  26. namespace,
  27. "get pods -l component={} -o json".format(logging_component),
  28. [],
  29. )
  30. try:
  31. pods = json.loads(pod_output)
  32. if not pods or not pods.get('items'):
  33. raise ValueError()
  34. except ValueError:
  35. # successful run but non-parsing data generally means there were no pods in the namespace
  36. return None, 'No pods were found for the "{}" logging component.'.format(logging_component)
  37. return pods['items'], None
  38. @staticmethod
  39. def not_running_pods(pods):
  40. """Returns: list of pods not in a ready and running state"""
  41. return [
  42. pod for pod in pods
  43. if not pod.get("status", {}).get("containerStatuses") or any(
  44. container['ready'] is False
  45. for container in pod['status']['containerStatuses']
  46. ) or not any(
  47. condition['type'] == 'Ready' and condition['status'] == 'True'
  48. for condition in pod['status'].get('conditions', [])
  49. )
  50. ]
  51. def exec_oc(self, namespace="logging", cmd_str="", extra_args=None):
  52. """
  53. Execute an 'oc' command in the remote host.
  54. Returns: output of command and namespace,
  55. or raises OpenShiftCheckException on error
  56. """
  57. config_base = self.get_var("openshift", "common", "config_base")
  58. args = {
  59. "namespace": namespace,
  60. "config_file": os.path.join(config_base, "master", "admin.kubeconfig"),
  61. "cmd": cmd_str,
  62. "extra_args": list(extra_args) if extra_args else [],
  63. }
  64. result = self.execute_module("ocutil", args)
  65. if result.get("failed"):
  66. msg = (
  67. 'Unexpected error using `oc` to validate the logging stack components.\n'
  68. 'Error executing `oc {cmd}`:\n'
  69. '{error}'
  70. ).format(cmd=args['cmd'], error=result['result'])
  71. if result['result'] == '[Errno 2] No such file or directory':
  72. msg = (
  73. "This host is supposed to be a master but does not have the `oc` command where expected.\n"
  74. "Has an installation been run on this host yet?"
  75. )
  76. raise OpenShiftCheckException(msg)
  77. return result.get("result", "")