1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #1556: Added API endpoints listing static field choices for each app

This commit is contained in:
Jeremy Stretch
2017-10-10 16:41:35 -04:00
parent afbbe1148f
commit f824d1eb3b
15 changed files with 187 additions and 8 deletions

View File

@ -16,6 +16,9 @@ class CircuitsRootView(routers.APIRootView):
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.APIRootView = CircuitsRootView router.APIRootView = CircuitsRootView
# Field choices
router.register(r'_choices', views.CircuitsFieldChoicesViewSet, base_name='field-choice')
# Providers # Providers
router.register(r'providers', views.ProviderViewSet) router.register(r'providers', views.ProviderViewSet)

View File

@ -11,10 +11,20 @@ from circuits.models import Provider, CircuitTermination, CircuitType, Circuit
from extras.models import Graph, GRAPH_TYPE_PROVIDER from extras.models import Graph, GRAPH_TYPE_PROVIDER
from extras.api.serializers import RenderedGraphSerializer from extras.api.serializers import RenderedGraphSerializer
from extras.api.views import CustomFieldModelViewSet from extras.api.views import CustomFieldModelViewSet
from utilities.api import WritableSerializerMixin from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
from . import serializers from . import serializers
#
# Field choices
#
class CircuitsFieldChoicesViewSet(FieldChoicesViewSet):
fields = (
(CircuitTermination, ['term_side']),
)
# #
# Providers # Providers
# #

View File

@ -16,6 +16,9 @@ class DCIMRootView(routers.APIRootView):
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.APIRootView = DCIMRootView router.APIRootView = DCIMRootView
# Field choices
router.register(r'_choices', views.DCIMFieldChoicesViewSet, base_name='field-choice')
# Sites # Sites
router.register(r'regions', views.RegionViewSet) router.register(r'regions', views.RegionViewSet)
router.register(r'sites', views.SiteViewSet) router.register(r'sites', views.SiteViewSet)

View File

@ -20,11 +20,27 @@ from dcim import filters
from extras.api.serializers import RenderedGraphSerializer from extras.api.serializers import RenderedGraphSerializer
from extras.api.views import CustomFieldModelViewSet from extras.api.views import CustomFieldModelViewSet
from extras.models import Graph, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_SITE from extras.models import Graph, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_SITE
from utilities.api import IsAuthenticatedOrLoginNotRequired, ServiceUnavailable, WritableSerializerMixin from utilities.api import IsAuthenticatedOrLoginNotRequired, FieldChoicesViewSet, ServiceUnavailable, WritableSerializerMixin
from .exceptions import MissingFilterException from .exceptions import MissingFilterException
from . import serializers from . import serializers
#
# Field choices
#
class DCIMFieldChoicesViewSet(FieldChoicesViewSet):
fields = (
(Device, ['face', 'status']),
(ConsolePort, ['connection_status']),
(Interface, ['form_factor']),
(InterfaceConnection, ['connection_status']),
(InterfaceTemplate, ['form_factor']),
(PowerPort, ['connection_status']),
(Rack, ['type', 'width']),
)
# #
# Regions # Regions
# #

View File

@ -16,6 +16,9 @@ class ExtrasRootView(routers.APIRootView):
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.APIRootView = ExtrasRootView router.APIRootView = ExtrasRootView
# Field choices
router.register(r'_choices', views.ExtrasFieldChoicesViewSet, base_name='field-choice')
# Graphs # Graphs
router.register(r'graphs', views.GraphViewSet) router.register(r'graphs', views.GraphViewSet)

View File

