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)
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.')
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()