Blame SOURCES/0004-Move-the-abstracted-plugin-runner-code-into-a-separa.patch

d4c6c5
From 952fc6f6dee99523360c9826ad865086cd31474f Mon Sep 17 00:00:00 2001
d4c6c5
From: Rob Crittenden <rcritten@redhat.com>
d4c6c5
Date: Mon, 18 Nov 2019 14:33:32 -0500
d4c6c5
Subject: [PATCH 4/5] Move the abstracted plugin runner code into a separate
d4c6c5
 file
d4c6c5
d4c6c5
This way main.py contains just the ipa-healthcheck main code
d4c6c5
and not the rest of the abstracted code.
d4c6c5
d4c6c5
Also replace sys.exit(1) with return 1.
d4c6c5
---
d4c6c5
 src/ipahealthcheck/core/core.py | 272 ++++++++++++++++++++++++++++++++
d4c6c5
 src/ipahealthcheck/core/main.py | 267 +------------------------------
d4c6c5
 2 files changed, 273 insertions(+), 266 deletions(-)
d4c6c5
 create mode 100644 src/ipahealthcheck/core/core.py
d4c6c5
d4c6c5
diff --git a/src/ipahealthcheck/core/core.py b/src/ipahealthcheck/core/core.py
d4c6c5
new file mode 100644
d4c6c5
index 0000000..182eac3
d4c6c5
--- /dev/null
d4c6c5
+++ b/src/ipahealthcheck/core/core.py
d4c6c5
@@ -0,0 +1,272 @@
d4c6c5
+#
d4c6c5
+# Copyright (C) 2019 FreeIPA Contributors see COPYING for license
d4c6c5
+#
d4c6c5
+
d4c6c5
+import argparse
d4c6c5
+import json
d4c6c5
+import logging
d4c6c5
+import pkg_resources
d4c6c5
+
d4c6c5
+from datetime import datetime
d4c6c5
+
d4c6c5
+from ipahealthcheck.core.config import read_config
d4c6c5
+from ipahealthcheck.core.plugin import Result, Results, json_to_results
d4c6c5
+from ipahealthcheck.core.output import output_registry
d4c6c5
+from ipahealthcheck.core import constants
d4c6c5
+from ipahealthcheck.core.service import ServiceCheck
d4c6c5
+
d4c6c5
+logging.basicConfig(format='%(message)s')
d4c6c5
+logger = logging.getLogger()
d4c6c5
+
d4c6c5
+
d4c6c5
+def find_registries(entry_points):
d4c6c5
+    registries = {}
d4c6c5
+    for entry_point in entry_points:
d4c6c5
+        registries.update({
d4c6c5
+            ep.name: ep.resolve()
d4c6c5
+            for ep in pkg_resources.iter_entry_points(entry_point)
d4c6c5
+        })
d4c6c5
+    return registries
d4c6c5
+
d4c6c5
+
d4c6c5
+def find_plugins(name, registry):
d4c6c5
+    for ep in pkg_resources.iter_entry_points(name):
d4c6c5
+        # load module
d4c6c5
+        ep.load()
d4c6c5
+    return registry.get_plugins()
d4c6c5
+
d4c6c5
+
d4c6c5
+def run_plugin(plugin, available=()):
d4c6c5
+    # manually calculate duration when we create results of our own
d4c6c5
+    start = datetime.utcnow()
d4c6c5
+    try:
d4c6c5
+        for result in plugin.check():
d4c6c5
+            if result is None:
d4c6c5
+                # Treat no result as success, fudge start time
d4c6c5
+                result = Result(plugin, constants.SUCCESS, start=start)
d4c6c5
+            yield result
d4c6c5
+    except Exception as e:
d4c6c5
+        logger.debug('Exception raised: %s', e)
d4c6c5
+        yield Result(plugin, constants.CRITICAL, exception=str(e),
d4c6c5
+                     start=start)
d4c6c5
+
d4c6c5
+
d4c6c5
+def source_or_check_matches(plugin, source, check):
d4c6c5
+    """Determine whether a given a plugin matches if a source
d4c6c5
+       and optional check are provided.
d4c6c5
+    """
d4c6c5
+    if source is not None and plugin.__module__ != source:
d4c6c5
+        return False
d4c6c5
+
d4c6c5
+    if check and plugin.__class__.__name__ != check:
d4c6c5
+        return False
d4c6c5
+
d4c6c5
+    return True
d4c6c5
+
d4c6c5
+
d4c6c5
+def run_service_plugins(plugins, config, source, check):
d4c6c5
+    """Execute plugins with the base class of ServiceCheck
d4c6c5
+
d4c6c5
+       This is a specialized check to use systemd to determine
d4c6c5
+       if a service is running or not.
d4c6c5
+    """
d4c6c5
+    results = Results()
d4c6c5
+    available = []
d4c6c5
+
d4c6c5
+    for plugin in plugins:
d4c6c5
+        if not isinstance(plugin, ServiceCheck):
d4c6c5
+            continue
d4c6c5
+
d4c6c5
+        logger.debug('Calling check %s', plugin)
d4c6c5
+        for result in plugin.check():
d4c6c5
+            # always run the service checks so dependencies work
d4c6c5
+            if result is not None and result.result == constants.SUCCESS:
d4c6c5
+                available.append(plugin.service.service_name)
d4c6c5
+            if not source_or_check_matches(plugin, source, check):
d4c6c5
+                continue
d4c6c5
+            if result is not None:
d4c6c5
+                results.add(result)
d4c6c5
+
d4c6c5
+    return results, set(available)
d4c6c5
+
d4c6c5
+
d4c6c5
+def run_plugins(plugins, config, available, source, check):
d4c6c5
+    """Execute plugins without the base class of ServiceCheck
d4c6c5
+
d4c6c5
+       These are the remaining, non-service checking checks
d4c6c5
+       that do validation for various parts of a system.
d4c6c5
+    """
d4c6c5
+    results = Results()
d4c6c5
+
d4c6c5
+    for plugin in plugins:
d4c6c5
+        if isinstance(plugin, ServiceCheck):
d4c6c5
+            continue
d4c6c5
+
d4c6c5
+        if not source_or_check_matches(plugin, source, check):
d4c6c5
+            continue
d4c6c5
+
d4c6c5
+        logger.debug('Calling check %s' % plugin)
d4c6c5
+        plugin.config = config
d4c6c5
+        if not set(plugin.requires).issubset(available):
d4c6c5
+            logger.debug('Skipping %s:%s because %s service(s) not running',
d4c6c5
+                         plugin.__class__.__module__,
d4c6c5
+                         plugin.__class__.__name__,
d4c6c5
+                         ', '.join(set(plugin.requires) - available))
d4c6c5
+            # Not providing a Result in this case because if a required
d4c6c5
+            # service isn't available then this could generate a lot of
d4c6c5
+            # false positives.
d4c6c5
+        else:
d4c6c5
+            for result in run_plugin(plugin, available):
d4c6c5
+                results.add(result)
d4c6c5
+
d4c6c5
+    return results
d4c6c5
+
d4c6c5
+
d4c6c5
+def list_sources(plugins):
d4c6c5
+    """Print list of all sources and checks"""
d4c6c5
+    source = None
d4c6c5
+    for plugin in plugins:
d4c6c5
+        if source != plugin.__class__.__module__:
d4c6c5
+            print(plugin.__class__.__module__)
d4c6c5
+            source = plugin.__class__.__module__
d4c6c5
+        print("  ", plugin.__class__.__name__)
d4c6c5
+
d4c6c5
+    return 0
d4c6c5
+
d4c6c5
+
d4c6c5
+def parse_options(output_registry):
d4c6c5
+    output_names = [plugin.__name__.lower() for
d4c6c5
+                    plugin in output_registry.plugins]
d4c6c5
+    parser = argparse.ArgumentParser()
d4c6c5
+    parser.add_argument('--debug', dest='debug', action='store_true',
d4c6c5
+                        default=False, help='Include debug output')
d4c6c5
+    parser.add_argument('--list-sources', dest='list_sources',
d4c6c5
+                        action='store_true', default=False,
d4c6c5
+                        help='List all available sources')
d4c6c5
+    parser.add_argument('--source', dest='source',
d4c6c5
+                        default=None,
d4c6c5
+                        help='Source of checks, e.g. ipahealthcheck.foo.bar')
d4c6c5
+    parser.add_argument('--check', dest='check',
d4c6c5
+                        default=None,
d4c6c5
+                        help='Check to execute, e.g. BazCheck')
d4c6c5
+    parser.add_argument('--output-type', dest='output', choices=output_names,
d4c6c5
+                        default='json', help='Output method')
d4c6c5
+    parser.add_argument('--output-file', dest='outfile', default=None,
d4c6c5
+                        help='File to store output')
d4c6c5
+    parser.add_argument('--input-file', dest='infile',
d4c6c5
+                        help='File to read as input')
d4c6c5
+    parser.add_argument('--failures-only', dest='failures_only',
d4c6c5
+                        action='store_true', default=False,
d4c6c5
+                        help='Exclude SUCCESS results on output')
d4c6c5
+    parser.add_argument('--severity', dest='severity', action="append",
d4c6c5
+                        help='Include only the selected severity(s)',
d4c6c5
+                        choices=[key for key in constants._nameToLevel])
d4c6c5
+    for plugin in output_registry.plugins:
d4c6c5
+        onelinedoc = plugin.__doc__.split('\n\n', 1)[0].strip()
d4c6c5
+        group = parser.add_argument_group(plugin.__name__.lower(),
d4c6c5
+                                          onelinedoc)
d4c6c5
+        for option in plugin.options:
d4c6c5
+            group.add_argument(option[0], **option[1])
d4c6c5
+
d4c6c5
+    options = parser.parse_args()
d4c6c5
+
d4c6c5
+    # Validation
d4c6c5
+    if options.check and not options.source:
d4c6c5
+        print("--source is required when --check is used")
d4c6c5
+        return 1
d4c6c5
+
d4c6c5
+    return options
d4c6c5
+
d4c6c5
+
d4c6c5
+def limit_results(results, source, check):
d4c6c5
+    """Return ony those results which match source and/or check"""
d4c6c5
+    new_results = Results()
d4c6c5
+    for result in results.results:
d4c6c5
+        if result.source == source:
d4c6c5
+            if check is None or result.check == check:
d4c6c5
+                new_results.add(result)
d4c6c5
+    return new_results
d4c6c5
+
d4c6c5
+
d4c6c5
+def run_healthcheck(entry_points, configfile):
d4c6c5
+    framework = object()
d4c6c5
+    plugins = []
d4c6c5
+    output = constants.DEFAULT_OUTPUT
d4c6c5
+
d4c6c5
+    logger.setLevel(logging.INFO)
d4c6c5
+
d4c6c5
+    options = parse_options(output_registry)
d4c6c5
+
d4c6c5
+    if options.debug:
d4c6c5
+        logger.setLevel(logging.DEBUG)
d4c6c5
+
d4c6c5
+    config = read_config(configfile)
d4c6c5
+    if config is None:
d4c6c5
+        return 1
d4c6c5
+
d4c6c5
+    for name, registry in find_registries(entry_points).items():
d4c6c5
+        try:
d4c6c5
+            registry.initialize(framework)
d4c6c5
+        except Exception as e:
d4c6c5
+            print("Unable to initialize %s: %s" % (name, e))
d4c6c5
+            return 1
d4c6c5
+        for plugin in find_plugins(name, registry):
d4c6c5
+            plugins.append(plugin)
d4c6c5
+
d4c6c5
+    for out in output_registry.plugins:
d4c6c5
+        if out.__name__.lower() == options.output:
d4c6c5
+            output = out(options)
d4c6c5
+
d4c6c5
+    if options.list_sources:
d4c6c5
+        return list_sources(plugins)
d4c6c5
+
d4c6c5
+    if options.infile:
d4c6c5
+        try:
d4c6c5
+            with open(options.infile, 'r') as f:
d4c6c5
+                raw_data = f.read()
d4c6c5
+
d4c6c5
+            json_data = json.loads(raw_data)
d4c6c5
+            results = json_to_results(json_data)
d4c6c5
+            available = ()
d4c6c5
+        except Exception as e:
d4c6c5
+            print("Unable to import '%s': %s" % (options.infile, e))
d4c6c5
+            return 1
d4c6c5
+        if options.source:
d4c6c5
+            results = limit_results(results, options.source, options.check)
d4c6c5
+    else:
d4c6c5
+        results, available = run_service_plugins(plugins, config,
d4c6c5
+                                                 options.source,
d4c6c5
+                                                 options.check)
d4c6c5
+        results.extend(run_plugins(plugins, config, available,
d4c6c5
+                                   options.source, options.check))
d4c6c5
+
d4c6c5
+    if options.source and len(results.results) == 0:
d4c6c5
+        for plugin in plugins:
d4c6c5
+            if not source_or_check_matches(plugin, options.source,
d4c6c5
+                                           options.check):
d4c6c5
+                continue
d4c6c5
+
d4c6c5
+            if not set(plugin.requires).issubset(available):
d4c6c5
+                print("Source '%s' is missing one or more requirements '%s'" %
d4c6c5
+                      (options.source, ', '.join(plugin.requires)))
d4c6c5
+                return 1
d4c6c5
+
d4c6c5
+        if options.check:
d4c6c5
+            print("Check '%s' not found in Source '%s'" %
d4c6c5
+                  (options.check, options.source))
d4c6c5
+        else:
d4c6c5
+            print("Source '%s' not found" % options.source)
d4c6c5
+        return 1
d4c6c5
+
d4c6c5
+    try:
d4c6c5
+        output.render(results)
d4c6c5
+    except Exception as e:
d4c6c5
+        logger.error('Output raised %s: %s', e.__class__.__name__, e)
d4c6c5
+
d4c6c5
+    return_value = 0
d4c6c5
+    for result in results.results:
d4c6c5
+        if result.result != constants.SUCCESS:
d4c6c5
+            return_value = 1
d4c6c5
+            break
d4c6c5
+
d4c6c5
+    return return_value
d4c6c5
diff --git a/src/ipahealthcheck/core/main.py b/src/ipahealthcheck/core/main.py
d4c6c5
index 2b818d4..d9e85d7 100644
d4c6c5
--- a/src/ipahealthcheck/core/main.py
d4c6c5
+++ b/src/ipahealthcheck/core/main.py
d4c6c5
@@ -2,276 +2,11 @@
d4c6c5
 # Copyright (C) 2019 FreeIPA Contributors see COPYING for license
