diff --git a/netbox/netbox/urls.py b/netbox/netbox/urls.py index 260d389cf..1c8051c06 100644 --- a/netbox/netbox/urls.py +++ b/netbox/netbox/urls.py @@ -42,6 +42,7 @@ _patterns = [ url(r'^api/ipam/', include('ipam.api.urls')), url(r'^api/secrets/', include('secrets.api.urls')), url(r'^api/tenancy/', include('tenancy.api.urls')), + url(r'^api/virtualization/', include('virtualization.api.urls')), url(r'^api/docs/', swagger_view, name='api_docs'), # Serving static media in Django to pipe it through LoginRequiredMiddleware diff --git a/netbox/virtualization/api/__init__.py b/netbox/virtualization/api/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/netbox/virtualization/api/serializers.py b/netbox/virtualization/api/serializers.py new file mode 100644 index 000000000..5b73d9bea --- /dev/null +++ b/netbox/virtualization/api/serializers.py @@ -0,0 +1,139 @@ +from __future__ import unicode_literals + +from rest_framework import serializers + +from dcim.api.serializers import NestedPlatformSerializer +from extras.api.customfields import CustomFieldModelSerializer +from tenancy.api.serializers import NestedTenantSerializer +from utilities.api import ModelValidationMixin +from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface + + +# +# Cluster types +# + +class ClusterTypeSerializer(ModelValidationMixin, serializers.ModelSerializer): + + class Meta: + model = ClusterType + fields = ['id', 'name', 'slug'] + + +class NestedClusterTypeSerializer(serializers.ModelSerializer): + url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:clustertype-detail') + + class Meta: + model = ClusterType + fields = ['id', 'url', 'name', 'slug'] + + +# +# Cluster groups +# + +class ClusterGroupSerializer(ModelValidationMixin, serializers.ModelSerializer): + + class Meta: + model = ClusterGroup + fields = ['id', 'name', 'slug'] + + +class NestedClusterGroupSerializer(serializers.ModelSerializer): + url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:clustergroup-detail') + + class Meta: + model = ClusterGroup + fields = ['id', 'url', 'name', 'slug'] + + +# +# Clusters +# + +class ClusterSerializer(CustomFieldModelSerializer): + type = NestedClusterTypeSerializer() + group = NestedClusterGroupSerializer() + + class Meta: + model = Cluster + fields = ['id', 'name', 'type', 'group', 'comments', 'custom_fields'] + + +class NestedClusterSerializer(serializers.ModelSerializer): + url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:cluster-detail') + + class Meta: + model = Cluster + fields = ['id', 'url', 'name'] + + +class WritableClusterSerializer(ModelValidationMixin, CustomFieldModelSerializer): + + class Meta: + model = Cluster + fields = ['id', 'name', 'type', 'group', 'comments', 'custom_fields'] + + +# +# Virtual machines +# + +class VirtualMachineSerializer(CustomFieldModelSerializer): + cluster = NestedClusterSerializer() + tenant = NestedTenantSerializer() + platform = NestedPlatformSerializer() + + class Meta: + model = VirtualMachine + fields = [ + 'id', 'name', 'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6', 'comments', 'custom_fields', + ] + + +class NestedVirtualMachineSerializer(serializers.ModelSerializer): + url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:virtualmachine-detail') + + class Meta: + model = VirtualMachine + fields = ['id', 'url', 'name'] + + +class WritableVirtualMachineSerializer(ModelValidationMixin, CustomFieldModelSerializer): + + class Meta: + model = Cluster + fields = [ + 'id', 'name', 'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6', 'comments', 'custom_fields', + ] + + +# +# VM interfaces +# + +class VMInterfaceSerializer(serializers.ModelSerializer): + virtual_machine = NestedVirtualMachineSerializer() + + class Meta: + model = VMInterface + fields = [ + 'id', 'name', 'virtual_machine', 'enabled', 'mac_address', 'mtu', 'description', + ] + + +class NestedVMInterfaceSerializer(serializers.ModelSerializer): + url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:vminterface-detail') + + class Meta: + model = VMInterface + fields = ['id', 'url', 'name'] + + +class WritableVMInterfaceSerializer(ModelValidationMixin, serializers.ModelSerializer): + + class Meta: + model = VMInterface + fields = [ + 'id', 'name', 'virtual_machine', 'enabled', 'mac_address', 'mtu', 'description', + ] diff --git a/netbox/virtualization/api/urls.py b/netbox/virtualization/api/urls.py new file mode 100644 index 000000000..a53fdbde2 --- /dev/null +++ b/netbox/virtualization/api/urls.py @@ -0,0 +1,29 @@ +from __future__ import unicode_literals + +from rest_framework import routers + +from . import views + + +class VirtualizationRootView(routers.APIRootView): + """ + Virtualization API root view + """ + def get_view_name(self): + return 'Virtualization' + + +router = routers.DefaultRouter() +router.APIRootView = VirtualizationRootView + +# Clusters +router.register(r'cluster-types', views.ClusterTypeViewSet) +router.register(r'cluster-groups', views.ClusterGroupViewSet) +router.register(r'clusters', views.ClusterViewSet) + +# VirtualMachines +router.register(r'virtual-machines', views.VirtualMachineViewSet) +router.register(r'vm-interfaces', views.VMInterfaceViewSet) + +app_name = 'virtualization-api' +urlpatterns = router.urls diff --git a/netbox/virtualization/api/views.py b/netbox/virtualization/api/views.py new file mode 100644 index 000000000..79fd73ca8 --- /dev/null +++ b/netbox/virtualization/api/views.py @@ -0,0 +1,44 @@ +from __future__ import unicode_literals + +from rest_framework.viewsets import ModelViewSet + +from extras.api.views import CustomFieldModelViewSet +from utilities.api import WritableSerializerMixin +from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface +from . import serializers + + +# +# Clusters +# + +class ClusterTypeViewSet(ModelViewSet): + queryset = ClusterType.objects.all() + serializer_class = serializers.ClusterTypeSerializer + + +class ClusterGroupViewSet(ModelViewSet): + queryset = ClusterGroup.objects.all() + serializer_class = serializers.ClusterGroupSerializer + + +class ClusterViewSet(WritableSerializerMixin, CustomFieldModelViewSet): + queryset = Cluster.objects.select_related('type', 'group') + serializer_class = serializers.ClusterSerializer + write_serializer_class = serializers.WritableClusterSerializer + + +# +# Virtual machines +# + +class VirtualMachineViewSet(WritableSerializerMixin, CustomFieldModelViewSet): + queryset = VirtualMachine.objects.all() + serializer_class = serializers.VirtualMachineSerializer + write_serializer_class = serializers.WritableVirtualMachineSerializer + + +class VMInterfaceViewSet(WritableSerializerMixin, ModelViewSet): + queryset = VMInterface.objects.select_related('virtual_machine') + serializer_class = serializers.VMInterfaceSerializer + write_serializer_class = serializers.WritableVMInterfaceSerializer diff --git a/netbox/virtualization/tables.py b/netbox/virtualization/tables.py index 3beb7b53b..a5bbad9a2 100644 --- a/netbox/virtualization/tables.py +++ b/netbox/virtualization/tables.py @@ -9,13 +9,13 @@ from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterf CLUSTERTYPE_ACTIONS = """ {% if perms.virtualization.change_clustertype %} - + {% endif %} """ CLUSTERGROUP_ACTIONS = """ {% if perms.virtualization.change_clustergroup %} - + {% endif %} """