From bb6eff89405011a6acda1876c3379fe3c6710cac Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 7 Feb 2023 16:26:06 -0500 Subject: [PATCH] Add a REST API endpoint to synchronize config context data --- netbox/extras/api/views.py | 6 ++++-- netbox/netbox/api/features.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 netbox/netbox/api/features.py diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index 1423824cd..8b97491b1 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -17,6 +17,7 @@ from extras.models import CustomField from extras.reports import get_report, get_reports, run_report from extras.scripts import get_script, get_scripts, run_script from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired +from netbox.api.features import SyncedDataMixin from netbox.api.metadata import ContentTypeMetadata from netbox.api.viewsets import NetBoxModelViewSet from utilities.exceptions import RQWorkerNotRunningException @@ -147,9 +148,10 @@ class JournalEntryViewSet(NetBoxModelViewSet): # Config contexts # -class ConfigContextViewSet(NetBoxModelViewSet): +class ConfigContextViewSet(SyncedDataMixin, NetBoxModelViewSet): queryset = ConfigContext.objects.prefetch_related( - 'regions', 'site_groups', 'sites', 'locations', 'roles', 'platforms', 'tenant_groups', 'tenants', + 'regions', 'site_groups', 'sites', 'locations', 'roles', 'platforms', 'tenant_groups', 'tenants', 'data_source', + 'data_file', ) serializer_class = serializers.ConfigContextSerializer filterset_class = filtersets.ConfigContextFilterSet diff --git a/netbox/netbox/api/features.py b/netbox/netbox/api/features.py new file mode 100644 index 000000000..db018ca12 --- /dev/null +++ b/netbox/netbox/api/features.py @@ -0,0 +1,30 @@ +from django.shortcuts import get_object_or_404 +from rest_framework.decorators import action +from rest_framework.exceptions import PermissionDenied +from rest_framework.response import Response + +from utilities.permissions import get_permission_for_model + +__all__ = ( + 'SyncedDataMixin', +) + + +class SyncedDataMixin: + + @action(detail=True, methods=['post']) + def sync(self, request, pk): + """ + Provide a /sync API endpoint to synchronize an object's data from its associated DataFile (if any). + """ + permission = get_permission_for_model(self.queryset.model, 'sync') + if not request.user.has_perm(permission): + raise PermissionDenied(f"Missing permission: {permission}") + + obj = get_object_or_404(self.queryset, pk=pk) + if obj.data_file: + obj.sync_data() + obj.save() + serializer = self.serializer_class(obj, context={'request': request}) + + return Response(serializer.data)