Procházet zdrojové kódy

Closes #20295: Make cable terminations REST API endpoint read-only (#20394)

Jeremy Stretch před 4 měsíci
rodič
revize
12818f1786

+ 6 - 388
contrib/openapi.json

@@ -21698,191 +21698,6 @@
                         "description": ""
                     }
                 }
-            },
-            "post": {
-                "operationId": "dcim_cable_terminations_create",
-                "description": "Post a list of cable termination objects.",
-                "tags": [
-                    "dcim"
-                ],
-                "requestBody": {
-                    "content": {
-                        "application/json": {
-                            "schema": {
-                                "$ref": "#/components/schemas/CableTerminationRequest"
-                            }
-                        },
-                        "multipart/form-data": {
-                            "schema": {
-                                "$ref": "#/components/schemas/CableTerminationRequest"
-                            }
-                        }
-                    },
-                    "required": true
-                },
-                "security": [
-                    {
-                        "cookieAuth": []
-                    },
-                    {
-                        "tokenAuth": []
-                    }
-                ],
-                "responses": {
-                    "201": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/CableTermination"
-                                }
-                            }
-                        },
-                        "description": ""
-                    }
-                }
-            },
-            "put": {
-                "operationId": "dcim_cable_terminations_bulk_update",
-                "description": "Put a list of cable termination objects.",
-                "tags": [
-                    "dcim"
-                ],
-                "requestBody": {
-                    "content": {
-                        "application/json": {
-                            "schema": {
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/CableTerminationRequest"
-                                }
-                            }
-                        },
-                        "multipart/form-data": {
-                            "schema": {
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/CableTerminationRequest"
-                                }
-                            }
-                        }
-                    },
-                    "required": true
-                },
-                "security": [
-                    {
-                        "cookieAuth": []
-                    },
-                    {
-                        "tokenAuth": []
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "type": "array",
-                                    "items": {
-                                        "$ref": "#/components/schemas/CableTermination"
-                                    }
-                                }
-                            }
-                        },
-                        "description": ""
-                    }
-                }
-            },
-            "patch": {
-                "operationId": "dcim_cable_terminations_bulk_partial_update",
-                "description": "Patch a list of cable termination objects.",
-                "tags": [
-                    "dcim"
-                ],
-                "requestBody": {
-                    "content": {
-                        "application/json": {
-                            "schema": {
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/CableTerminationRequest"
-                                }
-                            }
-                        },
-                        "multipart/form-data": {
-                            "schema": {
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/CableTerminationRequest"
-                                }
-                            }
-                        }
-                    },
-                    "required": true
-                },
-                "security": [
-                    {
-                        "cookieAuth": []
-                    },
-                    {
-                        "tokenAuth": []
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "type": "array",
-                                    "items": {
-                                        "$ref": "#/components/schemas/CableTermination"
-                                    }
-                                }
-                            }
-                        },
-                        "description": ""
-                    }
-                }
-            },
-            "delete": {
-                "operationId": "dcim_cable_terminations_bulk_destroy",
-                "description": "Delete a list of cable termination objects.",
-                "tags": [
-                    "dcim"
-                ],
-                "requestBody": {
-                    "content": {
-                        "application/json": {
-                            "schema": {
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/CableTerminationRequest"
-                                }
-                            }
-                        },
-                        "multipart/form-data": {
-                            "schema": {
-                                "type": "array",
-                                "items": {
-                                    "$ref": "#/components/schemas/CableTerminationRequest"
-                                }
-                            }
-                        }
-                    },
-                    "required": true
-                },
-                "security": [
-                    {
-                        "cookieAuth": []
-                    },
-                    {
-                        "tokenAuth": []
-                    }
-                ],
-                "responses": {
-                    "204": {
-                        "description": "No response body"
-                    }
-                }
             }
         },
         "/api/dcim/cable-terminations/{id}/": {
@@ -21923,142 +21738,6 @@
                         "description": ""
                     }
                 }
