From b67b4f66da8136e0b0f8c54782622c54312c491d Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 16 May 2024 10:45:32 -0700 Subject: [PATCH] 16145 script api use module.script name instead of pk --- netbox/extras/api/views.py | 21 +++++++++++++++++---- netbox/extras/tests/test_api.py | 8 ++++++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index 1f76467b5..1be171dfa 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -1,3 +1,4 @@ +from django.http import Http404 from django.shortcuts import get_object_or_404 from django_rq.queues import get_connection from rest_framework import status @@ -13,7 +14,7 @@ from rq import Worker from core.models import Job, ObjectType from extras import filtersets from extras.models import * -from extras.scripts import run_script +from extras.scripts import get_module_and_script, run_script from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired from netbox.api.features import SyncedDataMixin from netbox.api.metadata import ContentTypeMetadata @@ -215,21 +216,33 @@ class ScriptViewSet(ModelViewSet): _ignore_model_permissions = True lookup_value_regex = '[^/]+' # Allow dots + def _get_script(self, 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 + + return module, script + def retrieve(self, request, pk): - script = get_object_or_404(self.queryset, pk=pk) + module, script = self._get_script(pk) serializer = serializers.ScriptDetailSerializer(script, context={'request': request}) return Response(serializer.data) def post(self, request, pk): """ - Run a Script identified by the id and return the pending Job as the result + Run a Script identified by the name and return the pending Job as the result """ if not request.user.has_perm('extras.run_script'): raise PermissionDenied("This user does not have permission to run scripts.") - script = get_object_or_404(self.queryset, pk=pk) + module, script = self._get_script(pk) input_serializer = serializers.ScriptInputSerializer( data=request.data, context={'script': script} diff --git a/netbox/extras/tests/test_api.py b/netbox/extras/tests/test_api.py index 5d243ae1a..e4e2edb4f 100644 --- a/netbox/extras/tests/test_api.py +++ b/netbox/extras/tests/test_api.py @@ -780,12 +780,16 @@ class ScriptTest(APITestCase): def python_class(self): return self.TestScriptClass + def get_test_script(self, *args): + module = ScriptModule.objects.first() + return module, module.scripts.first() + def setUp(self): super().setUp() # Monkey-patch the Script model to return our TestScriptClass above from extras.api.views import ScriptViewSet - Script.python_class = self.python_class + ScriptViewSet._get_script = self.get_test_script def test_get_script(self): module = ScriptModule.objects.get( @@ -793,7 +797,7 @@ class ScriptTest(APITestCase): file_path='/var/tmp/script.py' ) script = module.scripts.all().first() - url = reverse('extras-api:script-detail', kwargs={'pk': script.pk}) + url = reverse('extras-api:script-detail', kwargs={'pk': None}) response = self.client.get(url, **self.header) self.assertEqual(response.data['name'], self.TestScriptClass.Meta.name)