فهرست منبع

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

Jeremy Stretch 4 ماه پیش
والد
کامیت
12818f1786
4فایلهای تغییر یافته به همراه41 افزوده شده و 394 حذف شده
  1. 6 388
      contrib/openapi.json
  2. 6 4
      netbox/dcim/api/serializers_/cables.py
  3. 2 2
      netbox/dcim/api/views.py
  4. 27 0
      netbox/dcim/tests/test_api.py

+ 6 - 388
contrib/openapi.json

@@ -21698,191 +21698,6 @@
                         "description": ""
                         "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}/": {
         "/api/dcim/cable-terminations/{id}/": {
@@ -21923,142 +21738,6 @@
                         "description": ""
                         "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/": {
         "/api/dcim/cables/": {
@@ -204463,7 +204142,8 @@
                         "readOnly": true
                         "readOnly": true
                     },
                     },
                     "cable": {
                     "cable": {
-                        "type": "integer"
+                        "type": "integer",
+                        "readOnly": true
                     },
                     },
                     "cable_end": {
                     "cable_end": {
                         "enum": [
                         "enum": [
@@ -204473,16 +204153,16 @@
                         "type": "string",
                         "type": "string",
                         "description": "* `A` - A\n* `B` - B",
                         "description": "* `A` - A\n* `B` - B",
                         "x-spec-enum-id": "1db84f9b93b261c8",
                         "x-spec-enum-id": "1db84f9b93b261c8",
+                        "readOnly": true,
                         "title": "End"
                         "title": "End"
                     },
                     },
                     "termination_type": {
                     "termination_type": {
-                        "type": "string"
+                        "type": "string",
+                        "readOnly": true
                     },
                     },
                     "termination_id": {
                     "termination_id": {
                         "type": "integer",
                         "type": "integer",
-                        "maximum": 9223372036854775807,
-                        "minimum": 0,
-                        "format": "int64"
+                        "readOnly": true
                     },
                     },
                     "termination": {
                     "termination": {
                         "nullable": true,
                         "nullable": true,
@@ -204514,40 +204194,6 @@
                     "url"
                     "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": {
             "Circuit": {
                 "type": "object",
                 "type": "object",
                 "description": "Adds support for custom fields and tags.",
                 "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": {
             "PatchedCircuitGroupRequest": {
                 "type": "object",
                 "type": "object",
                 "description": "Adds support for custom fields and tags.",
                 "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.types import OpenApiTypes
 from drf_spectacular.utils import extend_schema_field
 from drf_spectacular.utils import extend_schema_field
 from rest_framework import serializers
 from rest_framework import serializers
 
 
 from dcim.choices import *
 from dcim.choices import *
-from dcim.constants import *
 from dcim.models import Cable, CablePath, CableTermination
 from dcim.models import Cable, CablePath, CableTermination
 from netbox.api.fields import ChoiceField, ContentTypeField
 from netbox.api.fields import ChoiceField, ContentTypeField
 from netbox.api.serializers import BaseModelSerializer, GenericObjectSerializer, NetBoxModelSerializer
 from netbox.api.serializers import BaseModelSerializer, GenericObjectSerializer, NetBoxModelSerializer
@@ -51,9 +49,11 @@ class TracedCableSerializer(BaseModelSerializer):
 
 
 class CableTerminationSerializer(NetBoxModelSerializer):
 class CableTerminationSerializer(NetBoxModelSerializer):
     termination_type = ContentTypeField(
     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:
     class Meta:
         model = CableTermination
         model = CableTermination
@@ -61,6 +61,8 @@ class CableTerminationSerializer(NetBoxModelSerializer):
             'id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id',
             'id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id',
             'termination', 'created', 'last_updated',
             '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))
     @extend_schema_field(serializers.JSONField(allow_null=True))
     def get_termination(self, obj):
     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.authentication import IsAuthenticatedOrLoginNotRequired
 from netbox.api.metadata import ContentTypeMetadata
 from netbox.api.metadata import ContentTypeMetadata
 from netbox.api.pagination import StripCountAnnotationsPaginator
 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 netbox.api.viewsets.mixins import SequentialBulkCreatesMixin
 from utilities.api import get_serializer_for_model
 from utilities.api import get_serializer_for_model
 from utilities.query_functions import CollateAsChar
 from utilities.query_functions import CollateAsChar
@@ -563,7 +563,7 @@ class CableViewSet(NetBoxModelViewSet):
     filterset_class = filtersets.CableFilterSet
     filterset_class = filtersets.CableFilterSet
 
 
 
 
-class CableTerminationViewSet(NetBoxModelViewSet):
+class CableTerminationViewSet(NetBoxReadOnlyModelViewSet):
     metadata_class = ContentTypeMetadata
     metadata_class = ContentTypeMetadata
     queryset = CableTermination.objects.all()
     queryset = CableTermination.objects.all()
     serializer_class = serializers.CableTerminationSerializer
     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):
 class ConnectedDeviceTest(APITestCase):
 
 
     @classmethod
     @classmethod