diff options
author | Scott Dodson <sdodson@redhat.com> | 2017-02-13 09:28:27 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-13 09:28:27 -0500 |
commit | db243097dabeaf8d3c5c906dd819e2f43fec891a (patch) | |
tree | e53937a8accdef9e13c5b0466ea1d195eab16d4f /roles/openshift_health_checker/openshift_checks | |
parent | 3921f01be97ccfbb54e11666ce3647774c3fdbb9 (diff) | |
parent | c24b9acb9d04f9613dcc7423791d09f83ef03670 (diff) | |
download | openshift-db243097dabeaf8d3c5c906dd819e2f43fec891a.tar.gz openshift-db243097dabeaf8d3c5c906dd819e2f43fec891a.tar.bz2 openshift-db243097dabeaf8d3c5c906dd819e2f43fec891a.tar.xz openshift-db243097dabeaf8d3c5c906dd819e2f43fec891a.zip |
Merge pull request #3234 from rhcarvalho/check-module
Replace multi-role checks with action-plugin-based checks
Diffstat (limited to 'roles/openshift_health_checker/openshift_checks')
5 files changed, 205 insertions, 0 deletions
diff --git a/roles/openshift_health_checker/openshift_checks/__init__.py b/roles/openshift_health_checker/openshift_checks/__init__.py new file mode 100644 index 000000000..c31242624 --- /dev/null +++ b/roles/openshift_health_checker/openshift_checks/__init__.py @@ -0,0 +1,84 @@ +""" +Health checks for OpenShift clusters. +""" + +import os +from abc import ABCMeta, abstractmethod, abstractproperty +from importlib import import_module +import operator + +import six +from six.moves import reduce + + +class OpenShiftCheckException(Exception): + """Raised when a check cannot proceed.""" + pass + + +@six.add_metaclass(ABCMeta) +class OpenShiftCheck(object): + """A base class for defining checks for an OpenShift cluster environment.""" + + def __init__(self, module_executor): + self.module_executor = module_executor + + @abstractproperty + def name(self): + """The name of this check, usually derived from the class name.""" + return "openshift_check" + + @property + def tags(self): + """A list of tags that this check satisfy. + + Tags are used to reference multiple checks with a single '@tagname' + special check name. + """ + return [] + + @classmethod + def is_active(cls, task_vars): # pylint: disable=unused-argument + """Returns true if this check applies to the ansible-playbook run.""" + return True + + @abstractmethod + def run(self, tmp, task_vars): + """Executes a check, normally implemented as a module.""" + return {} + + @classmethod + def subclasses(cls): + """Returns a generator of subclasses of this class and its subclasses.""" + for subclass in cls.__subclasses__(): # pylint: disable=no-member + yield subclass + for subclass in subclass.subclasses(): + yield subclass + + +def get_var(task_vars, *keys, **kwargs): + """Helper function to get deeply nested values from task_vars. + + Ansible task_vars structures are Python dicts, often mapping strings to + other dicts. This helper makes it easier to get a nested value, raising + OpenShiftCheckException when a key is not found. + """ + try: + value = reduce(operator.getitem, keys, task_vars) + except (KeyError, TypeError): + if "default" in kwargs: + return kwargs["default"] + raise OpenShiftCheckException("'{}' is undefined".format(".".join(map(str, keys)))) + return value + + +# Dynamically import all submodules for the side effect of loading checks. + +EXCLUDES = ( + "__init__.py", + "mixins.py", +) + +for name in os.listdir(os.path.dirname(__file__)): + if name.endswith(".py") and name not in EXCLUDES: + import_module(__package__ + "." + name[:-3]) diff --git a/roles/openshift_health_checker/openshift_checks/mixins.py b/roles/openshift_health_checker/openshift_checks/mixins.py new file mode 100644 index 000000000..4029fba62 --- /dev/null +++ b/roles/openshift_health_checker/openshift_checks/mixins.py @@ -0,0 +1,21 @@ +# pylint: disable=missing-docstring +from openshift_checks import get_var + + +class NotContainerized(object): + """Mixin for checks that are only active when not in containerized mode.""" + + @classmethod + def is_active(cls, task_vars): + return ( + # This mixin is meant to be used with subclasses of + # OpenShiftCheck. Pylint disables this by default on mixins, + # though it relies on the class name ending in 'mixin'. + # pylint: disable=no-member + super(NotContainerized, cls).is_active(task_vars) and + not cls.is_containerized(task_vars) + ) + + @staticmethod + def is_containerized(task_vars): + return get_var(task_vars, "openshift", "common", "is_containerized") diff --git a/roles/openshift_health_checker/openshift_checks/package_availability.py b/roles/openshift_health_checker/openshift_checks/package_availability.py new file mode 100644 index 000000000..8faeef5ee --- /dev/null +++ b/roles/openshift_health_checker/openshift_checks/package_availability.py @@ -0,0 +1,66 @@ +# pylint: disable=missing-docstring +from openshift_checks import OpenShiftCheck, get_var +from openshift_checks.mixins import NotContainerized + + +class PackageAvailability(NotContainerized, OpenShiftCheck): + """Check that required RPM packages are available.""" + + name = "package_availability" + tags = ["preflight"] + + def run(self, tmp, task_vars): + rpm_prefix = get_var(task_vars, "openshift", "common", "service_type") + group_names = get_var(task_vars, "group_names", default=[]) + + packages = set() + + if "masters" in group_names: + packages.update(self.master_packages(rpm_prefix)) + if "nodes" in group_names: + packages.update(self.node_packages(rpm_prefix)) + + args = {"packages": sorted(set(packages))} + return self.module_executor("check_yum_update", args, tmp, task_vars) + + @staticmethod + def master_packages(rpm_prefix): + return [ + "{rpm_prefix}".format(rpm_prefix=rpm_prefix), + "{rpm_prefix}-clients".format(rpm_prefix=rpm_prefix), + "{rpm_prefix}-master".format(rpm_prefix=rpm_prefix), + "bash-completion", + "cockpit-bridge", + "cockpit-docker", + "cockpit-kubernetes", + "cockpit-shell", + "cockpit-ws", + "etcd", + "httpd-tools", + ] + + @staticmethod + def node_packages(rpm_prefix): + return [ + "{rpm_prefix}".format(rpm_prefix=rpm_prefix), + "{rpm_prefix}-node".format(rpm_prefix=rpm_prefix), + "{rpm_prefix}-sdn-ovs".format(rpm_prefix=rpm_prefix), + "bind", + "ceph-common", + "dnsmasq", + "docker", + "firewalld", + "flannel", + "glusterfs-fuse", + "iptables-services", + "iptables", + "iscsi-initiator-utils", + "libselinux-python", + "nfs-utils", + "ntp", + "openssl", + "pyparted", + "python-httplib2", + "PyYAML", + "yum-utils", + ] diff --git a/roles/openshift_health_checker/openshift_checks/package_update.py b/roles/openshift_health_checker/openshift_checks/package_update.py new file mode 100644 index 000000000..86b7b6245 --- /dev/null +++ b/roles/openshift_health_checker/openshift_checks/package_update.py @@ -0,0 +1,14 @@ +# pylint: disable=missing-docstring +from openshift_checks import OpenShiftCheck +from openshift_checks.mixins import NotContainerized + + +class PackageUpdate(NotContainerized, OpenShiftCheck): + """Check that there are no conflicts in RPM packages.""" + + name = "package_update" + tags = ["preflight"] + + def run(self, tmp, task_vars): + args = {"packages": []} + return self.module_executor("check_yum_update", args, tmp, task_vars) diff --git a/roles/openshift_health_checker/openshift_checks/package_version.py b/roles/openshift_health_checker/openshift_checks/package_version.py new file mode 100644 index 000000000..7fa09cbfd --- /dev/null +++ b/roles/openshift_health_checker/openshift_checks/package_version.py @@ -0,0 +1,20 @@ +# pylint: disable=missing-docstring +from openshift_checks import OpenShiftCheck, get_var +from openshift_checks.mixins import NotContainerized + + +class PackageVersion(NotContainerized, OpenShiftCheck): + """Check that available RPM packages match the required versions.""" + + name = "package_version" + tags = ["preflight"] + + def run(self, tmp, task_vars): + rpm_prefix = get_var(task_vars, "openshift", "common", "service_type") + openshift_release = get_var(task_vars, "openshift_release") + + args = { + "prefix": rpm_prefix, + "version": openshift_release, + } + return self.module_executor("aos_version", args, tmp, task_vars) |