mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 17:26:10 -06:00
Misc cleanup
This commit is contained in:
parent
b2257b613e
commit
090a28131e
@ -917,6 +917,10 @@ class ReportModule(JobResultsMixin, WebhooksMixin, PythonModuleMixin, ManagedFil
|
|||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('extras:report_list')
|
return reverse('extras:report_list')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self.file_path
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def reports(self):
|
def reports(self):
|
||||||
module = self.get_module()
|
module = self.get_module()
|
||||||
|
@ -3,6 +3,7 @@ import traceback
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.functional import classproperty
|
||||||
from django_rq import job
|
from django_rq import job
|
||||||
|
|
||||||
from .choices import JobResultStatusChoices, LogLevelChoices
|
from .choices import JobResultStatusChoices, LogLevelChoices
|
||||||
@ -26,7 +27,7 @@ def run_report(job_result, *args, **kwargs):
|
|||||||
method for queueing into the background processor.
|
method for queueing into the background processor.
|
||||||
"""
|
"""
|
||||||
module_name, report_name = job_result.name.split('.', 1)
|
module_name, report_name = job_result.name.split('.', 1)
|
||||||
report = get_report(module_name, report_name)
|
report = get_report(module_name, report_name)()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
job_result.start()
|
job_result.start()
|
||||||
@ -83,7 +84,7 @@ class Report(object):
|
|||||||
self.active_test = None
|
self.active_test = None
|
||||||
self.failed = False
|
self.failed = False
|
||||||
|
|
||||||
self.logger = logging.getLogger(f"netbox.reports.{self.full_name}")
|
self.logger = logging.getLogger(f"netbox.reports.{self.__module__}.{self.__class__.__name__}")
|
||||||
|
|
||||||
# Compile test methods and initialize results skeleton
|
# Compile test methods and initialize results skeleton
|
||||||
test_methods = []
|
test_methods = []
|
||||||
@ -101,13 +102,17 @@ class Report(object):
|
|||||||
raise Exception("A report must contain at least one test method.")
|
raise Exception("A report must contain at least one test method.")
|
||||||
self.test_methods = test_methods
|
self.test_methods = test_methods
|
||||||
|
|
||||||
@property
|
@classproperty
|
||||||
def module(self):
|
def module(self):
|
||||||
return self.__module__
|
return self.__module__
|
||||||
|
|
||||||
@property
|
@classproperty
|
||||||
def class_name(self):
|
def class_name(self):
|
||||||
return self.__class__.__name__
|
return self.__name__
|
||||||
|
|
||||||
|
@classproperty
|
||||||
|
def full_name(self):
|
||||||
|
return f'{self.module}.{self.class_name}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
@ -116,9 +121,9 @@ class Report(object):
|
|||||||
"""
|
"""
|
||||||
return self.class_name
|
return self.class_name
|
||||||
|
|
||||||
@property
|
#
|
||||||
def full_name(self):
|
# Logging methods
|
||||||
return f'{self.module}.{self.class_name}'
|
#
|
||||||
|
|
||||||
def _log(self, obj, message, level=LogLevelChoices.LOG_DEFAULT):
|
def _log(self, obj, message, level=LogLevelChoices.LOG_DEFAULT):
|
||||||
"""
|
"""
|
||||||
@ -175,6 +180,10 @@ class Report(object):
|
|||||||
self.logger.info(f"Failure | {obj}: {message}")
|
self.logger.info(f"Failure | {obj}: {message}")
|
||||||
self.failed = True
|
self.failed = True
|
||||||
|
|
||||||
|
#
|
||||||
|
# Run methods
|
||||||
|
#
|
||||||
|
|
||||||
def run(self, job_result):
|
def run(self, job_result):
|
||||||
"""
|
"""
|
||||||
Run the report and save its results. Each test method will be executed in order.
|
Run the report and save its results. Each test method will be executed in order.
|
||||||
|
@ -267,7 +267,7 @@ class BaseScript:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
# Initiate the log
|
# Initiate the log
|
||||||
self.logger = logging.getLogger(f"netbox.scripts.{self.module()}.{self.__class__.__name__}")
|
self.logger = logging.getLogger(f"netbox.scripts.{self.__module__}.{self.__class__.__name__}")
|
||||||
self.log = []
|
self.log = []
|
||||||
|
|
||||||
# Declare the placeholder for the current request
|
# Declare the placeholder for the current request
|
||||||
@ -280,22 +280,26 @@ class BaseScript:
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
@classproperty
|
||||||
|
def module(self):
|
||||||
|
return self.__module__
|
||||||
|
|
||||||
|
@classproperty
|
||||||
|
def class_name(self):
|
||||||
|
return self.__name__
|
||||||
|
|
||||||
|
@classproperty
|
||||||
|
def full_name(self):
|
||||||
|
return f'{self.module}.{self.class_name}'
|
||||||
|
|
||||||
@classproperty
|
@classproperty
|
||||||
def name(self):
|
def name(self):
|
||||||
return getattr(self.Meta, 'name', self.__name__)
|
return getattr(self.Meta, 'name', self.__name__)
|
||||||
|
|
||||||
@classproperty
|
|
||||||
def full_name(self):
|
|
||||||
return '.'.join([self.__module__, self.__name__])
|
|
||||||
|
|
||||||
@classproperty
|
@classproperty
|
||||||
def description(self):
|
def description(self):
|
||||||
return getattr(self.Meta, 'description', '')
|
return getattr(self.Meta, 'description', '')
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def module(cls):
|
|
||||||
return cls.__module__
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def root_module(cls):
|
def root_module(cls):
|
||||||
return cls.__module__.split(".")[0]
|
return cls.__module__.split(".")[0]
|
||||||
|
@ -852,20 +852,17 @@ class ReportView(ContentTypePermissionRequiredMixin, View):
|
|||||||
).first()
|
).first()
|
||||||
|
|
||||||
return render(request, 'extras/report.html', {
|
return render(request, 'extras/report.html', {
|
||||||
|
'module': module,
|
||||||
'report': report,
|
'report': report,
|
||||||
'form': ReportForm(),
|
'form': ReportForm(),
|
||||||
})
|
})
|
||||||
|
|
||||||
def post(self, request, module, name):
|
def post(self, request, module, name):
|
||||||
|
|
||||||
# Permissions check
|
|
||||||
if not request.user.has_perm('extras.run_report'):
|
if not request.user.has_perm('extras.run_report'):
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
|
|
||||||
report = get_report(module, name)
|
module = get_object_or_404(ReportModule.objects.restrict(request.user), file_path=f'{module}.py')
|
||||||
if report is None:
|
report = module.reports[name]()
|
||||||
raise Http404
|
|
||||||
|
|
||||||
form = ReportForm(request.POST)
|
form = ReportForm(request.POST)
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
@ -891,6 +888,7 @@ class ReportView(ContentTypePermissionRequiredMixin, View):
|
|||||||
return redirect('extras:report_result', job_result_pk=job_result.pk)
|
return redirect('extras:report_result', job_result_pk=job_result.pk)
|
||||||
|
|
||||||
return render(request, 'extras/report.html', {
|
return render(request, 'extras/report.html', {
|
||||||
|
'module': module,
|
||||||
'report': report,
|
'report': report,
|
||||||
'form': form,
|
'form': form,
|
||||||
})
|
})
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'extras:report_list' %}">Reports</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'extras:report_list' %}">Reports</a></li>
|
||||||
<li class="breadcrumb-item"><a href="{% url 'extras:report_list' %}#module.{{ report.module }}">{{ report.module|bettertitle }}</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'extras:report_list' %}#module{{ module.pk }}">{{ report.module|bettertitle }}</a></li>
|
||||||
{% endblock breadcrumbs %}
|
{% endblock breadcrumbs %}
|
||||||
|
|
||||||
{% block subtitle %}
|
{% block subtitle %}
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
{% for module in report_modules %}
|
{% for module in report_modules %}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h5 class="card-header">
|
<h5 class="card-header" id="module{{ module.pk }}">
|
||||||
{% if perms.extras.delete_reportmodule %}
|
{% if perms.extras.delete_reportmodule %}
|
||||||
<div class="float-end">
|
<div class="float-end">
|
||||||
<a href="{% url 'extras:reportmodule_delete' pk=module.pk %}" class="btn btn-danger btn-sm">
|
<a href="{% url 'extras:reportmodule_delete' pk=module.pk %}" class="btn btn-danger btn-sm">
|
||||||
@ -34,7 +34,6 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a name="module.{{ module.name }}"></a>
|
|
||||||
<i class="mdi mdi-file-document-outline"></i> {{ module.name|bettertitle }}
|
<i class="mdi mdi-file-document-outline"></i> {{ module.name|bettertitle }}
|
||||||
</h5>
|
</h5>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@ -51,6 +50,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for report_name, report in module.reports.items %}
|
{% for report_name, report in module.reports.items %}
|
||||||
|
{% with last_result=job_results|get_key:report.full_name %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'extras:report' module=report.module name=report.class_name %}" id="{{ report.module }}.{{ report.class_name }}">{{ report.name }}</a>
|
<a href="{% url 'extras:report' module=report.module name=report.class_name %}" id="{{ report.module }}.{{ report.class_name }}">{{ report.name }}</a>
|
||||||
@ -59,7 +59,6 @@
|
|||||||
{% include 'extras/inc/job_label.html' with result=report.result %}
|
{% include 'extras/inc/job_label.html' with result=report.result %}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ report.description|markdown|placeholder }}</td>
|
<td>{{ report.description|markdown|placeholder }}</td>
|
||||||
{% with last_result=job_results|get_key:report.full_name %}
|
|
||||||
{% if last_result %}
|
{% if last_result %}
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'extras:report_result' job_result_pk=last_result.pk %}">{{ last_result.created|annotated_date }}</a>
|
<a href="{% url 'extras:report_result' job_result_pk=last_result.pk %}">{{ last_result.created|annotated_date }}</a>
|
||||||
@ -87,9 +86,8 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
{% endwith %}
|
|
||||||
</tr>
|
</tr>
|
||||||
{% for method, stats in report.result.data.items %}
|
{% for method, stats in last_result.data.items %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="4" class="method">
|
<td colspan="4" class="method">
|
||||||
<span class="ps-3">{{ method }}</span>
|
<span class="ps-3">{{ method }}</span>
|
||||||
@ -102,6 +100,7 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% endwith %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'extras:script_list' %}">Scripts</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'extras:script_list' %}">Scripts</a></li>
|
||||||
<li class="breadcrumb-item"><a href="{% url 'extras:script_list' %}#module.{{ module }}">{{ module|bettertitle }}</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'extras:script_list' %}#module{{ module.pk }}">{{ module|bettertitle }}</a></li>
|
||||||
{% endblock breadcrumbs %}
|
{% endblock breadcrumbs %}
|
||||||
|
|
||||||
{% block subtitle %}
|
{% block subtitle %}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
{% for module in script_modules %}
|
{% for module in script_modules %}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h5 class="card-header">
|
<h5 class="card-header" id="module{{ module.pk }}">
|
||||||
{% if perms.extras.delete_scriptmodule %}
|
{% if perms.extras.delete_scriptmodule %}
|
||||||
<div class="float-end">
|
<div class="float-end">
|
||||||
<a href="{% url 'extras:scriptmodule_delete' pk=module.pk %}" class="btn btn-danger btn-sm">
|
<a href="{% url 'extras:scriptmodule_delete' pk=module.pk %}" class="btn btn-danger btn-sm">
|
||||||
@ -33,7 +33,6 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a name="module.{{ module.name }}"></a>
|
|
||||||
<i class="mdi mdi-file-document-outline"></i> {{ module.name|bettertitle }}
|
<i class="mdi mdi-file-document-outline"></i> {{ module.name|bettertitle }}
|
||||||
</h5>
|
</h5>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@ -49,6 +48,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for script_name, script_class in module.scripts.items %}
|
{% for script_name, script_class in module.scripts.items %}
|
||||||
|
{% with last_result=job_results|get_key:script_class.full_name %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'extras:script' module=script_class.root_module name=script_name %}" name="script.{{ script_name }}">{{ script_class.name }}</a>
|
<a href="{% url 'extras:script' module=script_class.root_module name=script_name %}" name="script.{{ script_name }}">{{ script_class.name }}</a>
|
||||||
@ -59,7 +59,6 @@
|
|||||||
<td>
|
<td>
|
||||||
{{ script_class.Meta.description|markdown|placeholder }}
|
{{ script_class.Meta.description|markdown|placeholder }}
|
||||||
</td>
|
</td>
|
||||||
{% with last_result=job_results|get_key:script_class.full_name %}
|
|
||||||
{% if last_result %}
|
{% if last_result %}
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'extras:script_result' job_result_pk=last_result.pk %}">{{ last_result.created|annotated_date }}</a>
|
<a href="{% url 'extras:script_result' job_result_pk=last_result.pk %}">{{ last_result.created|annotated_date }}</a>
|
||||||
@ -71,8 +70,8 @@
|
|||||||
<td class="text-muted">Never</td>
|
<td class="text-muted">Never</td>
|
||||||
<td class="text-end">{{ ''|placeholder }}</td>
|
<td class="text-end">{{ ''|placeholder }}</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endwith %}
|
|
||||||
</tr>
|
</tr>
|
||||||
|
{% endwith %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
Loading…
Reference in New Issue
Block a user