From 348fca7e28c78df33996c8097b298881f9b7acc9 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Sun, 11 Apr 2021 12:57:53 -0400 Subject: [PATCH] Fixes #6117: Handle exception when attempting to assign an MPTT-enabled model as its own parent --- docs/release-notes/version-2.10.md | 1 + netbox/dcim/models/racks.py | 6 ++++++ netbox/dcim/models/sites.py | 10 ++++++++++ netbox/tenancy/models.py | 10 ++++++++++ 4 files changed, 27 insertions(+) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 390c318f7..7d99959cc 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -17,6 +17,7 @@ * [#6073](https://github.com/netbox-community/netbox/issues/6073) - Permit users to manage their own REST API tokens without needing explicit permission * [#6081](https://github.com/netbox-community/netbox/issues/6081) - Fix interface connections REST API endpoint * [#6108](https://github.com/netbox-community/netbox/issues/6108) - Do not infer tenant assignment from parent objects for prefixes, IP addresses +* [#6117](https://github.com/netbox-community/netbox/issues/6117) - Handle exception when attempting to assign an MPTT-enabled model as its own parent * [#6131](https://github.com/netbox-community/netbox/issues/6131) - Correct handling of boolean fields when cloning objects --- diff --git a/netbox/dcim/models/racks.py b/netbox/dcim/models/racks.py index dfaf7da61..0bd7e5afd 100644 --- a/netbox/dcim/models/racks.py +++ b/netbox/dcim/models/racks.py @@ -111,6 +111,12 @@ class RackGroup(MPTTModel, ChangeLoggedModel): def clean(self): super().clean() + # An MPTT model cannot be its own parent + if self.pk and self.parent_id == self.pk: + raise ValidationError({ + "parent": "Cannot assign self as parent." + }) + # Parent RackGroup (if any) must belong to the same Site if self.parent and self.parent.site != self.site: raise ValidationError(f"Parent rack group ({self.parent}) must belong to the same site ({self.site})") diff --git a/netbox/dcim/models/sites.py b/netbox/dcim/models/sites.py index 923b33124..908750905 100644 --- a/netbox/dcim/models/sites.py +++ b/netbox/dcim/models/sites.py @@ -7,6 +7,7 @@ from timezone_field import TimeZoneField from dcim.choices import * from dcim.constants import * +from django.core.exceptions import ValidationError from dcim.fields import ASNField from extras.models import ChangeLoggedModel, CustomFieldModel, ObjectChange, TaggedItem from extras.utils import extras_features @@ -87,6 +88,15 @@ class Region(MPTTModel, ChangeLoggedModel): object_data=serialize_object(self, exclude=['level', 'lft', 'rght', 'tree_id']) ) + def clean(self): + super().clean() + + # An MPTT model cannot be its own parent + if self.pk and self.parent_id == self.pk: + raise ValidationError({ + "parent": "Cannot assign self as parent." + }) + # # Sites diff --git a/netbox/tenancy/models.py b/netbox/tenancy/models.py index 3ba644c09..dbb8c4835 100644 --- a/netbox/tenancy/models.py +++ b/netbox/tenancy/models.py @@ -1,3 +1,4 @@ +from django.core.exceptions import ValidationError from django.db import models from django.urls import reverse from mptt.models import MPTTModel, TreeForeignKey @@ -74,6 +75,15 @@ class TenantGroup(MPTTModel, ChangeLoggedModel): object_data=serialize_object(self, exclude=['level', 'lft', 'rght', 'tree_id']) ) + def clean(self): + super().clean() + + # An MPTT model cannot be its own parent + if self.pk and self.parent_id == self.pk: + raise ValidationError({ + "parent": "Cannot assign self as parent." + }) + @extras_features('custom_fields', 'custom_links', 'export_templates', 'webhooks') class Tenant(ChangeLoggedModel, CustomFieldModel):