16145 script api use module.script name instead of pk

This commit is contained in:
Arthur 2024-05-16 10:45:32 -07:00
parent 755513a148
commit b67b4f66da
2 changed files with 23 additions and 6 deletions

View File

@ -1,3 +1,4 @@
from django.http import Http404
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django_rq.queues import get_connection from django_rq.queues import get_connection
from rest_framework import status from rest_framework import status
@ -13,7 +14,7 @@ from rq import Worker
from core.models import Job, ObjectType from core.models import Job, ObjectType
from extras import filtersets from extras import filtersets
from extras.models import * 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.authentication import IsAuthenticatedOrLoginNotRequired
from netbox.api.features import SyncedDataMixin from netbox.api.features import SyncedDataMixin
from netbox.api.metadata import ContentTypeMetadata from netbox.api.metadata import ContentTypeMetadata
@ -215,21 +216,33 @@ class ScriptViewSet(ModelViewSet):
_ignore_model_permissions = True _ignore_model_permissions = True
lookup_value_regex = '[^/]+' # Allow dots 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): 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}) serializer = serializers.ScriptDetailSerializer(script, context={'request': request})
return Response(serializer.data) return Response(serializer.data)
def post(self, request, pk): 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'): if not request.user.has_perm('extras.run_script'):
raise PermissionDenied("This user does not have permission to run scripts.") 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( input_serializer = serializers.ScriptInputSerializer(
data=request.data, data=request.data,
context={'script': script} context={'script': script}

View File

@ -780,12 +780,16 @@ class ScriptTest(APITestCase):
def python_class(self): def python_class(self):
return self.TestScriptClass return self.TestScriptClass
def get_test_script(self, *args):
module = ScriptModule.objects.first()
return module, module.scripts.first()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
# Monkey-patch the Script model to return our TestScriptClass above # Monkey-patch the Script model to return our TestScriptClass above
from extras.api.views import ScriptViewSet from extras.api.views import ScriptViewSet
Script.python_class = self.python_class ScriptViewSet._get_script = self.get_test_script
def test_get_script(self): def test_get_script(self):
module = ScriptModule.objects.get( module = ScriptModule.objects.get(
@ -793,7 +797,7 @@ class ScriptTest(APITestCase):
file_path='/var/tmp/script.py' file_path='/var/tmp/script.py'
) )
script = module.scripts.all().first() 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) response = self.client.get(url, **self.header)
self.assertEqual(response.data['name'], self.TestScriptClass.Meta.name) self.assertEqual(response.data['name'], self.TestScriptClass.Meta.name)