mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-23 13:52:17 -06:00
#11559: Add device config API endpoint & cleanup
This commit is contained in:
@@ -604,6 +604,7 @@ class InventoryItemTemplateSerializer(ValidatedModelSerializer):
|
||||
|
||||
class DeviceRoleSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail')
|
||||
config_template = NestedConfigTemplateSerializer(required=False, allow_null=True, default=None)
|
||||
device_count = serializers.IntegerField(read_only=True)
|
||||
virtualmachine_count = serializers.IntegerField(read_only=True)
|
||||
|
||||
@@ -618,6 +619,7 @@ class DeviceRoleSerializer(NetBoxModelSerializer):
|
||||
class PlatformSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail')
|
||||
manufacturer = NestedManufacturerSerializer(required=False, allow_null=True)
|
||||
config_template = NestedConfigTemplateSerializer(required=False, allow_null=True, default=None)
|
||||
device_count = serializers.IntegerField(read_only=True)
|
||||
virtualmachine_count = serializers.IntegerField(read_only=True)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import socket
|
||||
|
||||
from django.http import Http404, HttpResponse, HttpResponseForbidden
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from drf_yasg import openapi
|
||||
from drf_yasg.openapi import Parameter
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.renderers import JSONRenderer
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.status import HTTP_400_BAD_REQUEST
|
||||
from rest_framework.routers import APIRootView
|
||||
from rest_framework.viewsets import ViewSet
|
||||
|
||||
@@ -15,14 +15,14 @@ from dcim import filtersets
|
||||
from dcim.constants import CABLE_TRACE_SVG_DEFAULT_WIDTH
|
||||
from dcim.models import *
|
||||
from dcim.svg import CableTraceSVG
|
||||
from extras.api.views import ConfigContextQuerySetMixin
|
||||
from extras.api.nested_serializers import NestedConfigTemplateSerializer
|
||||
from extras.api.mixins import ConfigContextQuerySetMixin, ConfigTemplateRenderMixin
|
||||
from ipam.models import Prefix, VLAN
|
||||
from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired
|
||||
from netbox.api.exceptions import ServiceUnavailable
|
||||
from netbox.api.metadata import ContentTypeMetadata
|
||||
from netbox.api.pagination import StripCountAnnotationsPaginator
|
||||
from netbox.api.renderers import TextRenderer
|
||||
from netbox.api.viewsets import NetBoxModelViewSet
|
||||
from netbox.config import get_config
|
||||
from netbox.constants import NESTED_SERIALIZER_PREFIX
|
||||
from utilities.api import get_serializer_for_model
|
||||
from utilities.utils import count_related
|
||||
@@ -391,10 +391,10 @@ class PlatformViewSet(NetBoxModelViewSet):
|
||||
# Devices/modules
|
||||
#
|
||||
|
||||
class DeviceViewSet(ConfigContextQuerySetMixin, NetBoxModelViewSet):
|
||||
class DeviceViewSet(ConfigContextQuerySetMixin, ConfigTemplateRenderMixin, NetBoxModelViewSet):
|
||||
queryset = Device.objects.prefetch_related(
|
||||
'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'site', 'location', 'rack', 'parent_bay',
|
||||
'virtual_chassis__master', 'primary_ip4__nat_outside', 'primary_ip6__nat_outside', 'tags',
|
||||
'virtual_chassis__master', 'primary_ip4__nat_outside', 'primary_ip6__nat_outside', 'config_template', 'tags',
|
||||
)
|
||||
filterset_class = filtersets.DeviceFilterSet
|
||||
pagination_class = StripCountAnnotationsPaginator
|
||||
@@ -419,6 +419,19 @@ class DeviceViewSet(ConfigContextQuerySetMixin, NetBoxModelViewSet):
|
||||
|
||||
return serializers.DeviceWithConfigContextSerializer
|
||||
|
||||
@action(detail=True, methods=['post'], url_path='render-config', renderer_classes=[JSONRenderer, TextRenderer])
|
||||
def render_config(self, request, pk):
|
||||
"""
|
||||
Resolve and render the preferred ConfigTemplate for this Device.
|
||||
"""
|
||||
device = self.get_object()
|
||||
configtemplate = device.get_config_template()
|
||||
if not configtemplate:
|
||||
return Response({'error': 'No config template found for this device.'}, status=HTTP_400_BAD_REQUEST)
|
||||
context = {**request.data, 'device': device}
|
||||
|
||||
return self.render_configtemplate(request, configtemplate, context)
|
||||
|
||||
|
||||
class VirtualDeviceContextViewSet(NetBoxModelViewSet):
|
||||
queryset = VirtualDeviceContext.objects.prefetch_related(
|
||||
|
||||
@@ -1987,6 +1987,17 @@ class DeviceInventoryView(DeviceComponentsView):
|
||||
)
|
||||
|
||||
|
||||
@register_model_view(Device, 'configcontext', path='config-context')
|
||||
class DeviceConfigContextView(ObjectConfigContextView):
|
||||
queryset = Device.objects.annotate_config_context_data()
|
||||
base_template = 'dcim/device/base.html'
|
||||
tab = ViewTab(
|
||||
label=_('Config Context'),
|
||||
permission='extras.view_configcontext',
|
||||
weight=2000
|
||||
)
|
||||
|
||||
|
||||
@register_model_view(Device, 'render-config')
|
||||
class DeviceRenderConfigView(generic.ObjectView):
|
||||
queryset = Device.objects.all()
|
||||
@@ -1994,7 +2005,7 @@ class DeviceRenderConfigView(generic.ObjectView):
|
||||
tab = ViewTab(
|
||||
label=_('Render Config'),
|
||||
permission='extras.view_configtemplate',
|
||||
weight=2000
|
||||
weight=2100
|
||||
)
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
@@ -2020,17 +2031,6 @@ class DeviceRenderConfigView(generic.ObjectView):
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(Device, 'configcontext', path='config-context')
|
||||
class DeviceConfigContextView(ObjectConfigContextView):
|
||||
queryset = Device.objects.annotate_config_context_data()
|
||||
base_template = 'dcim/device/base.html'
|
||||
tab = ViewTab(
|
||||
label=_('Config Context'),
|
||||
permission='extras.view_configcontext',
|
||||
weight=2100
|
||||
)
|
||||
|
||||
|
||||
class DeviceBulkImportView(generic.BulkImportView):
|
||||
queryset = Device.objects.all()
|
||||
model_form = forms.DeviceImportForm
|
||||
|
||||
Reference in New Issue
Block a user