John Anderson 5 лет назад
Родитель
Сommit
f48a079ae6

+ 3 - 12
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()

+ 3 - 2
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)
 

+ 0 - 43
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):
         """

+ 8 - 0
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__

+ 0 - 40
netbox/extras/tables.py

@@ -61,28 +61,6 @@ OBJECTCHANGE_REQUEST_ID = """
 <a href="{% url 'extras:objectchange_list' %}?request_id={{ value }}">{{ value }}</a>
 """
 
-JOB_RESULT_CREATED = """
-<a href="{{ record.get_absolute_url }}">{{ value|date:"SHORT_DATETIME_FORMAT" }}</a>
-"""
-
-JOB_RESULT_COMPLETED = """
-<span>{% if value %}{{ value|date:"SHORT_DATETIME_FORMAT" }}{% else %}—{% endif %}</span>
-"""
-
-JOB_RESULT_STATUS = """
-{% if record.status == 'failed' %}
-    <label class="label label-danger">Failed</label>
-{% elif record.status == 'pending' %}
-    <label class="label label-default">Pending</label>
-{% elif record.status == 'running' %}
-    <label class="label label-warning">Running</label>
-{% elif record.status == 'completed' %}
-    <label class="label label-success">Passed</label>
-{% else %}
-    <label class="label label-default">N/A</label>
-{% 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')
-

+ 2 - 7
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):

+ 0 - 1
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(

+ 10 - 1
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,
         })

+ 0 - 3
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);

+ 2 - 2
netbox/templates/home.html

@@ -280,8 +280,8 @@
                 <table class="table table-hover panel-body">
                     {% for result in report_results %}
                         <tr>
-                            <td><a href="{% url 'extras:report' name=result.report %}">{{ result.report }}</a></td>
-                            <td class="text-right"><span title="{{ result.created }}">{% include 'extras/inc/report_label.html' %}</span></td>
+                            <td><a href="{% url 'extras:report' name=result.name %}">{{ result.name }}</a></td>
+                            <td class="text-right"><span title="{{ result.created }}">{% include 'extras/inc/job_label.html' %}</span></td>
                         </tr>
                     {% endfor %}
                 </table>

+ 1 - 0
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.