HEX
Server: Apache
System: Linux msm5694.mjhst.com 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64
User: camjab_ssh (1000)
PHP: 5.3.29
Disabled: NONE
Upload Files
File: //lib64/nagios/plugins/check_uptrack_local
#!/usr/bin/python2
# Ksplice Uptrack local Nagios plugin
#
# Copyright (C) 2010-2012 Oracle and/or its affiliates. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function
import optparse
import os
import sys
import time
import yaml
try:
    from yaml import CSafeLoader as yaml_loader
except ImportError:
    from yaml import SafeLoader as yaml_loader

NAGIOS_OK = 0
NAGIOS_WARNING = 1
NAGIOS_CRITICAL = 2
NAGIOS_UNKNOWN = 3

INACTIVE_THRESHOLD = 12 * 60 * 60  # 12 hours, in seconds


def exit_nagios(status, text, perf=None, longtext=None, longperf=None):
    sys.stdout.write(text)
    if perf:
        sys.stdout.write("|" + perf)
    print()
    if longtext:
        sys.stdout.write(longtext)
    if longperf:
        sys.stdout.write("|" + longperf)
    if longtext or longperf:
        print()
    sys.exit(status)


try:
    import Uptrack
except ImportError as e:
    exit_nagios(NAGIOS_UNKNOWN, "Import error", longtext=str(e))


def parse_states(spec):
    out = []
    mapping = dict(o='outofdate', u='unsupported', i='inactive')
    for s in spec.split(","):
        if s in mapping:
            out.append(mapping[s])
    return out


def last_checkin(results):
    """ Returns the last checkin time in UTC epoch seconds.
    """
    return time.mktime(results["Time"].timetuple())


def my_upgrade_plan(upgrade_plan):
    steps = upgrade_plan["Plan"]
    steps_str = "No updates to install or remove."
    out_of_date = False
    if len(steps) > 0:
        out_of_date = True
        steps_str = "Steps for upgrade:\n  * " + \
            "\n  * ".join(["%s %s (%s)"
                           % (update_info['Command'], update_info['ID'], update_info['Name'])
                           for update_info in steps])
    return out_of_date, steps_str


def unsupported(results):
    return results["Result"]["Code"] == Uptrack.ERROR_UNSUPPORTED


def results_message(results):
    return results["Result"]["Message"]


def get_host(results):
    return results["Client"]["Hostname"]


def get_ip(results):
    """
    The results file may have a 'LocalIP_error' instead of a LocalIP.
    """
    try:
        return results["Client"]["LocalIP"]
    except KeyError:
        return "unknown IP"


def get_uuid():
    try:
        return open(Uptrack.UPTRACK_UUID_FILE).read().strip()
    except Exception:
        return "unknown UUID"


def main():
    parser = optparse.OptionParser("""Usage: %prog [options]""")

    specs = optparse.OptionGroup(
        parser,
        "Nagios State specification",
        "These options select under which circumstances the plugin "
        "will return which Nagios state. Each option should be a "
        "comma-separated string containing zero or more of the "
        "choices 'o', 'u', and 'i', for out of date, unsupported, "
        "and inactive machines, respectively.")

    specs.add_option("-w", "--warning",
                     type="string",
                     action="store",
                     dest="warning",
                     default="",
                     help="Machine states to trigger a WARNING state.")
    specs.add_option("-c", "--critical",
                     type="string",
                     action="store",
                     dest="critical",
                     default="",
                     help="Machine states to trigger a CRITICAL state.")
    parser.add_option_group(specs)

    (opts, unused_args) = parser.parse_args()

    if not opts.critical and not opts.warning:
        # If no options are specified, default to a CRITICAL status for out of
        # date machines and a WARNING status for inactive machines.
        opts.critical = 'o'
        opts.warning = 'i'

    states = dict()

    sysname, unused_hostname, release, version, arch, unused_userarch = Uptrack.getUname()
    path = os.path.join(Uptrack.UPTRACK_CACHE_DIR, sysname, arch, release, version)

    try:
        results = yaml.load(open(os.path.join(path, "results"), 'r').read(),
                            Loader=yaml_loader)
    except Exception as e:
        longtext = "\n".join(
            [str(e),
             "",
             "It looks like the Uptrack client has never been run on this system.",
             "Please run 'uptrack-upgrade -n' to update the list of available updates.",
             "For assistance, please contact ksplice-support_ww@oracle.com."]
        )
        exit_nagios(NAGIOS_UNKNOWN, "%s is UNKNOWN" % (get_uuid(),),
                    longtext=longtext)

    out_of_date = False
    try:
        upgrade_plan = yaml.load(open(os.path.join(path, "upgrade_plan"), 'r').read(),
                                 Loader=yaml_loader)
        # Am I out of date?
        out_of_date, plan = my_upgrade_plan(upgrade_plan)
    except Exception:
        # Unsupported kernels and trying to upgrade with an invalid access key
        # are some of the ways to have a results file but no upgrade plan.
        plan = results_message(results)

    if out_of_date:
        states["outofdate"] = True

    # Am I unsupported?
    if unsupported(results):
        states["unsupported"] = True

    # Am I inactive?
    if time.time() - last_checkin(results) > INACTIVE_THRESHOLD:
        states["inactive"] = True

    # Summarize all issues in the perfdata
    perfdata = ";".join([state for (state, val) in states.items() if val])

    for (rv, spec) in [(NAGIOS_CRITICAL, opts.critical),
                       (NAGIOS_WARNING, opts.warning)]:
        for state in parse_states(spec):
            if states.get(state):
                exit_nagios(rv,
                            "%s (%s) is %s" % (get_host(results), get_ip(results), state.upper()),
                            perf=perfdata, longtext=plan)

    exit_nagios(NAGIOS_OK, "%s (%s) is OK" % (get_host(results), get_ip(results)),
                perf=perfdata)


if __name__ == '__main__':
    sys.exit(main())