Closes #10545: Standardize description & comment fields on primary models (#10834)

* Standardize description & comments fields on primary models

* Update REST API serializers

* Update forms

* Update tables

* Update templates
This commit is contained in:
Jeremy Stretch 2022-11-04 08:28:09 -04:00 committed by GitHub
parent e2f5ee661a
commit bc6b5bc4be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
105 changed files with 1014 additions and 534 deletions

View File

@ -69,18 +69,69 @@ A new `PluginMenu` class has been introduced, which enables a plugin to inject a
* circuits.provider * circuits.provider
* Removed the `asn`, `noc_contact`, `admin_contact`, and `portal_url` fields * 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 * dcim.DeviceType
* Added a `description` field
* Added optional `weight` and `weight_unit` fields * Added optional `weight` and `weight_unit` fields
* dcim.Module
* Added a `description` field
* dcim.ModuleType * dcim.ModuleType
* Added a `description` field
* Added optional `weight` and `weight_unit` fields * Added optional `weight` and `weight_unit` fields
* dcim.PowerFeed
* Added a `description` field
* dcim.PowerPanel
* Added `description` and `comments` fields
* dcim.Rack * dcim.Rack
* Added a `description` field
* Added optional `weight` and `weight_unit` fields * Added optional `weight` and `weight_unit` fields
* dcim.RackReservation
* Added a `comments` field
* dcim.VirtualChassis
* Added `description` and `comments` fields
* extras.CustomLink * extras.CustomLink
* Renamed `content_type` field to `content_types` * Renamed `content_type` field to `content_types`
* extras.ExportTemplate * extras.ExportTemplate
* Renamed `content_type` field to `content_types` * Renamed `content_type` field to `content_types`
* ipam.Aggregate
* Added a `comments` field
* ipam.ASN
* Added a `comments` field
* ipam.FHRPGroup * ipam.FHRPGroup
* Added a `comments` field
* Added optional `name` 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 ### GraphQL API Changes

View File

@ -31,8 +31,8 @@ class ProviderSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = Provider model = Provider
fields = [ fields = [
'id', 'url', 'display', 'name', 'slug', 'account', 'id', 'url', 'display', 'name', 'slug', 'account', 'description', 'comments', 'asns', 'tags',
'comments', 'asns', 'tags', 'custom_fields', 'created', 'last_updated', 'circuit_count', 'custom_fields', 'created', 'last_updated', 'circuit_count',
] ]

View File

@ -30,6 +30,10 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm):
required=False, required=False,
label='Account number' label='Account number'
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField( comments = CommentField(
widget=SmallTextarea, widget=SmallTextarea,
label='Comments' label='Comments'
@ -40,7 +44,7 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm):
(None, ('asns', 'account', )), (None, ('asns', 'account', )),
) )
nullable_fields = ( nullable_fields = (
'asns', 'account', 'comments', 'asns', 'account', 'description', 'comments',
) )

View File

@ -18,7 +18,7 @@ class ProviderCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = Provider model = Provider
fields = ( fields = (
'name', 'slug', 'account', 'comments', 'name', 'slug', 'account', 'description', 'comments',
) )

View File

@ -1,4 +1,3 @@
from django import forms
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from circuits.models import * from circuits.models import *
@ -7,8 +6,8 @@ from ipam.models import ASN
from netbox.forms import NetBoxModelForm from netbox.forms import NetBoxModelForm
from tenancy.forms import TenancyForm from tenancy.forms import TenancyForm
from utilities.forms import ( from utilities.forms import (
BootstrapMixin, CommentField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField, CommentField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SelectSpeedWidget, SlugField,
SelectSpeedWidget, SmallTextarea, SlugField, StaticSelect, StaticSelect,
) )
__all__ = ( __all__ = (
@ -30,14 +29,14 @@ class ProviderForm(NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Provider', ('name', 'slug', 'asns', 'tags')), ('Provider', ('name', 'slug', 'asns', 'description', 'tags')),
('Support Info', ('account',)), ('Support Info', ('account',)),
) )
class Meta: class Meta:
model = Provider model = Provider
fields = [ fields = [
'name', 'slug', 'account', 'asns', 'comments', 'tags', 'name', 'slug', 'account', 'asns', 'description', 'comments', 'tags',
] ]
help_texts = { help_texts = {
'name': "Full name of the provider", 'name': "Full name of the provider",

View File

@ -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),
),
]

View File