d4c6c5
 #
d4c6c5
 
d4c6c5
-import argparse
d4c6c5
-import json
d4c6c5
-import logging
d4c6c5
 from os import environ
d4c6c5
-import pkg_resources
d4c6c5
 import sys
d4c6c5
 
d4c6c5
-from datetime import datetime
d4c6c5
-
d4c6c5
-from ipahealthcheck.core.config import read_config
d4c6c5
-from ipahealthcheck.core.plugin import Result, Results, json_to_results
d4c6c5
-from ipahealthcheck.core.output import output_registry
d4c6c5
 from ipahealthcheck.core import constants
d4c6c5
-from ipahealthcheck.core.service import ServiceCheck
d4c6c5
-
d4c6c5
-logging.basicConfig(format='%(message)s')
d4c6c5
-logger = logging.getLogger()
d4c6c5
-
d4c6c5
-
d4c6c5
-def find_registries(entry_points):
d4c6c5
-    registries = {}
d4c6c5
-    for entry_point in entry_points:
d4c6c5
-        registries.update({
d4c6c5
-            ep.name: ep.resolve()
d4c6c5
-            for ep in pkg_resources.iter_entry_points(entry_point)
d4c6c5
-        })
d4c6c5
-    return registries
d4c6c5
-
d4c6c5
-
d4c6c5
-def find_plugins(name, registry):
d4c6c5
-    for ep in pkg_resources.iter_entry_points(name):
d4c6c5
-        # load module
d4c6c5
-        ep.load()
d4c6c5
-    return registry.get_plugins()
d4c6c5
-
d4c6c5
-
d4c6c5
-def run_plugin(plugin, available=()):
d4c6c5
-    # manually calculate duration when we create results of our own
d4c6c5
-    start = datetime.utcnow()
d4c6c5
-    try:
d4c6c5
-        for result in plugin.check():
d4c6c5
-            if result is None:
d4c6c5
-                # Treat no result as success, fudge start time
d4c6c5
-                result = Result(plugin, constants.SUCCESS, start=start)
d4c6c5
-            yield result
d4c6c5
-    except Exception as e:
d4c6c5
-        logger.debug('Exception raised: %s', e)
d4c6c5
-        yield Result(plugin, constants.CRITICAL, exception=str(e),
d4c6c5
-                     start=start)
d4c6c5
-
d4c6c5
-
d4c6c5
-def source_or_check_matches(plugin, source, check):
d4c6c5
-    """Determine whether a given a plugin matches if a source
d4c6c5
-       and optional check are provided.
d4c6c5
-    """
d4c6c5
-    if source is not None and plugin.__module__ != source:
d4c6c5
-        return False
d4c6c5
-
d4c6c5
-    if check and plugin.__class__.__name__ != check:
d4c6c5
-        return False
d4c6c5
-
d4c6c5
-    return True
d4c6c5
-
d4c6c5
-
d4c6c5
-def run_service_plugins(plugins, config, source, check):
d4c6c5
-    """Execute plugins with the base class of ServiceCheck
d4c6c5
-
d4c6c5
-       This is a specialized check to use systemd to determine
d4c6c5
-       if a service is running or not.
d4c6c5
-    """
d4c6c5
-    results = Results()
d4c6c5
-    available = []
d4c6c5
-
d4c6c5
-    for plugin in plugins:
d4c6c5
-        if not isinstance(plugin, ServiceCheck):
d4c6c5
-            continue
d4c6c5
-
d4c6c5
-        logger.debug('Calling check %s', plugin)
d4c6c5
-        for result in plugin.check():
d4c6c5
-            # always run the service checks so dependencies work
d4c6c5
-            if result is not None and result.result == constants.SUCCESS:
d4c6c5
-                available.append(plugin.service.service_name)
d4c6c5
-            if not source_or_check_matches(plugin, source, check):
d4c6c5
-                continue
d4c6c5
-            if result is not None:
d4c6c5
-                results.add(result)
d4c6c5
-
d4c6c5
-    return results, set(available)
d4c6c5
-
d4c6c5
-
d4c6c5
-def run_plugins(plugins, config, available, source, check):
d4c6c5
-    """Execute plugins without the base class of ServiceCheck
d4c6c5
-
d4c6c5
-       These are the remaining, non-service checking checks
d4c6c5
-       that do validation for various parts of a system.
d4c6c5
-    """
d4c6c5
-    results = Results()
d4c6c5
-
d4c6c5
-    for plugin in plugins:
d4c6c5
-        if isinstance(plugin, ServiceCheck):
d4c6c5
-            continue
d4c6c5
-
d4c6c5
-        if not source_or_check_matches(plugin, source, check):
d4c6c5
-            continue
d4c6c5
-
d4c6c5
-        logger.debug('Calling check %s' % plugin)
d4c6c5
-        plugin.config = config
d4c6c5
-        if not set(plugin.requires).issubset(available):
d4c6c5
-            logger.debug('Skipping %s:%s because %s service(s) not running',
d4c6c5
-                         plugin.__class__.__module__,
d4c6c5
-                         plugin.__class__.__name__,
d4c6c5
-                         ', '.join(set(plugin.requires) - available))
d4c6c5
-            # Not providing a Result in this case because if a required
d4c6c5
-            # service isn't available then this could generate a lot of
d4c6c5
-            # false positives.
d4c6c5
-        else:
d4c6c5
-            for result in run_plugin(plugin, available):
d4c6c5
-                results.add(result)
d4c6c5
-
d4c6c5
-    return results
d4c6c5
-
d4c6c5
-
d4c6c5
-def list_sources(plugins):
d4c6c5
-    """Print list of all sources and checks"""
d4c6c5
-    source = None
d4c6c5
-    for plugin in plugins:
d4c6c5
-        if source != plugin.__class__.__module__:
d4c6c5
-            print(plugin.__class__.__module__)
d4c6c5
-            source = plugin.__class__.__module__
d4c6c5
-        print("  ", plugin.__class__.__name__)
d4c6c5
-
d4c6c5
-    return 0
d4c6c5
-
d4c6c5
-
d4c6c5
-def parse_options(output_registry):
d4c6c5
-    output_names = [plugin.__name__.lower() for
d4c6c5
-                    plugin in output_registry.plugins]
d4c6c5
-    parser = argparse.ArgumentParser()
d4c6c5
-    parser.add_argument('--debug', dest='debug', action='store_true',
d4c6c5
-                        default=False, help='Include debug output')
d4c6c5
-    parser.add_argument('--list-sources', dest='list_sources',
d4c6c5
-                        action='store_true', default=False,
d4c6c5
-                        help='List all available sources')
d4c6c5
-    parser.add_argument('--source', dest='source',
d4c6c5
-                        default=None,
d4c6c5
-                        help='Source of checks, e.g. ipahealthcheck.foo.bar')
d4c6c5
-    parser.add_argument('--check', dest='check',
d4c6c5
-                        default=None,
d4c6c5
-                        help='Check to execute, e.g. BazCheck')
d4c6c5
-    parser.add_argument('--output-type', dest='output', choices=output_names,
d4c6c5
-                        default='json', help='Output method')
d4c6c5
-    parser.add_argument('--output-file', dest='outfile', default=None,
d4c6c5
-                        help='File to store output')
d4c6c5
-    parser.add_argument('--input-file', dest='infile',
d4c6c5
-                        help='File to read as input')
d4c6c5
-    parser.add_argument('--failures-only', dest='failures_only',
d4c6c5
-                        action='store_true', default=False,
d4c6c5
-                        help='Exclude SUCCESS results on output')
d4c6c5
-    parser.add_argument('--severity', dest='severity', action="append",
d4c6c5
-                        help='Include only the selected severity(s)',
d4c6c5
-                        choices=[key for key in constants._nameToLevel])
d4c6c5
-    for plugin in output_registry.plugins:
d4c6c5
-        onelinedoc = plugin.__doc__.split('\n\n', 1)[0].strip()
d4c6c5
-        group = parser.add_argument_group(plugin.__name__.lower(),
d4c6c5
-                                          onelinedoc)
d4c6c5
-        for option in plugin.options:
d4c6c5
-            group.add_argument(option[0], **option[1])
d4c6c5
-
d4c6c5
-    options = parser.parse_args()
d4c6c5
-
d4c6c5
-    # Validation
d4c6c5
-    if options.check and not options.source:
d4c6c5
-        print("--source is required when --check is used")
d4c6c5
-        sys.exit(1)
d4c6c5
-
d4c6c5
-    return options
d4c6c5
-
d4c6c5
-
d4c6c5
-def limit_results(results, source, check):
d4c6c5
-    """Return ony those results which match source and/or check"""
d4c6c5
-    new_results = Results()
d4c6c5
-    for result in results.results:
d4c6c5
-        if result.source == source:
d4c6c5
-            if check is None or result.check == check:
d4c6c5
-                new_results.add(result)
d4c6c5
-    return new_results
d4c6c5
-
d4c6c5
-
d4c6c5
-def run_healthcheck(entry_points, configfile):
d4c6c5
-    framework = object()
d4c6c5
-    plugins = []
d4c6c5
-    output = constants.DEFAULT_OUTPUT
d4c6c5
-
d4c6c5
-    logger.setLevel(logging.INFO)
d4c6c5
-
d4c6c5
-    options = parse_options(output_registry)
d4c6c5
-
d4c6c5
-    if options.debug:
d4c6c5
-        logger.setLevel(logging.DEBUG)
d4c6c5
-
d4c6c5
-    config = read_config(configfile)
d4c6c5
-    if config is None:
d4c6c5
-        sys.exit(1)
d4c6c5
-
d4c6c5
-    for name, registry in find_registries(entry_points).items():
d4c6c5
-        try:
d4c6c5
-            registry.initialize(framework)
d4c6c5
-        except Exception as e:
d4c6c5
-            print("Unable to initialize %s: %s" % (name, e))
d4c6c5
-            sys.exit(1)
d4c6c5
-        for plugin in find_plugins(name, registry):
d4c6c5
-            plugins.append(plugin)
d4c6c5
-
d4c6c5
-    for out in output_registry.plugins:
d4c6c5
-        if out.__name__.lower() == options.output:
d4c6c5
-            output = out(options)
d4c6c5
-
d4c6c5
-    if options.list_sources:
d4c6c5
-        return list_sources(plugins)
d4c6c5
-
d4c6c5
-    if options.infile:
d4c6c5
-        try:
d4c6c5
-            with open(options.infile, 'r') as f:
d4c6c5
-                raw_data = f.read()
d4c6c5
-
d4c6c5
-            json_data = json.loads(raw_data)
d4c6c5
-            results = json_to_results(json_data)
d4c6c5
-            available = ()
d4c6c5
-        except Exception as e:
d4c6c5
-            print("Unable to import '%s': %s" % (options.infile, e))
d4c6c5
-            sys.exit(1)
d4c6c5
-        if options.source:
d4c6c5
-            results = limit_results(results, options.source, options.check)
d4c6c5
-    else:
d4c6c5
-        results, available = run_service_plugins(plugins, config,
d4c6c5
-                                                 options.source,
d4c6c5
-                                                 options.check)
d4c6c5
-        results.extend(run_plugins(plugins, config, available,
d4c6c5
-                                   options.source, options.check))
d4c6c5
-
d4c6c5
-    if options.source and len(results.results) == 0:
d4c6c5
-        for plugin in plugins:
d4c6c5
-            if not source_or_check_matches(plugin, options.source,
d4c6c5
-                                           options.check):
d4c6c5
-                continue
d4c6c5
-
d4c6c5
-            if not set(plugin.requires).issubset(available):
d4c6c5
-                print("Source '%s' is missing one or more requirements '%s'" %
d4c6c5
-                      (options.source, ', '.join(plugin.requires)))
d4c6c5
-                sys.exit(1)
d4c6c5
-
d4c6c5
-        if options.check:
d4c6c5
-            print("Check '%s' not found in Source '%s'" %
d4c6c5
-                  (options.check, options.source))
d4c6c5
-        else:
d4c6c5
-            print("Source '%s' not found" % options.source)
d4c6c5
-        sys.exit(1)
d4c6c5
-
d4c6c5
-    try:
d4c6c5
-        output.render(results)
d4c6c5
-    except Exception as e:
d4c6c5
-        logger.error('Output raised %s: %s', e.__class__.__name__, e)
d4c6c5
-
d4c6c5
-    return_value = 0
d4c6c5
-    for result in results.results:
d4c6c5
-        if result.result != constants.SUCCESS:
d4c6c5
-            return_value = 1
d4c6c5
-            break
d4c6c5
-
d4c6c5
-    return return_value
d4c6c5
+from ipahealthcheck.core.core import run_healthcheck
d4c6c5
 
d4c6c5
 
d4c6c5
 def main():
d4c6c5
-- 
d4c6c5
2.20.1
d4c6c5