-            },
-            "put": {
-                "operationId": "dcim_cable_terminations_update",
-                "description": "Put a cable termination object.",
-                "parameters": [
-                    {
-                        "in": "path",
-                        "name": "id",
-                        "schema": {
-                            "type": "integer"
-                        },
-                        "description": "A unique integer value identifying this cable termination.",
-                        "required": true
-                    }
-                ],
-                "tags": [
-                    "dcim"
-                ],
-                "requestBody": {
-                    "content": {
-                        "application/json": {
-                            "schema": {
-                                "$ref": "#/components/schemas/CableTerminationRequest"
-                            }
-                        },
-                        "multipart/form-data": {
-                            "schema": {
-                                "$ref": "#/components/schemas/CableTerminationRequest"
-                            }
-                        }
-                    },
-                    "required": true
-                },
-                "security": [
-                    {
-                        "cookieAuth": []
-                    },
-                    {
-                        "tokenAuth": []
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/CableTermination"
-                                }
-                            }
-                        },
-                        "description": ""
-                    }
-                }
-            },
-            "patch": {
-                "operationId": "dcim_cable_terminations_partial_update",
-                "description": "Patch a cable termination object.",
-                "parameters": [
-                    {
-                        "in": "path",
-                        "name": "id",
-                        "schema": {
-                            "type": "integer"
-                        },
-                        "description": "A unique integer value identifying this cable termination.",
-                        "required": true
-                    }
-                ],
-                "tags": [
-                    "dcim"
-                ],
-                "requestBody": {
-                    "content": {
-                        "application/json": {
-                            "schema": {
-                                "$ref": "#/components/schemas/PatchedCableTerminationRequest"
-                            }
-                        },
-                        "multipart/form-data": {
-                            "schema": {
-                                "$ref": "#/components/schemas/PatchedCableTerminationRequest"
-                            }
-                        }
-                    }
-                },
-                "security": [
-                    {
-                        "cookieAuth": []
-                    },
-                    {
-                        "tokenAuth": []
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/CableTermination"
-                                }
-                            }
-                        },
-                        "description": ""
-                    }
-                }
-            },
-            "delete": {
-                "operationId": "dcim_cable_terminations_destroy",
-                "description": "Delete a cable termination object.",
-                "parameters": [
-                    {
-                        "in": "path",
-                        "name": "id",
-                        "schema": {
-                            "type": "integer"
-                        },
-                        "description": "A unique integer value identifying this cable termination.",
-                        "required": true
-                    }
-                ],
-                "tags": [
-                    "dcim"
-                ],
-                "security": [
-                    {
-                        "cookieAuth": []
-                    },
-                    {
-                        "tokenAuth": []
-                    }
-                ],
-                "responses": {
-                    "204": {
-                        "description": "No response body"
-                    }
-                }
             }
         },
         "/api/dcim/cables/": {
@@ -204463,7 +204142,8 @@
                         "readOnly": true
                     },
                     "cable": {
-                        "type": "integer"
+                        "type": "integer",
+                        "readOnly": true
                     },
                     "cable_end": {
                         "enum": [
@@ -204473,16 +204153,16 @@
                         "type": "string",
                         "description": "* `A` - A\n* `B` - B",
                         "x-spec-enum-id": "1db84f9b93b261c8",
+                        "readOnly": true,
                         "title": "End"
                     },
                     "termination_type": {
-                        "type": "string"
+                        "type": "string",
+                        "readOnly": true
                     },
                     "termination_id": {
                         "type": "integer",
-                        "maximum": 9223372036854775807,
-                        "minimum": 0,
-                        "format": "int64"
+                        "readOnly": true
                     },
                     "termination": {
                         "nullable": true,
@@ -204514,40 +204194,6 @@
                     "url"
                 ]
             },
-            "CableTerminationRequest": {
-                "type": "object",
-                "description": "Adds support for custom fields and tags.",
-                "properties": {
-                    "cable": {
-                        "type": "integer"
-                    },
-                    "cable_end": {
-                        "enum": [
-                            "A",
-                            "B"
-                        ],
-                        "type": "string",
-                        "description": "* `A` - A\n* `B` - B",
-                        "x-spec-enum-id": "1db84f9b93b261c8",
-                        "title": "End"
-                    },
-                    "termination_type": {
-                        "type": "string"
-                    },
-                    "termination_id": {
-                        "type": "integer",
-                        "maximum": 9223372036854775807,
-                        "minimum": 0,
-                        "format": "int64"
-                    }
-                },
-                "required": [
-                    "cable",
-                    "cable_end",
-                    "termination_id",
-                    "termination_type"
-                ]
-            },
             "Circuit": {
                 "type": "object",
                 "description": "Adds support for custom fields and tags.",
@@ -226099,34 +225745,6 @@
                     }
                 }
             },
