1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Implemented rough UI for accessing report results

This commit is contained in:
Jeremy Stretch
2017-09-22 12:11:10 -04:00
parent b5ab498e75
commit 79fdf641c0
6 changed files with 85 additions and 18 deletions

View File

@ -32,6 +32,10 @@ class Command(BaseCommand):
report = report_cls() report = report_cls()
results = report.run() results = report.run()
# Record the results
ReportResult.objects.filter(report=report_name_full).delete()
ReportResult(report=report_name_full, failed=report.failed, data=results).save()
# Report on success/failure # Report on success/failure
status = self.style.ERROR('FAILED') if report.failed else self.style.SUCCESS('SUCCESS') status = self.style.ERROR('FAILED') if report.failed else self.style.SUCCESS('SUCCESS')
for test_name, attrs in results.items(): for test_name, attrs in results.items():

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-09-21 20:31 # Generated by Django 1.11.4 on 2017-09-22 15:21
from __future__ import unicode_literals from __future__ import unicode_literals
from django.conf import settings from django.conf import settings
@ -20,8 +20,9 @@ class Migration(migrations.Migration):
name='ReportResult', name='ReportResult',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_created=True)),
('report', models.CharField(max_length=255, unique=True)), ('report', models.CharField(max_length=255, unique=True)),
('created', models.DateTimeField(auto_now_add=True)),
('failed', models.BooleanField()),
('data', django.contrib.postgres.fields.jsonb.JSONField()), ('data', django.contrib.postgres.fields.jsonb.JSONField()),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
], ],

View File

@ -398,8 +398,9 @@ class ReportResult(models.Model):
This model stores the results from running a user-defined report. This model stores the results from running a user-defined report.
""" """
report = models.CharField(max_length=255, unique=True) report = models.CharField(max_length=255, unique=True)
created = models.DateTimeField(auto_created=True) created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.SET_NULL, related_name='+', blank=True, null=True) user = models.ForeignKey(User, on_delete=models.SET_NULL, related_name='+', blank=True, null=True)
failed = models.BooleanField()
data = JSONField() data = JSONField()
class Meta: class Meta:

View File

@ -20,7 +20,18 @@ def is_report(obj):
def get_reports(): def get_reports():
""" """
Compile a list of all reports available across all modules in the reports path. Compile a list of all reports available across all modules in the reports path. Returns a list of tuples:
[
(module_name, (
(report_name, report_class),
(report_name, report_class)
),
(module_name, (
(report_name, report_class),
(report_name, report_class)
)
]
""" """
module_list = [] module_list = []
@ -30,8 +41,8 @@ def get_reports():
report_list = [] report_list = []
# Iterate through all Report classes within the module # Iterate through all Report classes within the module
for report_name, report_cls in inspect.getmembers(module, is_report): for report_name, report_class in inspect.getmembers(module, is_report):
report_list.append((report_name, report_cls)) report_list.append((report_name, report_class))
module_list.append((module_name, report_list)) module_list.append((module_name, report_list))
@ -92,7 +103,7 @@ class Report(object):
""" """
if level not in LOG_LEVEL_CODES: if level not in LOG_LEVEL_CODES:
raise Exception("Unknown logging level: {}".format(level)) raise Exception("Unknown logging level: {}".format(level))
logline = [timezone.now(), level, obj, message] logline = [timezone.now().isoformat(), level, str(obj), message]
self.results[self.active_test]['log'].append(logline) self.results[self.active_test]['log'].append(logline)
def log_success(self, obj, message=None): def log_success(self, obj, message=None):

View File

@ -1,7 +1,8 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from collections import OrderedDict
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, render
from django.urls import reverse from django.urls import reverse
from django.views.generic import View from django.views.generic import View
@ -52,9 +53,19 @@ class ReportListView(View):
def get(self, request): def get(self, request):
reports = get_reports() reports = get_reports()
results = {r.name: r for r in ReportResult.objects.all()} results = {r.report: r for r in ReportResult.objects.all()}
foo = []
for module, report_list in reports:
module_reports = []
for report_name, report_class in report_list:
module_reports.append({
'name': report_name,
'description': report_class.description,
'results': results.get('{}.{}'.format(module, report_name), None)
})
foo.append((module, module_reports))
return render(request, 'extras/report_list.html', { return render(request, 'extras/report_list.html', {
'reports': reports, 'reports': foo,
'results': results,
}) })

View File

@ -5,13 +5,52 @@
<h1>Reports</h1> <h1>Reports</h1>
<div class="row"> <div class="row">
<div class="col-md-9"> <div class="col-md-9">
{% for module, report_list in reports %} {% for module, module_reports in reports %}
<h2>{{ module|bettertitle }}</h2> <h3>{{ module|bettertitle }}</h3>
<ul> <table class="table table-hover">
{% for name, cls in report_list %} <thead>
<li>{{ name }}</li> <tr>
<th>Name</th>
<th>Description</th>
<th>Last Run</th>
<th class="text-right">Status</th>
</tr>
</thead>
<tbody>
{% for report in module_reports %}
<tr>
<td>{{ report.name }}</td>
<td>{{ report.description|default:"" }}</td>
{% if report.results %}
<td>{{ report.results.created }}</td>
<td class="text-right">
{% if report.results.failed %}
<label class="label label-danger">Failed</label>
{% else %}
<label class="label label-success">Passed</label>
{% endif %}
</td>
{% else %}
<td class="text-muted">Never</td>
<td class="text-muted text-right">&mdash;</td>
{% endif %}
</tr>
{% for method, stats in report.results.data.items %}
<tr>
<td colspan="4">
<div class="pull-right">
<label class="label label-success">{{ stats.success }}</label>
<label class="label label-info">{{ stats.info }}</label>
<label class="label label-warning">{{ stats.warning }}</label>
<label class="label label-danger">{{ stats.failed }}</label>
</div>
<span style="font-family: monospace">{{ method }}</span>
</td>
</tr>
{% endfor %} {% endfor %}
</ul> {% endfor %}
</tbody>
</table>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>