@ -7,7 +7,7 @@ from django.urls import reverse
from circuits.choices import * from circuits.choices import *
from dcim.models import CabledObjectModel from dcim.models import CabledObjectModel
from netbox.models import ( from netbox.models import (
ChangeLoggedModel, CustomFieldsMixin, CustomLinksMixin, OrganizationalModel, NetBoxModel, TagsMixin, ChangeLoggedModel, CustomFieldsMixin, CustomLinksMixin, OrganizationalModel, PrimaryModel, TagsMixin,
) )
from netbox.models.features import WebhooksMixin from netbox.models.features import WebhooksMixin
@ -27,7 +27,7 @@ class CircuitType(OrganizationalModel):
return reverse('circuits:circuittype', args=[self.pk]) 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 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 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, blank=True,
null=True, null=True,
verbose_name='Commit rate (Kbps)') verbose_name='Commit rate (Kbps)')
description = models.CharField(
max_length=200,
blank=True
)
comments = models.TextField(
blank=True
)
# Generic relations # Generic relations
contacts = GenericRelation( contacts = GenericRelation(

View File

@ -2,8 +2,7 @@ from django.contrib.contenttypes.fields import GenericRelation
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from dcim.fields import ASNField from netbox.models import PrimaryModel
from netbox.models import NetBoxModel
__all__ = ( __all__ = (
'ProviderNetwork', '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 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. stores information pertinent to the user's relationship with the Provider.
@ -34,9 +33,6 @@ class Provider(NetBoxModel):
blank=True, blank=True,
verbose_name='Account number' verbose_name='Account number'
) )
comments = models.TextField(
blank=True
)
# Generic relations # Generic relations
contacts = GenericRelation( contacts = GenericRelation(
@ -57,7 +53,7 @@ class Provider(NetBoxModel):
return reverse('circuits:provider', args=[self.pk]) 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 This represents a provider network which exists outside of NetBox, the details of which are unknown or
unimportant to the user. unimportant to the user.
@ -75,13 +71,6 @@ class ProviderNetwork(NetBoxModel):
blank=True, blank=True,
verbose_name='Service ID' verbose_name='Service ID'
) )
description = models.CharField(
max_length=200,
blank=True
)
comments = models.TextField(
blank=True
)
class Meta: class Meta:
ordering = ('provider', 'name') ordering = ('provider', 'name')

View File

@ -39,8 +39,8 @@ class ProviderTable(ContactsColumnMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Provider model = Provider
fields = ( fields = (
'pk', 'id', 'name', 'asns', 'account', 'asn_count', 'pk', 'id', 'name', 'asns', 'account', 'asn_count', 'circuit_count', 'description', 'comments', 'contacts',
'circuit_count', 'comments', 'contacts', 'tags', 'created', 'last_updated', 'tags', 'created', 'last_updated',
) )
default_columns = ('pk', 'name', 'account', 'circuit_count') default_columns = ('pk', 'name', 'account', 'circuit_count')

View File

@ -210,8 +210,8 @@ class RackSerializer(NetBoxModelSerializer):
fields = [ fields = [
'id', 'url', 'display', 'name', 'facility_id', 'site', 'location', 'tenant', 'status', 'role', 'serial', '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', 'asset_tag', 'type', 'width', 'u_height', 'weight', 'weight_unit', 'desc_units', 'outer_width',
'outer_depth', 'outer_unit', 'mounting_depth', 'comments', 'tags', 'custom_fields', 'created', 'outer_depth', 'outer_unit', 'mounting_depth', 'description', 'comments', 'tags', 'custom_fields',
'last_updated', 'device_count', 'powerfeed_count', 'created', 'last_updated', 'device_count', 'powerfeed_count',
] ]
@ -243,8 +243,8 @@ class RackReservationSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = RackReservation model = RackReservation
fields = [ fields = [
'id', 'url', 'display', 'rack', 'units', 'created', 'last_updated', 'user', 'tenant', 'description', 'tags', 'id', 'url', 'display', 'rack', 'units', 'created', 'last_updated', 'user', 'tenant', 'description',
'custom_fields', 'comments', 'tags', 'custom_fields',
] ]
@ -324,8 +324,8 @@ class DeviceTypeSerializer(NetBoxModelSerializer):
model = DeviceType model = DeviceType
fields = [ fields = [
'id', 'url', 'display', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', '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', 'subdevice_role', 'airflow', 'weight', 'weight_unit', 'front_image', 'rear_image', 'description',
'custom_fields', 'created', 'last_updated', 'device_count', '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') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:moduletype-detail')
manufacturer = NestedManufacturerSerializer() manufacturer = NestedManufacturerSerializer()
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False) weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False)
# module_count = serializers.IntegerField(read_only=True)
class Meta: class Meta:
model = ModuleType model = ModuleType
fields = [ fields = [
'id', 'url', 'display', 'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'comments', 'tags', 'id', 'url', 'display', 'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'description',
'custom_fields', 'created', 'last_updated', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
] ]
@ -656,8 +655,8 @@ class DeviceSerializer(NetBoxModelSerializer):
fields = [ fields = [
'id', 'url', 'display', 'name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', 'id', 'url', 'display', 'name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag',
'site', 'location', 'rack', 'position', 'face', 'parent_device', 'status', 'airflow', 'primary_ip', 'site', 'location', 'rack', 'position', 'face', 'parent_device', 'status', 'airflow', 'primary_ip',
'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments', 'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'description',
'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated', 'comments', 'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated',
] ]
@swagger_serializer_method(serializer_or_field=NestedDeviceSerializer) @swagger_serializer_method(serializer_or_field=NestedDeviceSerializer)
@ -681,8 +680,8 @@ class ModuleSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = Module model = Module
fields = [ fields = [
'id', 'url', 'display', 'device', 'module_bay', 'module_type', 'serial', 'asset_tag', 'comments', 'tags', 'id', 'url', 'display', 'device', 'module_bay', 'module_type', 'serial', 'asset_tag', 'description',
'custom_fields', 'created', 'last_updated', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
] ]
@ -1020,7 +1019,7 @@ class CableSerializer(NetBoxModelSerializer):
model = Cable model = Cable
fields = [ fields = [
'id', 'url', 'display', 'type', 'a_terminations', 'b_terminations', 'status', 'tenant', 'label', 'color', '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: class Meta:
model = VirtualChassis model = VirtualChassis
fields = [ fields = [
'id', 'url', 'display', 'name', 'domain', 'master', 'tags', 'custom_fields', 'member_count', 'id', 'url', 'display', 'name', 'domain', 'master', 'description', 'comments', 'tags', 'custom_fields',
'created', 'last_updated', 'member_count', 'created', 'last_updated',
] ]
@ -1108,8 +1107,8 @@ class PowerPanelSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = PowerPanel model = PowerPanel
fields = [ fields = [
'id', 'url', 'display', 'site', 'location', 'name', 'tags', 'custom_fields', 'powerfeed_count', 'id', 'url', 'display', 'site', 'location', 'name', 'description', 'comments', 'tags', 'custom_fields',
'created', 'last_updated', 'powerfeed_count', 'created', 'last_updated',
] ]
@ -1142,7 +1141,7 @@ class PowerFeedSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
model = PowerFeed model = PowerFeed
fields = [ fields = [
'id', 'url', 'display', 'power_panel', 'rack', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'id', 'url', 'display', 'power_panel', 'rack', 'name', 'status', 'type', 'supply', 'phase', 'voltage',
'amperage', 'max_utilization', 'comments', 'mark_connected', 'cable', 'cable_end', 'link_peers', 'amperage', 'max_utilization', 'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type',
'link_peers_type', 'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable', 'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable', 'description',
'tags', 'custom_fields', 'created', 'last_updated', '_occupied', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
] ]

View File

@ -127,22 +127,26 @@ class SiteBulkEditForm(NetBoxModelBulkEditForm):
required=False, required=False,
label='Contact E-mail' label='Contact E-mail'
) )
description = forms.CharField(
max_length=100,
required=False
)
time_zone = TimeZoneFormField( time_zone = TimeZoneFormField(
choices=add_blank_choice(TimeZoneFormField().choices), choices=add_blank_choice(TimeZoneFormField().choices),
required=False, required=False,
widget=StaticSelect() widget=StaticSelect()
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = Site model = Site
fieldsets = ( fieldsets = (
(None, ('status', 'region', 'group', 'tenant', 'asns', 'time_zone', 'description')), (None, ('status', 'region', 'group', 'tenant', 'asns', 'time_zone', 'description')),
) )
nullable_fields = ( 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, required=False,
min_value=1 min_value=1
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
weight = forms.DecimalField( weight = forms.DecimalField(
min_value=0, min_value=0,
required=False required=False
@ -299,10 +299,18 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
initial='', initial='',
widget=StaticSelect() widget=StaticSelect()
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = Rack model = Rack
fieldsets = ( fieldsets = (
('Rack', ('status', 'role', 'tenant', 'serial', 'asset_tag')), ('Rack', ('status', 'role', 'tenant', 'serial', 'asset_tag', 'description')),
('Location', ('region', 'site_group', 'site', 'location')), ('Location', ('region', 'site_group', 'site', 'location')),
('Hardware', ( ('Hardware', (
'type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', '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')), ('Weight', ('weight', 'weight_unit')),
) )
nullable_fields = ( nullable_fields = (
'location', 'tenant', 'role', 'serial', 'asset_tag', 'outer_width', 'outer_depth', 'outer_unit', 'comments', 'location', 'tenant', 'role', 'serial', 'asset_tag', 'outer_width', 'outer_depth', 'outer_unit', 'weight',
'weight', 'weight_unit' 'weight_unit', 'description', 'comments',
) )
@ -328,14 +336,19 @@ class RackReservationBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
max_length=100, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = RackReservation model = RackReservation
fieldsets = ( fieldsets = (
(None, ('user', 'tenant', 'description')), (None, ('user', 'tenant', 'description')),
) )
nullable_fields = ('comments',)
class ManufacturerBulkEditForm(NetBoxModelBulkEditForm): class ManufacturerBulkEditForm(NetBoxModelBulkEditForm):
@ -383,13 +396,21 @@ class DeviceTypeBulkEditForm(NetBoxModelBulkEditForm):
initial='', initial='',
widget=StaticSelect() widget=StaticSelect()
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = DeviceType model = DeviceType
fieldsets = ( 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')), ('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): class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
@ -410,13 +431,21 @@ class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
initial='', initial='',
widget=StaticSelect() widget=StaticSelect()
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = ModuleType model = ModuleType
fieldsets = ( fieldsets = (
('Module Type', ('manufacturer', 'part_number')), ('Module Type', ('manufacturer', 'part_number', 'description')),
('Weight', ('weight', 'weight_unit')), ('Weight', ('weight', 'weight_unit')),
) )
nullable_fields = ('part_number', 'weight', 'weight_unit') nullable_fields = ('part_number', 'weight', 'weight_unit', 'description', 'comments')
class DeviceRoleBulkEditForm(NetBoxModelBulkEditForm): class DeviceRoleBulkEditForm(NetBoxModelBulkEditForm):
@ -512,15 +541,23 @@ class DeviceBulkEditForm(NetBoxModelBulkEditForm):
required=False, required=False,
label='Serial Number' label='Serial Number'
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = Device model = Device
fieldsets = ( fieldsets = (
('Device', ('device_role', 'status', 'tenant', 'platform')), ('Device', ('device_role', 'status', 'tenant', 'platform', 'description')),
('Location', ('site', 'location')), ('Location', ('site', 'location')),
('Hardware', ('manufacturer', 'device_type', 'airflow', 'serial')), ('Hardware', ('manufacturer', 'device_type', 'airflow', 'serial')),
) )
nullable_fields = ( nullable_fields = (
'location', 'tenant', 'platform', 'serial', 'airflow', 'location', 'tenant', 'platform', 'serial', 'airflow', 'description', 'comments',
) )
@ -541,12 +578,20 @@ class ModuleBulkEditForm(NetBoxModelBulkEditForm):
required=False, required=False,
label='Serial Number' label='Serial Number'
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = Module model = Module
fieldsets = ( fieldsets = (
(None, ('manufacturer', 'module_type', 'serial')), (None, ('manufacturer', 'module_type', 'serial', 'description')),
) )
nullable_fields = ('serial',) nullable_fields = ('serial', 'description', 'comments')
class CableBulkEditForm(NetBoxModelBulkEditForm): class CableBulkEditForm(NetBoxModelBulkEditForm):
@ -583,14 +628,22 @@ class CableBulkEditForm(NetBoxModelBulkEditForm):
initial='', initial='',
widget=StaticSelect() widget=StaticSelect()
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = Cable model = Cable
fieldsets = ( fieldsets = (
(None, ('type', 'status', 'tenant', 'label')), (None, ('type', 'status', 'tenant', 'label', 'description')),
('Attributes', ('color', 'length', 'length_unit')), ('Attributes', ('color', 'length', 'length_unit')),
) )
nullable_fields = ( 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, max_length=30,
required=False required=False
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = VirtualChassis model = VirtualChassis
fieldsets = ( fieldsets = (
(None, ('domain',)), (None, ('domain', 'description')),
) )
nullable_fields = ('domain',) nullable_fields = ('domain', 'description', 'comments')
class PowerPanelBulkEditForm(NetBoxModelBulkEditForm): class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
@ -637,12 +698,20 @@ class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
'site_id': '$site' 'site_id': '$site'
} }
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = PowerPanel model = PowerPanel
fieldsets = ( 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): class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
@ -691,6 +760,10 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
required=False, required=False,
widget=BulkEditNullBooleanSelect widget=BulkEditNullBooleanSelect
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField( comments = CommentField(
widget=SmallTextarea, widget=SmallTextarea,
label='Comments' label='Comments'
@ -698,10 +771,10 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
model = PowerFeed model = PowerFeed
fieldsets = ( 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')) ('Power', ('supply', 'phase', 'voltage', 'amperage', 'max_utilization'))
) )
nullable_fields = ('location', 'comments') nullable_fields = ('location', 'description', 'comments')
# #

View File

@ -196,7 +196,8 @@ class RackCSVForm(NetBoxModelCSVForm):
model = Rack model = Rack
fields = ( fields = (
'site', 'location', 'name', 'facility_id', 'tenant', 'status', 'role', 'type', 'serial', 'asset_tag', '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): def __init__(self, data=None, *args, **kwargs):
@ -240,7 +241,7 @@ class RackReservationCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = RackReservation model = RackReservation
fields = ('site', 'location', 'rack', 'units', 'tenant', 'description') fields = ('site', 'location', 'rack', 'units', 'tenant', 'description', 'comments')
def __init__(self, data=None, *args, **kwargs): def __init__(self, data=None, *args, **kwargs):
super().__init__(data, *args, **kwargs) super().__init__(data, *args, **kwargs)
@ -387,7 +388,7 @@ class DeviceCSVForm(BaseDeviceCSVForm):
fields = [ fields = [
'name', 'device_role', 'tenant', 'manufacturer', 'device_type', 'platform', 'serial', 'asset_tag', 'status', 'name', 'device_role', 'tenant', 'manufacturer', 'device_type', 'platform', 'serial', 'asset_tag', 'status',
'site', 'location', 'rack', 'position', 'face', 'airflow', 'virtual_chassis', 'vc_position', 'vc_priority', 'site', 'location', 'rack', 'position', 'face', 'airflow', 'virtual_chassis', 'vc_position', 'vc_priority',
'cluster', 'comments', 'cluster', 'description', 'comments',
] ]
def __init__(self, data=None, *args, **kwargs): def __init__(self, data=None, *args, **kwargs):
@ -424,7 +425,7 @@ class ModuleCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = Module model = Module
fields = ( 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): def __init__(self, data=None, *args, **kwargs):
@ -927,7 +928,7 @@ class CableCSVForm(NetBoxModelCSVForm):
model = Cable model = Cable
fields = [ fields = [
'side_a_device', 'side_a_type', 'side_a_name', 'side_b_device', 'side_b_type', 'side_b_name', 'type', '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 = { help_texts = {
'color': mark_safe('RGB color in hexadecimal (e.g. <code>00ff00</code>)'), 'color': mark_safe('RGB color in hexadecimal (e.g. <code>00ff00</code>)'),
@ -984,7 +985,7 @@ class VirtualChassisCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = VirtualChassis model = VirtualChassis
fields = ('name', 'domain', 'master') fields = ('name', 'domain', 'master', 'description')
# #
@ -1005,7 +1006,7 @@ class PowerPanelCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = PowerPanel model = PowerPanel
fields = ('site', 'location', 'name') fields = ('site', 'location', 'name', 'description', 'comments')
def __init__(self, data=None, *args, **kwargs): def __init__(self, data=None, *args, **kwargs):
super().__init__(data, *args, **kwargs) super().__init__(data, *args, **kwargs)
@ -1061,7 +1062,7 @@ class PowerFeedCSVForm(NetBoxModelCSVForm):
model = PowerFeed model = PowerFeed
fields = ( fields = (
'site', 'power_panel', 'location', 'rack', 'name', 'status', 'type', 'mark_connected', 'supply', 'phase', '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): def __init__(self, data=None, *args, **kwargs):

View File

@ -278,7 +278,7 @@ class RackForm(TenancyForm, NetBoxModelForm):
fields = [ fields = [
'region', 'site_group', 'site', 'location', 'name', 'facility_id', 'tenant_group', 'tenant', 'status', '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', '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 = { help_texts = {
'site': "The site at which the rack exists", 'site': "The site at which the rack exists",
@ -342,6 +342,7 @@ class RackReservationForm(TenancyForm, NetBoxModelForm):
), ),
widget=StaticSelect() widget=StaticSelect()
) )
comments = CommentField()
fieldsets = ( fieldsets = (
('Reservation', ('region', 'site_group', 'site', 'location', 'rack', 'units', 'user', 'description', 'tags')), ('Reservation', ('region', 'site_group', 'site', 'location', 'rack', 'units', 'user', 'description', 'tags')),
@ -352,7 +353,7 @@ class RackReservationForm(TenancyForm, NetBoxModelForm):
model = RackReservation model = RackReservation
fields = [ fields = [
'region', 'site_group', 'site', 'location', 'rack', 'units', 'user', 'tenant_group', 'tenant', 'region', 'site_group', 'site', 'location', 'rack', 'units', 'user', 'tenant_group', 'tenant',
'description', 'tags', 'description', 'comments', 'tags',
] ]
@ -383,10 +384,10 @@ class DeviceTypeForm(NetBoxModelForm):
fieldsets = ( fieldsets = (
('Device Type', ( ('Device Type', (
'manufacturer', 'model', 'slug', 'part_number', 'tags', 'manufacturer', 'model', 'slug', 'description', 'tags',
)), )),
('Chassis', ( ('Chassis', (
'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'u_height', 'is_full_depth', 'part_number', 'subdevice_role', 'airflow',
)), )),
('Attributes', ('weight', 'weight_unit')), ('Attributes', ('weight', 'weight_unit')),
('Images', ('front_image', 'rear_image')), ('Images', ('front_image', 'rear_image')),
@ -396,7 +397,7 @@ class DeviceTypeForm(NetBoxModelForm):
model = DeviceType model = DeviceType
fields = [ fields = [
'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', '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 = { widgets = {
'airflow': StaticSelect(), 'airflow': StaticSelect(),
@ -418,15 +419,14 @@ class ModuleTypeForm(NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Module Type', ( ('Module Type', ('manufacturer', 'model', 'part_number', 'description', 'tags')),
'manufacturer', 'model', 'part_number', 'tags', 'weight', 'weight_unit' ('Weight', ('weight', 'weight_unit'))
)),
) )
class Meta: class Meta:
model = ModuleType model = ModuleType
fields = [ fields = [
'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'comments', 'tags', 'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'description', 'comments', 'tags',
] ]
widgets = { widgets = {
@ -591,7 +591,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
'name', 'device_role', 'device_type', 'serial', 'asset_tag', 'region', 'site_group', 'site', 'rack', 'name', 'device_role', 'device_type', 'serial', 'asset_tag', 'region', 'site_group', 'site', 'rack',
'location', 'position', 'face', 'status', 'airflow', 'platform', 'primary_ip4', 'primary_ip6', 'location', 'position', 'face', 'status', 'airflow', 'platform', 'primary_ip4', 'primary_ip6',
'cluster_group', 'cluster', 'tenant_group', 'tenant', 'virtual_chassis', 'vc_position', 'vc_priority', '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 = { help_texts = {
'device_role': "The function this device serves", 'device_role': "The function this device serves",
@ -705,7 +705,7 @@ class ModuleForm(NetBoxModelForm):
fieldsets = ( fieldsets = (
('Module', ( ('Module', (
'device', 'module_bay', 'manufacturer', 'module_type', 'tags', 'device', 'module_bay', 'manufacturer', 'module_type', 'description', 'tags',
)), )),
('Hardware', ( ('Hardware', (
'serial', 'asset_tag', 'replicate_components', 'adopt_components', 'serial', 'asset_tag', 'replicate_components', 'adopt_components',
@ -716,7 +716,7 @@ class ModuleForm(NetBoxModelForm):
model = Module model = Module
fields = [ fields = [
'device', 'module_bay', 'manufacturer', 'module_type', 'serial', 'asset_tag', 'tags', '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): def __init__(self, *args, **kwargs):
@ -793,11 +793,13 @@ class ModuleForm(NetBoxModelForm):
class CableForm(TenancyForm, NetBoxModelForm): class CableForm(TenancyForm, NetBoxModelForm):
comments = CommentField()
class Meta: class Meta:
model = Cable model = Cable
fields = [ 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 = { widgets = {
'status': StaticSelect, 'status': StaticSelect,
@ -840,15 +842,16 @@ class PowerPanelForm(NetBoxModelForm):
'site_id': '$site' 'site_id': '$site'
} }
) )
comments = CommentField()
fieldsets = ( fieldsets = (
('Power Panel', ('region', 'site_group', 'site', 'location', 'name', 'tags')), ('Power Panel', ('region', 'site_group', 'site', 'location', 'name', 'description', 'tags')),
) )
class Meta: class Meta:
model = PowerPanel model = PowerPanel
fields = [ 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() comments = CommentField()
fieldsets = ( fieldsets = (
('Power Panel', ('region', 'site', 'power_panel')), ('Power Panel', ('region', 'site', 'power_panel', 'description')),
('Power Feed', ('rack', 'name', 'status', 'type', 'mark_connected', 'tags')), ('Power Feed', ('rack', 'name', 'status', 'type', 'mark_connected', 'tags')),
('Characteristics', ('supply', 'voltage', 'amperage', 'phase', 'max_utilization')), ('Characteristics', ('supply', 'voltage', 'amperage', 'phase', 'max_utilization')),
) )
@ -903,7 +906,7 @@ class PowerFeedForm(NetBoxModelForm):
model = PowerFeed model = PowerFeed
fields = [ fields = [
'region', 'site_group', 'site', 'power_panel', 'rack', 'name', 'status', 'type', 'mark_connected', 'supply', '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 = { widgets = {
'status': StaticSelect(), 'status': StaticSelect(),
@ -922,11 +925,12 @@ class VirtualChassisForm(NetBoxModelForm):
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
) )
comments = CommentField()
class Meta: class Meta:
model = VirtualChassis model = VirtualChassis
fields = [ fields = [
'name', 'domain', 'master', 'tags', 'name', 'domain', 'master', 'description', 'comments', 'tags',
] ]
widgets = { widgets = {
'master': SelectWithPK(), 'master': SelectWithPK(),

View File

@ -30,7 +30,7 @@ class DeviceTypeImportForm(BootstrapMixin, forms.ModelForm):
model = DeviceType model = DeviceType
fields = [ fields = [
'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', '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: class Meta:
model = ModuleType model = ModuleType
fields = ['manufacturer', 'model', 'part_number', 'comments'] fields = ['manufacturer', 'model', 'part_number', 'description', 'comments']
# #

View File

@ -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),
),
]

View File

@ -12,8 +12,8 @@ from django.urls import reverse
from dcim.choices import * from dcim.choices import *
from dcim.constants import * from dcim.constants import *
from dcim.fields import PathField from dcim.fields import PathField
from dcim.utils import decompile_path_node, object_to_path_node, path_node_to_object from dcim.utils import decompile_path_node, object_to_path_node
from netbox.models import NetBoxModel from netbox.models import PrimaryModel
from utilities.fields import ColorField from utilities.fields import ColorField
from utilities.querysets import RestrictedQuerySet from utilities.querysets import RestrictedQuerySet
from utilities.utils import to_meters from utilities.utils import to_meters
@ -34,7 +34,7 @@ trace_paths = Signal()
# Cables # Cables
# #
class Cable(NetBoxModel): class Cable(PrimaryModel):
""" """
A physical connection between two endpoints. A physical connection between two endpoints.
""" """

View File

@ -18,7 +18,7 @@ from dcim.constants import *
from extras.models import ConfigContextModel from extras.models import ConfigContextModel
from extras.querysets import ConfigContextModelQuerySet from extras.querysets import ConfigContextModelQuerySet
from netbox.config import ConfigItem from netbox.config import ConfigItem
from netbox.models import OrganizationalModel, NetBoxModel from netbox.models import OrganizationalModel, PrimaryModel
from utilities.choices import ColorChoices from utilities.choices import ColorChoices
from utilities.fields import ColorField, NaturalOrderingField from utilities.fields import ColorField, NaturalOrderingField
from .device_components import * from .device_components import *
@ -54,7 +54,7 @@ class Manufacturer(OrganizationalModel):
return reverse('dcim:manufacturer', args=[self.pk]) 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 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). well as high-level functional role(s).
@ -117,9 +117,6 @@ class DeviceType(NetBoxModel, WeightMixin):
upload_to='devicetype-images', upload_to='devicetype-images',
blank=True blank=True
) )
comments = models.TextField(
blank=True
)
clone_fields = ( clone_fields = (
'manufacturer', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'weight', 'weight_unit', '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 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 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 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, blank=True,
help_text='Discrete part number (optional)' help_text='Discrete part number (optional)'
) )
comments = models.TextField(
blank=True
)
# Generic relations # Generic relations
images = GenericRelation( images = GenericRelation(
@ -443,7 +437,7 @@ class Platform(OrganizationalModel):
return reverse('dcim:platform', args=[self.pk]) 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, 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. 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, null=True,
validators=[MaxValueValidator(255)] validators=[MaxValueValidator(255)]
) )
comments = models.TextField(
blank=True
)
# Generic relations # Generic relations
contacts = GenericRelation( contacts = GenericRelation(
@ -906,7 +897,7 @@ class Device(NetBoxModel, ConfigContextModel):
return round(total_weight / 1000, 2) 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 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. (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', verbose_name='Asset tag',
help_text='A unique tag used to identify this device' help_text='A unique tag used to identify this device'
) )
comments = models.TextField(
blank=True
)
clone_fields = ('device', 'module_type') clone_fields = ('device', 'module_type')
@ -1019,7 +1007,7 @@ class Module(NetBoxModel, ConfigContextModel):
# Virtual chassis # Virtual chassis
# #
class VirtualChassis(NetBoxModel): class VirtualChassis(PrimaryModel):
""" """
A collection of Devices which operate with a shared control plane (e.g. a switch stack). A collection of Devices which operate with a shared control plane (e.g. a switch stack).
""" """

View File

@ -6,9 +6,8 @@ from django.db import models
from django.urls import reverse from django.urls import reverse
from dcim.choices import * from dcim.choices import *
from dcim.constants import *
from netbox.config import ConfigItem from netbox.config import ConfigItem
from netbox.models import NetBoxModel from netbox.models import PrimaryModel
from utilities.validators import ExclusionValidator from utilities.validators import ExclusionValidator
from .device_components import CabledObjectModel, PathEndpoint from .device_components import CabledObjectModel, PathEndpoint
@ -22,7 +21,7 @@ __all__ = (
# Power # Power
# #
class PowerPanel(NetBoxModel): class PowerPanel(PrimaryModel):
""" """
A distribution point for electrical power; e.g. a data center RPP. 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. An electrical circuit delivered from a PowerPanel.
""" """
@ -132,9 +131,6 @@ class PowerFeed(NetBoxModel, PathEndpoint, CabledObjectModel):
default=0, default=0,
editable=False editable=False
) )
comments = models.TextField(
blank=True
)
clone_fields = ( clone_fields = (
'power_panel', 'rack', 'status', 'type', 'mark_connected', 'supply', 'phase', 'voltage', 'amperage', 'power_panel', 'rack', 'status', 'type', 'mark_connected', 'supply', 'phase', 'voltage', 'amperage',

View File

@ -14,7 +14,7 @@ from django.urls import reverse
from dcim.choices import * from dcim.choices import *
from dcim.constants import * from dcim.constants import *
from dcim.svg import RackElevationSVG from dcim.svg import RackElevationSVG
from netbox.models import OrganizationalModel, NetBoxModel from netbox.models import OrganizationalModel, PrimaryModel
from utilities.choices import ColorChoices from utilities.choices import ColorChoices
from utilities.fields import ColorField, NaturalOrderingField from utilities.fields import ColorField, NaturalOrderingField
from utilities.utils import array_to_string, drange from utilities.utils import array_to_string, drange
@ -46,7 +46,7 @@ class RackRole(OrganizationalModel):
return reverse('dcim:rackrole', args=[self.pk]) 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. 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. 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.' 'distance between the front and rear rails.'
) )
) )
comments = models.TextField(
blank=True
)
# Generic relations # Generic relations
vlan_groups = GenericRelation( vlan_groups = GenericRelation(
@ -463,7 +460,7 @@ class Rack(NetBoxModel, WeightMixin):
return round(total_weight / 1000, 2) return round(total_weight / 1000, 2)
class RackReservation(NetBoxModel): class RackReservation(PrimaryModel):
""" """
One or more reserved units within a Rack. One or more reserved units within a Rack.
""" """

View File

@ -6,7 +6,7 @@ from timezone_field import TimeZoneField
from dcim.choices import * from dcim.choices import *
from dcim.constants import * from dcim.constants import *
from netbox.models import NestedGroupModel, NetBoxModel from netbox.models import NestedGroupModel, PrimaryModel
from utilities.fields import NaturalOrderingField from utilities.fields import NaturalOrderingField
__all__ = ( __all__ = (
@ -131,7 +131,7 @@ class SiteGroup(NestedGroupModel):
# Sites # Sites
# #
class Site(NetBoxModel): class Site(PrimaryModel):
""" """
A Site represents a geographic location within a network; typically a building or campus. The optional facility 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). 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( time_zone = TimeZoneField(
blank=True blank=True
) )
description = models.CharField(
max_length=200,
blank=True
)
physical_address = models.CharField( physical_address = models.CharField(
max_length=200, max_length=200,
blank=True blank=True
@ -214,9 +210,6 @@ class Site(NetBoxModel):
null=True, null=True,
help_text='GPS coordinate (longitude)' help_text='GPS coordinate (longitude)'
) )
comments = models.TextField(
blank=True
)
# Generic relations # Generic relations
vlan_groups = GenericRelation( vlan_groups = GenericRelation(

View File

@ -111,6 +111,7 @@ class CableTable(TenancyColumnsMixin, NetBoxTable):
order_by=('_abs_length', 'length_unit') order_by=('_abs_length', 'length_unit')
) )
color = columns.ColorColumn() color = columns.ColorColumn()
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='dcim:cable_list' url_name='dcim:cable_list'
) )
@ -120,7 +121,7 @@ class CableTable(TenancyColumnsMixin, NetBoxTable):
fields = ( fields = (
'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'device_a', 'device_b', 'rack_a', 'rack_b', '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', '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 = ( default_columns = (
'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'status', 'type', 'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'status', 'type',

View File

@ -1,21 +1,5 @@
import django_tables2 as tables import django_tables2 as tables
from dcim.models import ( from dcim import models
ConsolePort,
ConsoleServerPort,
Device,
DeviceBay,
DeviceRole,
FrontPort,
Interface,
InventoryItem,
InventoryItemRole,
ModuleBay,
Platform,
PowerOutlet,
PowerPort,
RearPort,
VirtualChassis,
)
from django_tables2.utils import Accessor from django_tables2.utils import Accessor
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
@ -106,7 +90,7 @@ class DeviceRoleTable(NetBoxTable):
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = DeviceRole model = models.DeviceRole
fields = ( fields = (
'pk', 'id', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'description', 'slug', 'tags', 'pk', 'id', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'description', 'slug', 'tags',
'actions', 'created', 'last_updated', 'actions', 'created', 'last_updated',
@ -137,7 +121,7 @@ class PlatformTable(NetBoxTable):
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Platform model = models.Platform
fields = ( fields = (
'pk', 'id', 'name', 'manufacturer', 'device_count', 'vm_count', 'slug', 'napalm_driver', 'napalm_args', 'pk', 'id', 'name', 'manufacturer', 'device_count', 'vm_count', 'slug', 'napalm_driver', 'napalm_args',
'description', 'tags', 'actions', 'created', 'last_updated', 'description', 'tags', 'actions', 'created', 'last_updated',
@ -220,12 +204,12 @@ class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Device model = models.Device
fields = ( fields = (
'pk', 'id', 'name', 'status', 'tenant', 'tenant_group', 'device_role', 'manufacturer', 'device_type', 'pk', 'id', 'name', 'status', 'tenant', 'tenant_group', 'device_role', 'manufacturer', 'device_type',
'platform', 'serial', 'asset_tag', 'region', 'site_group', 'site', 'location', 'rack', 'position', 'face', 'platform', 'serial', 'asset_tag', 'region', 'site_group', 'site', 'location', 'rack', 'position', 'face',
'airflow', 'primary_ip', 'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position', '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 = ( default_columns = (
'pk', 'name', 'status', 'tenant', 'site', 'location', 'rack', 'device_role', 'manufacturer', 'device_type', 'pk', 'name', 'status', 'tenant', 'site', 'location', 'rack', 'device_role', 'manufacturer', 'device_type',
@ -252,7 +236,7 @@ class DeviceImportTable(TenancyColumnsMixin, NetBoxTable):
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Device model = models.Device
fields = ('id', 'name', 'status', 'tenant', 'tenant_group', 'site', 'rack', 'position', 'device_role', 'device_type') fields = ('id', 'name', 'status', 'tenant', 'tenant_group', 'site', 'rack', 'position', 'device_role', 'device_type')
empty_text = False empty_text = False
@ -326,7 +310,7 @@ class ConsolePortTable(ModularDeviceComponentTable, PathEndpointTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = ConsolePort model = models.ConsolePort
fields = ( fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'speed', 'description', 'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'speed', 'description',
'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created', 'last_updated', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created', 'last_updated',
@ -345,7 +329,7 @@ class DeviceConsolePortTable(ConsolePortTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = ConsolePort model = models.ConsolePort
fields = ( fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'speed', 'description', 'mark_connected', 'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'speed', 'description', 'mark_connected',
'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions' 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions'
@ -368,7 +352,7 @@ class ConsoleServerPortTable(ModularDeviceComponentTable, PathEndpointTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = ConsoleServerPort model = models.ConsoleServerPort
fields = ( fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'speed', 'description', 'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'speed', 'description',
'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created', 'last_updated', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created', 'last_updated',
@ -388,7 +372,7 @@ class DeviceConsoleServerPortTable(ConsoleServerPortTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = ConsoleServerPort model = models.ConsoleServerPort
fields = ( fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'speed', 'description', 'mark_connected', 'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'speed', 'description', 'mark_connected',
'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions',
@ -411,7 +395,7 @@ class PowerPortTable(ModularDeviceComponentTable, PathEndpointTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = PowerPort model = models.PowerPort
fields = ( fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'description', 'mark_connected', 'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'description', 'mark_connected',
'maximum_draw', 'allocated_draw', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created', 'maximum_draw', 'allocated_draw', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created',
@ -432,7 +416,7 @@ class DevicePowerPortTable(PowerPortTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = PowerPort model = models.PowerPort
fields = ( fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'maximum_draw', 'allocated_draw', 'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'maximum_draw', 'allocated_draw',
'description', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions', 'description', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions',
@ -460,7 +444,7 @@ class PowerOutletTable(ModularDeviceComponentTable, PathEndpointTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = PowerOutlet model = models.PowerOutlet
fields = ( fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'description', 'power_port', 'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'description', 'power_port',
'feed_leg', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created', 'feed_leg', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'created',
@ -480,7 +464,7 @@ class DevicePowerOutletTable(PowerOutletTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = PowerOutlet model = models.PowerOutlet
fields = ( fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'power_port', 'feed_leg', 'description', 'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'power_port', 'feed_leg', 'description',
'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'tags', 'actions',
@ -544,7 +528,7 @@ class InterfaceTable(ModularDeviceComponentTable, BaseInterfaceTable, PathEndpoi
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = Interface model = models.Interface
fields = ( fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'enabled', 'type', 'mgmt_only', 'mtu', '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', '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): class Meta(DeviceComponentTable.Meta):
model = Interface model = models.Interface
fields = ( fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'enabled', 'type', 'parent', 'bridge', 'lag', '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', '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): class Meta(DeviceComponentTable.Meta):
model = FrontPort model = models.FrontPort
fields = ( fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'color', 'rear_port', 'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'color', 'rear_port',
'rear_port_position', 'description', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'tags', 'rear_port_position', 'description', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'tags',
@ -640,7 +624,7 @@ class DeviceFrontPortTable(FrontPortTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = FrontPort model = models.FrontPort
fields = ( fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'rear_port', 'rear_port_position', 'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'rear_port', 'rear_port_position',
'description', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'tags', 'actions', 'description', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'tags', 'actions',
@ -666,7 +650,7 @@ class RearPortTable(ModularDeviceComponentTable, CableTerminationTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = RearPort model = models.RearPort
fields = ( fields = (
'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'color', 'positions', 'description', 'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'color', 'positions', 'description',
'mark_connected', 'cable', 'cable_color', 'link_peer', 'tags', 'created', 'last_updated', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'tags', 'created', 'last_updated',
@ -686,7 +670,7 @@ class DeviceRearPortTable(RearPortTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = RearPort model = models.RearPort
fields = ( fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'positions', 'description', 'mark_connected', 'pk', 'id', 'name', 'module_bay', 'module', 'label', 'type', 'positions', 'description', 'mark_connected',
'cable', 'cable_color', 'link_peer', 'tags', 'actions', 'cable', 'cable_color', 'link_peer', 'tags', 'actions',
@ -727,7 +711,7 @@ class DeviceBayTable(DeviceComponentTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = DeviceBay model = models.DeviceBay
fields = ( fields = (
'pk', 'id', 'name', 'device', 'label', 'status', 'device_role', 'device_type', 'installed_device', 'description', 'tags', 'pk', 'id', 'name', 'device', 'label', 'status', 'device_role', 'device_type', 'installed_device', 'description', 'tags',
'created', 'last_updated', 'created', 'last_updated',
@ -748,7 +732,7 @@ class DeviceDeviceBayTable(DeviceBayTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = DeviceBay model = models.DeviceBay
fields = ( fields = (
'pk', 'id', 'name', 'label', 'status', 'installed_device', 'description', 'tags', 'actions', 'pk', 'id', 'name', 'label', 'status', 'installed_device', 'description', 'tags', 'actions',
) )
@ -777,7 +761,7 @@ class ModuleBayTable(DeviceComponentTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = ModuleBay model = models.ModuleBay
fields = ( fields = (
'pk', 'id', 'name', 'device', 'label', 'position', 'installed_module', 'module_serial', 'module_asset_tag', 'pk', 'id', 'name', 'device', 'label', 'position', 'installed_module', 'module_serial', 'module_asset_tag',
'description', 'tags', 'description', 'tags',
@ -791,7 +775,7 @@ class DeviceModuleBayTable(ModuleBayTable):
) )
class Meta(DeviceComponentTable.Meta): class Meta(DeviceComponentTable.Meta):
model = ModuleBay model = models.ModuleBay
fields = ( fields = (
'pk', 'id', 'name', 'label', 'position', 'installed_module', 'module_serial', 'module_asset_tag', 'pk', 'id', 'name', 'label', 'position', 'installed_module', 'module_serial', 'module_asset_tag',
'description', 'tags', 'actions', 'description', 'tags', 'actions',
@ -821,7 +805,7 @@ class InventoryItemTable(DeviceComponentTable):
cable = None # Override DeviceComponentTable cable = None # Override DeviceComponentTable
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = InventoryItem model = models.InventoryItem
fields = ( fields = (
'pk', 'id', 'name', 'device', 'component', 'label', 'role', 'manufacturer', 'part_id', 'serial', 'pk', 'id', 'name', 'device', 'component', 'label', 'role', 'manufacturer', 'part_id', 'serial',
'asset_tag', 'description', 'discovered', 'tags', 'created', 'last_updated', 'asset_tag', 'description', 'discovered', 'tags', 'created', 'last_updated',
@ -840,7 +824,7 @@ class DeviceInventoryItemTable(InventoryItemTable):
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = InventoryItem model = models.InventoryItem
fields = ( fields = (
'pk', 'id', 'name', 'label', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'component', 'pk', 'id', 'name', 'label', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'component',
'description', 'discovered', 'tags', 'actions', 'description', 'discovered', 'tags', 'actions',
@ -865,7 +849,7 @@ class InventoryItemRoleTable(NetBoxTable):
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = InventoryItemRole model = models.InventoryItemRole
fields = ( fields = (
'pk', 'id', 'name', 'inventoryitem_count', 'color', 'description', 'slug', 'tags', 'actions', 'pk', 'id', 'name', 'inventoryitem_count', 'color', 'description', 'slug', 'tags', 'actions',
) )
@ -888,11 +872,15 @@ class VirtualChassisTable(NetBoxTable):
url_params={'virtual_chassis_id': 'pk'}, url_params={'virtual_chassis_id': 'pk'},
verbose_name='Members' verbose_name='Members'
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='dcim:virtualchassis_list' url_name='dcim:virtualchassis_list'
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = VirtualChassis model = models.VirtualChassis
fields = ('pk', 'id', 'name', 'domain', 'master', 'member_count', 'tags', 'created', 'last_updated',) fields = (
'pk', 'id', 'name', 'domain', 'master', 'member_count', 'description', 'comments', 'tags', 'created',
'last_updated',
)
default_columns = ('pk', 'name', 'domain', 'master', 'member_count') default_columns = ('pk', 'name', 'domain', 'master', 'member_count')

View File

@ -1,19 +1,6 @@
import django_tables2 as tables import django_tables2 as tables
from dcim.models import ( from dcim import models
ConsolePortTemplate,
ConsoleServerPortTemplate,
DeviceBayTemplate,
DeviceType,
FrontPortTemplate,
InterfaceTemplate,
InventoryItemTemplate,
Manufacturer,
ModuleBayTemplate,
PowerOutletTemplate,
PowerPortTemplate,
RearPortTemplate,
)
from netbox.tables import NetBoxTable, columns from netbox.tables import NetBoxTable, columns
from tenancy.tables import ContactsColumnMixin from tenancy.tables import ContactsColumnMixin
from .template_code import MODULAR_COMPONENT_TEMPLATE_BUTTONS, DEVICE_WEIGHT from .template_code import MODULAR_COMPONENT_TEMPLATE_BUTTONS, DEVICE_WEIGHT
@ -59,7 +46,7 @@ class ManufacturerTable(ContactsColumnMixin, NetBoxTable):
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Manufacturer model = models.Manufacturer
fields = ( fields = (
'pk', 'id', 'name', 'devicetype_count', 'inventoryitem_count', 'platform_count', 'description', 'slug', 'pk', 'id', 'name', 'devicetype_count', 'inventoryitem_count', 'platform_count', 'description', 'slug',
'contacts', 'actions', 'created', 'last_updated', 'contacts', 'actions', 'created', 'last_updated',
@ -100,15 +87,12 @@ class DeviceTypeTable(NetBoxTable):
template_code=DEVICE_WEIGHT, template_code=DEVICE_WEIGHT,
order_by=('_abs_weight', 'weight_unit') order_by=('_abs_weight', 'weight_unit')
) )
u_height = columns.TemplateColumn(
template_code='{{ value|floatformat }}'
)
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = DeviceType model = models.DeviceType
fields = ( fields = (
'pk', 'id', 'model', 'manufacturer', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', '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 = ( default_columns = (
'pk', 'model', 'manufacturer', 'part_number', 'u_height', 'is_full_depth', 'instance_count', 'pk', 'model', 'manufacturer', 'part_number', 'u_height', 'is_full_depth', 'instance_count',
@ -138,7 +122,7 @@ class ConsolePortTemplateTable(ComponentTemplateTable):
) )
class Meta(ComponentTemplateTable.Meta): class Meta(ComponentTemplateTable.Meta):
model = ConsolePortTemplate model = models.ConsolePortTemplate
fields = ('pk', 'name', 'label', 'type', 'description', 'actions') fields = ('pk', 'name', 'label', 'type', 'description', 'actions')
empty_text = "None" empty_text = "None"
@ -150,7 +134,7 @@ class ConsoleServerPortTemplateTable(ComponentTemplateTable):
) )
class Meta(ComponentTemplateTable.Meta): class Meta(ComponentTemplateTable.Meta):
model = ConsoleServerPortTemplate model = models.ConsoleServerPortTemplate
fields = ('pk', 'name', 'label', 'type', 'description', 'actions') fields = ('pk', 'name', 'label', 'type', 'description', 'actions')
empty_text = "None" empty_text = "None"
@ -162,7 +146,7 @@ class PowerPortTemplateTable(ComponentTemplateTable):
) )
class Meta(ComponentTemplateTable.Meta): class Meta(ComponentTemplateTable.Meta):
model = PowerPortTemplate model = models.PowerPortTemplate
fields = ('pk', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'actions') fields = ('pk', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'actions')
empty_text = "None" empty_text = "None"
@ -174,7 +158,7 @@ class PowerOutletTemplateTable(ComponentTemplateTable):
) )
class Meta(ComponentTemplateTable.Meta): class Meta(ComponentTemplateTable.Meta):
model = PowerOutletTemplate model = models.PowerOutletTemplate
fields = ('pk', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'actions') fields = ('pk', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'actions')
empty_text = "None" empty_text = "None"
@ -189,7 +173,7 @@ class InterfaceTemplateTable(ComponentTemplateTable):
) )
class Meta(ComponentTemplateTable.Meta): class Meta(ComponentTemplateTable.Meta):
model = InterfaceTemplate model = models.InterfaceTemplate
fields = ('pk', 'name', 'label', 'mgmt_only', 'type', 'description', 'poe_mode', 'poe_type', 'actions') fields = ('pk', 'name', 'label', 'mgmt_only', 'type', 'description', 'poe_mode', 'poe_type', 'actions')
empty_text = "None" empty_text = "None"
@ -205,7 +189,7 @@ class FrontPortTemplateTable(ComponentTemplateTable):
) )
class Meta(ComponentTemplateTable.Meta): class Meta(ComponentTemplateTable.Meta):
model = FrontPortTemplate model = models.FrontPortTemplate
fields = ('pk', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position', 'description', 'actions') fields = ('pk', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position', 'description', 'actions')
empty_text = "None" empty_text = "None"
@ -218,7 +202,7 @@ class RearPortTemplateTable(ComponentTemplateTable):
) )
class Meta(ComponentTemplateTable.Meta): class Meta(ComponentTemplateTable.Meta):
model = RearPortTemplate model = models.RearPortTemplate
fields = ('pk', 'name', 'label', 'type', 'color', 'positions', 'description', 'actions') fields = ('pk', 'name', 'label', 'type', 'color', 'positions', 'description', 'actions')
empty_text = "None" empty_text = "None"
@ -229,7 +213,7 @@ class ModuleBayTemplateTable(ComponentTemplateTable):
) )
class Meta(ComponentTemplateTable.Meta): class Meta(ComponentTemplateTable.Meta):
model = ModuleBayTemplate model = models.ModuleBayTemplate
fields = ('pk', 'name', 'label', 'position', 'description', 'actions') fields = ('pk', 'name', 'label', 'position', 'description', 'actions')
empty_text = "None" empty_text = "None"
@ -240,7 +224,7 @@ class DeviceBayTemplateTable(ComponentTemplateTable):
) )
class Meta(ComponentTemplateTable.Meta): class Meta(ComponentTemplateTable.Meta):
model = DeviceBayTemplate model = models.DeviceBayTemplate
fields = ('pk', 'name', 'label', 'description', 'actions') fields = ('pk', 'name', 'label', 'description', 'actions')
empty_text = "None" empty_text = "None"
@ -260,7 +244,7 @@ class InventoryItemTemplateTable(ComponentTemplateTable):
) )
class Meta(ComponentTemplateTable.Meta): class Meta(ComponentTemplateTable.Meta):
model = InventoryItemTemplate model = models.InventoryItemTemplate
fields = ( fields = (
'pk', 'name', 'label', 'parent', 'role', 'manufacturer', 'part_id', 'component', 'description', 'actions', 'pk', 'name', 'label', 'parent', 'role', 'manufacturer', 'part_id', 'component', 'description', 'actions',
) )

View File

@ -35,7 +35,7 @@ class ModuleTypeTable(NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = ModuleType model = ModuleType
fields = ( fields = (
'pk', 'id', 'model', 'manufacturer', 'part_number', 'weight', 'comments', 'tags', 'pk', 'id', 'model', 'manufacturer', 'part_number', 'weight', 'description', 'comments', 'tags',
) )
default_columns = ( default_columns = (
'pk', 'model', 'manufacturer', 'part_number', 'pk', 'model', 'manufacturer', 'part_number',
@ -64,8 +64,8 @@ class ModuleTable(NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Module model = Module
fields = ( fields = (
'pk', 'id', 'device', 'module_bay', 'manufacturer', 'module_type', 'serial', 'asset_tag', 'comments', 'pk', 'id', 'device', 'module_bay', 'manufacturer', 'module_type', 'serial', 'asset_tag', 'description',
'tags', 'comments', 'tags',
) )
default_columns = ( default_columns = (
'pk', 'id', 'device', 'module_bay', 'manufacturer', 'module_type', 'serial', 'asset_tag', 'pk', 'id', 'device', 'module_bay', 'manufacturer', 'module_type', 'serial', 'asset_tag',

View File

@ -31,6 +31,7 @@ class PowerPanelTable(ContactsColumnMixin, NetBoxTable):
url_params={'power_panel_id': 'pk'}, url_params={'power_panel_id': 'pk'},
verbose_name='Feeds' verbose_name='Feeds'
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='dcim:powerpanel_list' url_name='dcim:powerpanel_list'
) )
@ -38,7 +39,8 @@ class PowerPanelTable(ContactsColumnMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = PowerPanel model = PowerPanel
fields = ( 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') default_columns = ('pk', 'name', 'site', 'location', 'powerfeed_count')
@ -77,7 +79,7 @@ class PowerFeedTable(CableTerminationTable):
fields = ( fields = (
'pk', 'id', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', 'pk', 'id', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase',
'max_utilization', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'available_power', '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 = ( default_columns = (
'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', 'cable', 'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', 'cable',

View File

@ -90,8 +90,8 @@ class RackTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
fields = ( fields = (
'pk', 'id', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'tenant_group', 'role', 'serial', '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', 'asset_tag', 'type', 'u_height', 'width', 'outer_width', 'outer_depth', 'mounting_depth', 'weight',
'comments', 'device_count', 'get_utilization', 'get_power_utilization', 'contacts', 'tags', 'created', 'comments', 'device_count', 'get_utilization', 'get_power_utilization', 'description', 'contacts', 'tags',
'last_updated', 'created', 'last_updated',
) )
default_columns = ( default_columns = (
'pk', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'u_height', 'device_count', 'pk', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'u_height', 'device_count',
@ -123,6 +123,7 @@ class RackReservationTable(TenancyColumnsMixin, NetBoxTable):
orderable=False, orderable=False,
verbose_name='Units' verbose_name='Units'
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='dcim:rackreservation_list' url_name='dcim:rackreservation_list'
) )
@ -130,7 +131,7 @@ class RackReservationTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = RackReservation model = RackReservation
fields = ( fields = (
'pk', 'id', 'reservation', 'site', 'location', 'rack', 'unit_list', 'user', 'created', 'tenant', 'tenant_group', 'description', 'tags', 'pk', 'id', 'reservation', 'site', 'location', 'rack', 'unit_list', 'user', 'created', 'tenant',
'actions', 'created', 'last_updated', 'tenant_group', 'description', 'comments', 'tags', 'actions', 'created', 'last_updated',
) )
default_columns = ('pk', 'reservation', 'site', 'rack', 'unit_list', 'user', 'description') default_columns = ('pk', 'reservation', 'site', 'rack', 'unit_list', 'user', 'description')

View File

@ -31,8 +31,8 @@ class ASNSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = ASN model = ASN
fields = [ fields = [
'id', 'url', 'display', 'asn', 'rir', 'tenant', 'description', 'site_count', 'provider_count', 'tags', 'id', 'url', 'display', 'asn', 'rir', 'tenant', 'description', 'comments', 'tags', 'custom_fields',
'custom_fields', 'created', 'last_updated', 'created', 'last_updated', 'site_count', 'provider_count',
] ]
@ -61,8 +61,9 @@ class VRFSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = VRF model = VRF
fields = [ fields = [
'id', 'url', 'display', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'import_targets', 'id', 'url', 'display', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'comments',
'export_targets', 'tags', 'custom_fields', 'created', 'last_updated', 'ipaddress_count', 'prefix_count', 'import_targets', 'export_targets', 'tags', 'custom_fields', 'created', 'last_updated', 'ipaddress_count',
'prefix_count',
] ]
@ -77,7 +78,8 @@ class RouteTargetSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = RouteTarget model = RouteTarget
fields = [ 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: class Meta:
model = Aggregate model = Aggregate
fields = [ fields = [
'id', 'url', 'display', 'family', 'prefix', 'rir', 'tenant', 'date_added', 'description', 'tags', 'id', 'url', 'display', 'family', 'prefix', 'rir', 'tenant', 'date_added', 'description', 'comments',
'custom_fields', 'created', 'last_updated', 'tags', 'custom_fields', 'created', 'last_updated',
] ]
read_only_fields = ['family'] read_only_fields = ['family']
@ -123,8 +125,8 @@ class FHRPGroupSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = FHRPGroup model = FHRPGroup
fields = [ fields = [
'id', 'name', 'url', 'display', 'protocol', 'group_id', 'auth_type', 'auth_key', 'description', 'ip_addresses', 'id', 'name', 'url', 'display', 'protocol', 'group_id', 'auth_type', 'auth_key', 'description', 'comments',
'tags', 'custom_fields', 'created', 'last_updated', 'tags', 'custom_fields', 'created', 'last_updated', 'ip_addresses',
] ]
@ -215,7 +217,7 @@ class VLANSerializer(NetBoxModelSerializer):
model = VLAN model = VLAN
fields = [ fields = [
'id', 'url', 'display', 'site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description', '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 model = Prefix
fields = [ fields = [
'id', 'url', 'display', 'family', 'prefix', 'site', 'vrf', 'tenant', 'vlan', 'status', 'role', 'is_pool', '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'] read_only_fields = ['family']
@ -342,7 +345,7 @@ class IPRangeSerializer(NetBoxModelSerializer):
model = IPRange model = IPRange
fields = [ fields = [
'id', 'url', 'display', 'family', 'start_address', 'end_address', 'size', 'vrf', 'tenant', 'status', 'role', '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'] read_only_fields = ['family']
@ -371,8 +374,8 @@ class IPAddressSerializer(NetBoxModelSerializer):
model = IPAddress model = IPAddress
fields = [ fields = [
'id', 'url', 'display', 'family', 'address', 'vrf', 'tenant', 'status', 'role', 'assigned_object_type', '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', 'assigned_object_id', 'assigned_object', 'nat_inside', 'nat_outside', 'dns_name', 'description', 'comments',
'custom_fields', 'created', 'last_updated', 'tags', 'custom_fields', 'created', 'last_updated',
] ]
@swagger_serializer_method(serializer_or_field=serializers.JSONField) @swagger_serializer_method(serializer_or_field=serializers.JSONField)
@ -415,8 +418,8 @@ class ServiceTemplateSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = ServiceTemplate model = ServiceTemplate
fields = [ fields = [
'id', 'url', 'display', 'name', 'ports', 'protocol', 'description', 'tags', 'custom_fields', 'created', 'id', 'url', 'display', 'name', 'ports', 'protocol', 'description', 'comments', 'tags', 'custom_fields',
'last_updated', 'created', 'last_updated',
] ]
@ -436,7 +439,7 @@ class ServiceSerializer(NetBoxModelSerializer):
model = Service model = Service
fields = [ fields = [
'id', 'url', 'display', 'device', 'virtual_machine', 'name', 'ports', 'protocol', 'ipaddresses', '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 model = L2VPN
fields = [ fields = [
'id', 'url', 'display', 'identifier', 'name', 'slug', 'type', 'import_targets', 'export_targets', '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'
] ]

View File

@ -8,8 +8,8 @@ from ipam.models import ASN
from netbox.forms import NetBoxModelBulkEditForm from netbox.forms import NetBoxModelBulkEditForm
from tenancy.models import Tenant from tenancy.models import Tenant
from utilities.forms import ( from utilities.forms import (
add_blank_choice, BulkEditNullBooleanSelect, DynamicModelChoiceField, NumericArrayField, StaticSelect, add_blank_choice, BulkEditNullBooleanSelect, CommentField, DynamicModelChoiceField, NumericArrayField,
DynamicModelMultipleChoiceField, SmallTextarea, StaticSelect, DynamicModelMultipleChoiceField,
) )
__all__ = ( __all__ = (
@ -43,15 +43,19 @@ class VRFBulkEditForm(NetBoxModelBulkEditForm):
label='Enforce unique space' label='Enforce unique space'
) )
description = forms.CharField( description = forms.CharField(
max_length=100, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = VRF model = VRF
fieldsets = ( fieldsets = (
(None, ('tenant', 'enforce_unique', 'description')), (None, ('tenant', 'enforce_unique', 'description')),
) )
nullable_fields = ('tenant', 'description') nullable_fields = ('tenant', 'description', 'comments')
class RouteTargetBulkEditForm(NetBoxModelBulkEditForm): class RouteTargetBulkEditForm(NetBoxModelBulkEditForm):
@ -63,12 +67,16 @@ class RouteTargetBulkEditForm(NetBoxModelBulkEditForm):
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = RouteTarget model = RouteTarget
fieldsets = ( fieldsets = (
(None, ('tenant', 'description')), (None, ('tenant', 'description')),
) )
nullable_fields = ('tenant', 'description') nullable_fields = ('tenant', 'description', 'comments')
class RIRBulkEditForm(NetBoxModelBulkEditForm): class RIRBulkEditForm(NetBoxModelBulkEditForm):
@ -103,15 +111,19 @@ class ASNBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
max_length=100, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = ASN model = ASN
fieldsets = ( fieldsets = (
(None, ('sites', 'rir', 'tenant', 'description')), (None, ('sites', 'rir', 'tenant', 'description')),
) )
nullable_fields = ('date_added', 'description') nullable_fields = ('date_added', 'description', 'comments')
class AggregateBulkEditForm(NetBoxModelBulkEditForm): class AggregateBulkEditForm(NetBoxModelBulkEditForm):
@ -128,15 +140,19 @@ class AggregateBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
max_length=100, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = Aggregate model = Aggregate
fieldsets = ( fieldsets = (
(None, ('rir', 'tenant', 'date_added', 'description')), (None, ('rir', 'tenant', 'date_added', 'description')),
) )
nullable_fields = ('date_added', 'description') nullable_fields = ('date_added', 'description', 'comments')
class RoleBulkEditForm(NetBoxModelBulkEditForm): class RoleBulkEditForm(NetBoxModelBulkEditForm):
@ -206,9 +222,13 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
label='Treat as 100% utilized' label='Treat as 100% utilized'
) )
description = forms.CharField( description = forms.CharField(
max_length=100, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = Prefix model = Prefix
fieldsets = ( fieldsets = (
@ -217,7 +237,7 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
('Addressing', ('vrf', 'prefix_length', 'is_pool', 'mark_utilized')), ('Addressing', ('vrf', 'prefix_length', 'is_pool', 'mark_utilized')),
) )
nullable_fields = ( nullable_fields = (
'site', 'vrf', 'tenant', 'role', 'description', 'site', 'vrf', 'tenant', 'role', 'description', 'comments',
) )
@ -241,16 +261,20 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
max_length=100, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = IPRange model = IPRange
fieldsets = ( fieldsets = (
(None, ('status', 'role', 'vrf', 'tenant', 'description')), (None, ('status', 'role', 'vrf', 'tenant', 'description')),
) )
nullable_fields = ( nullable_fields = (
'vrf', 'tenant', 'role', 'description', 'vrf', 'tenant', 'role', 'description', 'comments',
) )
@ -285,9 +309,13 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
label='DNS name' label='DNS name'
) )
description = forms.CharField( description = forms.CharField(
max_length=100, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = IPAddress model = IPAddress
fieldsets = ( fieldsets = (
@ -295,7 +323,7 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
('Addressing', ('vrf', 'mask_length', 'dns_name')), ('Addressing', ('vrf', 'mask_length', 'dns_name')),
) )
nullable_fields = ( 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, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = FHRPGroup model = FHRPGroup
fieldsets = ( fieldsets = (
(None, ('protocol', 'group_id', 'name', 'description')), (None, ('protocol', 'group_id', 'name', 'description')),
('Authentication', ('auth_type', 'auth_key')), ('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): class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
@ -405,9 +437,13 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
max_length=100, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = VLAN model = VLAN
fieldsets = ( fieldsets = (
@ -415,7 +451,7 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
('Site & Group', ('region', 'site_group', 'site', 'group')), ('Site & Group', ('region', 'site_group', 'site', 'group')),
) )
nullable_fields = ( nullable_fields = (
'site', 'group', 'tenant', 'role', 'description', 'site', 'group', 'tenant', 'role', 'description', 'comments',
) )
@ -433,15 +469,19 @@ class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
max_length=100, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = ServiceTemplate model = ServiceTemplate
fieldsets = ( fieldsets = (
(None, ('protocol', 'ports', 'description')), (None, ('protocol', 'ports', 'description')),
) )
nullable_fields = ('description',) nullable_fields = ('description', 'comments')
class ServiceBulkEditForm(ServiceTemplateBulkEditForm): class ServiceBulkEditForm(ServiceTemplateBulkEditForm):
@ -459,15 +499,19 @@ class L2VPNBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
max_length=100, max_length=200,
required=False required=False
) )
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = L2VPN model = L2VPN
fieldsets = ( fieldsets = (
(None, ('type', 'description', 'tenant')), (None, ('type', 'tenant', 'description')),
) )
nullable_fields = ('tenant', 'description',) nullable_fields = ('tenant', 'description', 'comments')
class L2VPNTerminationBulkEditForm(NetBoxModelBulkEditForm): class L2VPNTerminationBulkEditForm(NetBoxModelBulkEditForm):

View File

@ -41,7 +41,7 @@ class VRFCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = VRF model = VRF
fields = ('name', 'rd', 'tenant', 'enforce_unique', 'description') fields = ('name', 'rd', 'tenant', 'enforce_unique', 'description', 'comments')
class RouteTargetCSVForm(NetBoxModelCSVForm): class RouteTargetCSVForm(NetBoxModelCSVForm):
@ -54,7 +54,7 @@ class RouteTargetCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = RouteTarget model = RouteTarget
fields = ('name', 'description', 'tenant') fields = ('name', 'tenant', 'description', 'comments')
class RIRCSVForm(NetBoxModelCSVForm): class RIRCSVForm(NetBoxModelCSVForm):
@ -83,7 +83,7 @@ class AggregateCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = Aggregate model = Aggregate
fields = ('prefix', 'rir', 'tenant', 'date_added', 'description') fields = ('prefix', 'rir', 'tenant', 'date_added', 'description', 'comments')
class ASNCSVForm(NetBoxModelCSVForm): class ASNCSVForm(NetBoxModelCSVForm):
@ -101,7 +101,7 @@ class ASNCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = ASN model = ASN
fields = ('asn', 'rir', 'tenant', 'description') fields = ('asn', 'rir', 'tenant', 'description', 'comments')
help_texts = {} help_texts = {}
@ -159,7 +159,7 @@ class PrefixCSVForm(NetBoxModelCSVForm):
model = Prefix model = Prefix
fields = ( fields = (
'prefix', 'vrf', 'tenant', 'site', 'vlan_group', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized', 'prefix', 'vrf', 'tenant', 'site', 'vlan_group', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized',
'description', 'description', 'comments',
) )
def __init__(self, data=None, *args, **kwargs): def __init__(self, data=None, *args, **kwargs):
@ -204,7 +204,7 @@ class IPRangeCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = IPRange model = IPRange
fields = ( 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 model = IPAddress
fields = [ fields = [
'address', 'vrf', 'tenant', 'status', 'role', 'device', 'virtual_machine', 'interface', 'is_primary', '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): def __init__(self, data=None, *args, **kwargs):
@ -326,7 +326,7 @@ class FHRPGroupCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = FHRPGroup 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): class VLANGroupCSVForm(NetBoxModelCSVForm):
@ -389,7 +389,7 @@ class VLANCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = VLAN model = VLAN
fields = ('site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description') fields = ('site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description', 'comments')
help_texts = { help_texts = {
'vid': 'Numeric VLAN ID (1-4094)', 'vid': 'Numeric VLAN ID (1-4094)',
'name': 'VLAN name', 'name': 'VLAN name',
@ -404,7 +404,7 @@ class ServiceTemplateCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = ServiceTemplate model = ServiceTemplate
fields = ('name', 'protocol', 'ports', 'description') fields = ('name', 'protocol', 'ports', 'description', 'comments')
class ServiceCSVForm(NetBoxModelCSVForm): class ServiceCSVForm(NetBoxModelCSVForm):
@ -427,7 +427,7 @@ class ServiceCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = Service model = Service
fields = ('device', 'virtual_machine', 'name', 'protocol', 'ports', 'description') fields = ('device', 'virtual_machine', 'name', 'protocol', 'ports', 'description', 'comments')
class L2VPNCSVForm(NetBoxModelCSVForm): class L2VPNCSVForm(NetBoxModelCSVForm):
@ -443,7 +443,7 @@ class L2VPNCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = L2VPN model = L2VPN
fields = ('identifier', 'name', 'slug', 'type', 'description') fields = ('identifier', 'name', 'slug', 'type', 'description', 'comments')
class L2VPNTerminationCSVForm(NetBoxModelCSVForm): class L2VPNTerminationCSVForm(NetBoxModelCSVForm):

View File

@ -11,7 +11,7 @@ from netbox.forms import NetBoxModelForm
from tenancy.forms import TenancyForm from tenancy.forms import TenancyForm
from utilities.exceptions import PermissionsViolation from utilities.exceptions import PermissionsViolation
from utilities.forms import ( from utilities.forms import (
add_blank_choice, BootstrapMixin, ContentTypeChoiceField, DatePicker, DynamicModelChoiceField, add_blank_choice, BootstrapMixin, CommentField, ContentTypeChoiceField, DatePicker, DynamicModelChoiceField,
DynamicModelMultipleChoiceField, NumericArrayField, SlugField, StaticSelect, StaticSelectMultiple, DynamicModelMultipleChoiceField, NumericArrayField, SlugField, StaticSelect, StaticSelectMultiple,
) )
from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface
@ -49,6 +49,7 @@ class VRFForm(TenancyForm, NetBoxModelForm):
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
required=False required=False
) )
comments = CommentField()
fieldsets = ( fieldsets = (
('VRF', ('name', 'rd', 'enforce_unique', 'description', 'tags')), ('VRF', ('name', 'rd', 'enforce_unique', 'description', 'tags')),
@ -59,8 +60,8 @@ class VRFForm(TenancyForm, NetBoxModelForm):
class Meta: class Meta:
model = VRF model = VRF
fields = [ fields = [
'name', 'rd', 'enforce_unique', 'description', 'import_targets', 'export_targets', 'tenant_group', 'tenant', 'name', 'rd', 'enforce_unique', 'import_targets', 'export_targets', 'tenant_group', 'tenant', 'description',
'tags', 'comments', 'tags',
] ]
labels = { labels = {
'rd': "RD", 'rd': "RD",
@ -75,11 +76,12 @@ class RouteTargetForm(TenancyForm, NetBoxModelForm):
('Route Target', ('name', 'description', 'tags')), ('Route Target', ('name', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')), ('Tenancy', ('tenant_group', 'tenant')),
) )
comments = CommentField()
class Meta: class Meta:
model = RouteTarget model = RouteTarget
fields = [ 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(), queryset=RIR.objects.all(),
label='RIR' label='RIR'
) )
comments = CommentField()
fieldsets = ( fieldsets = (
('Aggregate', ('prefix', 'rir', 'date_added', 'description', 'tags')), ('Aggregate', ('prefix', 'rir', 'date_added', 'description', 'tags')),
@ -113,7 +116,7 @@ class AggregateForm(TenancyForm, NetBoxModelForm):
class Meta: class Meta:
model = Aggregate model = Aggregate
fields = [ fields = [
'prefix', 'rir', 'date_added', 'description', 'tenant_group', 'tenant', 'tags', 'prefix', 'rir', 'date_added', 'tenant_group', 'tenant', 'description', 'comments', 'tags',
] ]
help_texts = { help_texts = {
'prefix': "IPv4 or IPv6 network", 'prefix': "IPv4 or IPv6 network",
@ -134,6 +137,7 @@ class ASNForm(TenancyForm, NetBoxModelForm):
label='Sites', label='Sites',
required=False required=False
) )
comments = CommentField()
fieldsets = ( fieldsets = (
('ASN', ('asn', 'rir', 'sites', 'description', 'tags')), ('ASN', ('asn', 'rir', 'sites', 'description', 'tags')),
@ -143,7 +147,7 @@ class ASNForm(TenancyForm, NetBoxModelForm):
class Meta: class Meta:
model = ASN model = ASN
fields = [ fields = [
'asn', 'rir', 'sites', 'tenant_group', 'tenant', 'description', 'tags' 'asn', 'rir', 'sites', 'tenant_group', 'tenant', 'description', 'comments', 'tags'
] ]
help_texts = { help_texts = {
'asn': "AS number", 'asn': "AS number",
@ -235,6 +239,7 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False required=False
) )
comments = CommentField()
fieldsets = ( fieldsets = (
('Prefix', ('prefix', 'status', 'vrf', 'role', 'is_pool', 'mark_utilized', 'description', 'tags')), ('Prefix', ('prefix', 'status', 'vrf', 'role', 'is_pool', 'mark_utilized', 'description', 'tags')),
@ -245,8 +250,8 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
class Meta: class Meta:
model = Prefix model = Prefix
fields = [ fields = [
'prefix', 'vrf', 'site', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized', 'description', 'prefix', 'vrf', 'site', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized', 'tenant_group', 'tenant',
'tenant_group', 'tenant', 'tags', 'description', 'comments', 'tags',
] ]
widgets = { widgets = {
'status': StaticSelect(), 'status': StaticSelect(),
@ -263,6 +268,7 @@ class IPRangeForm(TenancyForm, NetBoxModelForm):
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False required=False
) )
comments = CommentField()
fieldsets = ( fieldsets = (
('IP Range', ('vrf', 'start_address', 'end_address', 'role', 'status', 'description', 'tags')), ('IP Range', ('vrf', 'start_address', 'end_address', 'role', 'status', 'description', 'tags')),
@ -272,7 +278,8 @@ class IPRangeForm(TenancyForm, NetBoxModelForm):
class Meta: class Meta:
model = IPRange model = IPRange
fields = [ 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 = { widgets = {
'status': StaticSelect(), 'status': StaticSelect(),
@ -394,13 +401,14 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
required=False, required=False,
label='Make this the primary IP for the device/VM' label='Make this the primary IP for the device/VM'
) )
comments = CommentField()
class Meta: class Meta:
model = IPAddress model = IPAddress
fields = [ fields = [
'address', 'vrf', 'status', 'role', 'dns_name', 'description', 'primary_for_parent', 'nat_site', 'nat_rack', 'address', 'vrf', 'status', 'role', 'dns_name', 'primary_for_parent', 'nat_site', 'nat_rack', 'nat_device',
'nat_device', 'nat_cluster', 'nat_virtual_machine', 'nat_vrf', 'nat_inside', 'tenant_group', 'tenant', 'nat_cluster', 'nat_virtual_machine', 'nat_vrf', 'nat_inside', 'tenant_group', 'tenant', 'description',
'tags', 'comments', 'tags',
] ]
widgets = { widgets = {
'status': StaticSelect(), 'status': StaticSelect(),
@ -535,6 +543,7 @@ class FHRPGroupForm(NetBoxModelForm):
required=False, required=False,
label='Status' label='Status'
) )
comments = CommentField()
fieldsets = ( fieldsets = (
('FHRP Group', ('protocol', 'group_id', 'name', 'description', 'tags')), ('FHRP Group', ('protocol', 'group_id', 'name', 'description', 'tags')),
@ -545,7 +554,8 @@ class FHRPGroupForm(NetBoxModelForm):
class Meta: class Meta:
model = FHRPGroup model = FHRPGroup
fields = ( 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): def save(self, *args, **kwargs):
@ -767,11 +777,13 @@ class VLANForm(TenancyForm, NetBoxModelForm):
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False required=False
) )
comments = CommentField()
class Meta: class Meta:
model = VLAN model = VLAN
fields = [ 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 = { help_texts = {
'site': "Leave blank if this VLAN spans multiple sites", '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." help_text="Comma-separated list of one or more port numbers. A range may be specified using a hyphen."
) )
comments = CommentField()
fieldsets = ( fieldsets = (
('Service Template', ( ('Service Template', (
@ -803,7 +816,7 @@ class ServiceTemplateForm(NetBoxModelForm):
class Meta: class Meta:
model = ServiceTemplate model = ServiceTemplate
fields = ('name', 'protocol', 'ports', 'description', 'tags') fields = ('name', 'protocol', 'ports', 'description', 'comments', 'tags')
widgets = { widgets = {
'protocol': StaticSelect(), 'protocol': StaticSelect(),
} }
@ -834,11 +847,12 @@ class ServiceForm(NetBoxModelForm):
'virtual_machine_id': '$virtual_machine', 'virtual_machine_id': '$virtual_machine',
} }
) )
comments = CommentField()
class Meta: class Meta:
model = Service model = Service
fields = [ fields = [
'device', 'virtual_machine', 'name', 'protocol', 'ports', 'ipaddresses', 'description', 'tags', 'device', 'virtual_machine', 'name', 'protocol', 'ports', 'ipaddresses', 'description', 'comments', 'tags',
] ]
help_texts = { help_texts = {
'ipaddresses': "IP address assignment is optional. If no IPs are selected, the service is assumed to be " '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(), queryset=RouteTarget.objects.all(),
required=False required=False
) )
comments = CommentField()
fieldsets = ( fieldsets = (
('L2VPN', ('name', 'slug', 'type', 'identifier', 'description', 'tags')), ('L2VPN', ('name', 'slug', 'type', 'identifier', 'description', 'tags')),
@ -909,7 +924,8 @@ class L2VPNForm(TenancyForm, NetBoxModelForm):
class Meta: class Meta:
model = L2VPN model = L2VPN
fields = ( 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 = { widgets = {
'type': StaticSelect(), 'type': StaticSelect(),

View File

@ -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),
),
]

View File

@ -4,7 +4,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from netbox.models import ChangeLoggedModel, NetBoxModel from netbox.models import ChangeLoggedModel, PrimaryModel
from netbox.models.features import WebhooksMixin from netbox.models.features import WebhooksMixin
from ipam.choices import * from ipam.choices import *
from ipam.constants 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.) A grouping of next hope resolution protocol (FHRP) peers. (For instance, VRRP or HSRP.)
""" """
@ -41,10 +41,6 @@ class FHRPGroup(NetBoxModel):
blank=True, blank=True,
verbose_name='Authentication key' verbose_name='Authentication key'
) )
description = models.CharField(
max_length=200,
blank=True
)
ip_addresses = GenericRelation( ip_addresses = GenericRelation(
to='ipam.IPAddress', to='ipam.IPAddress',
content_type_field='assigned_object_type', content_type_field='assigned_object_type',

View File

@ -9,7 +9,7 @@ from django.utils.functional import cached_property
from dcim.fields import ASNField from dcim.fields import ASNField
from dcim.models import Device from dcim.models import Device
from netbox.models import OrganizationalModel, NetBoxModel from netbox.models import OrganizationalModel, PrimaryModel
from ipam.choices import * from ipam.choices import *
from ipam.constants import * from ipam.constants import *
from ipam.fields import IPNetworkField, IPAddressField from ipam.fields import IPNetworkField, IPAddressField
@ -76,7 +76,7 @@ class RIR(OrganizationalModel):
return reverse('ipam:rir', args=[self.pk]) 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 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. one or more ASNs assigned to it.
@ -86,10 +86,6 @@ class ASN(NetBoxModel):
verbose_name='ASN', verbose_name='ASN',
help_text='32-bit autonomous system number' help_text='32-bit autonomous system number'
) )
description = models.CharField(
max_length=200,
blank=True
)
rir = models.ForeignKey( rir = models.ForeignKey(
to='ipam.RIR', to='ipam.RIR',
on_delete=models.PROTECT, on_delete=models.PROTECT,
@ -139,7 +135,7 @@ class ASN(NetBoxModel):
return self.asn 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 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. 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, blank=True,
null=True null=True
) )
description = models.CharField(
max_length=200,
blank=True
)
clone_fields = ( clone_fields = (
'rir', 'tenant', 'date_added', 'description', 'rir', 'tenant', 'date_added', 'description',
@ -264,7 +256,7 @@ class Role(OrganizationalModel):
return reverse('ipam:role', args=[self.pk]) 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 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 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, default=False,
help_text="Treat as 100% utilized" help_text="Treat as 100% utilized"
) )
description = models.CharField(
max_length=200,
blank=True
)
# Cached depth & child counts # Cached depth & child counts
_depth = models.PositiveSmallIntegerField( _depth = models.PositiveSmallIntegerField(
@ -545,7 +533,7 @@ class Prefix(GetAvailablePrefixesMixin, NetBoxModel):
return min(utilization, 100) return min(utilization, 100)
class IPRange(NetBoxModel): class IPRange(PrimaryModel):
""" """
A range of IP addresses, defined by start and end addresses. A range of IP addresses, defined by start and end addresses.
""" """
@ -587,10 +575,6 @@ class IPRange(NetBoxModel):
null=True, null=True,
help_text='The primary function of this range' help_text='The primary function of this range'
) )
description = models.CharField(
max_length=200,
blank=True
)
clone_fields = ( clone_fields = (
'vrf', 'tenant', 'status', 'role', 'description', 'vrf', 'tenant', 'status', 'role', 'description',
@ -740,7 +724,7 @@ class IPRange(NetBoxModel):
return int(float(child_count) / self.size * 100) 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 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 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', verbose_name='DNS Name',
help_text='Hostname or FQDN (not case-sensitive)' help_text='Hostname or FQDN (not case-sensitive)'
) )
description = models.CharField(
max_length=200,
blank=True
)
objects = IPAddressManager() objects = IPAddressManager()

View File

@ -8,7 +8,7 @@ from django.utils.functional import cached_property
from ipam.choices import L2VPNTypeChoices from ipam.choices import L2VPNTypeChoices
from ipam.constants import L2VPN_ASSIGNMENT_MODELS from ipam.constants import L2VPN_ASSIGNMENT_MODELS
from netbox.models import NetBoxModel from netbox.models import NetBoxModel, PrimaryModel
__all__ = ( __all__ = (
'L2VPN', 'L2VPN',
@ -16,7 +16,7 @@ __all__ = (
) )
class L2VPN(NetBoxModel): class L2VPN(PrimaryModel):
name = models.CharField( name = models.CharField(
max_length=100, max_length=100,
unique=True unique=True
@ -43,10 +43,6 @@ class L2VPN(NetBoxModel):
related_name='exporting_l2vpns', related_name='exporting_l2vpns',
blank=True blank=True
) )
description = models.CharField(
max_length=200,
blank=True
)
tenant = models.ForeignKey( tenant = models.ForeignKey(
to='tenancy.Tenant', to='tenancy.Tenant',
on_delete=models.PROTECT, on_delete=models.PROTECT,

View File

@ -6,7 +6,7 @@ from django.urls import reverse
from ipam.choices import * from ipam.choices import *
from ipam.constants import * from ipam.constants import *
from netbox.models import NetBoxModel from netbox.models import PrimaryModel
from utilities.utils import array_to_string from utilities.utils import array_to_string
@ -30,10 +30,6 @@ class ServiceBase(models.Model):
), ),
verbose_name='Port numbers' verbose_name='Port numbers'
) )
description = models.CharField(
max_length=200,
blank=True
)
class Meta: class Meta:
abstract = True abstract = True
@ -46,7 +42,7 @@ class ServiceBase(models.Model):
return array_to_string(self.ports) 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. 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]) 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 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. optionally be tied to one or more specific IPAddresses belonging to its parent.

View File

@ -8,12 +8,10 @@ from django.urls import reverse
from dcim.models import Interface from dcim.models import Interface
from ipam.choices import * from ipam.choices import *
from ipam.constants import * from ipam.constants import *
from ipam.models import L2VPNTermination
from ipam.querysets import VLANQuerySet from ipam.querysets import VLANQuerySet
from netbox.models import OrganizationalModel, NetBoxModel from netbox.models import OrganizationalModel, PrimaryModel
from virtualization.models import VMInterface from virtualization.models import VMInterface
__all__ = ( __all__ = (
'VLAN', 'VLAN',
'VLANGroup', 'VLANGroup',
@ -63,10 +61,6 @@ class VLANGroup(OrganizationalModel):
), ),
help_text='Highest permissible ID of a child VLAN' help_text='Highest permissible ID of a child VLAN'
) )
description = models.CharField(
max_length=200,
blank=True
)
class Meta: class Meta:
ordering = ('name', 'pk') # Name may be non-unique ordering = ('name', 'pk') # Name may be non-unique
@ -120,7 +114,7 @@ class VLANGroup(OrganizationalModel):
return None 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 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, 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, blank=True,
null=True null=True
) )
description = models.CharField(
max_length=200,
blank=True
)
l2vpn_terminations = GenericRelation( l2vpn_terminations = GenericRelation(
to='ipam.L2VPNTermination', to='ipam.L2VPNTermination',

View File

@ -2,7 +2,7 @@ from django.db import models
from django.urls import reverse from django.urls import reverse
from ipam.constants import * from ipam.constants import *
from netbox.models import NetBoxModel from netbox.models import PrimaryModel
__all__ = ( __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 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 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', verbose_name='Enforce unique space',
help_text='Prevent duplicate prefixes/IP addresses within this VRF' help_text='Prevent duplicate prefixes/IP addresses within this VRF'
) )
description = models.CharField(
max_length=200,
blank=True
)
import_targets = models.ManyToManyField( import_targets = models.ManyToManyField(
to='ipam.RouteTarget', to='ipam.RouteTarget',
related_name='importing_vrfs', related_name='importing_vrfs',
@ -73,7 +69,7 @@ class VRF(NetBoxModel):
return reverse('ipam:vrf', args=[self.pk]) 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. 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, unique=True,
help_text='Route target value (formatted in accordance with RFC 4360)' help_text='Route target value (formatted in accordance with RFC 4360)'
) )
description = models.CharField(
max_length=200,
blank=True
)
tenant = models.ForeignKey( tenant = models.ForeignKey(
to='tenancy.Tenant', to='tenancy.Tenant',
on_delete=models.PROTECT, on_delete=models.PROTECT,

View File

@ -20,7 +20,6 @@ class FHRPGroupTable(NetBoxTable):
group_id = tables.Column( group_id = tables.Column(
linkify=True linkify=True
) )
comments = columns.MarkdownColumn()
ip_addresses = tables.TemplateColumn( ip_addresses = tables.TemplateColumn(
template_code=IPADDRESSES, template_code=IPADDRESSES,
orderable=False, orderable=False,
@ -29,6 +28,7 @@ class FHRPGroupTable(NetBoxTable):
member_count = tables.Column( member_count = tables.Column(
verbose_name='Members' verbose_name='Members'
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:fhrpgroup_list' url_name='ipam:fhrpgroup_list'
) )
@ -36,7 +36,7 @@ class FHRPGroupTable(NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = FHRPGroup model = FHRPGroup
fields = ( 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', 'member_count', 'tags', 'created', 'last_updated',
) )
default_columns = ( default_columns = (

View File

@ -120,6 +120,7 @@ class ASNTable(TenancyColumnsMixin, NetBoxTable):
linkify_item=True, linkify_item=True,
verbose_name='Sites' verbose_name='Sites'
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:asn_list' url_name='ipam:asn_list'
) )
@ -127,8 +128,8 @@ class ASNTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = ASN model = ASN
fields = ( fields = (
'pk', 'asn', 'asn_asdot', 'rir', 'site_count', 'provider_count', 'tenant', 'tenant_group', 'description', 'sites', 'tags', 'pk', 'asn', 'asn_asdot', 'rir', 'site_count', 'provider_count', 'tenant', 'tenant_group', 'description',
'created', 'last_updated', 'actions', 'comments', 'sites', 'tags', 'created', 'last_updated', 'actions',
) )
default_columns = ('pk', 'asn', 'rir', 'site_count', 'provider_count', 'sites', 'description', 'tenant') default_columns = ('pk', 'asn', 'rir', 'site_count', 'provider_count', 'sites', 'description', 'tenant')
@ -153,6 +154,7 @@ class AggregateTable(TenancyColumnsMixin, NetBoxTable):
accessor='get_utilization', accessor='get_utilization',
orderable=False orderable=False
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:aggregate_list' url_name='ipam:aggregate_list'
) )
@ -160,8 +162,8 @@ class AggregateTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Aggregate model = Aggregate
fields = ( fields = (
'pk', 'id', 'prefix', 'rir', 'tenant', 'tenant_group', 'child_count', 'utilization', 'date_added', 'description', 'tags', 'pk', 'id', 'prefix', 'rir', 'tenant', 'tenant_group', 'child_count', 'utilization', 'date_added',
'created', 'last_updated', 'description', 'comments', 'tags', 'created', 'last_updated',
) )
default_columns = ('pk', 'prefix', 'rir', 'tenant', 'child_count', 'utilization', 'date_added', 'description') default_columns = ('pk', 'prefix', 'rir', 'tenant', 'child_count', 'utilization', 'date_added', 'description')
@ -278,6 +280,7 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
accessor='get_utilization', accessor='get_utilization',
orderable=False orderable=False
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:prefix_list' url_name='ipam:prefix_list'
) )
@ -285,8 +288,9 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Prefix model = Prefix
fields = ( fields = (
'pk', 'id', 'prefix', 'prefix_flat', 'status', 'children', 'vrf', 'utilization', 'tenant', 'tenant_group', 'site', 'pk', 'id', 'prefix', 'prefix_flat', 'status', 'children', 'vrf', 'utilization', 'tenant', 'tenant_group',
'vlan_group', 'vlan', 'role', 'is_pool', 'mark_utilized', 'description', 'tags', 'created', 'last_updated', 'site', 'vlan_group', 'vlan', 'role', 'is_pool', 'mark_utilized', 'description', 'comments', 'tags',
'created', 'last_updated',
) )
default_columns = ( default_columns = (
'pk', 'prefix', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role', 'description', 'pk', 'prefix', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role', 'description',
@ -317,6 +321,7 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
accessor='utilization', accessor='utilization',
orderable=False orderable=False
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:iprange_list' url_name='ipam:iprange_list'
) )
@ -324,8 +329,8 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = IPRange model = IPRange
fields = ( fields = (
'pk', 'id', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'tenant_group', 'description', 'pk', 'id', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'tenant_group',
'utilization', 'tags', 'created', 'last_updated', 'utilization', 'description', 'comments', 'tags', 'created', 'last_updated',
) )
default_columns = ( default_columns = (
'pk', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'description', '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(), linkify=lambda record: record.assigned_object.get_absolute_url(),
verbose_name='Assigned' verbose_name='Assigned'
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:ipaddress_list' url_name='ipam:ipaddress_list'
) )
@ -385,8 +391,8 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = IPAddress model = IPAddress
fields = ( fields = (
'pk', 'id', 'address', 'vrf', 'status', 'role', 'tenant', 'tenant_group', 'nat_inside', 'nat_outside', 'assigned', 'dns_name', 'description', 'pk', 'id', 'address', 'vrf', 'status', 'role', 'tenant', 'tenant_group', 'nat_inside', 'nat_outside',
'tags', 'created', 'last_updated', 'assigned', 'dns_name', 'description', 'comments', 'tags', 'created', 'last_updated',
) )
default_columns = ( default_columns = (
'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned', 'dns_name', 'description', 'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned', 'dns_name', 'description',

View File

@ -29,12 +29,16 @@ class L2VPNTable(TenancyColumnsMixin, NetBoxTable):
template_code=L2VPN_TARGETS, template_code=L2VPN_TARGETS,
orderable=False orderable=False
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn(
url_name='ipam:prefix_list'
)
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = L2VPN model = L2VPN
fields = ( fields = (
'pk', 'name', 'slug', 'identifier', 'type', 'description', 'import_targets', 'export_targets', 'tenant', 'tenant_group', 'pk', 'name', 'slug', 'identifier', 'type', 'import_targets', 'export_targets', 'tenant', 'tenant_group',
'actions', 'description', 'comments', 'tags', 'created', 'last_updated', 'actions',
) )
default_columns = ('pk', 'name', 'identifier', 'type', 'description', 'actions') default_columns = ('pk', 'name', 'identifier', 'type', 'description', 'actions')

View File

@ -17,13 +17,16 @@ class ServiceTemplateTable(NetBoxTable):
accessor=tables.A('port_list'), accessor=tables.A('port_list'),
order_by=tables.A('ports'), order_by=tables.A('ports'),
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:servicetemplate_list' url_name='ipam:servicetemplate_list'
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = ServiceTemplate 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') default_columns = ('pk', 'name', 'protocol', 'ports', 'description')
@ -39,6 +42,7 @@ class ServiceTable(NetBoxTable):
accessor=tables.A('port_list'), accessor=tables.A('port_list'),
order_by=tables.A('ports'), order_by=tables.A('ports'),
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:service_list' url_name='ipam:service_list'
) )
@ -46,7 +50,7 @@ class ServiceTable(NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Service model = Service
fields = ( fields = (
'pk', 'id', 'name', 'parent', 'protocol', 'ports', 'ipaddresses', 'description', 'tags', 'created', 'pk', 'id', 'name', 'parent', 'protocol', 'ports', 'ipaddresses', 'description', 'comments', 'tags',
'last_updated', 'created', 'last_updated',
) )
default_columns = ('pk', 'name', 'parent', 'protocol', 'ports', 'description') default_columns = ('pk', 'name', 'parent', 'protocol', 'ports', 'description')

View File

@ -121,6 +121,7 @@ class VLANTable(TenancyColumnsMixin, NetBoxTable):
orderable=False, orderable=False,
verbose_name='Prefixes' verbose_name='Prefixes'
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:vlan_list' url_name='ipam:vlan_list'
) )
@ -129,7 +130,7 @@ class VLANTable(TenancyColumnsMixin, NetBoxTable):
model = VLAN model = VLAN
fields = ( fields = (
'pk', 'id', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'tenant_group', 'status', 'role', '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') default_columns = ('pk', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'status', 'role', 'description')
row_attrs = { row_attrs = {

View File

@ -38,6 +38,7 @@ class VRFTable(TenancyColumnsMixin, NetBoxTable):
template_code=VRF_TARGETS, template_code=VRF_TARGETS,
orderable=False orderable=False
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:vrf_list' url_name='ipam:vrf_list'
) )
@ -45,8 +46,8 @@ class VRFTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = VRF model = VRF
fields = ( fields = (
'pk', 'id', 'name', 'rd', 'tenant', 'tenant_group', 'enforce_unique', 'description', 'import_targets', 'export_targets', 'pk', 'id', 'name', 'rd', 'tenant', 'tenant_group', 'enforce_unique', 'import_targets', 'export_targets',
'tags', 'created', 'last_updated', 'description', 'comments', 'tags', 'created', 'last_updated',
) )
default_columns = ('pk', 'name', 'rd', 'tenant', 'description') default_columns = ('pk', 'name', 'rd', 'tenant', 'description')
@ -59,11 +60,14 @@ class RouteTargetTable(TenancyColumnsMixin, NetBoxTable):
name = tables.Column( name = tables.Column(
linkify=True linkify=True
) )
comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:vrf_list' url_name='ipam:vrf_list'
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = RouteTarget 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') default_columns = ('pk', 'name', 'tenant', 'description')

View File

@ -10,8 +10,9 @@ from netbox.models.features import *
__all__ = ( __all__ = (
'ChangeLoggedModel', 'ChangeLoggedModel',
'NestedGroupModel', 'NestedGroupModel',
'OrganizationalModel',
'NetBoxModel', 'NetBoxModel',
'OrganizationalModel',
'PrimaryModel',
) )
@ -58,7 +59,7 @@ class ChangeLoggedModel(ChangeLoggingMixin, CustomValidationMixin, models.Model)
class NetBoxModel(CloningMixin, NetBoxFeatureSet, 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() objects = RestrictedQuerySet.as_manager()
@ -66,6 +67,22 @@ class NetBoxModel(CloningMixin, NetBoxFeatureSet, models.Model):
abstract = True 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): class NestedGroupModel(NetBoxFeatureSet, MPTTModel):
""" """
Base model for objects which are used to form a hierarchy (regions, locations, etc.). These models nest Base model for objects which are used to form a hierarchy (regions, locations, etc.). These models nest

View File

@ -33,6 +33,10 @@
<th scope="row">Account</th> <th scope="row">Account</th>
<td>{{ object.account|placeholder }}</td> <td>{{ object.account|placeholder }}</td>
</tr> </tr>
<tr>
<th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>
</tr>
<tr> <tr>
<th scope="row">Circuits</th> <th scope="row">Circuits</th>
<td> <td>

View File

@ -32,6 +32,10 @@
<th scope="row">Label</th> <th scope="row">Label</th>
<td>{{ object.label|placeholder }}</td> <td>{{ object.label|placeholder }}</td>
</tr> </tr>
<tr>
<th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>
</tr>
<tr> <tr>
<th scope="row">Color</th> <th scope="row">Color</th>
<td> <td>
@ -57,6 +61,7 @@
</div> </div>
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-6"> <div class="col col-md-6">

View File

@ -80,6 +80,7 @@
{% render_field form.tenant_group %} {% render_field form.tenant_group %}
{% render_field form.tenant %} {% render_field form.tenant %}
{% render_field form.label %} {% render_field form.label %}
{% render_field form.description %}
{% render_field form.color %} {% render_field form.color %}
<div class="row mb-3"> <div class="row mb-3">
<label class="col-sm-3 col-form-label text-lg-end">{{ form.length.label }}</label> <label class="col-sm-3 col-form-label text-lg-end">{{ form.length.label }}</label>
@ -92,16 +93,22 @@
<div class="invalid-feedback"></div> <div class="invalid-feedback"></div>
</div> </div>
{% render_field form.tags %} {% render_field form.tags %}
{% if form.custom_fields %}
<div class="field-group">
<div class="row mb-3">
<h5 class="offset-sm-3">Custom Fields</h5>
</div>
{% render_custom_fields form %}
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="card">
<h5 class="card-header text-center">Comments</h5>
<div class="card-body">
{% render_field form.comments %}
</div>
</div>
{% if form.custom_fields %}
<div class="card">
<h5 class="card-header offset-sm-3">Custom Fields</h5>
<div class="card-body">
{% render_custom_fields form %}
</div>
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="row my-3"> <div class="row my-3">

View File

@ -94,7 +94,11 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Airflow</td> <th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>
</tr>
<tr>
<th scope="row">Airflow</th>
<td> <td>
{{ object.get_airflow_display|placeholder }} {{ object.get_airflow_display|placeholder }}
</td> </td>

View File

@ -10,6 +10,7 @@
</div> </div>
{% render_field form.name %} {% render_field form.name %}
{% render_field form.device_role %} {% render_field form.device_role %}
{% render_field form.description %}
{% render_field form.tags %} {% render_field form.tags %}
</div> </div>

View File

@ -27,6 +27,10 @@
<td>Part Number</td> <td>Part Number</td>
<td>{{ object.part_number|placeholder }}</td> <td>{{ object.part_number|placeholder }}</td>
</tr> </tr>
<tr>
<td>Description</td>
<td>{{ object.description|placeholder }}</td>
</tr>
<tr> <tr>
<td>Height (U)</td> <td>Height (U)</td>
<td>{{ object.u_height|floatformat }}</td> <td>{{ object.u_height|floatformat }}</td>

View File

@ -62,6 +62,10 @@
<th scope="row">Module Type</th> <th scope="row">Module Type</th>
<td>{{ object.module_type|linkify }}</td> <td>{{ object.module_type|linkify }}</td>
</tr> </tr>
<tr>
<th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>
</tr>
<tr> <tr>
<th scope="row">Serial Number</th> <th scope="row">Serial Number</th>
<td class="font-monospace">{{ object.serial|placeholder }}</td> <td class="font-monospace">{{ object.serial|placeholder }}</td>

View File

@ -22,6 +22,10 @@
<td>Part Number</td> <td>Part Number</td>
<td>{{ object.part_number|placeholder }}</td> <td>{{ object.part_number|placeholder }}</td>
</tr> </tr>
<tr>
<th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>
</tr>
<tr> <tr>
<td>Weight</td> <td>Weight</td>
<td> <td>

View File

@ -38,6 +38,10 @@
<th scope="row">Status</th> <th scope="row">Status</th>
<td>{% badge object.get_status_display bg_color=object.get_status_color %}</td> <td>{% badge object.get_status_display bg_color=object.get_status_color %}</td>
</tr> </tr>
<tr>
<th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>
</tr>
<tr> <tr>
<th scope="row">Connected Device</th> <th scope="row">Connected Device</th>
<td> <td>

View File

@ -14,26 +14,29 @@
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="col col-md-6"> <div class="col col-md-6">
<div class="card"> <div class="card">
<h5 class="card-header"> <h5 class="card-header">Power Panel</h5>
Power Panel <div class="card-body">
</h5> <table class="table table-hover attr-table">
<div class="card-body"> <tr>
<table class="table table-hover attr-table"> <th scope="row">Site</th>
<tr> <td>{{ object.site|linkify }}</td>
<th scope="row">Site</th> </tr>
<td>{{ object.site|linkify }}</td> <tr>
</tr> <th scope="row">Location</th>
<tr> <td>{{ object.location|linkify|placeholder }}</td>
<th scope="row">Location</th> </tr>
<td>{{ object.location|linkify|placeholder }}</td> <tr>
</tr> <th scope="row">Description</th>
</table> <td>{{ object.description|placeholder }}</td>
</div> </tr>
</div> </table>
{% include 'inc/panels/tags.html' %} </div>
{% plugin_left_page object %}
</div> </div>
{% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_left_page object %}
</div>
<div class="col col-md-6"> <div class="col col-md-6">
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/contacts.html' %} {% include 'inc/panels/contacts.html' %}

View File

@ -78,6 +78,10 @@
<th scope="row">Role</th> <th scope="row">Role</th>
<td>{{ object.role|linkify|placeholder }}</td> <td>{{ object.role|linkify|placeholder }}</td>
</tr> </tr>
<tr>
<th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>
</tr>
<tr> <tr>
<th scope="row">Serial Number</th> <th scope="row">Serial Number</th>
<td class="font-monospace">{{ object.serial|placeholder }}</td> <td class="font-monospace">{{ object.serial|placeholder }}</td>

View File

@ -13,6 +13,7 @@
{% render_field form.name %} {% render_field form.name %}
{% render_field form.status %} {% render_field form.status %}
{% render_field form.role %} {% render_field form.role %}
{% render_field form.description %}
{% render_field form.tags %} {% render_field form.tags %}
</div> </div>

View File

@ -73,6 +73,7 @@
</div> </div>
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-12 col-xl-7"> <div class="col col-12 col-xl-7">

View File

@ -27,11 +27,15 @@
<th scope="row">Master</th> <th scope="row">Master</th>
<td>{{ object.master|linkify }}</td> <td>{{ object.master|linkify }}</td>
</tr> </tr>
<tr>
<th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>
</tr>
</table> </table>
</div> </div>
</div> </div>
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-8"> <div class="col col-md-8">
@ -73,6 +77,7 @@
</div> </div>
{% endif %} {% endif %}
</div> </div>
{% include 'inc/panels/comments.html' %}
{% plugin_right_page object %} {% plugin_right_page object %}
</div> </div>
</div> </div>

View File

@ -17,12 +17,18 @@
</div> </div>
{% render_field vc_form.name %} {% render_field vc_form.name %}
{% render_field vc_form.domain %} {% render_field vc_form.domain %}
{% render_field vc_form.description %}
{% render_field vc_form.master %} {% render_field vc_form.master %}
{% render_field vc_form.tags %} {% render_field vc_form.tags %}
</div> </div>
<div class="field-group my-5">
<h5 class="text-center">Comments</h5>
{% render_field vc_form.comments %}
</div>
{% if vc_form.custom_fields %} {% if vc_form.custom_fields %}
<div class="field-group my-5"> <div class="field-group mb-5">
<div class="row mb-2"> <div class="row mb-2">
<h5 class="offset-sm-3">Custom Fields</h5> <h5 class="offset-sm-3">Custom Fields</h5>
</div> </div>

View File

@ -51,6 +51,7 @@
<div class="col col-md-6"> <div class="col col-md-6">
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_right_page object %} {% plugin_right_page object %}
</div> </div>
</div> </div>

View File

@ -67,6 +67,7 @@
<div class="col col-md-6"> <div class="col col-md-6">
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' with tags=object.tags.all url='ipam:asn_list' %} {% include 'inc/panels/tags.html' with tags=object.tags.all url='ipam:asn_list' %}
{% include 'inc/panels/comments.html' %}
{% plugin_right_page object %} {% plugin_right_page object %}
</div> </div>
</div> </div>

View File

@ -42,6 +42,7 @@
</div> </div>
</div> </div>
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-6"> <div class="col col-md-6">

View File

@ -13,7 +13,7 @@
{% render_field form.tags %} {% render_field form.tags %}
</div> </div>
<div class="field-group my-5"> <div class="field-group mb-5">
<div class="row mb-2"> <div class="row mb-2">
<h5 class="offset-sm-3">Authentication</h5> <h5 class="offset-sm-3">Authentication</h5>
</div> </div>
@ -22,7 +22,7 @@
</div> </div>
{% if not form.instance.pk %} {% if not form.instance.pk %}
<div class="field-group my-5"> <div class="field-group mb-5">
<div class="row mb-2"> <div class="row mb-2">
<h5 class="offset-sm-3">Virtual IP Address</h5> <h5 class="offset-sm-3">Virtual IP Address</h5>
</div> </div>
@ -32,6 +32,13 @@
</div> </div>
{% endif %} {% endif %}
<div class="field-group mb-5">
<div class="row mb-2">
<h5 class="offset-sm-3">Comments</h5>
</div>
{% render_field form.comments %}
</div>
{% if form.custom_fields %} {% if form.custom_fields %}
<div class="row mb-2"> <div class="row mb-2">
<h5 class="offset-sm-3">Custom Fields</h5> <h5 class="offset-sm-3">Custom Fields</h5>

View File

@ -108,6 +108,7 @@
</div> </div>
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-8"> <div class="col col-md-8">

View File

@ -138,6 +138,13 @@
</div> </div>
</div> </div>
<div class="field-group my-5">
<div class="row mb-2">
<h5 class="text-center">Comments</h5>
</div>
{% render_field form.comments %}
</div>
{% if form.custom_fields %} {% if form.custom_fields %}
<div class="field-group my-5"> <div class="field-group my-5">
<div class="row mb-2"> <div class="row mb-2">

View File

@ -70,9 +70,10 @@
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-6"> <div class="col col-md-6">
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% plugin_right_page object %} {% include 'inc/panels/comments.html' %}
{% plugin_right_page object %}
</div> </div>
</div> </div>
<div class="row"> <div class="row">

View File

@ -39,6 +39,7 @@
<div class="col col-md-6"> <div class="col col-md-6">
{% include 'inc/panels/contacts.html' %} {% include 'inc/panels/contacts.html' %}
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_right_page object %} {% plugin_right_page object %}
</div> </div>
</div> </div>

View File

@ -155,6 +155,7 @@
</div> </div>
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_right_page object %} {% plugin_right_page object %}
</div> </div>
</div> </div>

View File

@ -26,6 +26,7 @@
</div> </div>
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-6"> <div class="col col-md-6">

View File

@ -58,9 +58,10 @@
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-6"> <div class="col col-md-6">
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% plugin_right_page object %} {% include 'inc/panels/comments.html' %}
{% plugin_right_page object %}
</div> </div>
</div> </div>
<div class="row mb-3"> <div class="row mb-3">

View File

@ -65,6 +65,13 @@
{% render_field form.tags %} {% render_field form.tags %}
</div> </div>
<div class="field-group my-5">
<div class="row mb-2">
<h5 class="text-center">Comments</h5>
</div>
{% render_field form.comments %}
</div>
{% if form.custom_fields %} {% if form.custom_fields %}
<div class="row mb-2"> <div class="row mb-2">
<h5 class="offset-sm-3">Custom Fields</h5> <h5 class="offset-sm-3">Custom Fields</h5>

View File

@ -52,6 +52,13 @@
{% render_field form.tags %} {% render_field form.tags %}
</div> </div>
<div class="field-group my-5">
<div class="row mb-2">
<h5 class="text-center">Comments</h5>
</div>
{% render_field form.comments %}
</div>
{% if form.custom_fields %} {% if form.custom_fields %}
<div class="row mb-2"> <div class="row mb-2">
<h5 class="offset-sm-3">Custom Fields</h5> <h5 class="offset-sm-3">Custom Fields</h5>

View File

@ -31,12 +31,13 @@
</div> </div>
</div> </div>
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-6"> <div class="col col-md-6">
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% plugin_right_page object %} {% include 'inc/panels/comments.html' %}
</div> {% plugin_right_page object %}
</div>
</div> </div>
<div class="row mb-3"> <div class="row mb-3">
<div class="col col-md-12"> <div class="col col-md-12">

View File

@ -74,9 +74,10 @@
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-6"> <div class="col col-md-6">
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% plugin_right_page object %} {% include 'inc/panels/comments.html' %}
{% plugin_right_page object %}
</div> </div>
</div> </div>
<div class="row"> <div class="row">

View File

@ -55,6 +55,13 @@
{% endwith %} {% endwith %}
</div> </div>
<div class="field-group my-5">
<div class="row mb-2">
<h5 class="text-center">Comments</h5>
</div>
{% render_field form.comments %}
</div>
{% if form.custom_fields %} {% if form.custom_fields %}
<div class="field-group my-5"> <div class="field-group my-5">
<div class="row mb-2"> <div class="row mb-2">

View File

@ -55,6 +55,7 @@
<div class="col col-md-6"> <div class="col col-md-6">
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_right_page object %} {% plugin_right_page object %}
</div> </div>
</div> </div>

View File

@ -63,6 +63,10 @@
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
<tr>
<th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>
</tr>
<tr> <tr>
<th scope="row">Assignments</th> <th scope="row">Assignments</th>
<td>{{ assignment_count }}</td> <td>{{ assignment_count }}</td>

View File

@ -23,6 +23,10 @@
<th scope="row">Status</th> <th scope="row">Status</th>
<td>{% badge object.get_status_display bg_color=object.get_status_color %}</td> <td>{% badge object.get_status_display bg_color=object.get_status_color %}</td>
</tr> </tr>
<tr>
<th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>
</tr>
<tr> <tr>
<th scope="row">Group</th> <th scope="row">Group</th>
<td>{{ object.group|linkify|placeholder }}</td> <td>{{ object.group|linkify|placeholder }}</td>

View File

@ -29,6 +29,10 @@
<th scope="row">Platform</th> <th scope="row">Platform</th>
<td>{{ object.platform|linkify|placeholder }}</td> <td>{{ object.platform|linkify|placeholder }}</td>
</tr> </tr>
<tr>
<th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>
</tr>
<tr> <tr>
<th scope="row">Tenant</th> <th scope="row">Tenant</th>
<td> <td>

View File

@ -39,6 +39,7 @@
</div> </div>
</div> </div>
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-6"> <div class="col col-md-6">

View File

@ -40,6 +40,7 @@
</div> </div>
</div> </div>
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-6"> <div class="col col-md-6">

View File

@ -22,6 +22,12 @@
</div> </div>
</div> </div>
</div> </div>
<div class="field-group my-5">
<div class="row mb-2">
<h5 class="offset-sm-3">Comments</h5>
</div>
{% render_field form.comments %}
</div>
{% if form.custom_fields %} {% if form.custom_fields %}
<div class="field-group my-5"> <div class="field-group my-5">
<div class="row mb-2"> <div class="row mb-2">

View File

@ -85,8 +85,8 @@ class ContactSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = Contact model = Contact
fields = [ fields = [
'id', 'url', 'display', 'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'comments', 'tags', 'id', 'url', 'display', 'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description',
'custom_fields', 'created', 'last_updated', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
] ]

View File

@ -2,7 +2,7 @@ from django import forms
from netbox.forms import NetBoxModelBulkEditForm from netbox.forms import NetBoxModelBulkEditForm
from tenancy.models import * from tenancy.models import *
from utilities.forms import DynamicModelChoiceField from utilities.forms import CommentField, DynamicModelChoiceField, SmallTextarea
__all__ = ( __all__ = (
'ContactBulkEditForm', 'ContactBulkEditForm',
@ -101,9 +101,17 @@ class ContactBulkEditForm(NetBoxModelBulkEditForm):
link = forms.URLField( link = forms.URLField(
required=False required=False
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = Contact model = Contact
fieldsets = ( 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')

View File

@ -79,4 +79,4 @@ class ContactCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = Contact model = Contact
fields = ('name', 'title', 'phone', 'email', 'address', 'link', 'group', 'comments') fields = ('name', 'title', 'phone', 'email', 'address', 'link', 'group', 'description', 'comments')

View File

@ -103,13 +103,13 @@ class ContactForm(NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Contact', ('group', 'name', 'title', 'phone', 'email', 'address', 'link', 'tags')), ('Contact', ('group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'tags')),
) )
class Meta: class Meta:
model = Contact model = Contact
fields = ( fields = (
'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'comments', 'tags', 'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'comments', 'tags',
) )
widgets = { widgets = {
'address': SmallTextarea(attrs={'rows': 3}), 'address': SmallTextarea(attrs={'rows': 3}),

View File

@ -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),
),
]

View File

@ -2,9 +2,8 @@ from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.urls import reverse 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 netbox.models.features import WebhooksMixin
from tenancy.choices import * from tenancy.choices import *
@ -41,7 +40,7 @@ class ContactRole(OrganizationalModel):
return reverse('tenancy:contactrole', args=[self.pk]) return reverse('tenancy:contactrole', args=[self.pk])
class Contact(NetBoxModel): class Contact(PrimaryModel):
""" """
Contact information for a particular object(s) in NetBox. Contact information for a particular object(s) in NetBox.
""" """
@ -73,9 +72,6 @@ class Contact(NetBoxModel):
link = models.URLField( link = models.URLField(
blank=True blank=True
) )
comments = models.TextField(
blank=True
)
clone_fields = ( clone_fields = (
'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'group', 'name', 'title', 'phone', 'email', 'address', 'link',

View File

@ -1,9 +1,8 @@
from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.fields import GenericRelation
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from mptt.models import TreeForeignKey
from netbox.models import NestedGroupModel, NetBoxModel from netbox.models import NestedGroupModel, PrimaryModel
__all__ = ( __all__ = (
'Tenant', 'Tenant',
@ -31,7 +30,7 @@ class TenantGroup(NestedGroupModel):
return reverse('tenancy:tenantgroup', args=[self.pk]) 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 A Tenant represents an organization served by the NetBox owner. This is typically a customer or an internal
department. department.
@ -51,13 +50,6 @@ class Tenant(NetBoxModel):
blank=True, blank=True,
null=True null=True
) )
description = models.CharField(
max_length=200,
blank=True
)
comments = models.TextField(
blank=True
)
# Generic relations # Generic relations
contacts = GenericRelation( contacts = GenericRelation(

View File

@ -65,8 +65,8 @@ class ContactTable(NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Contact model = Contact
fields = ( fields = (
'pk', 'name', 'group', 'title', 'phone', 'email', 'address', 'link', 'comments', 'assignment_count', 'tags', 'pk', 'name', 'group', 'title', 'phone', 'email', 'address', 'link', 'description', 'comments',
'created', 'last_updated', 'assignment_count', 'tags', 'created', 'last_updated',
) )
default_columns = ('pk', 'name', 'group', 'assignment_count', 'title', 'phone', 'email') default_columns = ('pk', 'name', 'group', 'assignment_count', 'title', 'phone', 'email')

View File

@ -58,8 +58,8 @@ class ClusterSerializer(NetBoxModelSerializer):
class Meta: class Meta:
model = Cluster model = Cluster
fields = [ fields = [
'id', 'url', 'display', 'name', 'type', 'group', 'status', 'tenant', 'site', 'comments', 'tags', 'id', 'url', 'display', 'name', 'type', 'group', 'status', 'tenant', 'site', 'description', 'comments',
'custom_fields', 'created', 'last_updated', 'device_count', 'virtualmachine_count', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'virtualmachine_count',
] ]
@ -84,8 +84,8 @@ class VirtualMachineSerializer(NetBoxModelSerializer):
model = VirtualMachine model = VirtualMachine
fields = [ fields = [
'id', 'url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant', 'platform', 'id', 'url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant', 'platform',
'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'comments', 'local_context_data', 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description', 'comments',
'tags', 'custom_fields', 'created', 'last_updated', 'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated',
] ]
validators = [] validators = []

View File

@ -84,6 +84,10 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
'group_id': '$site_group', 'group_id': '$site_group',
} }
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField( comments = CommentField(
widget=SmallTextarea, widget=SmallTextarea,
label='Comments' label='Comments'
@ -91,11 +95,11 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
model = Cluster model = Cluster
fieldsets = ( fieldsets = (
(None, ('type', 'group', 'status', 'tenant',)), (None, ('type', 'group', 'status', 'tenant', 'description')),
('Site', ('region', 'site_group', 'site',)), ('Site', ('region', 'site_group', 'site')),
) )
nullable_fields = ( nullable_fields = (
'group', 'site', 'comments', 'tenant', 'group', 'site', 'tenant', 'description', 'comments',
) )
@ -153,6 +157,10 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
required=False, required=False,
label='Disk (GB)' label='Disk (GB)'
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField( comments = CommentField(
widget=SmallTextarea, widget=SmallTextarea,
label='Comments' label='Comments'
@ -160,11 +168,11 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
model = VirtualMachine model = VirtualMachine
fieldsets = ( fieldsets = (
(None, ('site', 'cluster', 'device', 'status', 'role', 'tenant', 'platform')), (None, ('site', 'cluster', 'device', 'status', 'role', 'tenant', 'platform', 'description')),
('Resources', ('vcpus', 'memory', 'disk')) ('Resources', ('vcpus', 'memory', 'disk'))
) )
nullable_fields = ( nullable_fields = (
'site', 'cluster', 'device', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments', 'site', 'cluster', 'device', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'description', 'comments',
) )

View File

@ -63,7 +63,7 @@ class ClusterCSVForm(NetBoxModelCSVForm):
class Meta: class Meta:
model = Cluster model = Cluster
fields = ('name', 'type', 'group', 'status', 'site', 'comments') fields = ('name', 'type', 'group', 'status', 'site', 'description', 'comments')
class VirtualMachineCSVForm(NetBoxModelCSVForm): class VirtualMachineCSVForm(NetBoxModelCSVForm):
@ -114,7 +114,7 @@ class VirtualMachineCSVForm(NetBoxModelCSVForm):
model = VirtualMachine model = VirtualMachine
fields = ( fields = (
'name', 'status', 'role', 'site', 'cluster', 'device', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'name', 'status', 'role', 'site', 'cluster', 'device', 'tenant', 'platform', 'vcpus', 'memory', 'disk',
'comments', 'description', 'comments',
) )

View File

@ -90,7 +90,7 @@ class ClusterForm(TenancyForm, NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Cluster', ('name', 'type', 'group', 'status', 'tags')), ('Cluster', ('name', 'type', 'group', 'status', 'description', 'tags')),
('Site', ('region', 'site_group', 'site')), ('Site', ('region', 'site_group', 'site')),
('Tenancy', ('tenant_group', 'tenant')), ('Tenancy', ('tenant_group', 'tenant')),
) )
@ -98,7 +98,8 @@ class ClusterForm(TenancyForm, NetBoxModelForm):
class Meta: class Meta:
model = Cluster model = Cluster
fields = ( 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 = { widgets = {
'status': StaticSelect(), 'status': StaticSelect(),
@ -220,9 +221,10 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
required=False, required=False,
label='' label=''
) )
comments = CommentField()
fieldsets = ( fieldsets = (
('Virtual Machine', ('name', 'role', 'status', 'tags')), ('Virtual Machine', ('name', 'role', 'status', 'description', 'tags')),
('Site/Cluster', ('site', 'cluster_group', 'cluster', 'device')), ('Site/Cluster', ('site', 'cluster_group', 'cluster', 'device')),
('Tenancy', ('tenant_group', 'tenant')), ('Tenancy', ('tenant_group', 'tenant')),
('Management', ('platform', 'primary_ip4', 'primary_ip6')), ('Management', ('platform', 'primary_ip4', 'primary_ip6')),
@ -234,7 +236,7 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
model = VirtualMachine model = VirtualMachine
fields = [ fields = [
'name', 'status', 'site', 'cluster_group', 'cluster', 'device', 'role', 'tenant_group', 'tenant', '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', 'local_context_data',
] ]
help_texts = { help_texts = {

View File

@ -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),
),
]

View File

@ -10,7 +10,7 @@ from dcim.models import BaseInterface, Device
from extras.models import ConfigContextModel from extras.models import ConfigContextModel
from extras.querysets import ConfigContextModelQuerySet from extras.querysets import ConfigContextModelQuerySet
from netbox.config import get_config 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.fields import NaturalOrderingField
from utilities.ordering import naturalize_interface from utilities.ordering import naturalize_interface
from utilities.query_functions import CollateAsChar from utilities.query_functions import CollateAsChar
@ -64,7 +64,7 @@ class ClusterGroup(OrganizationalModel):
# Clusters # Clusters
# #
class Cluster(NetBoxModel): class Cluster(PrimaryModel):
""" """
A cluster of VirtualMachines. Each Cluster may optionally be associated with one or more Devices. A cluster of VirtualMachines. Each Cluster may optionally be associated with one or more Devices.
""" """
@ -102,9 +102,6 @@ class Cluster(NetBoxModel):
blank=True, blank=True,
null=True null=True
) )
comments = models.TextField(
blank=True
)
# Generic relations # Generic relations
vlan_groups = GenericRelation( vlan_groups = GenericRelation(
@ -165,7 +162,7 @@ class Cluster(NetBoxModel):
# Virtual machines # Virtual machines
# #
class VirtualMachine(NetBoxModel, ConfigContextModel): class VirtualMachine(PrimaryModel, ConfigContextModel):
""" """
A virtual machine which runs inside a Cluster. A virtual machine which runs inside a Cluster.
""" """
@ -262,9 +259,6 @@ class VirtualMachine(NetBoxModel, ConfigContextModel):
null=True, null=True,
verbose_name='Disk (GB)' verbose_name='Disk (GB)'
) )
comments = models.TextField(
blank=True
)
# Generic relation # Generic relation
contacts = GenericRelation( contacts = GenericRelation(

View File

@ -86,7 +86,7 @@ class ClusterTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Cluster model = Cluster
fields = ( fields = (
'pk', 'id', 'name', 'type', 'group', 'status', 'tenant', 'tenant_group', 'site', 'comments', 'device_count', 'pk', 'id', 'name', 'type', 'group', 'status', 'tenant', 'tenant_group', 'site', 'description', 'comments',
'vm_count', 'contacts', 'tags', 'created', 'last_updated', 'device_count', 'vm_count', 'contacts', 'tags', 'created', 'last_updated',
) )
default_columns = ('pk', 'name', 'type', 'group', 'status', 'tenant', 'site', 'device_count', 'vm_count') default_columns = ('pk', 'name', 'type', 'group', 'status', 'tenant', 'site', 'device_count', 'vm_count')

View File

@ -75,8 +75,8 @@ class VirtualMachineTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable)
model = VirtualMachine model = VirtualMachine
fields = ( fields = (
'pk', 'id', 'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant', 'tenant_group', 'platform', 'pk', 'id', 'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant', 'tenant_group', 'platform',
'vcpus', 'memory', 'disk', 'primary_ip4', 'primary_ip6', 'primary_ip', 'comments', 'contacts', 'tags', 'vcpus', 'memory', 'disk', 'primary_ip4', 'primary_ip6', 'primary_ip', 'description', 'comments',
'created', 'last_updated', 'contacts', 'tags', 'created', 'last_updated',
) )
default_columns = ( default_columns = (
'pk', 'name', 'status', 'site', 'cluster', 'role', 'tenant', 'vcpus', 'memory', 'disk', 'primary_ip', 'pk', 'name', 'status', 'site', 'cluster', 'role', 'tenant', 'vcpus', 'memory', 'disk', 'primary_ip',

View File

@ -42,7 +42,7 @@ class WirelessLANSerializer(NetBoxModelSerializer):
model = WirelessLAN model = WirelessLAN
fields = [ fields = [
'id', 'url', 'display', 'ssid', 'description', 'group', 'vlan', 'tenant', 'auth_type', 'auth_cipher', '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 model = WirelessLink
fields = [ fields = [
'id', 'url', 'display', 'interface_a', 'interface_b', 'ssid', 'status', 'tenant', 'auth_type', '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',
] ]

View File

@ -4,7 +4,7 @@ from dcim.choices import LinkStatusChoices
from ipam.models import VLAN from ipam.models import VLAN
from netbox.forms import NetBoxModelBulkEditForm from netbox.forms import NetBoxModelBulkEditForm
from tenancy.models import Tenant 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.choices import *
from wireless.constants import SSID_MAX_LENGTH from wireless.constants import SSID_MAX_LENGTH
from wireless.models import * from wireless.models import *
@ -52,9 +52,6 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
description = forms.CharField(
required=False
)
auth_type = forms.ChoiceField( auth_type = forms.ChoiceField(
choices=add_blank_choice(WirelessAuthTypeChoices), choices=add_blank_choice(WirelessAuthTypeChoices),
required=False required=False
@ -67,6 +64,14 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
required=False, required=False,
label='Pre-shared key' label='Pre-shared key'
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = WirelessLAN model = WirelessLAN
fieldsets = ( fieldsets = (
@ -74,7 +79,7 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')), ('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')),
) )
nullable_fields = ( 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(), queryset=Tenant.objects.all(),
required=False required=False
) )
description = forms.CharField(
required=False
)
auth_type = forms.ChoiceField( auth_type = forms.ChoiceField(
choices=add_blank_choice(WirelessAuthTypeChoices), choices=add_blank_choice(WirelessAuthTypeChoices),
required=False required=False
@ -107,6 +109,14 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
required=False, required=False,
label='Pre-shared key' label='Pre-shared key'
) )
description = forms.CharField(
max_length=200,
required=False
)
comments = CommentField(
widget=SmallTextarea,
label='Comments'
)
model = WirelessLink model = WirelessLink
fieldsets = ( fieldsets = (
@ -114,5 +124,5 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')) ('Authentication', ('auth_type', 'auth_cipher', 'auth_psk'))
) )
nullable_fields = ( nullable_fields = (
'ssid', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'ssid', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'comments',
) )

Some files were not shown because too many files have changed in this diff Show More