diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md
index cc9fc90d2..158e7a77f 100644
--- a/docs/release-notes/version-3.4.md
+++ b/docs/release-notes/version-3.4.md
@@ -69,18 +69,69 @@ A new `PluginMenu` class has been introduced, which enables a plugin to inject a
* circuits.provider
* Removed the `asn`, `noc_contact`, `admin_contact`, and `portal_url` fields
+ * Added a `description` field
+* dcim.Cable
+ * Added `description` and `comments` fields
+* dcim.Device
+ * Added a `description` field
* dcim.DeviceType
+ * Added a `description` field
* Added optional `weight` and `weight_unit` fields
+* dcim.Module
+ * Added a `description` field
* dcim.ModuleType
+ * Added a `description` field
* Added optional `weight` and `weight_unit` fields
+* dcim.PowerFeed
+ * Added a `description` field
+* dcim.PowerPanel
+ * Added `description` and `comments` fields
* dcim.Rack
+ * Added a `description` field
* Added optional `weight` and `weight_unit` fields
+* dcim.RackReservation
+ * Added a `comments` field
+* dcim.VirtualChassis
+ * Added `description` and `comments` fields
* extras.CustomLink
* Renamed `content_type` field to `content_types`
* extras.ExportTemplate
* Renamed `content_type` field to `content_types`
+* ipam.Aggregate
+ * Added a `comments` field
+* ipam.ASN
+ * Added a `comments` field
* ipam.FHRPGroup
+ * Added a `comments` field
* Added optional `name` field
+* ipam.IPAddress
+ * Added a `comments` field
+* ipam.IPRange
+ * Added a `comments` field
+* ipam.L2VPN
+ * Added a `comments` field
+* ipam.Prefix
+ * Added a `comments` field
+* ipam.RouteTarget
+ * Added a `comments` field
+* ipam.Service
+ * Added a `comments` field
+* ipam.ServiceTemplate
+ * Added a `comments` field
+* ipam.VLAN
+ * Added a `comments` field
+* ipam.VRF
+ * Added a `comments` field
+* tenancy.Contact
+ * Added a `description` field
+* virtualization.Cluster
+ * Added a `description` field
+* virtualization.VirtualMachine
+ * Added a `description` field
+* wireless.WirelessLAN
+ * Added a `comments` field
+* wireless.WirelessLink
+ * Added a `comments` field
### GraphQL API Changes
diff --git a/netbox/circuits/api/serializers.py b/netbox/circuits/api/serializers.py
index 4a8e2bd28..2bcb0895a 100644
--- a/netbox/circuits/api/serializers.py
+++ b/netbox/circuits/api/serializers.py
@@ -31,8 +31,8 @@ class ProviderSerializer(NetBoxModelSerializer):
class Meta:
model = Provider
fields = [
- 'id', 'url', 'display', 'name', 'slug', 'account',
- 'comments', 'asns', 'tags', 'custom_fields', 'created', 'last_updated', 'circuit_count',
+ 'id', 'url', 'display', 'name', 'slug', 'account', 'description', 'comments', 'asns', 'tags',
+ 'custom_fields', 'created', 'last_updated', 'circuit_count',
]
diff --git a/netbox/circuits/forms/bulk_edit.py b/netbox/circuits/forms/bulk_edit.py
index 12975b5d6..6e9ae516c 100644
--- a/netbox/circuits/forms/bulk_edit.py
+++ b/netbox/circuits/forms/bulk_edit.py
@@ -30,6 +30,10 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm):
required=False,
label='Account number'
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
@@ -40,7 +44,7 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm):
(None, ('asns', 'account', )),
)
nullable_fields = (
- 'asns', 'account', 'comments',
+ 'asns', 'account', 'description', 'comments',
)
diff --git a/netbox/circuits/forms/bulk_import.py b/netbox/circuits/forms/bulk_import.py
index 77ebb3de9..d0bdb09a7 100644
--- a/netbox/circuits/forms/bulk_import.py
+++ b/netbox/circuits/forms/bulk_import.py
@@ -18,7 +18,7 @@ class ProviderCSVForm(NetBoxModelCSVForm):
class Meta:
model = Provider
fields = (
- 'name', 'slug', 'account', 'comments',
+ 'name', 'slug', 'account', 'description', 'comments',
)
diff --git a/netbox/circuits/forms/model_forms.py b/netbox/circuits/forms/model_forms.py
index 03c473d62..ab1b6bca2 100644
--- a/netbox/circuits/forms/model_forms.py
+++ b/netbox/circuits/forms/model_forms.py
@@ -1,4 +1,3 @@
-from django import forms
from django.utils.translation import gettext as _
from circuits.models import *
@@ -7,8 +6,8 @@ from ipam.models import ASN
from netbox.forms import NetBoxModelForm
from tenancy.forms import TenancyForm
from utilities.forms import (
- BootstrapMixin, CommentField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
- SelectSpeedWidget, SmallTextarea, SlugField, StaticSelect,
+ CommentField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SelectSpeedWidget, SlugField,
+ StaticSelect,
)
__all__ = (
@@ -30,14 +29,14 @@ class ProviderForm(NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Provider', ('name', 'slug', 'asns', 'tags')),
+ ('Provider', ('name', 'slug', 'asns', 'description', 'tags')),
('Support Info', ('account',)),
)
class Meta:
model = Provider
fields = [
- 'name', 'slug', 'account', 'asns', 'comments', 'tags',
+ 'name', 'slug', 'account', 'asns', 'description', 'comments', 'tags',
]
help_texts = {
'name': "Full name of the provider",
diff --git a/netbox/circuits/migrations/0041_standardize_description_comments.py b/netbox/circuits/migrations/0041_standardize_description_comments.py
new file mode 100644
index 000000000..49cdefcba
--- /dev/null
+++ b/netbox/circuits/migrations/0041_standardize_description_comments.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.1.2 on 2022-11-03 18:24
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('circuits', '0040_provider_remove_deprecated_fields'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='provider',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ ]
diff --git a/netbox/circuits/models/circuits.py b/netbox/circuits/models/circuits.py
index 7100c9796..9d302bb8e 100644
--- a/netbox/circuits/models/circuits.py
+++ b/netbox/circuits/models/circuits.py
@@ -7,7 +7,7 @@ from django.urls import reverse
from circuits.choices import *
from dcim.models import CabledObjectModel
from netbox.models import (
- ChangeLoggedModel, CustomFieldsMixin, CustomLinksMixin, OrganizationalModel, NetBoxModel, TagsMixin,
+ ChangeLoggedModel, CustomFieldsMixin, CustomLinksMixin, OrganizationalModel, PrimaryModel, TagsMixin,
)
from netbox.models.features import WebhooksMixin
@@ -27,7 +27,7 @@ class CircuitType(OrganizationalModel):
return reverse('circuits:circuittype', args=[self.pk])
-class Circuit(NetBoxModel):
+class Circuit(PrimaryModel):
"""
A communications circuit connects two points. Each Circuit belongs to a Provider; Providers may have multiple
circuits. Each circuit is also assigned a CircuitType and a Site. Circuit port speed and commit rate are measured
@@ -73,13 +73,6 @@ class Circuit(NetBoxModel):
blank=True,
null=True,
verbose_name='Commit rate (Kbps)')
- description = models.CharField(
- max_length=200,
- blank=True
- )
- comments = models.TextField(
- blank=True
- )
# Generic relations
contacts = GenericRelation(
diff --git a/netbox/circuits/models/providers.py b/netbox/circuits/models/providers.py
index bd63ff0c6..18a81dcef 100644
--- a/netbox/circuits/models/providers.py
+++ b/netbox/circuits/models/providers.py
@@ -2,8 +2,7 @@ from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from django.urls import reverse
-from dcim.fields import ASNField
-from netbox.models import NetBoxModel
+from netbox.models import PrimaryModel
__all__ = (
'ProviderNetwork',
@@ -11,7 +10,7 @@ __all__ = (
)
-class Provider(NetBoxModel):
+class Provider(PrimaryModel):
"""
Each Circuit belongs to a Provider. This is usually a telecommunications company or similar organization. This model
stores information pertinent to the user's relationship with the Provider.
@@ -34,9 +33,6 @@ class Provider(NetBoxModel):
blank=True,
verbose_name='Account number'
)
- comments = models.TextField(
- blank=True
- )
# Generic relations
contacts = GenericRelation(
@@ -57,7 +53,7 @@ class Provider(NetBoxModel):
return reverse('circuits:provider', args=[self.pk])
-class ProviderNetwork(NetBoxModel):
+class ProviderNetwork(PrimaryModel):
"""
This represents a provider network which exists outside of NetBox, the details of which are unknown or
unimportant to the user.
@@ -75,13 +71,6 @@ class ProviderNetwork(NetBoxModel):
blank=True,
verbose_name='Service ID'
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
- comments = models.TextField(
- blank=True
- )
class Meta:
ordering = ('provider', 'name')
diff --git a/netbox/circuits/tables/providers.py b/netbox/circuits/tables/providers.py
index a117274ff..9de8d25b2 100644
--- a/netbox/circuits/tables/providers.py
+++ b/netbox/circuits/tables/providers.py
@@ -39,8 +39,8 @@ class ProviderTable(ContactsColumnMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = Provider
fields = (
- 'pk', 'id', 'name', 'asns', 'account', 'asn_count',
- 'circuit_count', 'comments', 'contacts', 'tags', 'created', 'last_updated',
+ 'pk', 'id', 'name', 'asns', 'account', 'asn_count', 'circuit_count', 'description', 'comments', 'contacts',
+ 'tags', 'created', 'last_updated',
)
default_columns = ('pk', 'name', 'account', 'circuit_count')
diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py
index 19de84791..9317d7c51 100644
--- a/netbox/dcim/api/serializers.py
+++ b/netbox/dcim/api/serializers.py
@@ -210,8 +210,8 @@ class RackSerializer(NetBoxModelSerializer):
fields = [
'id', 'url', 'display', 'name', 'facility_id', 'site', 'location', 'tenant', 'status', 'role', 'serial',
'asset_tag', 'type', 'width', 'u_height', 'weight', 'weight_unit', 'desc_units', 'outer_width',
- 'outer_depth', 'outer_unit', 'mounting_depth', 'comments', 'tags', 'custom_fields', 'created',
- 'last_updated', 'device_count', 'powerfeed_count',
+ 'outer_depth', 'outer_unit', 'mounting_depth', 'description', 'comments', 'tags', 'custom_fields',
+ 'created', 'last_updated', 'device_count', 'powerfeed_count',
]
@@ -243,8 +243,8 @@ class RackReservationSerializer(NetBoxModelSerializer):
class Meta:
model = RackReservation
fields = [
- 'id', 'url', 'display', 'rack', 'units', 'created', 'last_updated', 'user', 'tenant', 'description', 'tags',
- 'custom_fields',
+ 'id', 'url', 'display', 'rack', 'units', 'created', 'last_updated', 'user', 'tenant', 'description',
+ 'comments', 'tags', 'custom_fields',
]
@@ -324,8 +324,8 @@ class DeviceTypeSerializer(NetBoxModelSerializer):
model = DeviceType
fields = [
'id', 'url', 'display', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth',
- 'subdevice_role', 'airflow', 'weight', 'weight_unit', 'front_image', 'rear_image', 'comments', 'tags',
- 'custom_fields', 'created', 'last_updated', 'device_count',
+ 'subdevice_role', 'airflow', 'weight', 'weight_unit', 'front_image', 'rear_image', 'description',
+ 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count',
]
@@ -333,13 +333,12 @@ class ModuleTypeSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:moduletype-detail')
manufacturer = NestedManufacturerSerializer()
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False)
- # module_count = serializers.IntegerField(read_only=True)
class Meta:
model = ModuleType
fields = [
- 'id', 'url', 'display', 'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'comments', 'tags',
- 'custom_fields', 'created', 'last_updated',
+ 'id', 'url', 'display', 'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'description',
+ 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
@@ -656,8 +655,8 @@ class DeviceSerializer(NetBoxModelSerializer):
fields = [
'id', 'url', 'display', 'name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag',
'site', 'location', 'rack', 'position', 'face', 'parent_device', 'status', 'airflow', 'primary_ip',
- 'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments',
- 'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated',
+ 'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'description',
+ 'comments', 'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated',
]
@swagger_serializer_method(serializer_or_field=NestedDeviceSerializer)
@@ -681,8 +680,8 @@ class ModuleSerializer(NetBoxModelSerializer):
class Meta:
model = Module
fields = [
- 'id', 'url', 'display', 'device', 'module_bay', 'module_type', 'serial', 'asset_tag', 'comments', 'tags',
- 'custom_fields', 'created', 'last_updated',
+ 'id', 'url', 'display', 'device', 'module_bay', 'module_type', 'serial', 'asset_tag', 'description',
+ 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
@@ -1020,7 +1019,7 @@ class CableSerializer(NetBoxModelSerializer):
model = Cable
fields = [
'id', 'url', 'display', 'type', 'a_terminations', 'b_terminations', 'status', 'tenant', 'label', 'color',
- 'length', 'length_unit', 'tags', 'custom_fields', 'created', 'last_updated',
+ 'length', 'length_unit', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
@@ -1086,8 +1085,8 @@ class VirtualChassisSerializer(NetBoxModelSerializer):
class Meta:
model = VirtualChassis
fields = [
- 'id', 'url', 'display', 'name', 'domain', 'master', 'tags', 'custom_fields', 'member_count',
- 'created', 'last_updated',
+ 'id', 'url', 'display', 'name', 'domain', 'master', 'description', 'comments', 'tags', 'custom_fields',
+ 'member_count', 'created', 'last_updated',
]
@@ -1108,8 +1107,8 @@ class PowerPanelSerializer(NetBoxModelSerializer):
class Meta:
model = PowerPanel
fields = [
- 'id', 'url', 'display', 'site', 'location', 'name', 'tags', 'custom_fields', 'powerfeed_count',
- 'created', 'last_updated',
+ 'id', 'url', 'display', 'site', 'location', 'name', 'description', 'comments', 'tags', 'custom_fields',
+ 'powerfeed_count', 'created', 'last_updated',
]
@@ -1142,7 +1141,7 @@ class PowerFeedSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
model = PowerFeed
fields = [
'id', 'url', 'display', 'power_panel', 'rack', 'name', 'status', 'type', 'supply', 'phase', 'voltage',
- 'amperage', 'max_utilization', 'comments', 'mark_connected', 'cable', 'cable_end', 'link_peers',
- 'link_peers_type', 'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable',
- 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
+ 'amperage', 'max_utilization', 'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type',
+ 'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable', 'description',
+ 'comments', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
]
diff --git a/netbox/dcim/forms/bulk_edit.py b/netbox/dcim/forms/bulk_edit.py
index e3b69dc81..1e58dd2f7 100644
--- a/netbox/dcim/forms/bulk_edit.py
+++ b/netbox/dcim/forms/bulk_edit.py
@@ -127,22 +127,26 @@ class SiteBulkEditForm(NetBoxModelBulkEditForm):
required=False,
label='Contact E-mail'
)
- description = forms.CharField(
- max_length=100,
- required=False
- )
time_zone = TimeZoneFormField(
choices=add_blank_choice(TimeZoneFormField().choices),
required=False,
widget=StaticSelect()
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = Site
fieldsets = (
(None, ('status', 'region', 'group', 'tenant', 'asns', 'time_zone', 'description')),
)
nullable_fields = (
- 'region', 'group', 'tenant', 'asns', 'description', 'time_zone',
+ 'region', 'group', 'tenant', 'asns', 'time_zone', 'description', 'comments',
)
@@ -285,10 +289,6 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
required=False,
min_value=1
)
- comments = CommentField(
- widget=SmallTextarea,
- label='Comments'
- )
weight = forms.DecimalField(
min_value=0,
required=False
@@ -299,10 +299,18 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
initial='',
widget=StaticSelect()
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = Rack
fieldsets = (
- ('Rack', ('status', 'role', 'tenant', 'serial', 'asset_tag')),
+ ('Rack', ('status', 'role', 'tenant', 'serial', 'asset_tag', 'description')),
('Location', ('region', 'site_group', 'site', 'location')),
('Hardware', (
'type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth',
@@ -310,8 +318,8 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
('Weight', ('weight', 'weight_unit')),
)
nullable_fields = (
- 'location', 'tenant', 'role', 'serial', 'asset_tag', 'outer_width', 'outer_depth', 'outer_unit', 'comments',
- 'weight', 'weight_unit'
+ 'location', 'tenant', 'role', 'serial', 'asset_tag', 'outer_width', 'outer_depth', 'outer_unit', 'weight',
+ 'weight_unit', 'description', 'comments',
)
@@ -328,14 +336,19 @@ class RackReservationBulkEditForm(NetBoxModelBulkEditForm):
required=False
)
description = forms.CharField(
- max_length=100,
+ max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = RackReservation
fieldsets = (
(None, ('user', 'tenant', 'description')),
)
+ nullable_fields = ('comments',)
class ManufacturerBulkEditForm(NetBoxModelBulkEditForm):
@@ -383,13 +396,21 @@ class DeviceTypeBulkEditForm(NetBoxModelBulkEditForm):
initial='',
widget=StaticSelect()
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = DeviceType
fieldsets = (
- ('Device Type', ('manufacturer', 'part_number', 'u_height', 'is_full_depth', 'airflow')),
+ ('Device Type', ('manufacturer', 'part_number', 'u_height', 'is_full_depth', 'airflow', 'description')),
('Weight', ('weight', 'weight_unit')),
)
- nullable_fields = ('part_number', 'airflow', 'weight', 'weight_unit')
+ nullable_fields = ('part_number', 'airflow', 'weight', 'weight_unit', 'description', 'comments')
class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
@@ -410,13 +431,21 @@ class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
initial='',
widget=StaticSelect()
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = ModuleType
fieldsets = (
- ('Module Type', ('manufacturer', 'part_number')),
+ ('Module Type', ('manufacturer', 'part_number', 'description')),
('Weight', ('weight', 'weight_unit')),
)
- nullable_fields = ('part_number', 'weight', 'weight_unit')
+ nullable_fields = ('part_number', 'weight', 'weight_unit', 'description', 'comments')
class DeviceRoleBulkEditForm(NetBoxModelBulkEditForm):
@@ -512,15 +541,23 @@ class DeviceBulkEditForm(NetBoxModelBulkEditForm):
required=False,
label='Serial Number'
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = Device
fieldsets = (
- ('Device', ('device_role', 'status', 'tenant', 'platform')),
+ ('Device', ('device_role', 'status', 'tenant', 'platform', 'description')),
('Location', ('site', 'location')),
('Hardware', ('manufacturer', 'device_type', 'airflow', 'serial')),
)
nullable_fields = (
- 'location', 'tenant', 'platform', 'serial', 'airflow',
+ 'location', 'tenant', 'platform', 'serial', 'airflow', 'description', 'comments',
)
@@ -541,12 +578,20 @@ class ModuleBulkEditForm(NetBoxModelBulkEditForm):
required=False,
label='Serial Number'
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = Module
fieldsets = (
- (None, ('manufacturer', 'module_type', 'serial')),
+ (None, ('manufacturer', 'module_type', 'serial', 'description')),
)
- nullable_fields = ('serial',)
+ nullable_fields = ('serial', 'description', 'comments')
class CableBulkEditForm(NetBoxModelBulkEditForm):
@@ -583,14 +628,22 @@ class CableBulkEditForm(NetBoxModelBulkEditForm):
initial='',
widget=StaticSelect()
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = Cable
fieldsets = (
- (None, ('type', 'status', 'tenant', 'label')),
+ (None, ('type', 'status', 'tenant', 'label', 'description')),
('Attributes', ('color', 'length', 'length_unit')),
)
nullable_fields = (
- 'type', 'status', 'tenant', 'label', 'color', 'length',
+ 'type', 'status', 'tenant', 'label', 'color', 'length', 'description', 'comments',
)
@@ -599,12 +652,20 @@ class VirtualChassisBulkEditForm(NetBoxModelBulkEditForm):
max_length=30,
required=False
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = VirtualChassis
fieldsets = (
- (None, ('domain',)),
+ (None, ('domain', 'description')),
)
- nullable_fields = ('domain',)
+ nullable_fields = ('domain', 'description', 'comments')
class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
@@ -637,12 +698,20 @@ class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
'site_id': '$site'
}
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = PowerPanel
fieldsets = (
- (None, ('region', 'site_group', 'site', 'location')),
+ (None, ('region', 'site_group', 'site', 'location', 'description')),
)
- nullable_fields = ('location',)
+ nullable_fields = ('location', 'description', 'comments')
class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
@@ -691,6 +760,10 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
required=False,
widget=BulkEditNullBooleanSelect
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
@@ -698,10 +771,10 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
model = PowerFeed
fieldsets = (
- (None, ('power_panel', 'rack', 'status', 'type', 'mark_connected')),
+ (None, ('power_panel', 'rack', 'status', 'type', 'mark_connected', 'description')),
('Power', ('supply', 'phase', 'voltage', 'amperage', 'max_utilization'))
)
- nullable_fields = ('location', 'comments')
+ nullable_fields = ('location', 'description', 'comments')
#
diff --git a/netbox/dcim/forms/bulk_import.py b/netbox/dcim/forms/bulk_import.py
index 13e788e75..4c90c9c02 100644
--- a/netbox/dcim/forms/bulk_import.py
+++ b/netbox/dcim/forms/bulk_import.py
@@ -196,7 +196,8 @@ class RackCSVForm(NetBoxModelCSVForm):
model = Rack
fields = (
'site', 'location', 'name', 'facility_id', 'tenant', 'status', 'role', 'type', 'serial', 'asset_tag',
- 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'comments',
+ 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth',
+ 'description', 'comments',
)
def __init__(self, data=None, *args, **kwargs):
@@ -240,7 +241,7 @@ class RackReservationCSVForm(NetBoxModelCSVForm):
class Meta:
model = RackReservation
- fields = ('site', 'location', 'rack', 'units', 'tenant', 'description')
+ fields = ('site', 'location', 'rack', 'units', 'tenant', 'description', 'comments')
def __init__(self, data=None, *args, **kwargs):
super().__init__(data, *args, **kwargs)
@@ -387,7 +388,7 @@ class DeviceCSVForm(BaseDeviceCSVForm):
fields = [
'name', 'device_role', 'tenant', 'manufacturer', 'device_type', 'platform', 'serial', 'asset_tag', 'status',
'site', 'location', 'rack', 'position', 'face', 'airflow', 'virtual_chassis', 'vc_position', 'vc_priority',
- 'cluster', 'comments',
+ 'cluster', 'description', 'comments',
]
def __init__(self, data=None, *args, **kwargs):
@@ -424,7 +425,7 @@ class ModuleCSVForm(NetBoxModelCSVForm):
class Meta:
model = Module
fields = (
- 'device', 'module_bay', 'module_type', 'serial', 'asset_tag', 'comments',
+ 'device', 'module_bay', 'module_type', 'serial', 'asset_tag', 'description', 'comments',
)
def __init__(self, data=None, *args, **kwargs):
@@ -927,7 +928,7 @@ class CableCSVForm(NetBoxModelCSVForm):
model = Cable
fields = [
'side_a_device', 'side_a_type', 'side_a_name', 'side_b_device', 'side_b_type', 'side_b_name', 'type',
- 'status', 'tenant', 'label', 'color', 'length', 'length_unit',
+ 'status', 'tenant', 'label', 'color', 'length', 'length_unit', 'description', 'comments',
]
help_texts = {
'color': mark_safe('RGB color in hexadecimal (e.g. 00ff00
)'),
@@ -984,7 +985,7 @@ class VirtualChassisCSVForm(NetBoxModelCSVForm):
class Meta:
model = VirtualChassis
- fields = ('name', 'domain', 'master')
+ fields = ('name', 'domain', 'master', 'description')
#
@@ -1005,7 +1006,7 @@ class PowerPanelCSVForm(NetBoxModelCSVForm):
class Meta:
model = PowerPanel
- fields = ('site', 'location', 'name')
+ fields = ('site', 'location', 'name', 'description', 'comments')
def __init__(self, data=None, *args, **kwargs):
super().__init__(data, *args, **kwargs)
@@ -1061,7 +1062,7 @@ class PowerFeedCSVForm(NetBoxModelCSVForm):
model = PowerFeed
fields = (
'site', 'power_panel', 'location', 'rack', 'name', 'status', 'type', 'mark_connected', 'supply', 'phase',
- 'voltage', 'amperage', 'max_utilization', 'comments',
+ 'voltage', 'amperage', 'max_utilization', 'description', 'comments',
)
def __init__(self, data=None, *args, **kwargs):
diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py
index 0da2f3430..539c48709 100644
--- a/netbox/dcim/forms/model_forms.py
+++ b/netbox/dcim/forms/model_forms.py
@@ -278,7 +278,7 @@ class RackForm(TenancyForm, NetBoxModelForm):
fields = [
'region', 'site_group', 'site', 'location', 'name', 'facility_id', 'tenant_group', 'tenant', 'status',
'role', 'serial', 'asset_tag', 'type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth',
- 'outer_unit', 'mounting_depth', 'weight', 'weight_unit', 'comments', 'tags',
+ 'outer_unit', 'mounting_depth', 'weight', 'weight_unit', 'description', 'comments', 'tags',
]
help_texts = {
'site': "The site at which the rack exists",
@@ -342,6 +342,7 @@ class RackReservationForm(TenancyForm, NetBoxModelForm):
),
widget=StaticSelect()
)
+ comments = CommentField()
fieldsets = (
('Reservation', ('region', 'site_group', 'site', 'location', 'rack', 'units', 'user', 'description', 'tags')),
@@ -352,7 +353,7 @@ class RackReservationForm(TenancyForm, NetBoxModelForm):
model = RackReservation
fields = [
'region', 'site_group', 'site', 'location', 'rack', 'units', 'user', 'tenant_group', 'tenant',
- 'description', 'tags',
+ 'description', 'comments', 'tags',
]
@@ -383,10 +384,10 @@ class DeviceTypeForm(NetBoxModelForm):
fieldsets = (
('Device Type', (
- 'manufacturer', 'model', 'slug', 'part_number', 'tags',
+ 'manufacturer', 'model', 'slug', 'description', 'tags',
)),
('Chassis', (
- 'u_height', 'is_full_depth', 'subdevice_role', 'airflow',
+ 'u_height', 'is_full_depth', 'part_number', 'subdevice_role', 'airflow',
)),
('Attributes', ('weight', 'weight_unit')),
('Images', ('front_image', 'rear_image')),
@@ -396,7 +397,7 @@ class DeviceTypeForm(NetBoxModelForm):
model = DeviceType
fields = [
'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow',
- 'weight', 'weight_unit', 'front_image', 'rear_image', 'comments', 'tags',
+ 'weight', 'weight_unit', 'front_image', 'rear_image', 'description', 'comments', 'tags',
]
widgets = {
'airflow': StaticSelect(),
@@ -418,15 +419,14 @@ class ModuleTypeForm(NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Module Type', (
- 'manufacturer', 'model', 'part_number', 'tags', 'weight', 'weight_unit'
- )),
+ ('Module Type', ('manufacturer', 'model', 'part_number', 'description', 'tags')),
+ ('Weight', ('weight', 'weight_unit'))
)
class Meta:
model = ModuleType
fields = [
- 'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'comments', 'tags',
+ 'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'description', 'comments', 'tags',
]
widgets = {
@@ -591,7 +591,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
'name', 'device_role', 'device_type', 'serial', 'asset_tag', 'region', 'site_group', 'site', 'rack',
'location', 'position', 'face', 'status', 'airflow', 'platform', 'primary_ip4', 'primary_ip6',
'cluster_group', 'cluster', 'tenant_group', 'tenant', 'virtual_chassis', 'vc_position', 'vc_priority',
- 'comments', 'tags', 'local_context_data'
+ 'description', 'comments', 'tags', 'local_context_data'
]
help_texts = {
'device_role': "The function this device serves",
@@ -705,7 +705,7 @@ class ModuleForm(NetBoxModelForm):
fieldsets = (
('Module', (
- 'device', 'module_bay', 'manufacturer', 'module_type', 'tags',
+ 'device', 'module_bay', 'manufacturer', 'module_type', 'description', 'tags',
)),
('Hardware', (
'serial', 'asset_tag', 'replicate_components', 'adopt_components',
@@ -716,7 +716,7 @@ class ModuleForm(NetBoxModelForm):
model = Module
fields = [
'device', 'module_bay', 'manufacturer', 'module_type', 'serial', 'asset_tag', 'tags',
- 'replicate_components', 'adopt_components', 'comments',
+ 'replicate_components', 'adopt_components', 'description', 'comments',
]
def __init__(self, *args, **kwargs):
@@ -793,11 +793,13 @@ class ModuleForm(NetBoxModelForm):
class CableForm(TenancyForm, NetBoxModelForm):
+ comments = CommentField()
class Meta:
model = Cable
fields = [
- 'type', 'status', 'tenant_group', 'tenant', 'label', 'color', 'length', 'length_unit', 'tags',
+ 'type', 'status', 'tenant_group', 'tenant', 'label', 'color', 'length', 'length_unit', 'description',
+ 'comments', 'tags',
]
widgets = {
'status': StaticSelect,
@@ -840,15 +842,16 @@ class PowerPanelForm(NetBoxModelForm):
'site_id': '$site'
}
)
+ comments = CommentField()
fieldsets = (
- ('Power Panel', ('region', 'site_group', 'site', 'location', 'name', 'tags')),
+ ('Power Panel', ('region', 'site_group', 'site', 'location', 'name', 'description', 'tags')),
)
class Meta:
model = PowerPanel
fields = [
- 'region', 'site_group', 'site', 'location', 'name', 'tags',
+ 'region', 'site_group', 'site', 'location', 'name', 'description', 'comments', 'tags',
]
@@ -894,7 +897,7 @@ class PowerFeedForm(NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Power Panel', ('region', 'site', 'power_panel')),
+ ('Power Panel', ('region', 'site', 'power_panel', 'description')),
('Power Feed', ('rack', 'name', 'status', 'type', 'mark_connected', 'tags')),
('Characteristics', ('supply', 'voltage', 'amperage', 'phase', 'max_utilization')),
)
@@ -903,7 +906,7 @@ class PowerFeedForm(NetBoxModelForm):
model = PowerFeed
fields = [
'region', 'site_group', 'site', 'power_panel', 'rack', 'name', 'status', 'type', 'mark_connected', 'supply',
- 'phase', 'voltage', 'amperage', 'max_utilization', 'comments', 'tags',
+ 'phase', 'voltage', 'amperage', 'max_utilization', 'description', 'comments', 'tags',
]
widgets = {
'status': StaticSelect(),
@@ -922,11 +925,12 @@ class VirtualChassisForm(NetBoxModelForm):
queryset=Device.objects.all(),
required=False,
)
+ comments = CommentField()
class Meta:
model = VirtualChassis
fields = [
- 'name', 'domain', 'master', 'tags',
+ 'name', 'domain', 'master', 'description', 'comments', 'tags',
]
widgets = {
'master': SelectWithPK(),
diff --git a/netbox/dcim/forms/object_import.py b/netbox/dcim/forms/object_import.py
index 023aba8f1..82ee093dd 100644
--- a/netbox/dcim/forms/object_import.py
+++ b/netbox/dcim/forms/object_import.py
@@ -30,7 +30,7 @@ class DeviceTypeImportForm(BootstrapMixin, forms.ModelForm):
model = DeviceType
fields = [
'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow',
- 'comments',
+ 'description', 'comments',
]
@@ -42,7 +42,7 @@ class ModuleTypeImportForm(BootstrapMixin, forms.ModelForm):
class Meta:
model = ModuleType
- fields = ['manufacturer', 'model', 'part_number', 'comments']
+ fields = ['manufacturer', 'model', 'part_number', 'description', 'comments']
#
diff --git a/netbox/dcim/migrations/0165_standardize_description_comments.py b/netbox/dcim/migrations/0165_standardize_description_comments.py
new file mode 100644
index 000000000..f17f1d321
--- /dev/null
+++ b/netbox/dcim/migrations/0165_standardize_description_comments.py
@@ -0,0 +1,78 @@
+# Generated by Django 4.1.2 on 2022-11-03 18:24
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('dcim', '0164_rack_mounting_depth'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='cable',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='cable',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ migrations.AddField(
+ model_name='device',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ migrations.AddField(
+ model_name='devicetype',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ migrations.AddField(
+ model_name='module',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ migrations.AddField(
+ model_name='moduletype',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ migrations.AddField(
+ model_name='powerfeed',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ migrations.AddField(
+ model_name='powerpanel',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='powerpanel',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ migrations.AddField(
+ model_name='rack',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ migrations.AddField(
+ model_name='rackreservation',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='virtualchassis',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='virtualchassis',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ ]
diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py
index fad3e8bd6..c51b59f94 100644
--- a/netbox/dcim/models/cables.py
+++ b/netbox/dcim/models/cables.py
@@ -12,8 +12,8 @@ from django.urls import reverse
from dcim.choices import *
from dcim.constants import *
from dcim.fields import PathField
-from dcim.utils import decompile_path_node, object_to_path_node, path_node_to_object
-from netbox.models import NetBoxModel
+from dcim.utils import decompile_path_node, object_to_path_node
+from netbox.models import PrimaryModel
from utilities.fields import ColorField
from utilities.querysets import RestrictedQuerySet
from utilities.utils import to_meters
@@ -34,7 +34,7 @@ trace_paths = Signal()
# Cables
#
-class Cable(NetBoxModel):
+class Cable(PrimaryModel):
"""
A physical connection between two endpoints.
"""
diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py
index 3710bf7f4..78282f893 100644
--- a/netbox/dcim/models/devices.py
+++ b/netbox/dcim/models/devices.py
@@ -18,7 +18,7 @@ from dcim.constants import *
from extras.models import ConfigContextModel
from extras.querysets import ConfigContextModelQuerySet
from netbox.config import ConfigItem
-from netbox.models import OrganizationalModel, NetBoxModel
+from netbox.models import OrganizationalModel, PrimaryModel
from utilities.choices import ColorChoices
from utilities.fields import ColorField, NaturalOrderingField
from .device_components import *
@@ -54,7 +54,7 @@ class Manufacturer(OrganizationalModel):
return reverse('dcim:manufacturer', args=[self.pk])
-class DeviceType(NetBoxModel, WeightMixin):
+class DeviceType(PrimaryModel, WeightMixin):
"""
A DeviceType represents a particular make (Manufacturer) and model of device. It specifies rack height and depth, as
well as high-level functional role(s).
@@ -117,9 +117,6 @@ class DeviceType(NetBoxModel, WeightMixin):
upload_to='devicetype-images',
blank=True
)
- comments = models.TextField(
- blank=True
- )
clone_fields = (
'manufacturer', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'weight', 'weight_unit',
@@ -298,7 +295,7 @@ class DeviceType(NetBoxModel, WeightMixin):
return self.subdevice_role == SubdeviceRoleChoices.ROLE_CHILD
-class ModuleType(NetBoxModel, WeightMixin):
+class ModuleType(PrimaryModel, WeightMixin):
"""
A ModuleType represents a hardware element that can be installed within a device and which houses additional
components; for example, a line card within a chassis-based switch such as the Cisco Catalyst 6500. Like a
@@ -318,9 +315,6 @@ class ModuleType(NetBoxModel, WeightMixin):
blank=True,
help_text='Discrete part number (optional)'
)
- comments = models.TextField(
- blank=True
- )
# Generic relations
images = GenericRelation(
@@ -443,7 +437,7 @@ class Platform(OrganizationalModel):
return reverse('dcim:platform', args=[self.pk])
-class Device(NetBoxModel, ConfigContextModel):
+class Device(PrimaryModel, ConfigContextModel):
"""
A Device represents a piece of physical hardware mounted within a Rack. Each Device is assigned a DeviceType,
DeviceRole, and (optionally) a Platform. Device names are not required, however if one is set it must be unique.
@@ -587,9 +581,6 @@ class Device(NetBoxModel, ConfigContextModel):
null=True,
validators=[MaxValueValidator(255)]
)
- comments = models.TextField(
- blank=True
- )
# Generic relations
contacts = GenericRelation(
@@ -906,7 +897,7 @@ class Device(NetBoxModel, ConfigContextModel):
return round(total_weight / 1000, 2)
-class Module(NetBoxModel, ConfigContextModel):
+class Module(PrimaryModel, ConfigContextModel):
"""
A Module represents a field-installable component within a Device which may itself hold multiple device components
(for example, a line card within a chassis switch). Modules are instantiated from ModuleTypes.
@@ -939,9 +930,6 @@ class Module(NetBoxModel, ConfigContextModel):
verbose_name='Asset tag',
help_text='A unique tag used to identify this device'
)
- comments = models.TextField(
- blank=True
- )
clone_fields = ('device', 'module_type')
@@ -1019,7 +1007,7 @@ class Module(NetBoxModel, ConfigContextModel):
# Virtual chassis
#
-class VirtualChassis(NetBoxModel):
+class VirtualChassis(PrimaryModel):
"""
A collection of Devices which operate with a shared control plane (e.g. a switch stack).
"""
diff --git a/netbox/dcim/models/power.py b/netbox/dcim/models/power.py
index 39f0f37ef..e79cf4c44 100644
--- a/netbox/dcim/models/power.py
+++ b/netbox/dcim/models/power.py
@@ -6,9 +6,8 @@ from django.db import models
from django.urls import reverse
from dcim.choices import *
-from dcim.constants import *
from netbox.config import ConfigItem
-from netbox.models import NetBoxModel
+from netbox.models import PrimaryModel
from utilities.validators import ExclusionValidator
from .device_components import CabledObjectModel, PathEndpoint
@@ -22,7 +21,7 @@ __all__ = (
# Power
#
-class PowerPanel(NetBoxModel):
+class PowerPanel(PrimaryModel):
"""
A distribution point for electrical power; e.g. a data center RPP.
"""
@@ -77,7 +76,7 @@ class PowerPanel(NetBoxModel):
)
-class PowerFeed(NetBoxModel, PathEndpoint, CabledObjectModel):
+class PowerFeed(PrimaryModel, PathEndpoint, CabledObjectModel):
"""
An electrical circuit delivered from a PowerPanel.
"""
@@ -132,9 +131,6 @@ class PowerFeed(NetBoxModel, PathEndpoint, CabledObjectModel):
default=0,
editable=False
)
- comments = models.TextField(
- blank=True
- )
clone_fields = (
'power_panel', 'rack', 'status', 'type', 'mark_connected', 'supply', 'phase', 'voltage', 'amperage',
diff --git a/netbox/dcim/models/racks.py b/netbox/dcim/models/racks.py
index e61765e69..e37fc8dc3 100644
--- a/netbox/dcim/models/racks.py
+++ b/netbox/dcim/models/racks.py
@@ -14,7 +14,7 @@ from django.urls import reverse
from dcim.choices import *
from dcim.constants import *
from dcim.svg import RackElevationSVG
-from netbox.models import OrganizationalModel, NetBoxModel
+from netbox.models import OrganizationalModel, PrimaryModel
from utilities.choices import ColorChoices
from utilities.fields import ColorField, NaturalOrderingField
from utilities.utils import array_to_string, drange
@@ -46,7 +46,7 @@ class RackRole(OrganizationalModel):
return reverse('dcim:rackrole', args=[self.pk])
-class Rack(NetBoxModel, WeightMixin):
+class Rack(PrimaryModel, WeightMixin):
"""
Devices are housed within Racks. Each rack has a defined height measured in rack units, and a front and rear face.
Each Rack is assigned to a Site and (optionally) a Location.
@@ -157,9 +157,6 @@ class Rack(NetBoxModel, WeightMixin):
'distance between the front and rear rails.'
)
)
- comments = models.TextField(
- blank=True
- )
# Generic relations
vlan_groups = GenericRelation(
@@ -463,7 +460,7 @@ class Rack(NetBoxModel, WeightMixin):
return round(total_weight / 1000, 2)
-class RackReservation(NetBoxModel):
+class RackReservation(PrimaryModel):
"""
One or more reserved units within a Rack.
"""
diff --git a/netbox/dcim/models/sites.py b/netbox/dcim/models/sites.py
index c352b69de..c760119fb 100644
--- a/netbox/dcim/models/sites.py
+++ b/netbox/dcim/models/sites.py
@@ -6,7 +6,7 @@ from timezone_field import TimeZoneField
from dcim.choices import *
from dcim.constants import *
-from netbox.models import NestedGroupModel, NetBoxModel
+from netbox.models import NestedGroupModel, PrimaryModel
from utilities.fields import NaturalOrderingField
__all__ = (
@@ -131,7 +131,7 @@ class SiteGroup(NestedGroupModel):
# Sites
#
-class Site(NetBoxModel):
+class Site(PrimaryModel):
"""
A Site represents a geographic location within a network; typically a building or campus. The optional facility
field can be used to include an external designation, such as a data center name (e.g. Equinix SV6).
@@ -188,10 +188,6 @@ class Site(NetBoxModel):
time_zone = TimeZoneField(
blank=True
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
physical_address = models.CharField(
max_length=200,
blank=True
@@ -214,9 +210,6 @@ class Site(NetBoxModel):
null=True,
help_text='GPS coordinate (longitude)'
)
- comments = models.TextField(
- blank=True
- )
# Generic relations
vlan_groups = GenericRelation(
diff --git a/netbox/dcim/tables/cables.py b/netbox/dcim/tables/cables.py
index e5410e42a..6e9d49719 100644
--- a/netbox/dcim/tables/cables.py
+++ b/netbox/dcim/tables/cables.py
@@ -111,6 +111,7 @@ class CableTable(TenancyColumnsMixin, NetBoxTable):
order_by=('_abs_length', 'length_unit')
)
color = columns.ColorColumn()
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='dcim:cable_list'
)
@@ -120,7 +121,7 @@ class CableTable(TenancyColumnsMixin, NetBoxTable):
fields = (
'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'device_a', 'device_b', 'rack_a', 'rack_b',
'location_a', 'location_b', 'site_a', 'site_b', 'status', 'type', 'tenant', 'tenant_group', 'color',
- 'length', 'tags', 'created', 'last_updated',
+ 'length', 'description', 'comments', 'tags', 'created', 'last_updated',
)
default_columns = (
'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'status', 'type',
diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py
index 3b129c963..45a210080 100644
--- a/netbox/dcim/tables/devices.py
+++ b/netbox/dcim/tables/devices.py
@@ -1,21 +1,5 @@
import django_tables2 as tables
-from dcim.models import (
- ConsolePort,
- ConsoleServerPort,
- Device,
- DeviceBay,
- DeviceRole,
- FrontPort,
- Interface,
- InventoryItem,
- InventoryItemRole,
- ModuleBay,
- Platform,
- PowerOutlet,
- PowerPort,
- RearPort,
- VirtualChassis,
-)
+from dcim import models
from django_tables2.utils import Accessor
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
@@ -106,7 +90,7 @@ class DeviceRoleTable(NetBoxTable):
)
class Meta(NetBoxTable.Meta):
- model = DeviceRole
+ model = models.DeviceRole
fields = (
'pk', 'id', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'description', 'slug', 'tags',
'actions', 'created', 'last_updated',
@@ -137,7 +121,7 @@ class PlatformTable(NetBoxTable):
)
class Meta(NetBoxTable.Meta):
- model = Platform
+ model = models.Platform
fields = (
'pk', 'id', 'name', 'manufacturer', 'device_count', 'vm_count', 'slug', 'napalm_driver', 'napalm_args',
'description', 'tags', 'actions', 'created', 'last_updated',
@@ -220,12 +204,12 @@ class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
)
class Meta(NetBoxTable.Meta):
- model = Device
+ model = models.Device
fields = (
'pk', 'id', 'name', 'status', 'tenant', 'tenant_group', 'device_role', 'manufacturer', 'device_type',
'platform', 'serial', 'asset_tag', 'region', 'site_group', 'site', 'location', 'rack', 'position', 'face',
'airflow', 'primary_ip', 'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position',
- 'vc_priority', 'comments', 'contacts', 'tags', 'created', 'last_updated',
+ 'vc_priority', 'description', 'comments', 'contacts', 'tags', 'created', 'last_updated',
)
default_columns = (
'pk', 'name', 'status', 'tenant', 'site', 'location', 'rack', 'device_role', 'manufacturer', 'device_type',
@@ -252,7 +236,7 @@ class DeviceImportTable(TenancyColumnsMixin, NetBoxTable):
)
class Meta(NetBoxTable.Meta):
- model = Device
+ model = models.Device
fields = ('id', 'name', 'status', 'tenant', 'tenant_group', 'site', 'rack', 'position', 'device_role', 'device_type')
empty_text = False
@@ -326,7 +310,7 @@ class ConsolePortTable(ModularDeviceComponentTable, PathEndpointTable):
)
class Meta(DeviceComponentTable.Meta):
- model = ConsolePort
+ model = models.ConsolePort
fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'speed', 'description',
'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created', 'last_updated',
@@ -345,7 +329,7 @@ class DeviceConsolePortTable(ConsolePortTable):
)
class Meta(DeviceComponentTable.Meta):
- model = ConsolePort
+ model = models.ConsolePort
fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'speed', 'description', 'mark_connected',
'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions'
@@ -368,7 +352,7 @@ class ConsoleServerPortTable(ModularDeviceComponentTable, PathEndpointTable):
)
class Meta(DeviceComponentTable.Meta):
- model = ConsoleServerPort
+ model = models.ConsoleServerPort
fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'speed', 'description',
'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created', 'last_updated',
@@ -388,7 +372,7 @@ class DeviceConsoleServerPortTable(ConsoleServerPortTable):
)
class Meta(DeviceComponentTable.Meta):
- model = ConsoleServerPort
+ model = models.ConsoleServerPort
fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'speed', 'description', 'mark_connected',
'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions',
@@ -411,7 +395,7 @@ class PowerPortTable(ModularDeviceComponentTable, PathEndpointTable):
)
class Meta(DeviceComponentTable.Meta):
- model = PowerPort
+ model = models.PowerPort
fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'description', 'mark_connected',
'maximum_draw', 'allocated_draw', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created',
@@ -432,7 +416,7 @@ class DevicePowerPortTable(PowerPortTable):
)
class Meta(DeviceComponentTable.Meta):
- model = PowerPort
+ model = models.PowerPort
fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'maximum_draw', 'allocated_draw',
'description', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions',
@@ -460,7 +444,7 @@ class PowerOutletTable(ModularDeviceComponentTable, PathEndpointTable):
)
class Meta(DeviceComponentTable.Meta):
- model = PowerOutlet
+ model = models.PowerOutlet
fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'description', 'power_port',
'feed_leg', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created',
@@ -480,7 +464,7 @@ class DevicePowerOutletTable(PowerOutletTable):
)
class Meta(DeviceComponentTable.Meta):
- model = PowerOutlet
+ model = models.PowerOutlet
fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'power_port', 'feed_leg', 'description',
'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions',
@@ -544,7 +528,7 @@ class InterfaceTable(ModularDeviceComponentTable, BaseInterfaceTable, PathEndpoi
)
class Meta(DeviceComponentTable.Meta):
- model = Interface
+ model = models.Interface
fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'enabled', 'type', 'mgmt_only', 'mtu',
'speed', 'duplex', 'mode', 'mac_address', 'wwn', 'poe_mode', 'poe_type', 'rf_role', 'rf_channel',
@@ -578,7 +562,7 @@ class DeviceInterfaceTable(InterfaceTable):
)
class Meta(DeviceComponentTable.Meta):
- model = Interface
+ model = models.Interface
fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'enabled', 'type', 'parent', 'bridge', 'lag',
'mgmt_only', 'mtu', 'mode', 'mac_address', 'wwn', 'rf_role', 'rf_channel', 'rf_channel_frequency',
@@ -617,7 +601,7 @@ class FrontPortTable(ModularDeviceComponentTable, CableTerminationTable):
)
class Meta(DeviceComponentTable.Meta):
- model = FrontPort
+ model = models.FrontPort
fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'color', 'rear_port',
'rear_port_position', 'description', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'tags',
@@ -640,7 +624,7 @@ class DeviceFrontPortTable(FrontPortTable):
)
class Meta(DeviceComponentTable.Meta):
- model = FrontPort
+ model = models.FrontPort
fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'rear_port', 'rear_port_position',
'description', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'tags', 'actions',
@@ -666,7 +650,7 @@ class RearPortTable(ModularDeviceComponentTable, CableTerminationTable):
)
class Meta(DeviceComponentTable.Meta):
- model = RearPort
+ model = models.RearPort
fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'color', 'positions', 'description',
'mark_connected', 'cable', 'cable_color', 'link_peer', 'tags', 'created', 'last_updated',
@@ -686,7 +670,7 @@ class DeviceRearPortTable(RearPortTable):
)
class Meta(DeviceComponentTable.Meta):
- model = RearPort
+ model = models.RearPort
fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'positions', 'description', 'mark_connected',
'cable', 'cable_color', 'link_peer', 'tags', 'actions',
@@ -727,7 +711,7 @@ class DeviceBayTable(DeviceComponentTable):
)
class Meta(DeviceComponentTable.Meta):
- model = DeviceBay
+ model = models.DeviceBay
fields = (
'pk', 'id', 'name', 'device', 'label', 'status', 'device_role', 'device_type', 'installed_device', 'description', 'tags',
'created', 'last_updated',
@@ -748,7 +732,7 @@ class DeviceDeviceBayTable(DeviceBayTable):
)
class Meta(DeviceComponentTable.Meta):
- model = DeviceBay
+ model = models.DeviceBay
fields = (
'pk', 'id', 'name', 'label', 'status', 'installed_device', 'description', 'tags', 'actions',
)
@@ -777,7 +761,7 @@ class ModuleBayTable(DeviceComponentTable):
)
class Meta(DeviceComponentTable.Meta):
- model = ModuleBay
+ model = models.ModuleBay
fields = (
'pk', 'id', 'name', 'device', 'label', 'position', 'installed_module', 'module_serial', 'module_asset_tag',
'description', 'tags',
@@ -791,7 +775,7 @@ class DeviceModuleBayTable(ModuleBayTable):
)
class Meta(DeviceComponentTable.Meta):
- model = ModuleBay
+ model = models.ModuleBay
fields = (
'pk', 'id', 'name', 'label', 'position', 'installed_module', 'module_serial', 'module_asset_tag',
'description', 'tags', 'actions',
@@ -821,7 +805,7 @@ class InventoryItemTable(DeviceComponentTable):
cable = None # Override DeviceComponentTable
class Meta(NetBoxTable.Meta):
- model = InventoryItem
+ model = models.InventoryItem
fields = (
'pk', 'id', 'name', 'device', 'component', 'label', 'role', 'manufacturer', 'part_id', 'serial',
'asset_tag', 'description', 'discovered', 'tags', 'created', 'last_updated',
@@ -840,7 +824,7 @@ class DeviceInventoryItemTable(InventoryItemTable):
)
class Meta(NetBoxTable.Meta):
- model = InventoryItem
+ model = models.InventoryItem
fields = (
'pk', 'id', 'name', 'label', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'component',
'description', 'discovered', 'tags', 'actions',
@@ -865,7 +849,7 @@ class InventoryItemRoleTable(NetBoxTable):
)
class Meta(NetBoxTable.Meta):
- model = InventoryItemRole
+ model = models.InventoryItemRole
fields = (
'pk', 'id', 'name', 'inventoryitem_count', 'color', 'description', 'slug', 'tags', 'actions',
)
@@ -888,11 +872,15 @@ class VirtualChassisTable(NetBoxTable):
url_params={'virtual_chassis_id': 'pk'},
verbose_name='Members'
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='dcim:virtualchassis_list'
)
class Meta(NetBoxTable.Meta):
- model = VirtualChassis
- fields = ('pk', 'id', 'name', 'domain', 'master', 'member_count', 'tags', 'created', 'last_updated',)
+ model = models.VirtualChassis
+ fields = (
+ 'pk', 'id', 'name', 'domain', 'master', 'member_count', 'description', 'comments', 'tags', 'created',
+ 'last_updated',
+ )
default_columns = ('pk', 'name', 'domain', 'master', 'member_count')
diff --git a/netbox/dcim/tables/devicetypes.py b/netbox/dcim/tables/devicetypes.py
index 19b04c70d..a52d41b70 100644
--- a/netbox/dcim/tables/devicetypes.py
+++ b/netbox/dcim/tables/devicetypes.py
@@ -1,19 +1,6 @@
import django_tables2 as tables
-from dcim.models import (
- ConsolePortTemplate,
- ConsoleServerPortTemplate,
- DeviceBayTemplate,
- DeviceType,
- FrontPortTemplate,
- InterfaceTemplate,
- InventoryItemTemplate,
- Manufacturer,
- ModuleBayTemplate,
- PowerOutletTemplate,
- PowerPortTemplate,
- RearPortTemplate,
-)
+from dcim import models
from netbox.tables import NetBoxTable, columns
from tenancy.tables import ContactsColumnMixin
from .template_code import MODULAR_COMPONENT_TEMPLATE_BUTTONS, DEVICE_WEIGHT
@@ -59,7 +46,7 @@ class ManufacturerTable(ContactsColumnMixin, NetBoxTable):
)
class Meta(NetBoxTable.Meta):
- model = Manufacturer
+ model = models.Manufacturer
fields = (
'pk', 'id', 'name', 'devicetype_count', 'inventoryitem_count', 'platform_count', 'description', 'slug',
'contacts', 'actions', 'created', 'last_updated',
@@ -100,15 +87,12 @@ class DeviceTypeTable(NetBoxTable):
template_code=DEVICE_WEIGHT,
order_by=('_abs_weight', 'weight_unit')
)
- u_height = columns.TemplateColumn(
- template_code='{{ value|floatformat }}'
- )
class Meta(NetBoxTable.Meta):
- model = DeviceType
+ model = models.DeviceType
fields = (
'pk', 'id', 'model', 'manufacturer', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role',
- 'airflow', 'weight', 'comments', 'instance_count', 'tags', 'created', 'last_updated',
+ 'airflow', 'weight', 'description', 'comments', 'instance_count', 'tags', 'created', 'last_updated',
)
default_columns = (
'pk', 'model', 'manufacturer', 'part_number', 'u_height', 'is_full_depth', 'instance_count',
@@ -138,7 +122,7 @@ class ConsolePortTemplateTable(ComponentTemplateTable):
)
class Meta(ComponentTemplateTable.Meta):
- model = ConsolePortTemplate
+ model = models.ConsolePortTemplate
fields = ('pk', 'name', 'label', 'type', 'description', 'actions')
empty_text = "None"
@@ -150,7 +134,7 @@ class ConsoleServerPortTemplateTable(ComponentTemplateTable):
)
class Meta(ComponentTemplateTable.Meta):
- model = ConsoleServerPortTemplate
+ model = models.ConsoleServerPortTemplate
fields = ('pk', 'name', 'label', 'type', 'description', 'actions')
empty_text = "None"
@@ -162,7 +146,7 @@ class PowerPortTemplateTable(ComponentTemplateTable):
)
class Meta(ComponentTemplateTable.Meta):
- model = PowerPortTemplate
+ model = models.PowerPortTemplate
fields = ('pk', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'actions')
empty_text = "None"
@@ -174,7 +158,7 @@ class PowerOutletTemplateTable(ComponentTemplateTable):
)
class Meta(ComponentTemplateTable.Meta):
- model = PowerOutletTemplate
+ model = models.PowerOutletTemplate
fields = ('pk', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'actions')
empty_text = "None"
@@ -189,7 +173,7 @@ class InterfaceTemplateTable(ComponentTemplateTable):
)
class Meta(ComponentTemplateTable.Meta):
- model = InterfaceTemplate
+ model = models.InterfaceTemplate
fields = ('pk', 'name', 'label', 'mgmt_only', 'type', 'description', 'poe_mode', 'poe_type', 'actions')
empty_text = "None"
@@ -205,7 +189,7 @@ class FrontPortTemplateTable(ComponentTemplateTable):
)
class Meta(ComponentTemplateTable.Meta):
- model = FrontPortTemplate
+ model = models.FrontPortTemplate
fields = ('pk', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position', 'description', 'actions')
empty_text = "None"
@@ -218,7 +202,7 @@ class RearPortTemplateTable(ComponentTemplateTable):
)
class Meta(ComponentTemplateTable.Meta):
- model = RearPortTemplate
+ model = models.RearPortTemplate
fields = ('pk', 'name', 'label', 'type', 'color', 'positions', 'description', 'actions')
empty_text = "None"
@@ -229,7 +213,7 @@ class ModuleBayTemplateTable(ComponentTemplateTable):
)
class Meta(ComponentTemplateTable.Meta):
- model = ModuleBayTemplate
+ model = models.ModuleBayTemplate
fields = ('pk', 'name', 'label', 'position', 'description', 'actions')
empty_text = "None"
@@ -240,7 +224,7 @@ class DeviceBayTemplateTable(ComponentTemplateTable):
)
class Meta(ComponentTemplateTable.Meta):
- model = DeviceBayTemplate
+ model = models.DeviceBayTemplate
fields = ('pk', 'name', 'label', 'description', 'actions')
empty_text = "None"
@@ -260,7 +244,7 @@ class InventoryItemTemplateTable(ComponentTemplateTable):
)
class Meta(ComponentTemplateTable.Meta):
- model = InventoryItemTemplate
+ model = models.InventoryItemTemplate
fields = (
'pk', 'name', 'label', 'parent', 'role', 'manufacturer', 'part_id', 'component', 'description', 'actions',
)
diff --git a/netbox/dcim/tables/modules.py b/netbox/dcim/tables/modules.py
index b644e6ba6..9df26eb73 100644
--- a/netbox/dcim/tables/modules.py
+++ b/netbox/dcim/tables/modules.py
@@ -35,7 +35,7 @@ class ModuleTypeTable(NetBoxTable):
class Meta(NetBoxTable.Meta):
model = ModuleType
fields = (
- 'pk', 'id', 'model', 'manufacturer', 'part_number', 'weight', 'comments', 'tags',
+ 'pk', 'id', 'model', 'manufacturer', 'part_number', 'weight', 'description', 'comments', 'tags',
)
default_columns = (
'pk', 'model', 'manufacturer', 'part_number',
@@ -64,8 +64,8 @@ class ModuleTable(NetBoxTable):
class Meta(NetBoxTable.Meta):
model = Module
fields = (
- 'pk', 'id', 'device', 'module_bay', 'manufacturer', 'module_type', 'serial', 'asset_tag', 'comments',
- 'tags',
+ 'pk', 'id', 'device', 'module_bay', 'manufacturer', 'module_type', 'serial', 'asset_tag', 'description',
+ 'comments', 'tags',
)
default_columns = (
'pk', 'id', 'device', 'module_bay', 'manufacturer', 'module_type', 'serial', 'asset_tag',
diff --git a/netbox/dcim/tables/power.py b/netbox/dcim/tables/power.py
index 04012ea4a..feff29e12 100644
--- a/netbox/dcim/tables/power.py
+++ b/netbox/dcim/tables/power.py
@@ -31,6 +31,7 @@ class PowerPanelTable(ContactsColumnMixin, NetBoxTable):
url_params={'power_panel_id': 'pk'},
verbose_name='Feeds'
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='dcim:powerpanel_list'
)
@@ -38,7 +39,8 @@ class PowerPanelTable(ContactsColumnMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = PowerPanel
fields = (
- 'pk', 'id', 'name', 'site', 'location', 'powerfeed_count', 'contacts', 'tags', 'created', 'last_updated',
+ 'pk', 'id', 'name', 'site', 'location', 'powerfeed_count', 'contacts', 'description', 'comments', 'tags',
+ 'created', 'last_updated',
)
default_columns = ('pk', 'name', 'site', 'location', 'powerfeed_count')
@@ -77,7 +79,7 @@ class PowerFeedTable(CableTerminationTable):
fields = (
'pk', 'id', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase',
'max_utilization', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'available_power',
- 'comments', 'tags', 'created', 'last_updated',
+ 'description', 'comments', 'tags', 'created', 'last_updated',
)
default_columns = (
'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', 'cable',
diff --git a/netbox/dcim/tables/racks.py b/netbox/dcim/tables/racks.py
index 1a355cc2a..b360002d2 100644
--- a/netbox/dcim/tables/racks.py
+++ b/netbox/dcim/tables/racks.py
@@ -90,8 +90,8 @@ class RackTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
fields = (
'pk', 'id', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'tenant_group', 'role', 'serial',
'asset_tag', 'type', 'u_height', 'width', 'outer_width', 'outer_depth', 'mounting_depth', 'weight',
- 'comments', 'device_count', 'get_utilization', 'get_power_utilization', 'contacts', 'tags', 'created',
- 'last_updated',
+ 'comments', 'device_count', 'get_utilization', 'get_power_utilization', 'description', 'contacts', 'tags',
+ 'created', 'last_updated',
)
default_columns = (
'pk', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'u_height', 'device_count',
@@ -123,6 +123,7 @@ class RackReservationTable(TenancyColumnsMixin, NetBoxTable):
orderable=False,
verbose_name='Units'
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='dcim:rackreservation_list'
)
@@ -130,7 +131,7 @@ class RackReservationTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = RackReservation
fields = (
- 'pk', 'id', 'reservation', 'site', 'location', 'rack', 'unit_list', 'user', 'created', 'tenant', 'tenant_group', 'description', 'tags',
- 'actions', 'created', 'last_updated',
+ 'pk', 'id', 'reservation', 'site', 'location', 'rack', 'unit_list', 'user', 'created', 'tenant',
+ 'tenant_group', 'description', 'comments', 'tags', 'actions', 'created', 'last_updated',
)
default_columns = ('pk', 'reservation', 'site', 'rack', 'unit_list', 'user', 'description')
diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py
index e04849c13..6ec062aee 100644
--- a/netbox/ipam/api/serializers.py
+++ b/netbox/ipam/api/serializers.py
@@ -31,8 +31,8 @@ class ASNSerializer(NetBoxModelSerializer):
class Meta:
model = ASN
fields = [
- 'id', 'url', 'display', 'asn', 'rir', 'tenant', 'description', 'site_count', 'provider_count', 'tags',
- 'custom_fields', 'created', 'last_updated',
+ 'id', 'url', 'display', 'asn', 'rir', 'tenant', 'description', 'comments', 'tags', 'custom_fields',
+ 'created', 'last_updated', 'site_count', 'provider_count',
]
@@ -61,8 +61,9 @@ class VRFSerializer(NetBoxModelSerializer):
class Meta:
model = VRF
fields = [
- 'id', 'url', 'display', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'import_targets',
- 'export_targets', 'tags', 'custom_fields', 'created', 'last_updated', 'ipaddress_count', 'prefix_count',
+ 'id', 'url', 'display', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'comments',
+ 'import_targets', 'export_targets', 'tags', 'custom_fields', 'created', 'last_updated', 'ipaddress_count',
+ 'prefix_count',
]
@@ -77,7 +78,8 @@ class RouteTargetSerializer(NetBoxModelSerializer):
class Meta:
model = RouteTarget
fields = [
- 'id', 'url', 'display', 'name', 'tenant', 'description', 'tags', 'custom_fields', 'created', 'last_updated',
+ 'id', 'url', 'display', 'name', 'tenant', 'description', 'comments', 'tags', 'custom_fields', 'created',
+ 'last_updated',
]
@@ -106,8 +108,8 @@ class AggregateSerializer(NetBoxModelSerializer):
class Meta:
model = Aggregate
fields = [
- 'id', 'url', 'display', 'family', 'prefix', 'rir', 'tenant', 'date_added', 'description', 'tags',
- 'custom_fields', 'created', 'last_updated',
+ 'id', 'url', 'display', 'family', 'prefix', 'rir', 'tenant', 'date_added', 'description', 'comments',
+ 'tags', 'custom_fields', 'created', 'last_updated',
]
read_only_fields = ['family']
@@ -123,8 +125,8 @@ class FHRPGroupSerializer(NetBoxModelSerializer):
class Meta:
model = FHRPGroup
fields = [
- 'id', 'name', 'url', 'display', 'protocol', 'group_id', 'auth_type', 'auth_key', 'description', 'ip_addresses',
- 'tags', 'custom_fields', 'created', 'last_updated',
+ 'id', 'name', 'url', 'display', 'protocol', 'group_id', 'auth_type', 'auth_key', 'description', 'comments',
+ 'tags', 'custom_fields', 'created', 'last_updated', 'ip_addresses',
]
@@ -215,7 +217,7 @@ class VLANSerializer(NetBoxModelSerializer):
model = VLAN
fields = [
'id', 'url', 'display', 'site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description',
- 'l2vpn_termination', 'tags', 'custom_fields', 'created', 'last_updated', 'prefix_count',
+ 'comments', 'l2vpn_termination', 'tags', 'custom_fields', 'created', 'last_updated', 'prefix_count',
]
@@ -273,7 +275,8 @@ class PrefixSerializer(NetBoxModelSerializer):
model = Prefix
fields = [
'id', 'url', 'display', 'family', 'prefix', 'site', 'vrf', 'tenant', 'vlan', 'status', 'role', 'is_pool',
- 'mark_utilized', 'description', 'tags', 'custom_fields', 'created', 'last_updated', 'children', '_depth',
+ 'mark_utilized', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'children',
+ '_depth',
]
read_only_fields = ['family']
@@ -342,7 +345,7 @@ class IPRangeSerializer(NetBoxModelSerializer):
model = IPRange
fields = [
'id', 'url', 'display', 'family', 'start_address', 'end_address', 'size', 'vrf', 'tenant', 'status', 'role',
- 'description', 'tags', 'custom_fields', 'created', 'last_updated', 'children',
+ 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'children',
]
read_only_fields = ['family']
@@ -371,8 +374,8 @@ class IPAddressSerializer(NetBoxModelSerializer):
model = IPAddress
fields = [
'id', 'url', 'display', 'family', 'address', 'vrf', 'tenant', 'status', 'role', 'assigned_object_type',
- 'assigned_object_id', 'assigned_object', 'nat_inside', 'nat_outside', 'dns_name', 'description', 'tags',
- 'custom_fields', 'created', 'last_updated',
+ 'assigned_object_id', 'assigned_object', 'nat_inside', 'nat_outside', 'dns_name', 'description', 'comments',
+ 'tags', 'custom_fields', 'created', 'last_updated',
]
@swagger_serializer_method(serializer_or_field=serializers.JSONField)
@@ -415,8 +418,8 @@ class ServiceTemplateSerializer(NetBoxModelSerializer):
class Meta:
model = ServiceTemplate
fields = [
- 'id', 'url', 'display', 'name', 'ports', 'protocol', 'description', 'tags', 'custom_fields', 'created',
- 'last_updated',
+ 'id', 'url', 'display', 'name', 'ports', 'protocol', 'description', 'comments', 'tags', 'custom_fields',
+ 'created', 'last_updated',
]
@@ -436,7 +439,7 @@ class ServiceSerializer(NetBoxModelSerializer):
model = Service
fields = [
'id', 'url', 'display', 'device', 'virtual_machine', 'name', 'ports', 'protocol', 'ipaddresses',
- 'description', 'tags', 'custom_fields', 'created', 'last_updated',
+ 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
#
@@ -465,7 +468,7 @@ class L2VPNSerializer(NetBoxModelSerializer):
model = L2VPN
fields = [
'id', 'url', 'display', 'identifier', 'name', 'slug', 'type', 'import_targets', 'export_targets',
- 'description', 'tenant', 'tags', 'custom_fields', 'created', 'last_updated'
+ 'description', 'comments', 'tenant', 'tags', 'custom_fields', 'created', 'last_updated'
]
diff --git a/netbox/ipam/forms/bulk_edit.py b/netbox/ipam/forms/bulk_edit.py
index 67bcf83fb..ed1d1d9e9 100644
--- a/netbox/ipam/forms/bulk_edit.py
+++ b/netbox/ipam/forms/bulk_edit.py
@@ -8,8 +8,8 @@ from ipam.models import ASN
from netbox.forms import NetBoxModelBulkEditForm
from tenancy.models import Tenant
from utilities.forms import (
- add_blank_choice, BulkEditNullBooleanSelect, DynamicModelChoiceField, NumericArrayField, StaticSelect,
- DynamicModelMultipleChoiceField,
+ add_blank_choice, BulkEditNullBooleanSelect, CommentField, DynamicModelChoiceField, NumericArrayField,
+ SmallTextarea, StaticSelect, DynamicModelMultipleChoiceField,
)
__all__ = (
@@ -43,15 +43,19 @@ class VRFBulkEditForm(NetBoxModelBulkEditForm):
label='Enforce unique space'
)
description = forms.CharField(
- max_length=100,
+ max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = VRF
fieldsets = (
(None, ('tenant', 'enforce_unique', 'description')),
)
- nullable_fields = ('tenant', 'description')
+ nullable_fields = ('tenant', 'description', 'comments')
class RouteTargetBulkEditForm(NetBoxModelBulkEditForm):
@@ -63,12 +67,16 @@ class RouteTargetBulkEditForm(NetBoxModelBulkEditForm):
max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = RouteTarget
fieldsets = (
(None, ('tenant', 'description')),
)
- nullable_fields = ('tenant', 'description')
+ nullable_fields = ('tenant', 'description', 'comments')
class RIRBulkEditForm(NetBoxModelBulkEditForm):
@@ -103,15 +111,19 @@ class ASNBulkEditForm(NetBoxModelBulkEditForm):
required=False
)
description = forms.CharField(
- max_length=100,
+ max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = ASN
fieldsets = (
(None, ('sites', 'rir', 'tenant', 'description')),
)
- nullable_fields = ('date_added', 'description')
+ nullable_fields = ('date_added', 'description', 'comments')
class AggregateBulkEditForm(NetBoxModelBulkEditForm):
@@ -128,15 +140,19 @@ class AggregateBulkEditForm(NetBoxModelBulkEditForm):
required=False
)
description = forms.CharField(
- max_length=100,
+ max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = Aggregate
fieldsets = (
(None, ('rir', 'tenant', 'date_added', 'description')),
)
- nullable_fields = ('date_added', 'description')
+ nullable_fields = ('date_added', 'description', 'comments')
class RoleBulkEditForm(NetBoxModelBulkEditForm):
@@ -206,9 +222,13 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
label='Treat as 100% utilized'
)
description = forms.CharField(
- max_length=100,
+ max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = Prefix
fieldsets = (
@@ -217,7 +237,7 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
('Addressing', ('vrf', 'prefix_length', 'is_pool', 'mark_utilized')),
)
nullable_fields = (
- 'site', 'vrf', 'tenant', 'role', 'description',
+ 'site', 'vrf', 'tenant', 'role', 'description', 'comments',
)
@@ -241,16 +261,20 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
required=False
)
description = forms.CharField(
- max_length=100,
+ max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = IPRange
fieldsets = (
(None, ('status', 'role', 'vrf', 'tenant', 'description')),
)
nullable_fields = (
- 'vrf', 'tenant', 'role', 'description',
+ 'vrf', 'tenant', 'role', 'description', 'comments',
)
@@ -285,9 +309,13 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
label='DNS name'
)
description = forms.CharField(
- max_length=100,
+ max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = IPAddress
fieldsets = (
@@ -295,7 +323,7 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
('Addressing', ('vrf', 'mask_length', 'dns_name')),
)
nullable_fields = (
- 'vrf', 'role', 'tenant', 'dns_name', 'description',
+ 'vrf', 'role', 'tenant', 'dns_name', 'description', 'comments',
)
@@ -329,13 +357,17 @@ class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = FHRPGroup
fieldsets = (
(None, ('protocol', 'group_id', 'name', 'description')),
('Authentication', ('auth_type', 'auth_key')),
)
- nullable_fields = ('auth_type', 'auth_key', 'name', 'description')
+ nullable_fields = ('auth_type', 'auth_key', 'name', 'description', 'comments')
class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
@@ -405,9 +437,13 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
required=False
)
description = forms.CharField(
- max_length=100,
+ max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = VLAN
fieldsets = (
@@ -415,7 +451,7 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
('Site & Group', ('region', 'site_group', 'site', 'group')),
)
nullable_fields = (
- 'site', 'group', 'tenant', 'role', 'description',
+ 'site', 'group', 'tenant', 'role', 'description', 'comments',
)
@@ -433,15 +469,19 @@ class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm):
required=False
)
description = forms.CharField(
- max_length=100,
+ max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = ServiceTemplate
fieldsets = (
(None, ('protocol', 'ports', 'description')),
)
- nullable_fields = ('description',)
+ nullable_fields = ('description', 'comments')
class ServiceBulkEditForm(ServiceTemplateBulkEditForm):
@@ -459,15 +499,19 @@ class L2VPNBulkEditForm(NetBoxModelBulkEditForm):
required=False
)
description = forms.CharField(
- max_length=100,
+ max_length=200,
required=False
)
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = L2VPN
fieldsets = (
- (None, ('type', 'description', 'tenant')),
+ (None, ('type', 'tenant', 'description')),
)
- nullable_fields = ('tenant', 'description',)
+ nullable_fields = ('tenant', 'description', 'comments')
class L2VPNTerminationBulkEditForm(NetBoxModelBulkEditForm):
diff --git a/netbox/ipam/forms/bulk_import.py b/netbox/ipam/forms/bulk_import.py
index 3aead6151..3a31b6757 100644
--- a/netbox/ipam/forms/bulk_import.py
+++ b/netbox/ipam/forms/bulk_import.py
@@ -41,7 +41,7 @@ class VRFCSVForm(NetBoxModelCSVForm):
class Meta:
model = VRF
- fields = ('name', 'rd', 'tenant', 'enforce_unique', 'description')
+ fields = ('name', 'rd', 'tenant', 'enforce_unique', 'description', 'comments')
class RouteTargetCSVForm(NetBoxModelCSVForm):
@@ -54,7 +54,7 @@ class RouteTargetCSVForm(NetBoxModelCSVForm):
class Meta:
model = RouteTarget
- fields = ('name', 'description', 'tenant')
+ fields = ('name', 'tenant', 'description', 'comments')
class RIRCSVForm(NetBoxModelCSVForm):
@@ -83,7 +83,7 @@ class AggregateCSVForm(NetBoxModelCSVForm):
class Meta:
model = Aggregate
- fields = ('prefix', 'rir', 'tenant', 'date_added', 'description')
+ fields = ('prefix', 'rir', 'tenant', 'date_added', 'description', 'comments')
class ASNCSVForm(NetBoxModelCSVForm):
@@ -101,7 +101,7 @@ class ASNCSVForm(NetBoxModelCSVForm):
class Meta:
model = ASN
- fields = ('asn', 'rir', 'tenant', 'description')
+ fields = ('asn', 'rir', 'tenant', 'description', 'comments')
help_texts = {}
@@ -159,7 +159,7 @@ class PrefixCSVForm(NetBoxModelCSVForm):
model = Prefix
fields = (
'prefix', 'vrf', 'tenant', 'site', 'vlan_group', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized',
- 'description',
+ 'description', 'comments',
)
def __init__(self, data=None, *args, **kwargs):
@@ -204,7 +204,7 @@ class IPRangeCSVForm(NetBoxModelCSVForm):
class Meta:
model = IPRange
fields = (
- 'start_address', 'end_address', 'vrf', 'tenant', 'status', 'role', 'description',
+ 'start_address', 'end_address', 'vrf', 'tenant', 'status', 'role', 'description', 'comments',
)
@@ -257,7 +257,7 @@ class IPAddressCSVForm(NetBoxModelCSVForm):
model = IPAddress
fields = [
'address', 'vrf', 'tenant', 'status', 'role', 'device', 'virtual_machine', 'interface', 'is_primary',
- 'dns_name', 'description',
+ 'dns_name', 'description', 'comments',
]
def __init__(self, data=None, *args, **kwargs):
@@ -326,7 +326,7 @@ class FHRPGroupCSVForm(NetBoxModelCSVForm):
class Meta:
model = FHRPGroup
- fields = ('protocol', 'group_id', 'auth_type', 'auth_key', 'name', 'description')
+ fields = ('protocol', 'group_id', 'auth_type', 'auth_key', 'name', 'description', 'comments')
class VLANGroupCSVForm(NetBoxModelCSVForm):
@@ -389,7 +389,7 @@ class VLANCSVForm(NetBoxModelCSVForm):
class Meta:
model = VLAN
- fields = ('site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description')
+ fields = ('site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description', 'comments')
help_texts = {
'vid': 'Numeric VLAN ID (1-4094)',
'name': 'VLAN name',
@@ -404,7 +404,7 @@ class ServiceTemplateCSVForm(NetBoxModelCSVForm):
class Meta:
model = ServiceTemplate
- fields = ('name', 'protocol', 'ports', 'description')
+ fields = ('name', 'protocol', 'ports', 'description', 'comments')
class ServiceCSVForm(NetBoxModelCSVForm):
@@ -427,7 +427,7 @@ class ServiceCSVForm(NetBoxModelCSVForm):
class Meta:
model = Service
- fields = ('device', 'virtual_machine', 'name', 'protocol', 'ports', 'description')
+ fields = ('device', 'virtual_machine', 'name', 'protocol', 'ports', 'description', 'comments')
class L2VPNCSVForm(NetBoxModelCSVForm):
@@ -443,7 +443,7 @@ class L2VPNCSVForm(NetBoxModelCSVForm):
class Meta:
model = L2VPN
- fields = ('identifier', 'name', 'slug', 'type', 'description')
+ fields = ('identifier', 'name', 'slug', 'type', 'description', 'comments')
class L2VPNTerminationCSVForm(NetBoxModelCSVForm):
diff --git a/netbox/ipam/forms/model_forms.py b/netbox/ipam/forms/model_forms.py
index 061462e71..9a5abc082 100644
--- a/netbox/ipam/forms/model_forms.py
+++ b/netbox/ipam/forms/model_forms.py
@@ -11,7 +11,7 @@ from netbox.forms import NetBoxModelForm
from tenancy.forms import TenancyForm
from utilities.exceptions import PermissionsViolation
from utilities.forms import (
- add_blank_choice, BootstrapMixin, ContentTypeChoiceField, DatePicker, DynamicModelChoiceField,
+ add_blank_choice, BootstrapMixin, CommentField, ContentTypeChoiceField, DatePicker, DynamicModelChoiceField,
DynamicModelMultipleChoiceField, NumericArrayField, SlugField, StaticSelect, StaticSelectMultiple,
)
from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface
@@ -49,6 +49,7 @@ class VRFForm(TenancyForm, NetBoxModelForm):
queryset=RouteTarget.objects.all(),
required=False
)
+ comments = CommentField()
fieldsets = (
('VRF', ('name', 'rd', 'enforce_unique', 'description', 'tags')),
@@ -59,8 +60,8 @@ class VRFForm(TenancyForm, NetBoxModelForm):
class Meta:
model = VRF
fields = [
- 'name', 'rd', 'enforce_unique', 'description', 'import_targets', 'export_targets', 'tenant_group', 'tenant',
- 'tags',
+ 'name', 'rd', 'enforce_unique', 'import_targets', 'export_targets', 'tenant_group', 'tenant', 'description',
+ 'comments', 'tags',
]
labels = {
'rd': "RD",
@@ -75,11 +76,12 @@ class RouteTargetForm(TenancyForm, NetBoxModelForm):
('Route Target', ('name', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')),
)
+ comments = CommentField()
class Meta:
model = RouteTarget
fields = [
- 'name', 'description', 'tenant_group', 'tenant', 'tags',
+ 'name', 'tenant_group', 'tenant', 'description', 'comments', 'tags',
]
@@ -104,6 +106,7 @@ class AggregateForm(TenancyForm, NetBoxModelForm):
queryset=RIR.objects.all(),
label='RIR'
)
+ comments = CommentField()
fieldsets = (
('Aggregate', ('prefix', 'rir', 'date_added', 'description', 'tags')),
@@ -113,7 +116,7 @@ class AggregateForm(TenancyForm, NetBoxModelForm):
class Meta:
model = Aggregate
fields = [
- 'prefix', 'rir', 'date_added', 'description', 'tenant_group', 'tenant', 'tags',
+ 'prefix', 'rir', 'date_added', 'tenant_group', 'tenant', 'description', 'comments', 'tags',
]
help_texts = {
'prefix': "IPv4 or IPv6 network",
@@ -134,6 +137,7 @@ class ASNForm(TenancyForm, NetBoxModelForm):
label='Sites',
required=False
)
+ comments = CommentField()
fieldsets = (
('ASN', ('asn', 'rir', 'sites', 'description', 'tags')),
@@ -143,7 +147,7 @@ class ASNForm(TenancyForm, NetBoxModelForm):
class Meta:
model = ASN
fields = [
- 'asn', 'rir', 'sites', 'tenant_group', 'tenant', 'description', 'tags'
+ 'asn', 'rir', 'sites', 'tenant_group', 'tenant', 'description', 'comments', 'tags'
]
help_texts = {
'asn': "AS number",
@@ -235,6 +239,7 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
queryset=Role.objects.all(),
required=False
)
+ comments = CommentField()
fieldsets = (
('Prefix', ('prefix', 'status', 'vrf', 'role', 'is_pool', 'mark_utilized', 'description', 'tags')),
@@ -245,8 +250,8 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
class Meta:
model = Prefix
fields = [
- 'prefix', 'vrf', 'site', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized', 'description',
- 'tenant_group', 'tenant', 'tags',
+ 'prefix', 'vrf', 'site', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized', 'tenant_group', 'tenant',
+ 'description', 'comments', 'tags',
]
widgets = {
'status': StaticSelect(),
@@ -263,6 +268,7 @@ class IPRangeForm(TenancyForm, NetBoxModelForm):
queryset=Role.objects.all(),
required=False
)
+ comments = CommentField()
fieldsets = (
('IP Range', ('vrf', 'start_address', 'end_address', 'role', 'status', 'description', 'tags')),
@@ -272,7 +278,8 @@ class IPRangeForm(TenancyForm, NetBoxModelForm):
class Meta:
model = IPRange
fields = [
- 'vrf', 'start_address', 'end_address', 'status', 'role', 'description', 'tenant_group', 'tenant', 'tags',
+ 'vrf', 'start_address', 'end_address', 'status', 'role', 'tenant_group', 'tenant', 'description',
+ 'comments', 'tags',
]
widgets = {
'status': StaticSelect(),
@@ -394,13 +401,14 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
required=False,
label='Make this the primary IP for the device/VM'
)
+ comments = CommentField()
class Meta:
model = IPAddress
fields = [
- 'address', 'vrf', 'status', 'role', 'dns_name', 'description', 'primary_for_parent', 'nat_site', 'nat_rack',
- 'nat_device', 'nat_cluster', 'nat_virtual_machine', 'nat_vrf', 'nat_inside', 'tenant_group', 'tenant',
- 'tags',
+ 'address', 'vrf', 'status', 'role', 'dns_name', 'primary_for_parent', 'nat_site', 'nat_rack', 'nat_device',
+ 'nat_cluster', 'nat_virtual_machine', 'nat_vrf', 'nat_inside', 'tenant_group', 'tenant', 'description',
+ 'comments', 'tags',
]
widgets = {
'status': StaticSelect(),
@@ -535,6 +543,7 @@ class FHRPGroupForm(NetBoxModelForm):
required=False,
label='Status'
)
+ comments = CommentField()
fieldsets = (
('FHRP Group', ('protocol', 'group_id', 'name', 'description', 'tags')),
@@ -545,7 +554,8 @@ class FHRPGroupForm(NetBoxModelForm):
class Meta:
model = FHRPGroup
fields = (
- 'protocol', 'group_id', 'auth_type', 'auth_key', 'name', 'description', 'ip_vrf', 'ip_address', 'ip_status', 'tags',
+ 'protocol', 'group_id', 'auth_type', 'auth_key', 'name', 'ip_vrf', 'ip_address', 'ip_status', 'description',
+ 'comments', 'tags',
)
def save(self, *args, **kwargs):
@@ -767,11 +777,13 @@ class VLANForm(TenancyForm, NetBoxModelForm):
queryset=Role.objects.all(),
required=False
)
+ comments = CommentField()
class Meta:
model = VLAN
fields = [
- 'site', 'group', 'vid', 'name', 'status', 'role', 'description', 'tenant_group', 'tenant', 'tags',
+ 'site', 'group', 'vid', 'name', 'status', 'role', 'tenant_group', 'tenant', 'description', 'comments',
+ 'tags',
]
help_texts = {
'site': "Leave blank if this VLAN spans multiple sites",
@@ -794,6 +806,7 @@ class ServiceTemplateForm(NetBoxModelForm):
),
help_text="Comma-separated list of one or more port numbers. A range may be specified using a hyphen."
)
+ comments = CommentField()
fieldsets = (
('Service Template', (
@@ -803,7 +816,7 @@ class ServiceTemplateForm(NetBoxModelForm):
class Meta:
model = ServiceTemplate
- fields = ('name', 'protocol', 'ports', 'description', 'tags')
+ fields = ('name', 'protocol', 'ports', 'description', 'comments', 'tags')
widgets = {
'protocol': StaticSelect(),
}
@@ -834,11 +847,12 @@ class ServiceForm(NetBoxModelForm):
'virtual_machine_id': '$virtual_machine',
}
)
+ comments = CommentField()
class Meta:
model = Service
fields = [
- 'device', 'virtual_machine', 'name', 'protocol', 'ports', 'ipaddresses', 'description', 'tags',
+ 'device', 'virtual_machine', 'name', 'protocol', 'ports', 'ipaddresses', 'description', 'comments', 'tags',
]
help_texts = {
'ipaddresses': "IP address assignment is optional. If no IPs are selected, the service is assumed to be "
@@ -899,6 +913,7 @@ class L2VPNForm(TenancyForm, NetBoxModelForm):
queryset=RouteTarget.objects.all(),
required=False
)
+ comments = CommentField()
fieldsets = (
('L2VPN', ('name', 'slug', 'type', 'identifier', 'description', 'tags')),
@@ -909,7 +924,8 @@ class L2VPNForm(TenancyForm, NetBoxModelForm):
class Meta:
model = L2VPN
fields = (
- 'name', 'slug', 'type', 'identifier', 'description', 'import_targets', 'export_targets', 'tenant', 'tags'
+ 'name', 'slug', 'type', 'identifier', 'import_targets', 'export_targets', 'tenant', 'description',
+ 'comments', 'tags'
)
widgets = {
'type': StaticSelect(),
diff --git a/netbox/ipam/migrations/0063_standardize_description_comments.py b/netbox/ipam/migrations/0063_standardize_description_comments.py
new file mode 100644
index 000000000..3a4959d14
--- /dev/null
+++ b/netbox/ipam/migrations/0063_standardize_description_comments.py
@@ -0,0 +1,73 @@
+# Generated by Django 4.1.2 on 2022-11-03 18:24
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ipam', '0062_unique_constraints'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='aggregate',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='asn',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='fhrpgroup',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='ipaddress',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='iprange',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='l2vpn',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='prefix',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='routetarget',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='service',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='servicetemplate',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='vlan',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='vrf',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ ]
diff --git a/netbox/ipam/models/fhrp.py b/netbox/ipam/models/fhrp.py
index 633affa41..759a6e1d3 100644
--- a/netbox/ipam/models/fhrp.py
+++ b/netbox/ipam/models/fhrp.py
@@ -4,7 +4,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.urls import reverse
-from netbox.models import ChangeLoggedModel, NetBoxModel
+from netbox.models import ChangeLoggedModel, PrimaryModel
from netbox.models.features import WebhooksMixin
from ipam.choices import *
from ipam.constants import *
@@ -15,7 +15,7 @@ __all__ = (
)
-class FHRPGroup(NetBoxModel):
+class FHRPGroup(PrimaryModel):
"""
A grouping of next hope resolution protocol (FHRP) peers. (For instance, VRRP or HSRP.)
"""
@@ -41,10 +41,6 @@ class FHRPGroup(NetBoxModel):
blank=True,
verbose_name='Authentication key'
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
ip_addresses = GenericRelation(
to='ipam.IPAddress',
content_type_field='assigned_object_type',
diff --git a/netbox/ipam/models/ip.py b/netbox/ipam/models/ip.py
index 75f90ff54..bf9bd6d7f 100644
--- a/netbox/ipam/models/ip.py
+++ b/netbox/ipam/models/ip.py
@@ -9,7 +9,7 @@ from django.utils.functional import cached_property
from dcim.fields import ASNField
from dcim.models import Device
-from netbox.models import OrganizationalModel, NetBoxModel
+from netbox.models import OrganizationalModel, PrimaryModel
from ipam.choices import *
from ipam.constants import *
from ipam.fields import IPNetworkField, IPAddressField
@@ -76,7 +76,7 @@ class RIR(OrganizationalModel):
return reverse('ipam:rir', args=[self.pk])
-class ASN(NetBoxModel):
+class ASN(PrimaryModel):
"""
An autonomous system (AS) number is typically used to represent an independent routing domain. A site can have
one or more ASNs assigned to it.
@@ -86,10 +86,6 @@ class ASN(NetBoxModel):
verbose_name='ASN',
help_text='32-bit autonomous system number'
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
rir = models.ForeignKey(
to='ipam.RIR',
on_delete=models.PROTECT,
@@ -139,7 +135,7 @@ class ASN(NetBoxModel):
return self.asn
-class Aggregate(GetAvailablePrefixesMixin, NetBoxModel):
+class Aggregate(GetAvailablePrefixesMixin, PrimaryModel):
"""
An aggregate exists at the root level of the IP address space hierarchy in NetBox. Aggregates are used to organize
the hierarchy and track the overall utilization of available address space. Each Aggregate is assigned to a RIR.
@@ -162,10 +158,6 @@ class Aggregate(GetAvailablePrefixesMixin, NetBoxModel):
blank=True,
null=True
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
clone_fields = (
'rir', 'tenant', 'date_added', 'description',
@@ -264,7 +256,7 @@ class Role(OrganizationalModel):
return reverse('ipam:role', args=[self.pk])
-class Prefix(GetAvailablePrefixesMixin, NetBoxModel):
+class Prefix(GetAvailablePrefixesMixin, PrimaryModel):
"""
A Prefix represents an IPv4 or IPv6 network, including mask length. Prefixes can optionally be assigned to Sites and
VRFs. A Prefix must be assigned a status and may optionally be assigned a used-define Role. A Prefix can also be
@@ -327,10 +319,6 @@ class Prefix(GetAvailablePrefixesMixin, NetBoxModel):
default=False,
help_text="Treat as 100% utilized"
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
# Cached depth & child counts
_depth = models.PositiveSmallIntegerField(
@@ -545,7 +533,7 @@ class Prefix(GetAvailablePrefixesMixin, NetBoxModel):
return min(utilization, 100)
-class IPRange(NetBoxModel):
+class IPRange(PrimaryModel):
"""
A range of IP addresses, defined by start and end addresses.
"""
@@ -587,10 +575,6 @@ class IPRange(NetBoxModel):
null=True,
help_text='The primary function of this range'
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
clone_fields = (
'vrf', 'tenant', 'status', 'role', 'description',
@@ -740,7 +724,7 @@ class IPRange(NetBoxModel):
return int(float(child_count) / self.size * 100)
-class IPAddress(NetBoxModel):
+class IPAddress(PrimaryModel):
"""
An IPAddress represents an individual IPv4 or IPv6 address and its mask. The mask length should match what is
configured in the real world. (Typically, only loopback interfaces are configured with /32 or /128 masks.) Like
@@ -813,10 +797,6 @@ class IPAddress(NetBoxModel):
verbose_name='DNS Name',
help_text='Hostname or FQDN (not case-sensitive)'
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
objects = IPAddressManager()
diff --git a/netbox/ipam/models/l2vpn.py b/netbox/ipam/models/l2vpn.py
index a457f334b..f3f7a1d55 100644
--- a/netbox/ipam/models/l2vpn.py
+++ b/netbox/ipam/models/l2vpn.py
@@ -8,7 +8,7 @@ from django.utils.functional import cached_property
from ipam.choices import L2VPNTypeChoices
from ipam.constants import L2VPN_ASSIGNMENT_MODELS
-from netbox.models import NetBoxModel
+from netbox.models import NetBoxModel, PrimaryModel
__all__ = (
'L2VPN',
@@ -16,7 +16,7 @@ __all__ = (
)
-class L2VPN(NetBoxModel):
+class L2VPN(PrimaryModel):
name = models.CharField(
max_length=100,
unique=True
@@ -43,10 +43,6 @@ class L2VPN(NetBoxModel):
related_name='exporting_l2vpns',
blank=True
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
tenant = models.ForeignKey(
to='tenancy.Tenant',
on_delete=models.PROTECT,
diff --git a/netbox/ipam/models/services.py b/netbox/ipam/models/services.py
index b566db375..690abf045 100644
--- a/netbox/ipam/models/services.py
+++ b/netbox/ipam/models/services.py
@@ -6,7 +6,7 @@ from django.urls import reverse
from ipam.choices import *
from ipam.constants import *
-from netbox.models import NetBoxModel
+from netbox.models import PrimaryModel
from utilities.utils import array_to_string
@@ -30,10 +30,6 @@ class ServiceBase(models.Model):
),
verbose_name='Port numbers'
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
class Meta:
abstract = True
@@ -46,7 +42,7 @@ class ServiceBase(models.Model):
return array_to_string(self.ports)
-class ServiceTemplate(ServiceBase, NetBoxModel):
+class ServiceTemplate(ServiceBase, PrimaryModel):
"""
A template for a Service to be applied to a device or virtual machine.
"""
@@ -62,7 +58,7 @@ class ServiceTemplate(ServiceBase, NetBoxModel):
return reverse('ipam:servicetemplate', args=[self.pk])
-class Service(ServiceBase, NetBoxModel):
+class Service(ServiceBase, PrimaryModel):
"""
A Service represents a layer-four service (e.g. HTTP or SSH) running on a Device or VirtualMachine. A Service may
optionally be tied to one or more specific IPAddresses belonging to its parent.
diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py
index e3a4b973b..4f5d513cf 100644
--- a/netbox/ipam/models/vlans.py
+++ b/netbox/ipam/models/vlans.py
@@ -8,12 +8,10 @@ from django.urls import reverse
from dcim.models import Interface
from ipam.choices import *
from ipam.constants import *
-from ipam.models import L2VPNTermination
from ipam.querysets import VLANQuerySet
-from netbox.models import OrganizationalModel, NetBoxModel
+from netbox.models import OrganizationalModel, PrimaryModel
from virtualization.models import VMInterface
-
__all__ = (
'VLAN',
'VLANGroup',
@@ -63,10 +61,6 @@ class VLANGroup(OrganizationalModel):
),
help_text='Highest permissible ID of a child VLAN'
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
class Meta:
ordering = ('name', 'pk') # Name may be non-unique
@@ -120,7 +114,7 @@ class VLANGroup(OrganizationalModel):
return None
-class VLAN(NetBoxModel):
+class VLAN(PrimaryModel):
"""
A VLAN is a distinct layer two forwarding domain identified by a 12-bit integer (1-4094). Each VLAN must be assigned
to a Site, however VLAN IDs need not be unique within a Site. A VLAN may optionally be assigned to a VLANGroup,
@@ -172,10 +166,6 @@ class VLAN(NetBoxModel):
blank=True,
null=True
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
l2vpn_terminations = GenericRelation(
to='ipam.L2VPNTermination',
diff --git a/netbox/ipam/models/vrfs.py b/netbox/ipam/models/vrfs.py
index a926bec3e..0f3c9793c 100644
--- a/netbox/ipam/models/vrfs.py
+++ b/netbox/ipam/models/vrfs.py
@@ -2,7 +2,7 @@ from django.db import models
from django.urls import reverse
from ipam.constants import *
-from netbox.models import NetBoxModel
+from netbox.models import PrimaryModel
__all__ = (
@@ -11,7 +11,7 @@ __all__ = (
)
-class VRF(NetBoxModel):
+class VRF(PrimaryModel):
"""
A virtual routing and forwarding (VRF) table represents a discrete layer three forwarding domain (e.g. a routing
table). Prefixes and IPAddresses can optionally be assigned to VRFs. (Prefixes and IPAddresses not assigned to a VRF
@@ -40,10 +40,6 @@ class VRF(NetBoxModel):
verbose_name='Enforce unique space',
help_text='Prevent duplicate prefixes/IP addresses within this VRF'
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
import_targets = models.ManyToManyField(
to='ipam.RouteTarget',
related_name='importing_vrfs',
@@ -73,7 +69,7 @@ class VRF(NetBoxModel):
return reverse('ipam:vrf', args=[self.pk])
-class RouteTarget(NetBoxModel):
+class RouteTarget(PrimaryModel):
"""
A BGP extended community used to control the redistribution of routes among VRFs, as defined in RFC 4364.
"""
@@ -82,10 +78,6 @@ class RouteTarget(NetBoxModel):
unique=True,
help_text='Route target value (formatted in accordance with RFC 4360)'
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
tenant = models.ForeignKey(
to='tenancy.Tenant',
on_delete=models.PROTECT,
diff --git a/netbox/ipam/tables/fhrp.py b/netbox/ipam/tables/fhrp.py
index beffdd232..89aa16e65 100644
--- a/netbox/ipam/tables/fhrp.py
+++ b/netbox/ipam/tables/fhrp.py
@@ -20,7 +20,6 @@ class FHRPGroupTable(NetBoxTable):
group_id = tables.Column(
linkify=True
)
- comments = columns.MarkdownColumn()
ip_addresses = tables.TemplateColumn(
template_code=IPADDRESSES,
orderable=False,
@@ -29,6 +28,7 @@ class FHRPGroupTable(NetBoxTable):
member_count = tables.Column(
verbose_name='Members'
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:fhrpgroup_list'
)
@@ -36,7 +36,7 @@ class FHRPGroupTable(NetBoxTable):
class Meta(NetBoxTable.Meta):
model = FHRPGroup
fields = (
- 'pk', 'group_id', 'protocol', 'name', 'auth_type', 'auth_key', 'description', 'ip_addresses',
+ 'pk', 'group_id', 'protocol', 'name', 'auth_type', 'auth_key', 'description', 'comments', 'ip_addresses',
'member_count', 'tags', 'created', 'last_updated',
)
default_columns = (
diff --git a/netbox/ipam/tables/ip.py b/netbox/ipam/tables/ip.py
index 44f40b8a1..f83831d2d 100644
--- a/netbox/ipam/tables/ip.py
+++ b/netbox/ipam/tables/ip.py
@@ -120,6 +120,7 @@ class ASNTable(TenancyColumnsMixin, NetBoxTable):
linkify_item=True,
verbose_name='Sites'
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:asn_list'
)
@@ -127,8 +128,8 @@ class ASNTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = ASN
fields = (
- 'pk', 'asn', 'asn_asdot', 'rir', 'site_count', 'provider_count', 'tenant', 'tenant_group', 'description', 'sites', 'tags',
- 'created', 'last_updated', 'actions',
+ 'pk', 'asn', 'asn_asdot', 'rir', 'site_count', 'provider_count', 'tenant', 'tenant_group', 'description',
+ 'comments', 'sites', 'tags', 'created', 'last_updated', 'actions',
)
default_columns = ('pk', 'asn', 'rir', 'site_count', 'provider_count', 'sites', 'description', 'tenant')
@@ -153,6 +154,7 @@ class AggregateTable(TenancyColumnsMixin, NetBoxTable):
accessor='get_utilization',
orderable=False
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:aggregate_list'
)
@@ -160,8 +162,8 @@ class AggregateTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = Aggregate
fields = (
- 'pk', 'id', 'prefix', 'rir', 'tenant', 'tenant_group', 'child_count', 'utilization', 'date_added', 'description', 'tags',
- 'created', 'last_updated',
+ 'pk', 'id', 'prefix', 'rir', 'tenant', 'tenant_group', 'child_count', 'utilization', 'date_added',
+ 'description', 'comments', 'tags', 'created', 'last_updated',
)
default_columns = ('pk', 'prefix', 'rir', 'tenant', 'child_count', 'utilization', 'date_added', 'description')
@@ -278,6 +280,7 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
accessor='get_utilization',
orderable=False
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:prefix_list'
)
@@ -285,8 +288,9 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = Prefix
fields = (
- 'pk', 'id', 'prefix', 'prefix_flat', 'status', 'children', 'vrf', 'utilization', 'tenant', 'tenant_group', 'site',
- 'vlan_group', 'vlan', 'role', 'is_pool', 'mark_utilized', 'description', 'tags', 'created', 'last_updated',
+ 'pk', 'id', 'prefix', 'prefix_flat', 'status', 'children', 'vrf', 'utilization', 'tenant', 'tenant_group',
+ 'site', 'vlan_group', 'vlan', 'role', 'is_pool', 'mark_utilized', 'description', 'comments', 'tags',
+ 'created', 'last_updated',
)
default_columns = (
'pk', 'prefix', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role', 'description',
@@ -317,6 +321,7 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
accessor='utilization',
orderable=False
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:iprange_list'
)
@@ -324,8 +329,8 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = IPRange
fields = (
- 'pk', 'id', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'tenant_group', 'description',
- 'utilization', 'tags', 'created', 'last_updated',
+ 'pk', 'id', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'tenant_group',
+ 'utilization', 'description', 'comments', 'tags', 'created', 'last_updated',
)
default_columns = (
'pk', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'description',
@@ -378,6 +383,7 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
linkify=lambda record: record.assigned_object.get_absolute_url(),
verbose_name='Assigned'
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:ipaddress_list'
)
@@ -385,8 +391,8 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = IPAddress
fields = (
- 'pk', 'id', 'address', 'vrf', 'status', 'role', 'tenant', 'tenant_group', 'nat_inside', 'nat_outside', 'assigned', 'dns_name', 'description',
- 'tags', 'created', 'last_updated',
+ 'pk', 'id', 'address', 'vrf', 'status', 'role', 'tenant', 'tenant_group', 'nat_inside', 'nat_outside',
+ 'assigned', 'dns_name', 'description', 'comments', 'tags', 'created', 'last_updated',
)
default_columns = (
'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned', 'dns_name', 'description',
diff --git a/netbox/ipam/tables/l2vpn.py b/netbox/ipam/tables/l2vpn.py
index 4a6af7c9b..2ece2c434 100644
--- a/netbox/ipam/tables/l2vpn.py
+++ b/netbox/ipam/tables/l2vpn.py
@@ -29,12 +29,16 @@ class L2VPNTable(TenancyColumnsMixin, NetBoxTable):
template_code=L2VPN_TARGETS,
orderable=False
)
+ comments = columns.MarkdownColumn()
+ tags = columns.TagColumn(
+ url_name='ipam:prefix_list'
+ )
class Meta(NetBoxTable.Meta):
model = L2VPN
fields = (
- 'pk', 'name', 'slug', 'identifier', 'type', 'description', 'import_targets', 'export_targets', 'tenant', 'tenant_group',
- 'actions',
+ 'pk', 'name', 'slug', 'identifier', 'type', 'import_targets', 'export_targets', 'tenant', 'tenant_group',
+ 'description', 'comments', 'tags', 'created', 'last_updated', 'actions',
)
default_columns = ('pk', 'name', 'identifier', 'type', 'description', 'actions')
diff --git a/netbox/ipam/tables/services.py b/netbox/ipam/tables/services.py
index 58d0a9aff..826ac98d5 100644
--- a/netbox/ipam/tables/services.py
+++ b/netbox/ipam/tables/services.py
@@ -17,13 +17,16 @@ class ServiceTemplateTable(NetBoxTable):
accessor=tables.A('port_list'),
order_by=tables.A('ports'),
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:servicetemplate_list'
)
class Meta(NetBoxTable.Meta):
model = ServiceTemplate
- fields = ('pk', 'id', 'name', 'protocol', 'ports', 'description', 'tags')
+ fields = (
+ 'pk', 'id', 'name', 'protocol', 'ports', 'description', 'comments', 'tags', 'created', 'last_updated',
+ )
default_columns = ('pk', 'name', 'protocol', 'ports', 'description')
@@ -39,6 +42,7 @@ class ServiceTable(NetBoxTable):
accessor=tables.A('port_list'),
order_by=tables.A('ports'),
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:service_list'
)
@@ -46,7 +50,7 @@ class ServiceTable(NetBoxTable):
class Meta(NetBoxTable.Meta):
model = Service
fields = (
- 'pk', 'id', 'name', 'parent', 'protocol', 'ports', 'ipaddresses', 'description', 'tags', 'created',
- 'last_updated',
+ 'pk', 'id', 'name', 'parent', 'protocol', 'ports', 'ipaddresses', 'description', 'comments', 'tags',
+ 'created', 'last_updated',
)
default_columns = ('pk', 'name', 'parent', 'protocol', 'ports', 'description')
diff --git a/netbox/ipam/tables/vlans.py b/netbox/ipam/tables/vlans.py
index f183f8a7b..6fa2cd2da 100644
--- a/netbox/ipam/tables/vlans.py
+++ b/netbox/ipam/tables/vlans.py
@@ -121,6 +121,7 @@ class VLANTable(TenancyColumnsMixin, NetBoxTable):
orderable=False,
verbose_name='Prefixes'
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:vlan_list'
)
@@ -129,7 +130,7 @@ class VLANTable(TenancyColumnsMixin, NetBoxTable):
model = VLAN
fields = (
'pk', 'id', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'tenant_group', 'status', 'role',
- 'description', 'tags', 'l2vpn', 'created', 'last_updated',
+ 'description', 'comments', 'tags', 'l2vpn', 'created', 'last_updated',
)
default_columns = ('pk', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'status', 'role', 'description')
row_attrs = {
diff --git a/netbox/ipam/tables/vrfs.py b/netbox/ipam/tables/vrfs.py
index 69807410b..635af48d0 100644
--- a/netbox/ipam/tables/vrfs.py
+++ b/netbox/ipam/tables/vrfs.py
@@ -38,6 +38,7 @@ class VRFTable(TenancyColumnsMixin, NetBoxTable):
template_code=VRF_TARGETS,
orderable=False
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:vrf_list'
)
@@ -45,8 +46,8 @@ class VRFTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = VRF
fields = (
- 'pk', 'id', 'name', 'rd', 'tenant', 'tenant_group', 'enforce_unique', 'description', 'import_targets', 'export_targets',
- 'tags', 'created', 'last_updated',
+ 'pk', 'id', 'name', 'rd', 'tenant', 'tenant_group', 'enforce_unique', 'import_targets', 'export_targets',
+ 'description', 'comments', 'tags', 'created', 'last_updated',
)
default_columns = ('pk', 'name', 'rd', 'tenant', 'description')
@@ -59,11 +60,14 @@ class RouteTargetTable(TenancyColumnsMixin, NetBoxTable):
name = tables.Column(
linkify=True
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:vrf_list'
)
class Meta(NetBoxTable.Meta):
model = RouteTarget
- fields = ('pk', 'id', 'name', 'tenant', 'tenant_group', 'description', 'tags', 'created', 'last_updated',)
+ fields = (
+ 'pk', 'id', 'name', 'tenant', 'tenant_group', 'description', 'comments', 'tags', 'created', 'last_updated',
+ )
default_columns = ('pk', 'name', 'tenant', 'description')
diff --git a/netbox/netbox/models/__init__.py b/netbox/netbox/models/__init__.py
index 38a6fcc9f..661470ee0 100644
--- a/netbox/netbox/models/__init__.py
+++ b/netbox/netbox/models/__init__.py
@@ -10,8 +10,9 @@ from netbox.models.features import *
__all__ = (
'ChangeLoggedModel',
'NestedGroupModel',
- 'OrganizationalModel',
'NetBoxModel',
+ 'OrganizationalModel',
+ 'PrimaryModel',
)
@@ -58,7 +59,7 @@ class ChangeLoggedModel(ChangeLoggingMixin, CustomValidationMixin, models.Model)
class NetBoxModel(CloningMixin, NetBoxFeatureSet, models.Model):
"""
- Primary models represent real objects within the infrastructure being modeled.
+ Base model for most object types. Suitable for use by plugins.
"""
objects = RestrictedQuerySet.as_manager()
@@ -66,6 +67,22 @@ class NetBoxModel(CloningMixin, NetBoxFeatureSet, models.Model):
abstract = True
+class PrimaryModel(NetBoxModel):
+ """
+ Primary models represent real objects within the infrastructure being modeled.
+ """
+ description = models.CharField(
+ max_length=200,
+ blank=True
+ )
+ comments = models.TextField(
+ blank=True
+ )
+
+ class Meta:
+ abstract = True
+
+
class NestedGroupModel(NetBoxFeatureSet, MPTTModel):
"""
Base model for objects which are used to form a hierarchy (regions, locations, etc.). These models nest
diff --git a/netbox/templates/circuits/provider.html b/netbox/templates/circuits/provider.html
index 0fc18a368..51f911350 100644
--- a/netbox/templates/circuits/provider.html
+++ b/netbox/templates/circuits/provider.html
@@ -33,6 +33,10 @@
Account
{{ object.account|placeholder }}
+
+ Description
+ {{ object.description|placeholder }}
+
Circuits
diff --git a/netbox/templates/dcim/cable.html b/netbox/templates/dcim/cable.html
index e032d7034..bd0f27106 100644
--- a/netbox/templates/dcim/cable.html
+++ b/netbox/templates/dcim/cable.html
@@ -32,6 +32,10 @@
Label
{{ object.label|placeholder }}
+
+ Description
+ {{ object.description|placeholder }}
+
Color
@@ -57,6 +61,7 @@
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_left_page object %}
diff --git a/netbox/templates/dcim/cable_edit.html b/netbox/templates/dcim/cable_edit.html
index 29bb60d70..1c747b44b 100644
--- a/netbox/templates/dcim/cable_edit.html
+++ b/netbox/templates/dcim/cable_edit.html
@@ -80,6 +80,7 @@
{% render_field form.tenant_group %}
{% render_field form.tenant %}
{% render_field form.label %}
+ {% render_field form.description %}
{% render_field form.color %}
{{ form.length.label }}
@@ -92,16 +93,22 @@
{% render_field form.tags %}
- {% if form.custom_fields %}
-
-
-
Custom Fields
-
- {% render_custom_fields form %}
-
- {% endif %}
+
+
+
+ {% render_field form.comments %}
+
+
+ {% if form.custom_fields %}
+
+
+
+ {% render_custom_fields form %}
+
+
+ {% endif %}
diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html
index b0cd76de4..046600d08 100644
--- a/netbox/templates/dcim/device.html
+++ b/netbox/templates/dcim/device.html
@@ -94,7 +94,11 @@
- Airflow
+ Description
+ {{ object.description|placeholder }}
+
+
+ Airflow
{{ object.get_airflow_display|placeholder }}
diff --git a/netbox/templates/dcim/device_edit.html b/netbox/templates/dcim/device_edit.html
index 38125e83c..b814e65ef 100644
--- a/netbox/templates/dcim/device_edit.html
+++ b/netbox/templates/dcim/device_edit.html
@@ -10,6 +10,7 @@
{% render_field form.name %}
{% render_field form.device_role %}
+ {% render_field form.description %}
{% render_field form.tags %}
diff --git a/netbox/templates/dcim/devicetype.html b/netbox/templates/dcim/devicetype.html
index 458c74ac1..930390a56 100644
--- a/netbox/templates/dcim/devicetype.html
+++ b/netbox/templates/dcim/devicetype.html
@@ -27,6 +27,10 @@
Part Number
{{ object.part_number|placeholder }}
+
+ Description
+ {{ object.description|placeholder }}
+
Height (U)
{{ object.u_height|floatformat }}
diff --git a/netbox/templates/dcim/module.html b/netbox/templates/dcim/module.html
index f2dac38f2..139ac2eb8 100644
--- a/netbox/templates/dcim/module.html
+++ b/netbox/templates/dcim/module.html
@@ -62,6 +62,10 @@
Module Type
{{ object.module_type|linkify }}
+
+ Description
+ {{ object.description|placeholder }}
+
Serial Number
{{ object.serial|placeholder }}
diff --git a/netbox/templates/dcim/moduletype.html b/netbox/templates/dcim/moduletype.html
index 8128e64be..fd0148c2f 100644
--- a/netbox/templates/dcim/moduletype.html
+++ b/netbox/templates/dcim/moduletype.html
@@ -22,6 +22,10 @@
Part Number
{{ object.part_number|placeholder }}
+
+ Description
+ {{ object.description|placeholder }}
+
Weight
diff --git a/netbox/templates/dcim/powerfeed.html b/netbox/templates/dcim/powerfeed.html
index 54ac96bab..6387c111d 100644
--- a/netbox/templates/dcim/powerfeed.html
+++ b/netbox/templates/dcim/powerfeed.html
@@ -38,6 +38,10 @@
Status
{% badge object.get_status_display bg_color=object.get_status_color %}
+
+ Description
+ {{ object.description|placeholder }}
+
Connected Device
diff --git a/netbox/templates/dcim/powerpanel.html b/netbox/templates/dcim/powerpanel.html
index b7fe8eb39..16bd82cc0 100644
--- a/netbox/templates/dcim/powerpanel.html
+++ b/netbox/templates/dcim/powerpanel.html
@@ -14,26 +14,29 @@
{% block content %}
-
-
-
-
-
- Site
- {{ object.site|linkify }}
-
-
- Location
- {{ object.location|linkify|placeholder }}
-
-
-
-
- {% include 'inc/panels/tags.html' %}
- {% plugin_left_page object %}
+
+
+
+
+
+ Site
+ {{ object.site|linkify }}
+
+
+ Location
+ {{ object.location|linkify|placeholder }}
+
+
+ Description
+ {{ object.description|placeholder }}
+
+
+
+ {% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/comments.html' %}
+ {% plugin_left_page object %}
+
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/contacts.html' %}
diff --git a/netbox/templates/dcim/rack.html b/netbox/templates/dcim/rack.html
index 7118f09ef..185634e8a 100644
--- a/netbox/templates/dcim/rack.html
+++ b/netbox/templates/dcim/rack.html
@@ -78,6 +78,10 @@
Role
{{ object.role|linkify|placeholder }}
+
+ Description
+ {{ object.description|placeholder }}
+
Serial Number
{{ object.serial|placeholder }}
diff --git a/netbox/templates/dcim/rack_edit.html b/netbox/templates/dcim/rack_edit.html
index a0af20c68..d214bbee8 100644
--- a/netbox/templates/dcim/rack_edit.html
+++ b/netbox/templates/dcim/rack_edit.html
@@ -13,6 +13,7 @@
{% render_field form.name %}
{% render_field form.status %}
{% render_field form.role %}
+ {% render_field form.description %}
{% render_field form.tags %}
diff --git a/netbox/templates/dcim/rackreservation.html b/netbox/templates/dcim/rackreservation.html
index ebdd1d845..52472e297 100644
--- a/netbox/templates/dcim/rackreservation.html
+++ b/netbox/templates/dcim/rackreservation.html
@@ -73,6 +73,7 @@
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_left_page object %}
diff --git a/netbox/templates/dcim/virtualchassis.html b/netbox/templates/dcim/virtualchassis.html
index 1ff9f2e9a..d0fba3ca2 100644
--- a/netbox/templates/dcim/virtualchassis.html
+++ b/netbox/templates/dcim/virtualchassis.html
@@ -27,11 +27,15 @@
Master
{{ object.master|linkify }}
+
+ Description
+ {{ object.description|placeholder }}
+
- {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/custom_fields.html' %}
{% plugin_left_page object %}
@@ -73,6 +77,7 @@
{% endif %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_right_page object %}
diff --git a/netbox/templates/dcim/virtualchassis_edit.html b/netbox/templates/dcim/virtualchassis_edit.html
index 87917f2a2..f98a9fe64 100644
--- a/netbox/templates/dcim/virtualchassis_edit.html
+++ b/netbox/templates/dcim/virtualchassis_edit.html
@@ -17,12 +17,18 @@
{% render_field vc_form.name %}
{% render_field vc_form.domain %}
+ {% render_field vc_form.description %}
{% render_field vc_form.master %}
{% render_field vc_form.tags %}
+
+
Comments
+ {% render_field vc_form.comments %}
+
+
{% if vc_form.custom_fields %}
-
+
Custom Fields
diff --git a/netbox/templates/ipam/aggregate.html b/netbox/templates/ipam/aggregate.html
index f3eff9df1..b95341b16 100644
--- a/netbox/templates/ipam/aggregate.html
+++ b/netbox/templates/ipam/aggregate.html
@@ -51,6 +51,7 @@
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_right_page object %}
diff --git a/netbox/templates/ipam/asn.html b/netbox/templates/ipam/asn.html
index 7afe981e6..3af5177cc 100644
--- a/netbox/templates/ipam/asn.html
+++ b/netbox/templates/ipam/asn.html
@@ -67,6 +67,7 @@
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' with tags=object.tags.all url='ipam:asn_list' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_right_page object %}
diff --git a/netbox/templates/ipam/fhrpgroup.html b/netbox/templates/ipam/fhrpgroup.html
index 89fc7083c..a74ddac70 100644
--- a/netbox/templates/ipam/fhrpgroup.html
+++ b/netbox/templates/ipam/fhrpgroup.html
@@ -42,6 +42,7 @@
{% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_left_page object %}
diff --git a/netbox/templates/ipam/fhrpgroup_edit.html b/netbox/templates/ipam/fhrpgroup_edit.html
index 02816b440..bf86e6c41 100644
--- a/netbox/templates/ipam/fhrpgroup_edit.html
+++ b/netbox/templates/ipam/fhrpgroup_edit.html
@@ -13,7 +13,7 @@
{% render_field form.tags %}
-
+
Authentication
@@ -22,7 +22,7 @@
{% if not form.instance.pk %}
-
+
Virtual IP Address
@@ -32,6 +32,13 @@
{% endif %}
+
+
+
Comments
+
+ {% render_field form.comments %}
+
+
{% if form.custom_fields %}
Custom Fields
diff --git a/netbox/templates/ipam/ipaddress.html b/netbox/templates/ipam/ipaddress.html
index 7f77e8137..4a110c2e6 100644
--- a/netbox/templates/ipam/ipaddress.html
+++ b/netbox/templates/ipam/ipaddress.html
@@ -108,6 +108,7 @@
{% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_left_page object %}
diff --git a/netbox/templates/ipam/ipaddress_edit.html b/netbox/templates/ipam/ipaddress_edit.html
index f4b21397a..b9a988009 100644
--- a/netbox/templates/ipam/ipaddress_edit.html
+++ b/netbox/templates/ipam/ipaddress_edit.html
@@ -138,6 +138,13 @@
+
+
+
Comments
+
+ {% render_field form.comments %}
+
+
{% if form.custom_fields %}
diff --git a/netbox/templates/ipam/iprange.html b/netbox/templates/ipam/iprange.html
index c78b5a132..6ba9e4bea 100644
--- a/netbox/templates/ipam/iprange.html
+++ b/netbox/templates/ipam/iprange.html
@@ -70,9 +70,10 @@
{% plugin_left_page object %}
- {% include 'inc/panels/tags.html' %}
- {% include 'inc/panels/custom_fields.html' %}
- {% plugin_right_page object %}
+ {% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/custom_fields.html' %}
+ {% include 'inc/panels/comments.html' %}
+ {% plugin_right_page object %}
diff --git a/netbox/templates/ipam/l2vpn.html b/netbox/templates/ipam/l2vpn.html
index c19363d33..4ffda2c98 100644
--- a/netbox/templates/ipam/l2vpn.html
+++ b/netbox/templates/ipam/l2vpn.html
@@ -39,6 +39,7 @@
{% include 'inc/panels/contacts.html' %}
{% include 'inc/panels/custom_fields.html' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_right_page object %}
diff --git a/netbox/templates/ipam/prefix.html b/netbox/templates/ipam/prefix.html
index b15aa60bb..a0baf3325 100644
--- a/netbox/templates/ipam/prefix.html
+++ b/netbox/templates/ipam/prefix.html
@@ -155,6 +155,7 @@
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_right_page object %}
diff --git a/netbox/templates/ipam/routetarget.html b/netbox/templates/ipam/routetarget.html
index e093aee61..ea7a98c97 100644
--- a/netbox/templates/ipam/routetarget.html
+++ b/netbox/templates/ipam/routetarget.html
@@ -26,6 +26,7 @@
{% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_left_page object %}
diff --git a/netbox/templates/ipam/service.html b/netbox/templates/ipam/service.html
index 47ae70dc9..fdc4be342 100644
--- a/netbox/templates/ipam/service.html
+++ b/netbox/templates/ipam/service.html
@@ -58,9 +58,10 @@
{% plugin_left_page object %}
- {% include 'inc/panels/custom_fields.html' %}
- {% include 'inc/panels/tags.html' %}
- {% plugin_right_page object %}
+ {% include 'inc/panels/custom_fields.html' %}
+ {% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/comments.html' %}
+ {% plugin_right_page object %}
diff --git a/netbox/templates/ipam/service_create.html b/netbox/templates/ipam/service_create.html
index 022821bcf..5c47dd2f8 100644
--- a/netbox/templates/ipam/service_create.html
+++ b/netbox/templates/ipam/service_create.html
@@ -65,6 +65,13 @@
{% render_field form.tags %}
+
+
+
Comments
+
+ {% render_field form.comments %}
+
+
{% if form.custom_fields %}
Custom Fields
diff --git a/netbox/templates/ipam/service_edit.html b/netbox/templates/ipam/service_edit.html
index f3e34a7d1..709d816c1 100644
--- a/netbox/templates/ipam/service_edit.html
+++ b/netbox/templates/ipam/service_edit.html
@@ -52,6 +52,13 @@
{% render_field form.tags %}
+
+
+
Comments
+
+ {% render_field form.comments %}
+
+
{% if form.custom_fields %}
Custom Fields
diff --git a/netbox/templates/ipam/servicetemplate.html b/netbox/templates/ipam/servicetemplate.html
index 6e2aacb34..afb4163b9 100644
--- a/netbox/templates/ipam/servicetemplate.html
+++ b/netbox/templates/ipam/servicetemplate.html
@@ -31,12 +31,13 @@
{% plugin_left_page object %}
-
-
- {% include 'inc/panels/custom_fields.html' %}
- {% include 'inc/panels/tags.html' %}
- {% plugin_right_page object %}
-
+
+
+ {% include 'inc/panels/custom_fields.html' %}
+ {% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/comments.html' %}
+ {% plugin_right_page object %}
+
diff --git a/netbox/templates/ipam/vlan.html b/netbox/templates/ipam/vlan.html
index 53bb75b8f..c0f68bae2 100644
--- a/netbox/templates/ipam/vlan.html
+++ b/netbox/templates/ipam/vlan.html
@@ -74,9 +74,10 @@
{% plugin_left_page object %}
- {% include 'inc/panels/custom_fields.html' %}
- {% include 'inc/panels/tags.html' %}
- {% plugin_right_page object %}
+ {% include 'inc/panels/custom_fields.html' %}
+ {% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/comments.html' %}
+ {% plugin_right_page object %}
diff --git a/netbox/templates/ipam/vlan_edit.html b/netbox/templates/ipam/vlan_edit.html
index 5aa577942..f4432efe3 100644
--- a/netbox/templates/ipam/vlan_edit.html
+++ b/netbox/templates/ipam/vlan_edit.html
@@ -55,6 +55,13 @@
{% endwith %}
+
+
+
Comments
+
+ {% render_field form.comments %}
+
+
{% if form.custom_fields %}
diff --git a/netbox/templates/ipam/vrf.html b/netbox/templates/ipam/vrf.html
index 831338600..b53862f9e 100644
--- a/netbox/templates/ipam/vrf.html
+++ b/netbox/templates/ipam/vrf.html
@@ -55,6 +55,7 @@
{% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_right_page object %}
diff --git a/netbox/templates/tenancy/contact.html b/netbox/templates/tenancy/contact.html
index 8e71628e9..d92226137 100644
--- a/netbox/templates/tenancy/contact.html
+++ b/netbox/templates/tenancy/contact.html
@@ -63,6 +63,10 @@
{% endif %}
+
+ Description
+ {{ object.description|placeholder }}
+
Assignments
{{ assignment_count }}
diff --git a/netbox/templates/virtualization/cluster.html b/netbox/templates/virtualization/cluster.html
index bc02424cc..510c5a48e 100644
--- a/netbox/templates/virtualization/cluster.html
+++ b/netbox/templates/virtualization/cluster.html
@@ -23,6 +23,10 @@
Status
{% badge object.get_status_display bg_color=object.get_status_color %}
+
+ Description
+ {{ object.description|placeholder }}
+
Group
{{ object.group|linkify|placeholder }}
diff --git a/netbox/templates/virtualization/virtualmachine.html b/netbox/templates/virtualization/virtualmachine.html
index c0e2ebd07..9d95b02ea 100644
--- a/netbox/templates/virtualization/virtualmachine.html
+++ b/netbox/templates/virtualization/virtualmachine.html
@@ -29,6 +29,10 @@
Platform
{{ object.platform|linkify|placeholder }}
+
+ Description
+ {{ object.description|placeholder }}
+
Tenant
diff --git a/netbox/templates/wireless/wirelesslan.html b/netbox/templates/wireless/wirelesslan.html
index 9250ef7ef..19e8b930d 100644
--- a/netbox/templates/wireless/wirelesslan.html
+++ b/netbox/templates/wireless/wirelesslan.html
@@ -39,6 +39,7 @@
{% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_left_page object %}
diff --git a/netbox/templates/wireless/wirelesslink.html b/netbox/templates/wireless/wirelesslink.html
index d1a93e40d..be98979c1 100644
--- a/netbox/templates/wireless/wirelesslink.html
+++ b/netbox/templates/wireless/wirelesslink.html
@@ -40,6 +40,7 @@
{% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/comments.html' %}
{% plugin_left_page object %}
diff --git a/netbox/templates/wireless/wirelesslink_edit.html b/netbox/templates/wireless/wirelesslink_edit.html
index 034d147de..462ae5148 100644
--- a/netbox/templates/wireless/wirelesslink_edit.html
+++ b/netbox/templates/wireless/wirelesslink_edit.html
@@ -22,6 +22,12 @@
+
+
+
Comments
+
+ {% render_field form.comments %}
+
{% if form.custom_fields %}
diff --git a/netbox/tenancy/api/serializers.py b/netbox/tenancy/api/serializers.py
index d2c6801c6..c8ef77117 100644
--- a/netbox/tenancy/api/serializers.py
+++ b/netbox/tenancy/api/serializers.py
@@ -85,8 +85,8 @@ class ContactSerializer(NetBoxModelSerializer):
class Meta:
model = Contact
fields = [
- 'id', 'url', 'display', 'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'comments', 'tags',
- 'custom_fields', 'created', 'last_updated',
+ 'id', 'url', 'display', 'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description',
+ 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
diff --git a/netbox/tenancy/forms/bulk_edit.py b/netbox/tenancy/forms/bulk_edit.py
index 4c1f03757..183a8e851 100644
--- a/netbox/tenancy/forms/bulk_edit.py
+++ b/netbox/tenancy/forms/bulk_edit.py
@@ -2,7 +2,7 @@ from django import forms
from netbox.forms import NetBoxModelBulkEditForm
from tenancy.models import *
-from utilities.forms import DynamicModelChoiceField
+from utilities.forms import CommentField, DynamicModelChoiceField, SmallTextarea
__all__ = (
'ContactBulkEditForm',
@@ -101,9 +101,17 @@ class ContactBulkEditForm(NetBoxModelBulkEditForm):
link = forms.URLField(
required=False
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = Contact
fieldsets = (
- (None, ('group', 'title', 'phone', 'email', 'address', 'link')),
+ (None, ('group', 'title', 'phone', 'email', 'address', 'link', 'description')),
)
- nullable_fields = ('group', 'title', 'phone', 'email', 'address', 'link', 'comments')
+ nullable_fields = ('group', 'title', 'phone', 'email', 'address', 'link', 'description', 'comments')
diff --git a/netbox/tenancy/forms/bulk_import.py b/netbox/tenancy/forms/bulk_import.py
index d617a27b5..a465230c5 100644
--- a/netbox/tenancy/forms/bulk_import.py
+++ b/netbox/tenancy/forms/bulk_import.py
@@ -79,4 +79,4 @@ class ContactCSVForm(NetBoxModelCSVForm):
class Meta:
model = Contact
- fields = ('name', 'title', 'phone', 'email', 'address', 'link', 'group', 'comments')
+ fields = ('name', 'title', 'phone', 'email', 'address', 'link', 'group', 'description', 'comments')
diff --git a/netbox/tenancy/forms/model_forms.py b/netbox/tenancy/forms/model_forms.py
index 80af04928..b466c94b2 100644
--- a/netbox/tenancy/forms/model_forms.py
+++ b/netbox/tenancy/forms/model_forms.py
@@ -103,13 +103,13 @@ class ContactForm(NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Contact', ('group', 'name', 'title', 'phone', 'email', 'address', 'link', 'tags')),
+ ('Contact', ('group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'tags')),
)
class Meta:
model = Contact
fields = (
- 'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'comments', 'tags',
+ 'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'comments', 'tags',
)
widgets = {
'address': SmallTextarea(attrs={'rows': 3}),
diff --git a/netbox/tenancy/migrations/0009_standardize_description_comments.py b/netbox/tenancy/migrations/0009_standardize_description_comments.py
new file mode 100644
index 000000000..af93b055c
--- /dev/null
+++ b/netbox/tenancy/migrations/0009_standardize_description_comments.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.1.2 on 2022-11-03 18:24
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('tenancy', '0008_unique_constraints'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='contact',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ ]
diff --git a/netbox/tenancy/models/contacts.py b/netbox/tenancy/models/contacts.py
index ba937c167..4fa8d87cb 100644
--- a/netbox/tenancy/models/contacts.py
+++ b/netbox/tenancy/models/contacts.py
@@ -2,9 +2,8 @@ from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.urls import reverse
-from mptt.models import TreeForeignKey
-from netbox.models import ChangeLoggedModel, NestedGroupModel, OrganizationalModel, NetBoxModel
+from netbox.models import ChangeLoggedModel, NestedGroupModel, OrganizationalModel, PrimaryModel
from netbox.models.features import WebhooksMixin
from tenancy.choices import *
@@ -41,7 +40,7 @@ class ContactRole(OrganizationalModel):
return reverse('tenancy:contactrole', args=[self.pk])
-class Contact(NetBoxModel):
+class Contact(PrimaryModel):
"""
Contact information for a particular object(s) in NetBox.
"""
@@ -73,9 +72,6 @@ class Contact(NetBoxModel):
link = models.URLField(
blank=True
)
- comments = models.TextField(
- blank=True
- )
clone_fields = (
'group', 'name', 'title', 'phone', 'email', 'address', 'link',
diff --git a/netbox/tenancy/models/tenants.py b/netbox/tenancy/models/tenants.py
index b76efcbf9..4c0c11e2a 100644
--- a/netbox/tenancy/models/tenants.py
+++ b/netbox/tenancy/models/tenants.py
@@ -1,9 +1,8 @@
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from django.urls import reverse
-from mptt.models import TreeForeignKey
-from netbox.models import NestedGroupModel, NetBoxModel
+from netbox.models import NestedGroupModel, PrimaryModel
__all__ = (
'Tenant',
@@ -31,7 +30,7 @@ class TenantGroup(NestedGroupModel):
return reverse('tenancy:tenantgroup', args=[self.pk])
-class Tenant(NetBoxModel):
+class Tenant(PrimaryModel):
"""
A Tenant represents an organization served by the NetBox owner. This is typically a customer or an internal
department.
@@ -51,13 +50,6 @@ class Tenant(NetBoxModel):
blank=True,
null=True
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
- comments = models.TextField(
- blank=True
- )
# Generic relations
contacts = GenericRelation(
diff --git a/netbox/tenancy/tables/contacts.py b/netbox/tenancy/tables/contacts.py
index 234dc2ad7..b66a1182f 100644
--- a/netbox/tenancy/tables/contacts.py
+++ b/netbox/tenancy/tables/contacts.py
@@ -65,8 +65,8 @@ class ContactTable(NetBoxTable):
class Meta(NetBoxTable.Meta):
model = Contact
fields = (
- 'pk', 'name', 'group', 'title', 'phone', 'email', 'address', 'link', 'comments', 'assignment_count', 'tags',
- 'created', 'last_updated',
+ 'pk', 'name', 'group', 'title', 'phone', 'email', 'address', 'link', 'description', 'comments',
+ 'assignment_count', 'tags', 'created', 'last_updated',
)
default_columns = ('pk', 'name', 'group', 'assignment_count', 'title', 'phone', 'email')
diff --git a/netbox/virtualization/api/serializers.py b/netbox/virtualization/api/serializers.py
index b88bc7712..bb4418b43 100644
--- a/netbox/virtualization/api/serializers.py
+++ b/netbox/virtualization/api/serializers.py
@@ -58,8 +58,8 @@ class ClusterSerializer(NetBoxModelSerializer):
class Meta:
model = Cluster
fields = [
- 'id', 'url', 'display', 'name', 'type', 'group', 'status', 'tenant', 'site', 'comments', 'tags',
- 'custom_fields', 'created', 'last_updated', 'device_count', 'virtualmachine_count',
+ 'id', 'url', 'display', 'name', 'type', 'group', 'status', 'tenant', 'site', 'description', 'comments',
+ 'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'virtualmachine_count',
]
@@ -84,8 +84,8 @@ class VirtualMachineSerializer(NetBoxModelSerializer):
model = VirtualMachine
fields = [
'id', 'url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant', 'platform',
- 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'comments', 'local_context_data',
- 'tags', 'custom_fields', 'created', 'last_updated',
+ 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description', 'comments',
+ 'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated',
]
validators = []
diff --git a/netbox/virtualization/forms/bulk_edit.py b/netbox/virtualization/forms/bulk_edit.py
index b2429744b..a94b2da1c 100644
--- a/netbox/virtualization/forms/bulk_edit.py
+++ b/netbox/virtualization/forms/bulk_edit.py
@@ -84,6 +84,10 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
'group_id': '$site_group',
}
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
@@ -91,11 +95,11 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
model = Cluster
fieldsets = (
- (None, ('type', 'group', 'status', 'tenant',)),
- ('Site', ('region', 'site_group', 'site',)),
+ (None, ('type', 'group', 'status', 'tenant', 'description')),
+ ('Site', ('region', 'site_group', 'site')),
)
nullable_fields = (
- 'group', 'site', 'comments', 'tenant',
+ 'group', 'site', 'tenant', 'description', 'comments',
)
@@ -153,6 +157,10 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
required=False,
label='Disk (GB)'
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
@@ -160,11 +168,11 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
model = VirtualMachine
fieldsets = (
- (None, ('site', 'cluster', 'device', 'status', 'role', 'tenant', 'platform')),
+ (None, ('site', 'cluster', 'device', 'status', 'role', 'tenant', 'platform', 'description')),
('Resources', ('vcpus', 'memory', 'disk'))
)
nullable_fields = (
- 'site', 'cluster', 'device', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments',
+ 'site', 'cluster', 'device', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'description', 'comments',
)
diff --git a/netbox/virtualization/forms/bulk_import.py b/netbox/virtualization/forms/bulk_import.py
index 2d7ee52e2..d140197dd 100644
--- a/netbox/virtualization/forms/bulk_import.py
+++ b/netbox/virtualization/forms/bulk_import.py
@@ -63,7 +63,7 @@ class ClusterCSVForm(NetBoxModelCSVForm):
class Meta:
model = Cluster
- fields = ('name', 'type', 'group', 'status', 'site', 'comments')
+ fields = ('name', 'type', 'group', 'status', 'site', 'description', 'comments')
class VirtualMachineCSVForm(NetBoxModelCSVForm):
@@ -114,7 +114,7 @@ class VirtualMachineCSVForm(NetBoxModelCSVForm):
model = VirtualMachine
fields = (
'name', 'status', 'role', 'site', 'cluster', 'device', 'tenant', 'platform', 'vcpus', 'memory', 'disk',
- 'comments',
+ 'description', 'comments',
)
diff --git a/netbox/virtualization/forms/model_forms.py b/netbox/virtualization/forms/model_forms.py
index 5438002b4..3f598d061 100644
--- a/netbox/virtualization/forms/model_forms.py
+++ b/netbox/virtualization/forms/model_forms.py
@@ -90,7 +90,7 @@ class ClusterForm(TenancyForm, NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Cluster', ('name', 'type', 'group', 'status', 'tags')),
+ ('Cluster', ('name', 'type', 'group', 'status', 'description', 'tags')),
('Site', ('region', 'site_group', 'site')),
('Tenancy', ('tenant_group', 'tenant')),
)
@@ -98,7 +98,8 @@ class ClusterForm(TenancyForm, NetBoxModelForm):
class Meta:
model = Cluster
fields = (
- 'name', 'type', 'group', 'status', 'tenant', 'region', 'site_group', 'site', 'comments', 'tags',
+ 'name', 'type', 'group', 'status', 'tenant', 'region', 'site_group', 'site', 'description', 'comments',
+ 'tags',
)
widgets = {
'status': StaticSelect(),
@@ -220,9 +221,10 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
required=False,
label=''
)
+ comments = CommentField()
fieldsets = (
- ('Virtual Machine', ('name', 'role', 'status', 'tags')),
+ ('Virtual Machine', ('name', 'role', 'status', 'description', 'tags')),
('Site/Cluster', ('site', 'cluster_group', 'cluster', 'device')),
('Tenancy', ('tenant_group', 'tenant')),
('Management', ('platform', 'primary_ip4', 'primary_ip6')),
@@ -234,7 +236,7 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
model = VirtualMachine
fields = [
'name', 'status', 'site', 'cluster_group', 'cluster', 'device', 'role', 'tenant_group', 'tenant',
- 'platform', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'comments', 'tags',
+ 'platform', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description', 'comments', 'tags',
'local_context_data',
]
help_texts = {
diff --git a/netbox/virtualization/migrations/0034_standardize_description_comments.py b/netbox/virtualization/migrations/0034_standardize_description_comments.py
new file mode 100644
index 000000000..8517adeca
--- /dev/null
+++ b/netbox/virtualization/migrations/0034_standardize_description_comments.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.1.2 on 2022-11-03 18:24
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('virtualization', '0033_unique_constraints'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='cluster',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ migrations.AddField(
+ model_name='virtualmachine',
+ name='description',
+ field=models.CharField(blank=True, max_length=200),
+ ),
+ ]
diff --git a/netbox/virtualization/models.py b/netbox/virtualization/models.py
index b859d25fe..b5129d581 100644
--- a/netbox/virtualization/models.py
+++ b/netbox/virtualization/models.py
@@ -10,7 +10,7 @@ from dcim.models import BaseInterface, Device
from extras.models import ConfigContextModel
from extras.querysets import ConfigContextModelQuerySet
from netbox.config import get_config
-from netbox.models import OrganizationalModel, NetBoxModel
+from netbox.models import NetBoxModel, OrganizationalModel, PrimaryModel
from utilities.fields import NaturalOrderingField
from utilities.ordering import naturalize_interface
from utilities.query_functions import CollateAsChar
@@ -64,7 +64,7 @@ class ClusterGroup(OrganizationalModel):
# Clusters
#
-class Cluster(NetBoxModel):
+class Cluster(PrimaryModel):
"""
A cluster of VirtualMachines. Each Cluster may optionally be associated with one or more Devices.
"""
@@ -102,9 +102,6 @@ class Cluster(NetBoxModel):
blank=True,
null=True
)
- comments = models.TextField(
- blank=True
- )
# Generic relations
vlan_groups = GenericRelation(
@@ -165,7 +162,7 @@ class Cluster(NetBoxModel):
# Virtual machines
#
-class VirtualMachine(NetBoxModel, ConfigContextModel):
+class VirtualMachine(PrimaryModel, ConfigContextModel):
"""
A virtual machine which runs inside a Cluster.
"""
@@ -262,9 +259,6 @@ class VirtualMachine(NetBoxModel, ConfigContextModel):
null=True,
verbose_name='Disk (GB)'
)
- comments = models.TextField(
- blank=True
- )
# Generic relation
contacts = GenericRelation(
diff --git a/netbox/virtualization/tables/clusters.py b/netbox/virtualization/tables/clusters.py
index ae4c610d7..a3e67373d 100644
--- a/netbox/virtualization/tables/clusters.py
+++ b/netbox/virtualization/tables/clusters.py
@@ -86,7 +86,7 @@ class ClusterTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = Cluster
fields = (
- 'pk', 'id', 'name', 'type', 'group', 'status', 'tenant', 'tenant_group', 'site', 'comments', 'device_count',
- 'vm_count', 'contacts', 'tags', 'created', 'last_updated',
+ 'pk', 'id', 'name', 'type', 'group', 'status', 'tenant', 'tenant_group', 'site', 'description', 'comments',
+ 'device_count', 'vm_count', 'contacts', 'tags', 'created', 'last_updated',
)
default_columns = ('pk', 'name', 'type', 'group', 'status', 'tenant', 'site', 'device_count', 'vm_count')
diff --git a/netbox/virtualization/tables/virtualmachines.py b/netbox/virtualization/tables/virtualmachines.py
index 29baff4cb..b1d44ad02 100644
--- a/netbox/virtualization/tables/virtualmachines.py
+++ b/netbox/virtualization/tables/virtualmachines.py
@@ -75,8 +75,8 @@ class VirtualMachineTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable)
model = VirtualMachine
fields = (
'pk', 'id', 'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant', 'tenant_group', 'platform',
- 'vcpus', 'memory', 'disk', 'primary_ip4', 'primary_ip6', 'primary_ip', 'comments', 'contacts', 'tags',
- 'created', 'last_updated',
+ 'vcpus', 'memory', 'disk', 'primary_ip4', 'primary_ip6', 'primary_ip', 'description', 'comments',
+ 'contacts', 'tags', 'created', 'last_updated',
)
default_columns = (
'pk', 'name', 'status', 'site', 'cluster', 'role', 'tenant', 'vcpus', 'memory', 'disk', 'primary_ip',
diff --git a/netbox/wireless/api/serializers.py b/netbox/wireless/api/serializers.py
index d65511765..109c3a341 100644
--- a/netbox/wireless/api/serializers.py
+++ b/netbox/wireless/api/serializers.py
@@ -42,7 +42,7 @@ class WirelessLANSerializer(NetBoxModelSerializer):
model = WirelessLAN
fields = [
'id', 'url', 'display', 'ssid', 'description', 'group', 'vlan', 'tenant', 'auth_type', 'auth_cipher',
- 'auth_psk', 'description', 'tags', 'custom_fields', 'created', 'last_updated',
+ 'auth_psk', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
@@ -59,5 +59,5 @@ class WirelessLinkSerializer(NetBoxModelSerializer):
model = WirelessLink
fields = [
'id', 'url', 'display', 'interface_a', 'interface_b', 'ssid', 'status', 'tenant', 'auth_type',
- 'auth_cipher', 'auth_psk', 'description', 'tags', 'custom_fields', 'created', 'last_updated',
+ 'auth_cipher', 'auth_psk', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
diff --git a/netbox/wireless/forms/bulk_edit.py b/netbox/wireless/forms/bulk_edit.py
index 639a1ed1b..543e7e0b3 100644
--- a/netbox/wireless/forms/bulk_edit.py
+++ b/netbox/wireless/forms/bulk_edit.py
@@ -4,7 +4,7 @@ from dcim.choices import LinkStatusChoices
from ipam.models import VLAN
from netbox.forms import NetBoxModelBulkEditForm
from tenancy.models import Tenant
-from utilities.forms import add_blank_choice, DynamicModelChoiceField
+from utilities.forms import add_blank_choice, CommentField, DynamicModelChoiceField, SmallTextarea
from wireless.choices import *
from wireless.constants import SSID_MAX_LENGTH
from wireless.models import *
@@ -52,9 +52,6 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
queryset=Tenant.objects.all(),
required=False
)
- description = forms.CharField(
- required=False
- )
auth_type = forms.ChoiceField(
choices=add_blank_choice(WirelessAuthTypeChoices),
required=False
@@ -67,6 +64,14 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
required=False,
label='Pre-shared key'
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = WirelessLAN
fieldsets = (
@@ -74,7 +79,7 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')),
)
nullable_fields = (
- 'ssid', 'group', 'vlan', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk',
+ 'ssid', 'group', 'vlan', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'comments',
)
@@ -92,9 +97,6 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
queryset=Tenant.objects.all(),
required=False
)
- description = forms.CharField(
- required=False
- )
auth_type = forms.ChoiceField(
choices=add_blank_choice(WirelessAuthTypeChoices),
required=False
@@ -107,6 +109,14 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
required=False,
label='Pre-shared key'
)
+ description = forms.CharField(
+ max_length=200,
+ required=False
+ )
+ comments = CommentField(
+ widget=SmallTextarea,
+ label='Comments'
+ )
model = WirelessLink
fieldsets = (
@@ -114,5 +124,5 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
('Authentication', ('auth_type', 'auth_cipher', 'auth_psk'))
)
nullable_fields = (
- 'ssid', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk',
+ 'ssid', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'comments',
)
diff --git a/netbox/wireless/forms/bulk_import.py b/netbox/wireless/forms/bulk_import.py
index 6a1ca4f36..03ac997a3 100644
--- a/netbox/wireless/forms/bulk_import.py
+++ b/netbox/wireless/forms/bulk_import.py
@@ -60,7 +60,9 @@ class WirelessLANCSVForm(NetBoxModelCSVForm):
class Meta:
model = WirelessLAN
- fields = ('ssid', 'group', 'vlan', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk')
+ fields = (
+ 'ssid', 'group', 'vlan', 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', 'description', 'comments',
+ )
class WirelessLinkCSVForm(NetBoxModelCSVForm):
@@ -94,5 +96,6 @@ class WirelessLinkCSVForm(NetBoxModelCSVForm):
class Meta:
model = WirelessLink
fields = (
- 'interface_a', 'interface_b', 'ssid', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk',
+ 'interface_a', 'interface_b', 'ssid', 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', 'description',
+ 'comments',
)
diff --git a/netbox/wireless/forms/model_forms.py b/netbox/wireless/forms/model_forms.py
index 386484193..d57c74575 100644
--- a/netbox/wireless/forms/model_forms.py
+++ b/netbox/wireless/forms/model_forms.py
@@ -2,7 +2,7 @@ from dcim.models import Device, Interface, Location, Region, Site, SiteGroup
from ipam.models import VLAN, VLANGroup
from netbox.forms import NetBoxModelForm
from tenancy.forms import TenancyForm
-from utilities.forms import DynamicModelChoiceField, SlugField, StaticSelect
+from utilities.forms import CommentField, DynamicModelChoiceField, SlugField, StaticSelect
from wireless.models import *
__all__ = (
@@ -82,6 +82,7 @@ class WirelessLANForm(TenancyForm, NetBoxModelForm):
'group_id': '$vlan_group',
}
)
+ comments = CommentField()
fieldsets = (
('Wireless LAN', ('ssid', 'group', 'description', 'tags')),
@@ -93,8 +94,8 @@ class WirelessLANForm(TenancyForm, NetBoxModelForm):
class Meta:
model = WirelessLAN
fields = [
- 'ssid', 'group', 'description', 'region', 'site_group', 'site', 'vlan_group', 'vlan', 'tenant_group',
- 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', 'tags',
+ 'ssid', 'group', 'region', 'site_group', 'site', 'vlan_group', 'vlan', 'tenant_group', 'tenant',
+ 'auth_type', 'auth_cipher', 'auth_psk', 'description', 'comments', 'tags',
]
widgets = {
'auth_type': StaticSelect,
@@ -183,6 +184,7 @@ class WirelessLinkForm(TenancyForm, NetBoxModelForm):
disabled_indicator='_occupied',
label='Interface'
)
+ comments = CommentField()
fieldsets = (
('Side A', ('site_a', 'location_a', 'device_a', 'interface_a')),
@@ -196,7 +198,8 @@ class WirelessLinkForm(TenancyForm, NetBoxModelForm):
model = WirelessLink
fields = [
'site_a', 'location_a', 'device_a', 'interface_a', 'site_b', 'location_b', 'device_b', 'interface_b',
- 'status', 'ssid', 'tenant_group', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'tags',
+ 'status', 'ssid', 'tenant_group', 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', 'description',
+ 'comments', 'tags',
]
widgets = {
'status': StaticSelect,
diff --git a/netbox/wireless/migrations/0007_standardize_description_comments.py b/netbox/wireless/migrations/0007_standardize_description_comments.py
new file mode 100644
index 000000000..e6e1ce8dd
--- /dev/null
+++ b/netbox/wireless/migrations/0007_standardize_description_comments.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.1.2 on 2022-11-03 18:24
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('wireless', '0006_unique_constraints'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='wirelesslan',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ migrations.AddField(
+ model_name='wirelesslink',
+ name='comments',
+ field=models.TextField(blank=True),
+ ),
+ ]
diff --git a/netbox/wireless/models.py b/netbox/wireless/models.py
index ee2744e40..96764b53c 100644
--- a/netbox/wireless/models.py
+++ b/netbox/wireless/models.py
@@ -2,11 +2,11 @@ from django.apps import apps
from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse
-from mptt.models import MPTTModel, TreeForeignKey
+from mptt.models import MPTTModel
from dcim.choices import LinkStatusChoices
from dcim.constants import WIRELESS_IFACE_TYPES
-from netbox.models import NestedGroupModel, NetBoxModel
+from netbox.models import NestedGroupModel, PrimaryModel
from .choices import *
from .constants import *
@@ -69,7 +69,7 @@ class WirelessLANGroup(NestedGroupModel):
return reverse('wireless:wirelesslangroup', args=[self.pk])
-class WirelessLAN(WirelessAuthenticationBase, NetBoxModel):
+class WirelessLAN(WirelessAuthenticationBase, PrimaryModel):
"""
A wireless network formed among an arbitrary number of access point and clients.
"""
@@ -98,10 +98,6 @@ class WirelessLAN(WirelessAuthenticationBase, NetBoxModel):
blank=True,
null=True
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
clone_fields = ('ssid', 'group', 'tenant', 'description')
@@ -122,7 +118,7 @@ def get_wireless_interface_types():
return {'type__in': WIRELESS_IFACE_TYPES}
-class WirelessLink(WirelessAuthenticationBase, NetBoxModel):
+class WirelessLink(WirelessAuthenticationBase, PrimaryModel):
"""
A point-to-point connection between two wireless Interfaces.
"""
@@ -157,10 +153,6 @@ class WirelessLink(WirelessAuthenticationBase, NetBoxModel):
blank=True,
null=True
)
- description = models.CharField(
- max_length=200,
- blank=True
- )
# Cache the associated device for the A and B interfaces. This enables filtering of WirelessLinks by their
# associated Devices.
diff --git a/netbox/wireless/tables/wirelesslan.py b/netbox/wireless/tables/wirelesslan.py
index af0cdae88..4aa5cc1fd 100644
--- a/netbox/wireless/tables/wirelesslan.py
+++ b/netbox/wireless/tables/wirelesslan.py
@@ -21,6 +21,7 @@ class WirelessLANGroupTable(NetBoxTable):
url_params={'group_id': 'pk'},
verbose_name='Wireless LANs'
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='wireless:wirelesslangroup_list'
)
@@ -28,7 +29,8 @@ class WirelessLANGroupTable(NetBoxTable):
class Meta(NetBoxTable.Meta):
model = WirelessLANGroup
fields = (
- 'pk', 'name', 'wirelesslan_count', 'description', 'slug', 'tags', 'created', 'last_updated', 'actions',
+ 'pk', 'name', 'wirelesslan_count', 'slug', 'description', 'comments', 'tags', 'created', 'last_updated',
+ 'actions',
)
default_columns = ('pk', 'name', 'wirelesslan_count', 'description')
@@ -43,6 +45,7 @@ class WirelessLANTable(TenancyColumnsMixin, NetBoxTable):
interface_count = tables.Column(
verbose_name='Interfaces'
)
+ comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='wireless:wirelesslan_list'
)
@@ -50,8 +53,8 @@ class WirelessLANTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = WirelessLAN
fields = (
- 'pk', 'ssid', 'group', 'tenant', 'tenant_group', 'description', 'vlan', 'interface_count', 'auth_type',
- 'auth_cipher', 'auth_psk', 'tags', 'created', 'last_updated',
+ 'pk', 'ssid', 'group', 'tenant', 'tenant_group', 'vlan', 'interface_count', 'auth_type', 'auth_cipher',
+ 'auth_psk', 'description', 'comments', 'tags', 'created', 'last_updated',
)
default_columns = ('pk', 'ssid', 'group', 'description', 'vlan', 'auth_type', 'interface_count')