mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-25 08:46:10 -06:00
Standardize description & comments fields on primary models
This commit is contained in:
parent
e2f5ee661a
commit
faf485d4d4
@ -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
|
||||||
|
|
||||||
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
@ -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(
|
||||||
|
@ -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')
|
||||||
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
@ -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.
|
||||||
"""
|
"""
|
||||||
|
@ -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).
|
||||||
"""
|
"""
|
||||||
|
@ -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',
|
||||||
|
@ -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.
|
||||||
"""
|
"""
|
||||||
|
@ -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(
|
||||||
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
@ -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',
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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.
|
||||||
|
@ -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',
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
@ -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',
|
||||||
|
@ -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(
|
||||||
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
@ -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(
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 4.1.2 on 2022-11-03 18:24
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wireless', '0006_unique_constraints'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='wirelesslan',
|
||||||
|
name='comments',
|
||||||
|
field=models.TextField(blank=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='wirelesslink',
|
||||||
|
name='comments',
|
||||||
|
field=models.TextField(blank=True),
|
||||||
|
),
|
||||||
|
]
|
@ -2,11 +2,11 @@ from django.apps import apps
|
|||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from mptt.models import MPTTModel, TreeForeignKey
|
from mptt.models import MPTTModel
|
||||||
|
|
||||||
from dcim.choices import LinkStatusChoices
|
from dcim.choices import LinkStatusChoices
|
||||||
from dcim.constants import WIRELESS_IFACE_TYPES
|
from dcim.constants import WIRELESS_IFACE_TYPES
|
||||||
from netbox.models import NestedGroupModel, NetBoxModel
|
from netbox.models import NestedGroupModel, PrimaryModel
|
||||||
from .choices import *
|
from .choices import *
|
||||||
from .constants import *
|
from .constants import *
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ class WirelessLANGroup(NestedGroupModel):
|
|||||||
return reverse('wireless:wirelesslangroup', args=[self.pk])
|
return reverse('wireless:wirelesslangroup', args=[self.pk])
|
||||||
|
|
||||||
|
|
||||||
class WirelessLAN(WirelessAuthenticationBase, NetBoxModel):
|
class WirelessLAN(WirelessAuthenticationBase, PrimaryModel):
|
||||||
"""
|
"""
|
||||||
A wireless network formed among an arbitrary number of access point and clients.
|
A wireless network formed among an arbitrary number of access point and clients.
|
||||||
"""
|
"""
|
||||||
@ -98,10 +98,6 @@ class WirelessLAN(WirelessAuthenticationBase, NetBoxModel):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
description = models.CharField(
|
|
||||||
max_length=200,
|
|
||||||
blank=True
|
|
||||||
)
|
|
||||||
|
|
||||||
clone_fields = ('ssid', 'group', 'tenant', 'description')
|
clone_fields = ('ssid', 'group', 'tenant', 'description')
|
||||||
|
|
||||||
@ -122,7 +118,7 @@ def get_wireless_interface_types():
|
|||||||
return {'type__in': WIRELESS_IFACE_TYPES}
|
return {'type__in': WIRELESS_IFACE_TYPES}
|
||||||
|
|
||||||
|
|
||||||
class WirelessLink(WirelessAuthenticationBase, NetBoxModel):
|
class WirelessLink(WirelessAuthenticationBase, PrimaryModel):
|
||||||
"""
|
"""
|
||||||
A point-to-point connection between two wireless Interfaces.
|
A point-to-point connection between two wireless Interfaces.
|
||||||
"""
|
"""
|
||||||
@ -157,10 +153,6 @@ class WirelessLink(WirelessAuthenticationBase, NetBoxModel):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
description = models.CharField(
|
|
||||||
max_length=200,
|
|
||||||
blank=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# Cache the associated device for the A and B interfaces. This enables filtering of WirelessLinks by their
|
# Cache the associated device for the A and B interfaces. This enables filtering of WirelessLinks by their
|
||||||
# associated Devices.
|
# associated Devices.
|
||||||
|
Loading…
Reference in New Issue
Block a user