kkthxbye-code 3 лет назад
Родитель
Сommit
cbb3378d10

+ 2 - 0
netbox/extras/choices.py

@@ -139,6 +139,7 @@ class LogLevelChoices(ChoiceSet):
 class JobResultStatusChoices(ChoiceSet):
 class JobResultStatusChoices(ChoiceSet):
 
 
     STATUS_PENDING = 'pending'
     STATUS_PENDING = 'pending'
+    STATUS_SCHEDULED = 'pending'
     STATUS_RUNNING = 'running'
     STATUS_RUNNING = 'running'
     STATUS_COMPLETED = 'completed'
     STATUS_COMPLETED = 'completed'
     STATUS_ERRORED = 'errored'
     STATUS_ERRORED = 'errored'
@@ -146,6 +147,7 @@ class JobResultStatusChoices(ChoiceSet):
 
 
     CHOICES = (
     CHOICES = (
         (STATUS_PENDING, 'Pending'),
         (STATUS_PENDING, 'Pending'),
+        (STATUS_SCHEDULED, 'Pending'),
         (STATUS_RUNNING, 'Running'),
         (STATUS_RUNNING, 'Running'),
         (STATUS_COMPLETED, 'Completed'),
         (STATUS_COMPLETED, 'Completed'),
         (STATUS_ERRORED, 'Errored'),
         (STATUS_ERRORED, 'Errored'),

+ 21 - 0
netbox/extras/filtersets.py

@@ -16,6 +16,7 @@ __all__ = (
     'ConfigContextFilterSet',
     'ConfigContextFilterSet',
     'ContentTypeFilterSet',
     'ContentTypeFilterSet',
     'CustomFieldFilterSet',
     'CustomFieldFilterSet',
+    'JobResultFilterSet',
     'CustomLinkFilterSet',
     'CustomLinkFilterSet',
     'ExportTemplateFilterSet',
     'ExportTemplateFilterSet',
     'ImageAttachmentFilterSet',
     'ImageAttachmentFilterSet',
@@ -86,6 +87,26 @@ class CustomFieldFilterSet(BaseFilterSet):
             Q(description__icontains=value)
             Q(description__icontains=value)
         )
         )
 
 
+class JobResultFilterSet(BaseFilterSet):
+    q = django_filters.CharFilter(
+        method='search',
+        label='Search',
+    )
+
+    # TODO: Add filters
+
+    class Meta:
+        model = JobResult
+        fields = [
+            'id', 'name', 'obj_type', 'created', 'completed', 'user', 'status'
+        ]
+
+    def search(self, queryset, name, value):
+        if not value.strip():
+            return queryset
+        return queryset.filter(
+            Q(name__icontains=value)
+        )
 
 
 class CustomLinkFilterSet(BaseFilterSet):
 class CustomLinkFilterSet(BaseFilterSet):
     q = django_filters.CharFilter(
     q = django_filters.CharFilter(

+ 8 - 0
netbox/extras/forms/filtersets.py

@@ -19,6 +19,7 @@ from virtualization.models import Cluster, ClusterGroup, ClusterType
 __all__ = (
 __all__ = (
     'ConfigContextFilterForm',
     'ConfigContextFilterForm',
     'CustomFieldFilterForm',
     'CustomFieldFilterForm',
+    'JobResultFilterForm',
     'CustomLinkFilterForm',
     'CustomLinkFilterForm',
     'ExportTemplateFilterForm',
     'ExportTemplateFilterForm',
     'JournalEntryFilterForm',
     'JournalEntryFilterForm',
@@ -65,6 +66,13 @@ class CustomFieldFilterForm(FilterForm):
     )
     )
 
 
 
 
+class JobResultFilterForm(FilterForm):
+    fieldsets = (
+        (None, ('q',)),
+        #('Attributes', ('type', 'content_type_id', 'group_name', 'weight', 'required', 'ui_visibility')),
+    )
+
+
 class CustomLinkFilterForm(FilterForm):
 class CustomLinkFilterForm(FilterForm):
     fieldsets = (
     fieldsets = (
         (None, ('q',)),
         (None, ('q',)),

+ 10 - 1
netbox/extras/models/models.py

@@ -509,12 +509,18 @@ class JobResult(models.Model):
         unique=True
         unique=True
     )
     )
 
 
+    objects = RestrictedQuerySet.as_manager()
+
     class Meta:
     class Meta:
         ordering = ['obj_type', 'name', '-created']
         ordering = ['obj_type', 'name', '-created']
 
 
     def __str__(self):
     def __str__(self):
         return str(self.job_id)
         return str(self.job_id)
 
 
+    def get_absolute_url(self):
+        # TODO: Fix this to point the right place
+        return reverse('virtualization:clustertype', args=[self.pk])
+
     @property
     @property
     def duration(self):
     def duration(self):
         if not self.completed:
         if not self.completed:
@@ -546,7 +552,7 @@ class JobResult(models.Model):
         args: additional args passed to the callable
         args: additional args passed to the callable
         kwargs: additional kargs passed to the callable
         kwargs: additional kargs passed to the callable
         """
         """
-        job_result = cls.objects.create(
+        job_result: JobResult = cls.objects.create(
             name=name,
             name=name,
             obj_type=obj_type,
             obj_type=obj_type,
             user=user,
             user=user,
@@ -556,6 +562,9 @@ class JobResult(models.Model):
         queue = django_rq.get_queue("default")
         queue = django_rq.get_queue("default")
         
         
         if schedule_at := kwargs.pop("schedule_at", None):
         if schedule_at := kwargs.pop("schedule_at", None):
+            job_result.status = JobResultStatusChoices.STATUS_SCHEDULED
+            job_result.save()
+            
             queue.enqueue_at(schedule_at, func, job_id=str(job_result.job_id), job_result=job_result, **kwargs)
             queue.enqueue_at(schedule_at, func, job_id=str(job_result.job_id), job_result=job_result, **kwargs)
         else:
         else:
             queue.enqueue(func, job_id=str(job_result.job_id), job_result=job_result, **kwargs)
             queue.enqueue(func, job_id=str(job_result.job_id), job_result=job_result, **kwargs)

+ 25 - 0
netbox/extras/tables/tables.py

@@ -8,6 +8,7 @@ from .template_code import *
 __all__ = (
 __all__ = (
     'ConfigContextTable',
     'ConfigContextTable',
     'CustomFieldTable',
     'CustomFieldTable',
+    'JobResultTable',
     'CustomLinkTable',
     'CustomLinkTable',
     'ExportTemplateTable',
     'ExportTemplateTable',
     'JournalEntryTable',
     'JournalEntryTable',
@@ -39,6 +40,30 @@ class CustomFieldTable(NetBoxTable):
         default_columns = ('pk', 'name', 'content_types', 'label', 'group_name', 'type', 'required', 'description')
         default_columns = ('pk', 'name', 'content_types', 'label', 'group_name', 'type', 'required', 'description')
 
 
 
 
+#
+# Custom fields
+#
+
+class JobResultTable(NetBoxTable):
+    name = tables.Column(
+        linkify=True
+    )
+    #obj_type = columns.ContentTypesColumn()
+    required = columns.BooleanColumn()
+    ui_visibility = columns.ChoiceFieldColumn(verbose_name="UI visibility")
+
+    actions = columns.ActionsColumn(
+        actions=() # TODO: Delete
+    )
+
+    class Meta(NetBoxTable.Meta):
+        model = JobResult
+        fields = (
+            'pk', 'id', 'name', 'obj_type', 'created', 'completed', 'user', 'status', 'job_id',
+        )
+        default_columns = ('pk', 'id', 'name', 'obj_type', 'created', 'completed', 'user', 'status', 'job_id')
+
+
 #
 #
 # Custom links
 # Custom links
 #
 #

+ 4 - 0
netbox/extras/urls.py

@@ -103,6 +103,10 @@ urlpatterns = [
     path('reports/results/<int:job_result_pk>/', views.ReportResultView.as_view(), name='report_result'),
     path('reports/results/<int:job_result_pk>/', views.ReportResultView.as_view(), name='report_result'),
     re_path(r'^reports/(?P<module>.([^.]+)).(?P<name>.(.+))/', views.ReportView.as_view(), name='report'),
     re_path(r'^reports/(?P<module>.([^.]+)).(?P<name>.(.+))/', views.ReportView.as_view(), name='report'),
 
 
+    # Job results
+    path('job-results/', views.JobResultListView.as_view(), name='jobresult_view'),
+    # path('custom-fields/<int:pk>/', views.CustomFieldView.as_view(), name='customfield'),
+
     # Scripts
     # Scripts
     path('scripts/', views.ScriptListView.as_view(), name='script_list'),
     path('scripts/', views.ScriptListView.as_view(), name='script_list'),
     path('scripts/results/<int:job_result_pk>/', views.ScriptResultView.as_view(), name='script_result'),
     path('scripts/results/<int:job_result_pk>/', views.ScriptResultView.as_view(), name='script_result'),

+ 11 - 0
netbox/extras/views.py

@@ -775,3 +775,14 @@ class ScriptResultView(ContentTypePermissionRequiredMixin, GetScriptMixin, View)
             'result': result,
             'result': result,
             'class_name': script.__class__.__name__
             'class_name': script.__class__.__name__
         })
         })
+
+
+#
+# Job results
+#
+
+class JobResultListView(generic.ObjectListView):
+    queryset = JobResult.objects.all()
+    filterset = filtersets.JobResultFilterSet
+    filterset_form = forms.JobResultFilterForm
+    table = tables.JobResultTable