@ -10,12 +10,27 @@ from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from extras import filters from extras import filters
from extras.models import ExportTemplate, Graph, ImageAttachment, ReportResult, TopologyMap, UserAction from extras.models import CustomField, ExportTemplate, Graph, ImageAttachment, ReportResult, TopologyMap, UserAction
from extras.reports import get_report, get_reports from extras.reports import get_report, get_reports
from utilities.api import WritableSerializerMixin from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
from . import serializers from . import serializers
#
# Field choices
#
class ExtrasFieldChoicesViewSet(FieldChoicesViewSet):
fields = (
(CustomField, ['type']),
(Graph, ['type']),
)
#
# Custom fields
#
class CustomFieldModelViewSet(ModelViewSet): class CustomFieldModelViewSet(ModelViewSet):
""" """
Include the applicable set of CustomFields in the ModelViewSet context. Include the applicable set of CustomFields in the ModelViewSet context.
@ -46,6 +61,10 @@ class CustomFieldModelViewSet(ModelViewSet):
return super(CustomFieldModelViewSet, self).get_queryset().prefetch_related('custom_field_values__field') return super(CustomFieldModelViewSet, self).get_queryset().prefetch_related('custom_field_values__field')
#
# Graphs
#
class GraphViewSet(WritableSerializerMixin, ModelViewSet): class GraphViewSet(WritableSerializerMixin, ModelViewSet):
queryset = Graph.objects.all() queryset = Graph.objects.all()
serializer_class = serializers.GraphSerializer serializer_class = serializers.GraphSerializer
@ -53,12 +72,20 @@ class GraphViewSet(WritableSerializerMixin, ModelViewSet):
filter_class = filters.GraphFilter filter_class = filters.GraphFilter
#
# Export templates
#
class ExportTemplateViewSet(WritableSerializerMixin, ModelViewSet): class ExportTemplateViewSet(WritableSerializerMixin, ModelViewSet):
queryset = ExportTemplate.objects.all() queryset = ExportTemplate.objects.all()
serializer_class = serializers.ExportTemplateSerializer serializer_class = serializers.ExportTemplateSerializer
filter_class = filters.ExportTemplateFilter filter_class = filters.ExportTemplateFilter
#
# Topology maps
#
class TopologyMapViewSet(WritableSerializerMixin, ModelViewSet): class TopologyMapViewSet(WritableSerializerMixin, ModelViewSet):
queryset = TopologyMap.objects.select_related('site') queryset = TopologyMap.objects.select_related('site')
serializer_class = serializers.TopologyMapSerializer serializer_class = serializers.TopologyMapSerializer
@ -85,12 +112,20 @@ class TopologyMapViewSet(WritableSerializerMixin, ModelViewSet):
return response return response
#
# Image attachments
#
class ImageAttachmentViewSet(WritableSerializerMixin, ModelViewSet): class ImageAttachmentViewSet(WritableSerializerMixin, ModelViewSet):
queryset = ImageAttachment.objects.all() queryset = ImageAttachment.objects.all()
serializer_class = serializers.ImageAttachmentSerializer serializer_class = serializers.ImageAttachmentSerializer
write_serializer_class = serializers.WritableImageAttachmentSerializer write_serializer_class = serializers.WritableImageAttachmentSerializer
#
# Reports
#
class ReportViewSet(ViewSet): class ReportViewSet(ViewSet):
_ignore_model_permissions = True _ignore_model_permissions = True
exclude_from_schema = True exclude_from_schema = True
@ -162,6 +197,10 @@ class ReportViewSet(ViewSet):
return Response(serializer.data) return Response(serializer.data)
#
# User activity
#
class RecentActivityViewSet(ReadOnlyModelViewSet): class RecentActivityViewSet(ReadOnlyModelViewSet):
""" """
List all UserActions to provide a log of recent activity. List all UserActions to provide a log of recent activity.

View File

@ -16,6 +16,9 @@ class IPAMRootView(routers.APIRootView):
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.APIRootView = IPAMRootView router.APIRootView = IPAMRootView
# Field choices
router.register(r'_choices', views.IPAMFieldChoicesViewSet, base_name='field-choice')
# VRFs # VRFs
router.register(r'vrfs', views.VRFViewSet) router.register(r'vrfs', views.VRFViewSet)

View File

@ -12,10 +12,24 @@ from django.shortcuts import get_object_or_404
from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
from ipam import filters from ipam import filters
from extras.api.views import CustomFieldModelViewSet from extras.api.views import CustomFieldModelViewSet
from utilities.api import WritableSerializerMixin from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
from . import serializers from . import serializers
#
# Field choices
#
class IPAMFieldChoicesViewSet(FieldChoicesViewSet):
fields = (
(Aggregate, ['family']),
(Prefix, ['family', 'status']),
(IPAddress, ['family', 'status', 'role']),
(VLAN, ['status']),
(Service, ['protocol']),
)
# #
# VRFs # VRFs
# #

View File

@ -16,6 +16,9 @@ class SecretsRootView(routers.APIRootView):
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.APIRootView = SecretsRootView router.APIRootView = SecretsRootView
# Field choices
router.register(r'_choices', views.SecretsFieldChoicesViewSet, base_name='field-choice')
# Secrets # Secrets
router.register(r'secret-roles', views.SecretRoleViewSet) router.register(r'secret-roles', views.SecretRoleViewSet)
router.register(r'secrets', views.SecretViewSet) router.register(r'secrets', views.SecretViewSet)

View File

