예제 #1
0
def not_reporting_filter(issue):
    db = get_db()
    peers = get_client_parameter(issue['hostname'], 'user_clients')
    if not peers:
        return False
    # Completely arbitrary: Even peered clients need to check in at least once
    # per month.
    if db.clients.find_one({'hostname': issue['hostname']})['submitted_at'] < \
       now - datetime.timedelta(days=31):
        return False
    peer_times = [d['submitted_at'] for d in
                  db.clients.find({'hostname': {'$in': peers}},
                                  projection=['submitted_at'])]
    cutoff = problem_checks()['not-reporting']['spec']['submitted_at']['$lt']
    return any(t >= cutoff for t in peer_times)
예제 #2
0
def set_handler(args):
    old_value = get_client_parameter(args.hostname, args.parameter)

    try:
        old = set_client_parameter(args.hostname, args.parameter, args.value)
    except Exception as e:
        sys.exit('Failed to set parameter: {}'.format(e))

    if not old_value:
        with logbook.StreamHandler(sys.stdout, bubble=True):
            log.info('Set parameter {} for host {} to {}', args.parameter,
                     args.hostname, args.value)
    elif old:
        with logbook.StreamHandler(sys.stdout, bubble=True):
            log.info('Changed parameter {} for host {} from {} to {}',
                     args.parameter, args.hostname, old, args.value)
    else:
        print('No changes.')
예제 #3
0
def audit_handler(args):
    def d(dt):
        return dt.strftime('%m/%d %H:%M')

    in_a_terminal = os.isatty(sys.stderr.fileno())
    if args.update_recent is None:
        args.update_recent = not in_a_terminal
    if args.display_recent is None:
        args.display_recent = in_a_terminal

    if args.full:
        args.ignore_grace_period = args.display_recent = \
            args.ignore_snoozed = args.ignore_filters = True

    db = get_db()

    for check_name, check in problem_checks().items():
        if 'spec' not in check:
            continue
        problems = [d for d in db.clients.find(check['spec'])]
        for problem in problems:
            if open_issue(problem['hostname'],
                          check_name,
                          as_of=problem['plugins']['submitted_at']):
                log.info('Opened {} issue for {} as of {}', check_name,
                         problem['hostname'],
                         problem['plugins']['submitted_at'])
        problem_hosts = [d['hostname'] for d in problems]
        for doc in close_issue({'$not': {'$in': problem_hosts}}, check_name):
            log.info('Closed {} issue for {}', check_name, doc['hostname'])

    check_pending_patches()
    check_ssl_certificates()

    issues = get_open_issues(include_suspended=args.ignore_suspended)

    default_alert_frequency = datetime.timedelta(hours=1)

    for key1, value1 in issues.items():
        key1_printed = False
        email_list = ''
        for key2, issue in value1.items():
            check = problem_checks().get(issue['name']) or {}
            filter = None if args.ignore_filters else check.get('filter', None)
            alert_frequency = check.get('alert-frequency',
                                        default_alert_frequency)
            # Not exactly on the hour, to avoid race conditions when running
            # hourly.
            if 0 == alert_frequency.total_seconds() % 3600:
                alert_frequency -= datetime.timedelta(minutes=1)
            alert_threshold = now - alert_frequency
            grace_period = check.get('grace-period', datetime.timedelta(0))
            filter_ok = not (filter and filter(issue))
            alert_ok = (args.display_recent or 'alerted_at' not in issue
                        or issue['alerted_at'] < alert_threshold)
            grace_ok = (args.ignore_grace_period or
                        business_hours(issue['opened_at'], now) > grace_period)
            snooze_ok = (args.ignore_snoozed or 'unsnooze_at' not in issue
                         or issue['unsnooze_at'] < now)
            if issue.get('unsnooze_at', now) > now:
                snoozed = ' [snoozed until {}]'.format(d(issue['unsnooze_at']))
            else:
                snoozed = ''
            client = db.clients.find_one({'hostname': key1},
                                         projection=['submitted_at'])
            if filter_ok and alert_ok and grace_ok and snooze_ok:
                if not key1_printed:
                    if client:
                        last_reported = d(client['submitted_at'])
                        print('{} [last reported at {}]'.format(
                            key1, last_reported))
                    else:
                        # This is a global issue, not a per-client issue
                        print(key1)
                    key1_printed = True
                print('  {} since {}{}'.format(key2, d(issue['opened_at']),
                                               snoozed))
                email_list += '{} since {}\n'.format(key2,
                                                     d(issue['opened_at']))
                if not in_a_terminal:
                    log.warn('{} {} since {}', key1, key2, issue['opened_at'])
                if args.update_recent:
                    db.issues.update({'_id': issue['_id']},
                                     {'$set': {
                                         'alerted_at': now
                                     }})
        if client and args.email and email_list:
            email = get_client_parameter(key1, 'user_email')
            if not email:
                log.warn("Can't send email for {} since user_email not set",
                         key1)
                continue
            subject = 'Please address issues on {}'.format(key1)
            body = dedent("""\
                The following issues have been identified on the PenguinDome
                (device management) client "{}", for which you are the listed
                owner. Please rectify these issues at your earliest
                convenience.\n\n""".format(key1))
            body += email_list
            smtp = smtplib.SMTP()
            smtp.connect()
            msg = dedent("""\
                From: PenguinDome
                To: {to}
                Subject: {subject}\n\n""").format(to=email, subject=subject)
            msg += body
            smtp.sendmail('PenguinDome', [email], msg)
            smtp.quit()