-            "PatchedCableTerminationRequest": {
-                "type": "object",
-                "description": "Adds support for custom fields and tags.",
-                "properties": {
-                    "cable": {
-                        "type": "integer"
-                    },
-                    "cable_end": {
-                        "enum": [
-                            "A",
-                            "B"
-                        ],
-                        "type": "string",
-                        "description": "* `A` - A\n* `B` - B",
-                        "x-spec-enum-id": "1db84f9b93b261c8",
-                        "title": "End"
-                    },
-                    "termination_type": {
-                        "type": "string"
-                    },
-                    "termination_id": {
-                        "type": "integer",
-                        "maximum": 9223372036854775807,
-                        "minimum": 0,
-                        "format": "int64"
-                    }
-                }
-            },
             "PatchedCircuitGroupRequest": {
                 "type": "object",
                 "description": "Adds support for custom fields and tags.",

+ 6 - 4
netbox/dcim/api/serializers_/cables.py

@@ -1,10 +1,8 @@
-from django.contrib.contenttypes.models import ContentType
 from drf_spectacular.types import OpenApiTypes
 from drf_spectacular.utils import extend_schema_field
 from rest_framework import serializers
 
 from dcim.choices import *
-from dcim.constants import *
 from dcim.models import Cable, CablePath, CableTermination
 from netbox.api.fields import ChoiceField, ContentTypeField
 from netbox.api.serializers import BaseModelSerializer, GenericObjectSerializer, NetBoxModelSerializer
@@ -51,9 +49,11 @@ class TracedCableSerializer(BaseModelSerializer):
 
 class CableTerminationSerializer(NetBoxModelSerializer):
     termination_type = ContentTypeField(
-        queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS)
+        read_only=True,
+    )
+    termination = serializers.SerializerMethodField(
+        read_only=True,
     )
-    termination = serializers.SerializerMethodField(read_only=True)
 
     class Meta:
         model = CableTermination
@@ -61,6 +61,8 @@ class CableTerminationSerializer(NetBoxModelSerializer):
             'id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id',
             'termination', 'created', 'last_updated',
         ]
+        read_only_fields = fields
+        brief_fields = ('id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id')
 
     @extend_schema_field(serializers.JSONField(allow_null=True))
     def get_termination(self, obj):

+ 2 - 2
netbox/dcim/api/views.py

@@ -16,7 +16,7 @@ from extras.api.mixins import ConfigContextQuerySetMixin, RenderConfigMixin
 from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired
 from netbox.api.metadata import ContentTypeMetadata
 from netbox.api.pagination import StripCountAnnotationsPaginator
-from netbox.api.viewsets import NetBoxModelViewSet, MPTTLockedMixin
+from netbox.api.viewsets import NetBoxModelViewSet, MPTTLockedMixin, NetBoxReadOnlyModelViewSet
 from netbox.api.viewsets.mixins import SequentialBulkCreatesMixin
 from utilities.api import get_serializer_for_model
 from utilities.query_functions import CollateAsChar
@@ -563,7 +563,7 @@ class CableViewSet(NetBoxModelViewSet):
     filterset_class = filtersets.CableFilterSet
 
 
-class CableTerminationViewSet(NetBoxModelViewSet):
+class CableTerminationViewSet(NetBoxReadOnlyModelViewSet):
     metadata_class = ContentTypeMetadata
     queryset = CableTermination.objects.all()
     serializer_class = serializers.CableTerminationSerializer

+ 27 - 0
netbox/dcim/tests/test_api.py

@@ -2376,6 +2376,33 @@ class CableTest(APIViewTestCases.APIViewTestCase):
         ]
 
 
+class CableTerminationTest(
+    APIViewTestCases.GetObjectViewTestCase,
+    APIViewTestCases.ListObjectsViewTestCase,
+):
+    model = CableTermination
+    brief_fields = ['cable', 'cable_end', 'display', 'id', 'termination_id', 'termination_type', 'url']
+
+    @classmethod
+    def setUpTestData(cls):
+        device1 = create_test_device('Device 1')
+        device2 = create_test_device('Device 2')
+
+        interfaces = []
+        for device in (device1, device2):
+            for i in range(0, 10):
+                interfaces.append(Interface(device=device, type=InterfaceTypeChoices.TYPE_1GE_FIXED, name=f'eth{i}'))
+        Interface.objects.bulk_create(interfaces)
+
+        cables = (
+            Cable(a_terminations=[interfaces[0]], b_terminations=[interfaces[10]], label='Cable 1'),
+            Cable(a_terminations=[interfaces[1]], b_terminations=[interfaces[11]], label='Cable 2'),
+            Cable(a_terminations=[interfaces[2]], b_terminations=[interfaces[12]], label='Cable 3'),
+        )
+        for cable in cables:
+            cable.save()
+
+
 class ConnectedDeviceTest(APITestCase):
 
     @classmethod