@ -12,7 +12,7 @@ from django.http import HttpResponseBadRequest
from secrets import filters from secrets import filters
from secrets.exceptions import InvalidKey from secrets.exceptions import InvalidKey
from secrets.models import Secret, SecretRole, SessionKey, UserKey from secrets.models import Secret, SecretRole, SessionKey, UserKey
from utilities.api import WritableSerializerMixin from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
from . import serializers from . import serializers
@ -22,6 +22,14 @@ ERR_PRIVKEY_MISSING = "Private key was not provided."
ERR_PRIVKEY_INVALID = "Invalid private key." ERR_PRIVKEY_INVALID = "Invalid private key."
#
# Field choices
#
class SecretsFieldChoicesViewSet(FieldChoicesViewSet):
fields = ()
# #
# Secret Roles # Secret Roles
# #

View File

@ -16,6 +16,9 @@ class TenancyRootView(routers.APIRootView):
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.APIRootView = TenancyRootView router.APIRootView = TenancyRootView
# Field choices
router.register(r'_choices', views.TenancyFieldChoicesViewSet, base_name='field-choice')
# Tenants # Tenants
router.register(r'tenant-groups', views.TenantGroupViewSet) router.register(r'tenant-groups', views.TenantGroupViewSet)
router.register(r'tenants', views.TenantViewSet) router.register(r'tenants', views.TenantViewSet)

View File

@ -5,10 +5,18 @@ from rest_framework.viewsets import ModelViewSet
from extras.api.views import CustomFieldModelViewSet from extras.api.views import CustomFieldModelViewSet
from tenancy import filters from tenancy import filters
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
from utilities.api import WritableSerializerMixin from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
from . import serializers from . import serializers
#
# Field choices
#
class TenancyFieldChoicesViewSet(FieldChoicesViewSet):
fields = ()
# #
# Tenant Groups # Tenant Groups
# #

View File

@ -1,12 +1,16 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from collections import OrderedDict
from django.conf import settings from django.conf import settings
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.http import Http404
from rest_framework.compat import is_authenticated from rest_framework.compat import is_authenticated
from rest_framework.exceptions import APIException from rest_framework.exceptions import APIException
from rest_framework.permissions import BasePermission from rest_framework.permissions import BasePermission
from rest_framework.response import Response
from rest_framework.serializers import Field, ModelSerializer, ValidationError from rest_framework.serializers import Field, ModelSerializer, ValidationError
from rest_framework.viewsets import ViewSet
WRITE_OPERATIONS = ['create', 'update', 'partial_update', 'delete'] WRITE_OPERATIONS = ['create', 'update', 'partial_update', 'delete']
@ -94,6 +98,55 @@ class ContentTypeFieldSerializer(Field):
raise ValidationError("Invalid content type") raise ValidationError("Invalid content type")
#
# Views
#
class FieldChoicesViewSet(ViewSet):
"""
Expose the built-in numeric values which represent static choices for a model's field.
"""
permission_classes = [IsAuthenticatedOrLoginNotRequired]
fields = []
def __init__(self, *args, **kwargs):
super(FieldChoicesViewSet, self).__init__(*args, **kwargs)
# Compile a dict of all fields in this view
self._fields = OrderedDict()
for cls, field_list in self.fields:
for field_name in field_list:
model_name = cls._meta.verbose_name.lower().replace(' ', '-')
key = ':'.join([model_name, field_name])
choices = []
for k, v in cls._meta.get_field(field_name).choices:
if type(v) in [list, tuple]:
for k2, v2 in v:
choices.append({
'value': v2,
'label': k2,
})
else:
choices.append({
'value': v,
'label': k,
})
self._fields[key] = choices
def list(self, request):
return Response(self._fields)
def retrieve(self, request, pk):
if pk not in self._fields:
raise Http404
return Response(self._fields[pk])
def get_view_name(self):
return "Field Choices"
# #
# Mixins # Mixins
# #

View File

@ -16,6 +16,9 @@ class VirtualizationRootView(routers.APIRootView):
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.APIRootView = VirtualizationRootView router.APIRootView = VirtualizationRootView
# Field choices
router.register(r'_choices', views.VirtualizationFieldChoicesViewSet, base_name='field-choice')
# Clusters # Clusters
router.register(r'cluster-types', views.ClusterTypeViewSet) router.register(r'cluster-types', views.ClusterTypeViewSet)
router.register(r'cluster-groups', views.ClusterGroupViewSet) router.register(r'cluster-groups', views.ClusterGroupViewSet)

View File

@ -4,12 +4,22 @@ from rest_framework.viewsets import ModelViewSet
from dcim.models import Interface from dcim.models import Interface
from extras.api.views import CustomFieldModelViewSet from extras.api.views import CustomFieldModelViewSet
from utilities.api import WritableSerializerMixin from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
from virtualization import filters from virtualization import filters
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine
from . import serializers from . import serializers
#
# Field choices
#
class VirtualizationFieldChoicesViewSet(FieldChoicesViewSet):
fields = (
(VirtualMachine, ['status']),
)
# #
# Clusters # Clusters
# #