#!/usr/bin/python

from __future__ import print_function
import subprocess
import sys
import json
import os
import time

class CheckSaltMaster:
    def __init__(self):
        self.event_minions = "/var/lib/salt-event-monitor/minions"

    def callShell(self, cmdline):
        cmd = subprocess.Popen(cmdline, shell=True,
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        res = cmd.communicate()
        if cmd.returncode != 0:
            print("CRITICAL: error: {0}".format(res[0].strip()))
            sys.exit(2)
        return res[0].strip()

    def getRegisteredMinions(self):
        minions = {}
        res = self.callShell("/usr/bin/salt-key --list=accepted | tail -n +2")
        minions['accepted'] = res.split()
        res = self.callShell("/usr/bin/salt-key --list=unaccepted | tail -n +2")
        minions['unaccepted'] = res.split()
        return minions

    def fetchReturn(self, minion):
        filename = '{0}/{1}.json'.format(self.event_minions, minion)
        if not os.path.isfile(filename):
            return None
        with open(filename, 'r') as fh:
            data = json.load(fh)
        return data

    def check(self):
        outdated = 0
        failed = 0
        failed_states = 0
        succeeded = 0
        succeeded_states = 0
        changes = 0
        minions = self.getRegisteredMinions()
        for minion in minions['accepted']:
            res = self.fetchReturn(minion)
            if not res:
                outdated += 1
                continue
            if time.time() - res['starttime'] > (60*60*5):
                outdated += 1
                continue
            succeeded_states += res['succeeded']
            failed_states += res['failed']
            changes += res['changes']
            if res['failed'] > 0:
                failed += 1
            else:
                succeeded += 1

        minionstats = 'minions: failed={0}, succeeded={1}, outdated={2}'.format(
            failed, succeeded, outdated)
        statestats = 'states: failed={0}, succeeded={1}, changed={2}'.format(
            failed_states, succeeded_states, changes)
        if failed > 0 or outdated > 0:
            print('CRITICAL: {0} / {1}'.format(minionstats, statestats))
            sys.exit(2)
        else:
            print('OK: {0} / {1}'.format(minionstats, statestats))
            sys.exit(0)

csm = CheckSaltMaster()
csm.check()

