From 5290c86e0809ca8e8d4505a859a4f1ed250a9fe4 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 9 Feb 2024 11:32:41 -0800 Subject: [PATCH] 14438 fix serializer and api view --- netbox/extras/api/serializers.py | 24 ++++++++++++++++----- netbox/extras/api/views.py | 36 +++++++++++++++++++------------- netbox/extras/scripts.py | 2 +- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index 22fc67078..66925b388 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -512,16 +512,17 @@ class ConfigTemplateSerializer(TaggableModelSerializer, ValidatedModelSerializer # class ScriptSerializer(ValidatedModelSerializer): + id = serializers.CharField(read_only=True) url = serializers.HyperlinkedIdentityField(view_name='extras-api:script-detail',) description = serializers.SerializerMethodField(read_only=True) vars = serializers.SerializerMethodField(read_only=True) - # result = NestedJobSerializer() + result = serializers.SerializerMethodField(read_only=True) display = serializers.SerializerMethodField(read_only=True) class Meta: model = Script fields = [ - 'id', 'url', 'module', 'name', 'description', 'vars', 'display', + 'id', 'url', 'module', 'name', 'description', 'vars', 'result', 'display', ] @extend_schema_field(serializers.JSONField(allow_null=True)) @@ -546,12 +547,25 @@ class ScriptSerializer(ValidatedModelSerializer): @extend_schema_field(NestedJobSerializer()) def get_result(self, obj): - return f'{obj.name} ({obj.module})' + job = obj.jobs.all().order_by('-created').first() + context = { + 'request': self.context['request'] + } + data = NestedJobSerializer(job, context=context).data + return data class ScriptDetailSerializer(ScriptSerializer): - # result = JobSerializer() - pass + result = serializers.SerializerMethodField(read_only=True) + + @extend_schema_field(JobSerializer()) + def get_result(self, obj): + job = obj.jobs.all().order_by('-created').first() + context = { + 'request': self.context['request'] + } + data = JobSerializer(job, context=context).data + return data class ScriptInputSerializer(serializers.Serializer): diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index 8f5841da1..c0cb1f2f4 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -9,7 +9,7 @@ from rest_framework.generics import RetrieveUpdateDestroyAPIView from rest_framework.renderers import JSONRenderer from rest_framework.response import Response from rest_framework.routers import APIRootView -from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet +from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet, ViewSet from rq import Worker from core.choices import JobStatusChoices @@ -214,24 +214,35 @@ class ConfigTemplateViewSet(SyncedDataMixin, ConfigTemplateRenderMixin, NetBoxMo # Scripts # -class ScriptViewSet(ViewSet): +class ScriptViewSet(ModelViewSet): permission_classes = [IsAuthenticatedOrLoginNotRequired] + queryset = Script.objects.all().prefetch_related('jobs') + serializer_class = serializers.ScriptSerializer + # filterset_class = filtersets.ScriptFilterSet + _ignore_model_permissions = True schema = None lookup_value_regex = '[^/]+' # Allow dots def _get_script(self, pk): - try: - module_name, script_name = pk.split('.', maxsplit=1) - except ValueError: - raise Http404 + # check if includes '.' for old module.script lookup + if '.' in pk: + try: + module_name, script_name = pk.split('.', maxsplit=1) + except ValueError: + raise Http404 - module, script = get_module_and_script(module_name, script_name) - if script is None: - raise Http404 + module, script = get_module_and_script(module_name, script_name) + if script is None: + raise Http404 + else: + pk = int(pk) + script = get_object_or_404(self.queryset, pk=pk) + module = script.module return module, script + ''' def list(self, request): results = { job.name: job @@ -252,15 +263,10 @@ class ScriptViewSet(ViewSet): serializer = serializers.ScriptSerializer(script_list, many=True, context={'request': request}) return Response({'count': len(script_list), 'results': serializer.data}) + ''' def retrieve(self, request, pk): module, script = self._get_script(pk) - object_type = ContentType.objects.get(app_label='extras', model='scriptmodule') - script.result = Job.objects.filter( - object_type=object_type, - name=script.class_name, - status__in=JobStatusChoices.TERMINAL_STATE_CHOICES - ).first() serializer = serializers.ScriptDetailSerializer(script, context={'request': request}) return Response(serializer.data) diff --git a/netbox/extras/scripts.py b/netbox/extras/scripts.py index 4286ff4bb..973d8ff65 100644 --- a/netbox/extras/scripts.py +++ b/netbox/extras/scripts.py @@ -579,7 +579,7 @@ def is_variable(obj): def get_module_and_script(module_name, script_name): module = ScriptModule.objects.get(file_path=f'{module_name}.py') - script = module.scripts.get(script_name) + script = module.scripts.get(name=script_name) return module, script