From f48a079ae61acb2a0a3e7c381d650935036bcd74 Mon Sep 17 00:00:00 2001 From: John Anderson Date: Mon, 29 Jun 2020 14:34:42 -0400 Subject: [PATCH] fix tests and cleanup --- netbox/extras/api/serializers.py | 15 ++------- netbox/extras/api/views.py | 5 +-- netbox/extras/models/models.py | 43 -------------------------- netbox/extras/scripts.py | 8 +++++ netbox/extras/tables.py | 40 ------------------------ netbox/extras/tests/test_api.py | 9 ++---- netbox/extras/views.py | 1 - netbox/netbox/views.py | 11 ++++++- netbox/project-static/js/job_result.js | 3 -- netbox/templates/home.html | 4 +-- netbox/utilities/utils.py | 1 + 11 files changed, 29 insertions(+), 111 deletions(-) diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index 2a8cae35c..636e813bd 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -284,21 +284,12 @@ class ScriptSerializer(serializers.Serializer): lookup_field='full_name', lookup_url_kwarg='pk' ) - id = serializers.SerializerMethodField(read_only=True) - name = serializers.SerializerMethodField(read_only=True) - description = serializers.SerializerMethodField(read_only=True) + id = serializers.CharField(read_only=True, source="full_name") + name = serializers.CharField(read_only=True) + description = serializers.CharField(read_only=True) vars = serializers.SerializerMethodField(read_only=True) result = NestedJobResultSerializer() - def get_id(self, instance): - return '{}.{}'.format(instance.__module__, instance.__name__) - - def get_name(self, instance): - return getattr(instance.Meta, 'name', instance.__name__) - - def get_description(self, instance): - return getattr(instance.Meta, 'description', '') - def get_vars(self, instance): return { k: v.__class__.__name__ for k, v in instance._get_vars().items() diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index e2ee57059..59000f45a 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -17,6 +17,7 @@ from extras.models import ( from extras.reports import get_report, get_reports from extras.scripts import get_script, get_scripts, run_script from utilities.api import IsAuthenticatedOrLoginNotRequired, ModelViewSet +from utilities.utils import copy_safe_request from . import serializers @@ -304,12 +305,12 @@ class ScriptViewSet(ViewSet): script.full_name, script_content_type, request.user, - data=form.cleaned_data, + data=data, request=copy_safe_request(request), commit=commit ) script.result = job_result - serializer = serializers.ScriptDetailSerializer(script) + serializer = serializers.ScriptDetailSerializer(script, context={'request': request}) return Response(serializer.data) diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index ab28e9d5b..a366187dc 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -573,25 +573,6 @@ class Script(models.Model): class Meta: managed = False - @classmethod - def get_absolute_url_from_job_result(cls, job_result): - """ - Given a JobResult that links to this content type, return URL to an instance which corresponds to that job - result, i.e. for historical records - """ - if job_result.obj_type.model_class() != cls: - return None - - module, script_name = job_result.name.split('.') - return reverse( - 'extras:script_history_detail', - kwargs={ - 'module': module, - 'script_name': script_name, - 'job_id': job_result.job_id - } - ) - # # Reports @@ -606,23 +587,6 @@ class Report(models.Model): class Meta: managed = False - @classmethod - def get_absolute_url_from_job_result(cls, job_result): - """ - Given a JobResult that links to this content type, return URL to an instance which corresponds to that job - result, i.e. for historical records - """ - if job_result.obj_type.model_class() != cls: - return None - - return reverse( - 'extras:report_history_detail', - kwargs={ - 'name': job_result.name, - 'job_id': job_result.job_id - } - ) - # # Job results @@ -676,12 +640,6 @@ class JobResult(models.Model): def __str__(self): return str(self.job_id) - def get_absolute_url(self): - """ - Job results are accessed only under the context of the content type they link to - """ - return self.obj_type.model_class().get_absolute_url_from_job_result(self) - @property def duration(self): if not self.completed: @@ -692,7 +650,6 @@ class JobResult(models.Model): return f"{int(minutes)} minutes, {seconds:.2f} seconds" - @classmethod def enqueue_job(cls, func, name, obj_type, user, *args, **kwargs): """ diff --git a/netbox/extras/scripts.py b/netbox/extras/scripts.py index c801bf3a2..e33d8028e 100644 --- a/netbox/extras/scripts.py +++ b/netbox/extras/scripts.py @@ -273,12 +273,20 @@ class BaseScript: self.source = inspect.getsource(self.__class__) def __str__(self): + return self.name + + @classproperty + def name(self): return getattr(self.Meta, 'name', self.__class__.__name__) @classproperty def full_name(self): return '.'.join([self.__module__, self.__name__]) + @classproperty + def description(self): + return getattr(self.Meta, 'description', '') + @classmethod def module(cls): return cls.__module__ diff --git a/netbox/extras/tables.py b/netbox/extras/tables.py index 1398ff667..c772d3db0 100644 --- a/netbox/extras/tables.py +++ b/netbox/extras/tables.py @@ -61,28 +61,6 @@ OBJECTCHANGE_REQUEST_ID = """ {{ value }} """ -JOB_RESULT_CREATED = """ -{{ value|date:"SHORT_DATETIME_FORMAT" }} -""" - -JOB_RESULT_COMPLETED = """ -{% if value %}{{ value|date:"SHORT_DATETIME_FORMAT" }}{% else %}—{% endif %} -""" - -JOB_RESULT_STATUS = """ -{% if record.status == 'failed' %} - -{% elif record.status == 'pending' %} - -{% elif record.status == 'running' %} - -{% elif record.status == 'completed' %} - -{% else %} - -{% endif %} -""" - class TagTable(BaseTable): pk = ToggleColumn() @@ -155,21 +133,3 @@ class ObjectChangeTable(BaseTable): class Meta(BaseTable.Meta): model = ObjectChange fields = ('time', 'user_name', 'action', 'changed_object_type', 'object_repr', 'request_id') - - -class JobResultHistoryTable(BaseTable): - created = tables.TemplateColumn( - template_code=JOB_RESULT_CREATED, - verbose_name='Run' - ) - completed = tables.TemplateColumn( - template_code=JOB_RESULT_COMPLETED - ) - status = tables.TemplateColumn( - template_code=JOB_RESULT_STATUS - ) - - class Meta(BaseTable.Meta): - model = JobResult - fields = ('created', 'completed', 'status') - diff --git a/netbox/extras/tests/test_api.py b/netbox/extras/tests/test_api.py index 5d7951e54..de9d58446 100644 --- a/netbox/extras/tests/test_api.py +++ b/netbox/extras/tests/test_api.py @@ -10,6 +10,7 @@ from extras.api.views import ScriptViewSet from extras.models import ConfigContext, Graph, ExportTemplate, Tag from extras.scripts import BooleanVar, IntegerVar, Script, StringVar from utilities.testing import APITestCase, APIViewTestCases +from utilities.utils import copy_safe_request class AppTest(APITestCase): @@ -263,13 +264,7 @@ class ScriptTest(APITestCase): response = self.client.post(url, data, format='json', **self.header) self.assertHttpStatus(response, status.HTTP_200_OK) - self.assertEqual(response.data['log'][0]['status'], 'info') - self.assertEqual(response.data['log'][0]['message'], script_data['var1']) - self.assertEqual(response.data['log'][1]['status'], 'success') - self.assertEqual(response.data['log'][1]['message'], script_data['var2']) - self.assertEqual(response.data['log'][2]['status'], 'failure') - self.assertEqual(response.data['log'][2]['message'], script_data['var3']) - self.assertEqual(response.data['output'], 'Script complete') + self.assertEqual(response.data['result']['status']['value'], 'pending') class CreatedUpdatedFilterTest(APITestCase): diff --git a/netbox/extras/views.py b/netbox/extras/views.py index 505fc6595..10a0b51d6 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -501,7 +501,6 @@ class ScriptView(ContentTypePermissionRequiredMixin, GetScriptMixin, View): if form.is_valid(): commit = form.cleaned_data.pop('_commit') - #output, execution_time = run_script(script, form.cleaned_data, request, commit) script_content_type = ContentType.objects.get(app_label='extras', model='script') job_result = JobResult.enqueue_job( diff --git a/netbox/netbox/views.py b/netbox/netbox/views.py index 613101cda..548173a32 100644 --- a/netbox/netbox/views.py +++ b/netbox/netbox/views.py @@ -1,6 +1,7 @@ from collections import OrderedDict from django.conf import settings +from django.contrib.contenttypes.models import ContentType from django.db.models import Count, F from django.shortcuts import render from django.views.generic import View @@ -24,6 +25,7 @@ from dcim.tables import ( CableTable, DeviceTable, DeviceTypeTable, PowerFeedTable, RackTable, RackGroupTable, SiteTable, VirtualChassisTable, ) +from extras.choices import JobResultStatusChoices from extras.models import ObjectChange, JobResult from ipam.filters import AggregateFilterSet, IPAddressFilterSet, PrefixFilterSet, VLANFilterSet, VRFFilterSet from ipam.models import Aggregate, IPAddress, Prefix, VLAN, VRF @@ -187,6 +189,13 @@ class HomeView(View): pk__lt=F('_connected_interface') ) + # Report Results + report_content_type = ContentType.objects.get(app_label='extras', model='report') + report_results = JobResult.objects.filter( + obj_type=report_content_type, + status__in=JobResultStatusChoices.TERMINAL_STATE_CHOICES + ).defer('data')[:10] + stats = { # Organization @@ -241,7 +250,7 @@ class HomeView(View): return render(request, self.template_name, { 'search_form': SearchForm(), 'stats': stats, - 'report_results': [],#ReportResult.objects.order_by('-created')[:10], + 'report_results': report_results, 'changelog': changelog[:15], 'new_release': new_release, }) diff --git a/netbox/project-static/js/job_result.js b/netbox/project-static/js/job_result.js index 3d7293713..8f3d360db 100644 --- a/netbox/project-static/js/job_result.js +++ b/netbox/project-static/js/job_result.js @@ -30,9 +30,6 @@ $(document).ready(function(){ url: url + pending_result_id + '/', method: 'GET', dataType: 'json', - beforeSend: function(xhr, settings) { - xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}"); - }, context: this, success: function(data) { updatePendingStatusLabel(data.status); diff --git a/netbox/templates/home.html b/netbox/templates/home.html index 50a411048..f4acda3a3 100644 --- a/netbox/templates/home.html +++ b/netbox/templates/home.html @@ -280,8 +280,8 @@ {% for result in report_results %} - - + + {% endfor %}
{{ result.report }}{% include 'extras/inc/report_label.html' %}{{ result.name }}{% include 'extras/inc/job_label.html' %}
diff --git a/netbox/utilities/utils.py b/netbox/utilities/utils.py index f734e6534..1c8f9f12c 100644 --- a/netbox/utilities/utils.py +++ b/netbox/utilities/utils.py @@ -12,6 +12,7 @@ from dcim.choices import CableLengthUnitChoices from extras.utils import is_taggable from utilities.constants import HTTP_REQUEST_META_SAFE_COPY + def csv_format(data): """ Encapsulate any data which contains a comma within double quotes.