show list of nodes without report for x hours in overview
- the amount of hours is defined as `UNRESPONSIVE_HOURS` in default_settings.py - small status layout improvement in nodes list - latest report button in nodes list - nedap/pypuppetdb repo as requirement ( new api was merged nedap/pypuppetdb#17 )
This commit is contained in:
@@ -5,6 +5,7 @@ import os
|
|||||||
import logging
|
import logging
|
||||||
import collections
|
import collections
|
||||||
import urllib
|
import urllib
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from flask import (
|
from flask import (
|
||||||
Flask, render_template, abort, url_for,
|
Flask, render_template, abort, url_for,
|
||||||
@@ -101,7 +102,15 @@ def index():
|
|||||||
|
|
||||||
latest_events = puppetdb._query('event-counts', query='["=", "latest-report?", true]', summarize_by='certname')
|
latest_events = puppetdb._query('event-counts', query='["=", "latest-report?", true]', summarize_by='certname')
|
||||||
|
|
||||||
return render_template('index.html', metrics=metrics, latest_event_count=latest_event_count, latest_events=latest_events)
|
unreported = []
|
||||||
|
for node in puppetdb.nodes():
|
||||||
|
node_last_seen = node.report_timestamp.replace(tzinfo=None)
|
||||||
|
if node_last_seen < (datetime.utcnow()-timedelta(hours=app.config['UNRESPONSIVE_HOURS'])):
|
||||||
|
delta = (datetime.utcnow()-node_last_seen)
|
||||||
|
node.noresponse = str(delta.days) + "d " + str(int(delta.seconds/3600)) +"h " + str(int((delta.seconds%3600)/60))+ "m"
|
||||||
|
unreported.append(node)
|
||||||
|
|
||||||
|
return render_template('index.html', metrics=metrics, latest_event_count=latest_event_count, latest_events=latest_events, unreported=unreported, unreported_time=app.config['UNRESPONSIVE_HOURS'])
|
||||||
|
|
||||||
@app.route('/nodes')
|
@app.route('/nodes')
|
||||||
def nodes():
|
def nodes():
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ PUPPETDB_TIMEOUT=20
|
|||||||
PUPPETDB_API=3
|
PUPPETDB_API=3
|
||||||
DEV_LISTEN_HOST='127.0.0.1'
|
DEV_LISTEN_HOST='127.0.0.1'
|
||||||
DEV_LISTEN_PORT=5000
|
DEV_LISTEN_PORT=5000
|
||||||
|
UNRESPONSIVE_HOURS=2
|
||||||
ENABLE_QUERY=True
|
ENABLE_QUERY=True
|
||||||
LOGLEVEL='info'
|
LOGLEVEL='info'
|
||||||
|
|||||||
@@ -65,3 +65,8 @@ h1.noop {
|
|||||||
width:20px;
|
width:20px;
|
||||||
text-align:center;
|
text-align:center;
|
||||||
}
|
}
|
||||||
|
.label-nothing {
|
||||||
|
background-color:#ddd;
|
||||||
|
width:20px;
|
||||||
|
color:#ddd;
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,16 +8,16 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
<div class="span4 stat">
|
<div class="span4 stat">
|
||||||
<h1 class="error">{{latest_event_count['failures']}} Failures</h1>
|
<h1 class="error">{{latest_event_count['failures']}} <small>Failed</small></h1>
|
||||||
<span>in the latest node reports</span>
|
<span>nodes in the latest reports</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="span4 stat">
|
<div class="span4 stat">
|
||||||
<h1 class="success">{{latest_event_count['successes']}} Successes</h1>
|
<h1 class="success">{{latest_event_count['successes']}} <small>Succeeded</small></h1>
|
||||||
<span>in the latest node reports</span>
|
<span>nodes in the latest reports</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="span4 stat">
|
<div class="span4 stat">
|
||||||
<h1 class="noop">{{latest_event_count['noopskip']}} Noop/Skip</h1>
|
<h1 class="noop">{{ unreported|length }} <small>Unreported</small></h1>
|
||||||
<span>in the latest node reports</span>
|
<span>nodes in the last {{ unreported_time }} hours</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -53,21 +53,34 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
|
<h2>Nodes without Report since {{ unreported_time }} hours</h2>
|
||||||
|
<table class='nodes table table-striped table-condensed'>
|
||||||
|
<tbody class="searchable">
|
||||||
|
{% for node in unreported %}
|
||||||
|
<tr>
|
||||||
|
<td style="width:110px;"><span class="label label-important">No Report</span></td>
|
||||||
|
<td>{{ node.noresponse }}</td>
|
||||||
|
<td><a href="{{url_for('node', node_name=node.name)}}">{{ node.name }}</a></td>
|
||||||
|
<td style="width:120px;"><a class="btn btn-small btn-primary" href="{{url_for('report_latest', node_name=node.name)}}">Latest Report</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
<h2>Latest Reports with events</h2>
|
<h2>Latest Reports with events</h2>
|
||||||
<hr />
|
<table class='nodes table table-striped table-condensed'>
|
||||||
<table class='nodes table table-striped table-condensed'>
|
<tbody class="searchable">
|
||||||
<tbody class="searchable">
|
{% for event in latest_events %}
|
||||||
{% for event in latest_events %}
|
<tr>
|
||||||
<tr>
|
<td style="width:110px;">
|
||||||
|
{% if event['failures'] %}<span class="label label-important numtag">{{event['failures']}}</span>{% else %}<span class="label numtag">0</span>{% endif%}
|
||||||
<td>{% if event['failures'] %}<span class="label label-important numtag">{{event['failures']}}</span>{% endif%}</td>
|
{% if event['successes'] %}<span class="label label-success numtag">{{event['successes']}}</span>{% else %}<span class="label numtag">0</span>{% endif%}
|
||||||
<td>{% if event['successes'] %}<span class="label label-success numtag">{{event['successes']}}</span>{% endif%}</td>
|
</td>
|
||||||
<td style="width:730px;"><a href="{{url_for('node', node_name=event['subject']['title'])}}">{{event['subject']['title']}}</a></td>
|
<td style="width:700px;"><a href="{{url_for('node', node_name=event['subject']['title'])}}">{{event['subject']['title']}}</a></td>
|
||||||
<td><a class="btn btn-small btn-primary" href="{{url_for('report_latest', node_name=event['subject']['title'])}}">Latest Report</a></td>
|
<td style="width:120px;"><a class="btn btn-small btn-primary" href="{{url_for('report_latest', node_name=event['subject']['title'])}}">Latest Report</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<table class='nodes table table-striped table-condensed'>
|
<table class='nodes table table-striped table-condensed'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th width>Status</th>
|
<th>Status</th>
|
||||||
<th>Hostname</th>
|
<th>Hostname</th>
|
||||||
<th>Catalog compiled at</th>
|
<th>Catalog compiled at</th>
|
||||||
{% if config.PUPPETDB_API > 2 %}
|
{% if config.PUPPETDB_API > 2 %}
|
||||||
@@ -30,15 +30,11 @@
|
|||||||
<tbody class="searchable">
|
<tbody class="searchable">
|
||||||
{% for node in nodes %}
|
{% for node in nodes %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{url_for('report_latest', node_name=node.name)}}">
|
<td><a href="{{url_for('report_latest', node_name=node.name)}}">
|
||||||
{% if node.status %}
|
{% if node.status['failures'] %}<span class="label numtag label-important">{{node.status['failures']}}</span>{% else %}<span class="label label-nothing">0</span>{% endif %}
|
||||||
{% if node.status['failures'] %}<span class="label label-important">{{node.status['failures']}}</span>{% endif %}
|
{% if node.status['successes'] %}<span class="label numtag label-success">{{node.status['successes']}}</span>{% else %}<span class="label label-nothing">0</span>{% endif %}
|
||||||
{% if node.status['successes'] %}<span class="label label-success">{{node.status['successes']}}</span>{% endif %}
|
{% if node.status['noops'] or node.status['skips'] %}<span class="label numtag">{{node.status['skips']+node.status['noops']}}</span>{% else %}<span class="label label-nothing">0</span>{% endif %}
|
||||||
{% if node.status['noops'] or node.status['skips'] %}<span class="label">{{node.status['skips']+node.status['noops']}}</span>{% endif %}
|
</a>
|
||||||
{% else %}
|
|
||||||
<span class="label">0</span>
|
|
||||||
{% endif %}
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
<td><a href="{{url_for('node', node_name=node.name)}}">{{node.name}}</a></td>
|
<td><a href="{{url_for('node', node_name=node.name)}}">{{node.name}}</a></td>
|
||||||
<td rel="utctimestamp">{{node.catalog_timestamp}}</td>
|
<td rel="utctimestamp">{{node.catalog_timestamp}}</td>
|
||||||
@@ -52,6 +48,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if node.report_timestamp %}
|
{% if node.report_timestamp %}
|
||||||
|
<a class="btn btn-small btn-primary" href="{{url_for('report_latest', node_name=node.name)}}">Latest Report</a>
|
||||||
<a class="btn btn-small btn-primary" href="{{url_for('reports_node', node=node.name)}}">Reports</a>
|
<a class="btn btn-small btn-primary" href="{{url_for('reports_node', node=node.name)}}">Reports</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ MarkupSafe==0.18
|
|||||||
WTForms==1.0.4
|
WTForms==1.0.4
|
||||||
Werkzeug==0.9.3
|
Werkzeug==0.9.3
|
||||||
itsdangerous==0.22
|
itsdangerous==0.22
|
||||||
git+https://github.com/juliushaertl/pypuppetdb.git@feature-v3-newapis#egg=pypuppetdb
|
git+https://github.com/nedap/pypuppetdb#egg=pypuppetdb
|
||||||
requests==1.2.3
|
requests==1.2.3
|
||||||
|
|||||||
Reference in New Issue
Block a user