mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 20:12:00 -06:00
Renamed CreatedUpdatedModel to ChangeLoggedModel and applied it to all primary and organizational models
This commit is contained in:
parent
81258ea35b
commit
b556d2d626
45
netbox/circuits/migrations/0012_change_logging.py
Normal file
45
netbox/circuits/migrations/0012_change_logging.py
Normal file
@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.12 on 2018-06-13 17:14
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('circuits', '0011_tags'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='circuittype',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='circuittype',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='circuit',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='circuit',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='provider',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='provider',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
]
|
@ -9,12 +9,12 @@ from taggit.managers import TaggableManager
|
||||
from dcim.constants import STATUS_CLASSES
|
||||
from dcim.fields import ASNField
|
||||
from extras.models import CustomFieldModel
|
||||
from utilities.models import CreatedUpdatedModel
|
||||
from utilities.models import ChangeLoggedModel
|
||||
from .constants import CIRCUIT_STATUS_ACTIVE, CIRCUIT_STATUS_CHOICES, TERM_SIDE_CHOICES
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Provider(CreatedUpdatedModel, CustomFieldModel):
|
||||
class Provider(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
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.
|
||||
@ -59,9 +59,8 @@ class Provider(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
tags = TaggableManager()
|
||||
|
||||
csv_headers = ['name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments']
|
||||
|
||||
serializer = 'circuits.api.serializers.ProviderSerializer'
|
||||
csv_headers = ['name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments']
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
@ -86,7 +85,7 @@ class Provider(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class CircuitType(models.Model):
|
||||
class CircuitType(ChangeLoggedModel):
|
||||
"""
|
||||
Circuits can be organized by their functional role. For example, a user might wish to define CircuitTypes named
|
||||
"Long Haul," "Metro," or "Out-of-Band".
|
||||
@ -99,6 +98,7 @@ class CircuitType(models.Model):
|
||||
unique=True
|
||||
)
|
||||
|
||||
serializer = 'circuits.api.serializers.CircuitTypeSerializer'
|
||||
csv_headers = ['name', 'slug']
|
||||
|
||||
class Meta:
|
||||
@ -118,7 +118,7 @@ class CircuitType(models.Model):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Circuit(CreatedUpdatedModel, CustomFieldModel):
|
||||
class Circuit(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
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. A Circuit may be terminated to a specific device
|
||||
@ -173,12 +173,11 @@ class Circuit(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
tags = TaggableManager()
|
||||
|
||||
serializer = 'circuits.api.serializers.CircuitSerializer'
|
||||
csv_headers = [
|
||||
'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'commit_rate', 'description', 'comments',
|
||||
]
|
||||
|
||||
serializer = 'circuits.api.serializers.CircuitSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['provider', 'cid']
|
||||
unique_together = ['provider', 'cid']
|
||||
|
135
netbox/dcim/migrations/0059_change_logging.py
Normal file
135
netbox/dcim/migrations/0059_change_logging.py
Normal file
@ -0,0 +1,135 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.12 on 2018-06-13 17:14
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dcim', '0058_relax_rack_naming_constraints'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='devicerole',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='devicerole',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='devicetype',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='devicetype',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='manufacturer',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='manufacturer',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='platform',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='platform',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rackgroup',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rackgroup',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rackreservation',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rackrole',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rackrole',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='region',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='region',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='virtualchassis',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='virtualchassis',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='device',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='device',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rack',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rack',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rackreservation',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='site',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='site',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
]
|
@ -1,27 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.12 on 2018-05-30 17:30
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dcim', '0058_relax_rack_naming_constraints'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='devicetype',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, default=django.utils.timezone.now),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='devicetype',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True),
|
||||
),
|
||||
]
|
@ -22,7 +22,7 @@ from extras.models import CustomFieldModel
|
||||
from extras.rpc import RPC_CLIENTS
|
||||
from utilities.fields import ColorField, NullableCharField
|
||||
from utilities.managers import NaturalOrderByManager
|
||||
from utilities.models import CreatedUpdatedModel
|
||||
from utilities.models import ChangeLoggedModel
|
||||
from .constants import *
|
||||
from .fields import ASNField, MACAddressField
|
||||
from .querysets import InterfaceQuerySet
|
||||
@ -33,7 +33,7 @@ from .querysets import InterfaceQuerySet
|
||||
#
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Region(MPTTModel):
|
||||
class Region(ChangeLoggedModel, MPTTModel):
|
||||
"""
|
||||
Sites can be grouped within geographic Regions.
|
||||
"""
|
||||
@ -53,6 +53,7 @@ class Region(MPTTModel):
|
||||
unique=True
|
||||
)
|
||||
|
||||
serializer = 'dcim.api.serializers.RegionSerializer'
|
||||
csv_headers = ['name', 'slug', 'parent']
|
||||
|
||||
class MPTTMeta:
|
||||
@ -81,7 +82,7 @@ class SiteManager(NaturalOrderByManager):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Site(CreatedUpdatedModel, CustomFieldModel):
|
||||
class Site(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
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).
|
||||
@ -162,13 +163,12 @@ class Site(CreatedUpdatedModel, CustomFieldModel):
|
||||
objects = SiteManager()
|
||||
tags = TaggableManager()
|
||||
|
||||
serializer = 'dcim.api.serializers.SiteSerializer'
|
||||
csv_headers = [
|
||||
'name', 'slug', 'status', 'region', 'tenant', 'facility', 'asn', 'time_zone', 'description', 'physical_address',
|
||||
'shipping_address', 'contact_name', 'contact_phone', 'contact_email', 'comments',
|
||||
]
|
||||
|
||||
serializer = 'dcim.api.serializers.SiteSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
|
||||
@ -231,7 +231,7 @@ class Site(CreatedUpdatedModel, CustomFieldModel):
|
||||
#
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class RackGroup(models.Model):
|
||||
class RackGroup(ChangeLoggedModel):
|
||||
"""
|
||||
Racks can be grouped as subsets within a Site. The scope of a group will depend on how Sites are defined. For
|
||||
example, if a Site spans a corporate campus, a RackGroup might be defined to represent each building within that
|
||||
@ -247,9 +247,8 @@ class RackGroup(models.Model):
|
||||
related_name='rack_groups'
|
||||
)
|
||||
|
||||
csv_headers = ['site', 'name', 'slug']
|
||||
|
||||
serializer = 'dcim.api.serializers.RackGroupSerializer'
|
||||
csv_headers = ['site', 'name', 'slug']
|
||||
|
||||
class Meta:
|
||||
ordering = ['site', 'name']
|
||||
@ -273,7 +272,7 @@ class RackGroup(models.Model):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class RackRole(models.Model):
|
||||
class RackRole(ChangeLoggedModel):
|
||||
"""
|
||||
Racks can be organized by functional role, similar to Devices.
|
||||
"""
|
||||
@ -286,6 +285,7 @@ class RackRole(models.Model):
|
||||
)
|
||||
color = ColorField()
|
||||
|
||||
serializer = 'dcim.api.serializers.RackRoleSerializer'
|
||||
csv_headers = ['name', 'slug', 'color']
|
||||
|
||||
class Meta:
|
||||
@ -310,7 +310,7 @@ class RackManager(NaturalOrderByManager):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Rack(CreatedUpdatedModel, CustomFieldModel):
|
||||
class Rack(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
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 RackGroup.
|
||||
@ -392,13 +392,12 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
|
||||
objects = RackManager()
|
||||
tags = TaggableManager()
|
||||
|
||||
serializer = 'dcim.api.serializers.RackSerializer'
|
||||
csv_headers = [
|
||||
'site', 'group_name', 'name', 'facility_id', 'tenant', 'role', 'type', 'serial', 'width', 'u_height',
|
||||
'desc_units', 'comments',
|
||||
]
|
||||
|
||||
serializer = 'dcim.api.serializers.RackSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['site', 'group', 'name']
|
||||
unique_together = [
|
||||
@ -570,7 +569,7 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class RackReservation(models.Model):
|
||||
class RackReservation(ChangeLoggedModel):
|
||||
"""
|
||||
One or more reserved units within a Rack.
|
||||
"""
|
||||
@ -582,9 +581,6 @@ class RackReservation(models.Model):
|
||||
units = ArrayField(
|
||||
base_field=models.PositiveSmallIntegerField()
|
||||
)
|
||||
created = models.DateTimeField(
|
||||
auto_now_add=True
|
||||
)
|
||||
tenant = models.ForeignKey(
|
||||
to='tenancy.Tenant',
|
||||
on_delete=models.PROTECT,
|
||||
@ -600,6 +596,8 @@ class RackReservation(models.Model):
|
||||
max_length=100
|
||||
)
|
||||
|
||||
serializer = 'dcim.api.serializers.RackReservationSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['created']
|
||||
|
||||
@ -647,7 +645,7 @@ class RackReservation(models.Model):
|
||||
#
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Manufacturer(models.Model):
|
||||
class Manufacturer(ChangeLoggedModel):
|
||||
"""
|
||||
A Manufacturer represents a company which produces hardware devices; for example, Juniper or Dell.
|
||||
"""
|
||||
@ -659,6 +657,7 @@ class Manufacturer(models.Model):
|
||||
unique=True
|
||||
)
|
||||
|
||||
serializer = 'dcim.api.serializers.ManufacturerSerializer'
|
||||
csv_headers = ['name', 'slug']
|
||||
|
||||
class Meta:
|
||||
@ -678,7 +677,7 @@ class Manufacturer(models.Model):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class DeviceType(CreatedUpdatedModel, CustomFieldModel):
|
||||
class DeviceType(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
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).
|
||||
@ -753,6 +752,7 @@ class DeviceType(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
tags = TaggableManager()
|
||||
|
||||
serializer = 'dcim.api.serializers.DeviceTypeSerializer'
|
||||
csv_headers = [
|
||||
'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'is_console_server',
|
||||
'is_pdu', 'is_network_device', 'subdevice_role', 'interface_ordering', 'comments',
|
||||
@ -998,7 +998,7 @@ class DeviceBayTemplate(models.Model):
|
||||
#
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class DeviceRole(models.Model):
|
||||
class DeviceRole(ChangeLoggedModel):
|
||||
"""
|
||||
Devices are organized by functional role; for example, "Core Switch" or "File Server". Each DeviceRole is assigned a
|
||||
color to be used when displaying rack elevations. The vm_role field determines whether the role is applicable to
|
||||
@ -1018,6 +1018,7 @@ class DeviceRole(models.Model):
|
||||
help_text='Virtual machines may be assigned to this role'
|
||||
)
|
||||
|
||||
serializer = 'dcim.api.serializers.DeviceRoleSerializer'
|
||||
csv_headers = ['name', 'slug', 'color', 'vm_role']
|
||||
|
||||
class Meta:
|
||||
@ -1039,7 +1040,7 @@ class DeviceRole(models.Model):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Platform(models.Model):
|
||||
class Platform(ChangeLoggedModel):
|
||||
"""
|
||||
Platform refers to the software or firmware running on a Device. For example, "Cisco IOS-XR" or "Juniper Junos".
|
||||
NetBox uses Platforms to determine how to interact with devices when pulling inventory data or other information by
|
||||
@ -1073,6 +1074,7 @@ class Platform(models.Model):
|
||||
verbose_name='Legacy RPC client'
|
||||
)
|
||||
|
||||
serializer = 'dcim.api.serializers.PlatformSerializer'
|
||||
csv_headers = ['name', 'slug', 'manufacturer', 'napalm_driver']
|
||||
|
||||
class Meta:
|
||||
@ -1098,7 +1100,7 @@ class DeviceManager(NaturalOrderByManager):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Device(CreatedUpdatedModel, CustomFieldModel):
|
||||
class Device(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
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.
|
||||
@ -1238,13 +1240,12 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
|
||||
objects = DeviceManager()
|
||||
tags = TaggableManager()
|
||||
|
||||
serializer = 'dcim.api.serializers.DeviceSerializer'
|
||||
csv_headers = [
|
||||
'name', 'device_role', 'tenant', 'manufacturer', 'model_name', 'platform', 'serial', 'asset_tag', 'status',
|
||||
'site', 'rack_group', 'rack_name', 'position', 'face', 'comments',
|
||||
]
|
||||
|
||||
serializer = 'dcim.api.serializers.DeviceSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
unique_together = [
|
||||
@ -2098,7 +2099,7 @@ class InventoryItem(models.Model):
|
||||
#
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class VirtualChassis(models.Model):
|
||||
class VirtualChassis(ChangeLoggedModel):
|
||||
"""
|
||||
A collection of Devices which operate with a shared control plane (e.g. a switch stack).
|
||||
"""
|
||||
@ -2112,6 +2113,8 @@ class VirtualChassis(models.Model):
|
||||
blank=True
|
||||
)
|
||||
|
||||
serializer = 'dcim.api.serializers.VirtualChassisSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['master']
|
||||
verbose_name_plural = 'virtual chassis'
|
||||
|
105
netbox/ipam/migrations/0023_change_logging.py
Normal file
105
netbox/ipam/migrations/0023_change_logging.py
Normal file
@ -0,0 +1,105 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.12 on 2018-06-13 17:14
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('ipam', '0022_tags'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='rir',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rir',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='role',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='role',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='vlangroup',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='vlangroup',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='aggregate',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='aggregate',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='ipaddress',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='ipaddress',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='prefix',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='prefix',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='service',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='service',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vlan',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vlan',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vrf',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vrf',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
]
|
@ -14,14 +14,14 @@ from taggit.managers import TaggableManager
|
||||
|
||||
from dcim.models import Interface
|
||||
from extras.models import CustomFieldModel
|
||||
from utilities.models import CreatedUpdatedModel
|
||||
from utilities.models import ChangeLoggedModel
|
||||
from .constants import *
|
||||
from .fields import IPNetworkField, IPAddressField
|
||||
from .querysets import PrefixQuerySet
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class VRF(CreatedUpdatedModel, CustomFieldModel):
|
||||
class VRF(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
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
|
||||
@ -59,9 +59,8 @@ class VRF(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
tags = TaggableManager()
|
||||
|
||||
csv_headers = ['name', 'rd', 'tenant', 'enforce_unique', 'description']
|
||||
|
||||
serializer = 'ipam.api.serializers.VRFSerializer'
|
||||
csv_headers = ['name', 'rd', 'tenant', 'enforce_unique', 'description']
|
||||
|
||||
class Meta:
|
||||
ordering = ['name', 'rd']
|
||||
@ -91,7 +90,7 @@ class VRF(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class RIR(models.Model):
|
||||
class RIR(ChangeLoggedModel):
|
||||
"""
|
||||
A Regional Internet Registry (RIR) is responsible for the allocation of a large portion of the global IP address
|
||||
space. This can be an organization like ARIN or RIPE, or a governing standard such as RFC 1918.
|
||||
@ -109,6 +108,7 @@ class RIR(models.Model):
|
||||
help_text='IP space managed by this RIR is considered private'
|
||||
)
|
||||
|
||||
serializer = 'ipam.api.serializers.RIRSerializer'
|
||||
csv_headers = ['name', 'slug', 'is_private']
|
||||
|
||||
class Meta:
|
||||
@ -131,7 +131,7 @@ class RIR(models.Model):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Aggregate(CreatedUpdatedModel, CustomFieldModel):
|
||||
class Aggregate(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
An aggregate exists at the root level of the IP address space hierarchy in NetBox. Aggregates are used to organize
|
||||
the hierarchy and track the overall utilization of available address space. Each Aggregate is assigned to a RIR.
|
||||
@ -162,9 +162,8 @@ class Aggregate(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
tags = TaggableManager()
|
||||
|
||||
csv_headers = ['prefix', 'rir', 'date_added', 'description']
|
||||
|
||||
serializer = 'ipam.api.serializers.AggregateSerializer'
|
||||
csv_headers = ['prefix', 'rir', 'date_added', 'description']
|
||||
|
||||
class Meta:
|
||||
ordering = ['family', 'prefix']
|
||||
@ -228,7 +227,7 @@ class Aggregate(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Role(models.Model):
|
||||
class Role(ChangeLoggedModel):
|
||||
"""
|
||||
A Role represents the functional role of a Prefix or VLAN; for example, "Customer," "Infrastructure," or
|
||||
"Management."
|
||||
@ -244,6 +243,7 @@ class Role(models.Model):
|
||||
default=1000
|
||||
)
|
||||
|
||||
serializer = 'ipam.api.serializers.RoleSerializer'
|
||||
csv_headers = ['name', 'slug', 'weight']
|
||||
|
||||
class Meta:
|
||||
@ -261,7 +261,7 @@ class Role(models.Model):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Prefix(CreatedUpdatedModel, CustomFieldModel):
|
||||
class Prefix(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
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
|
||||
@ -336,12 +336,11 @@ class Prefix(CreatedUpdatedModel, CustomFieldModel):
|
||||
objects = PrefixQuerySet.as_manager()
|
||||
tags = TaggableManager()
|
||||
|
||||
serializer = 'ipam.api.serializers.PrefixSerializer'
|
||||
csv_headers = [
|
||||
'prefix', 'vrf', 'tenant', 'site', 'vlan_group', 'vlan_vid', 'status', 'role', 'is_pool', 'description',
|
||||
]
|
||||
|
||||
serializer = 'ipam.api.serializers.PrefixSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['vrf', 'family', 'prefix']
|
||||
verbose_name_plural = 'prefixes'
|
||||
@ -503,7 +502,7 @@ class IPAddressManager(models.Manager):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class IPAddress(CreatedUpdatedModel, CustomFieldModel):
|
||||
class IPAddress(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
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
|
||||
@ -578,13 +577,12 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
|
||||
objects = IPAddressManager()
|
||||
tags = TaggableManager()
|
||||
|
||||
serializer = 'ipam.api.serializers.IPAddressSerializer'
|
||||
csv_headers = [
|
||||
'address', 'vrf', 'tenant', 'status', 'role', 'device', 'virtual_machine', 'interface_name', 'is_primary',
|
||||
'description',
|
||||
]
|
||||
|
||||
serializer = 'ipam.api.serializers.IPAddressSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['family', 'address']
|
||||
verbose_name = 'IP address'
|
||||
@ -663,7 +661,7 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class VLANGroup(models.Model):
|
||||
class VLANGroup(ChangeLoggedModel):
|
||||
"""
|
||||
A VLAN group is an arbitrary collection of VLANs within which VLAN IDs and names must be unique.
|
||||
"""
|
||||
@ -679,9 +677,8 @@ class VLANGroup(models.Model):
|
||||
null=True
|
||||
)
|
||||
|
||||
csv_headers = ['name', 'slug', 'site']
|
||||
|
||||
serializer = 'ipam.api.serializers.VLANGroupSerializer'
|
||||
csv_headers = ['name', 'slug', 'site']
|
||||
|
||||
class Meta:
|
||||
ordering = ['site', 'name']
|
||||
@ -717,7 +714,7 @@ class VLANGroup(models.Model):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class VLAN(CreatedUpdatedModel, CustomFieldModel):
|
||||
class VLAN(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
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,
|
||||
@ -778,9 +775,8 @@ class VLAN(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
tags = TaggableManager()
|
||||
|
||||
csv_headers = ['site', 'group_name', 'vid', 'name', 'tenant', 'status', 'role', 'description']
|
||||
|
||||
serializer = 'ipam.api.serializers.VLANSerializer'
|
||||
csv_headers = ['site', 'group_name', 'vid', 'name', 'tenant', 'status', 'role', 'description']
|
||||
|
||||
class Meta:
|
||||
ordering = ['site', 'group', 'vid']
|
||||
@ -835,7 +831,7 @@ class VLAN(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Service(CreatedUpdatedModel):
|
||||
class Service(ChangeLoggedModel):
|
||||
"""
|
||||
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.
|
||||
|
35
netbox/secrets/migrations/0005_change_logging.py
Normal file
35
netbox/secrets/migrations/0005_change_logging.py
Normal file
@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.12 on 2018-06-13 17:29
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('secrets', '0004_tags'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='secretrole',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='secretrole',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='secret',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='secret',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
]
|
@ -14,7 +14,7 @@ from django.urls import reverse
|
||||
from django.utils.encoding import force_bytes, python_2_unicode_compatible
|
||||
from taggit.managers import TaggableManager
|
||||
|
||||
from utilities.models import CreatedUpdatedModel
|
||||
from utilities.models import ChangeLoggedModel
|
||||
from .exceptions import InvalidKey
|
||||
from .hashers import SecretValidationHasher
|
||||
from .querysets import UserKeyQuerySet
|
||||
@ -48,12 +48,18 @@ def decrypt_master_key(master_key_cipher, private_key):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class UserKey(CreatedUpdatedModel):
|
||||
class UserKey(models.Model):
|
||||
"""
|
||||
A UserKey stores a user's personal RSA (public) encryption key, which is used to generate their unique encrypted
|
||||
copy of the master encryption key. The encrypted instance of the master key can be decrypted only with the user's
|
||||
matching (private) decryption key.
|
||||
"""
|
||||
created = models.DateField(
|
||||
auto_now_add=True
|
||||
)
|
||||
last_updated = models.DateTimeField(
|
||||
auto_now=True
|
||||
)
|
||||
user = models.OneToOneField(
|
||||
to=User,
|
||||
on_delete=models.CASCADE,
|
||||
@ -251,7 +257,7 @@ class SessionKey(models.Model):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class SecretRole(models.Model):
|
||||
class SecretRole(ChangeLoggedModel):
|
||||
"""
|
||||
A SecretRole represents an arbitrary functional classification of Secrets. For example, a user might define roles
|
||||
such as "Login Credentials" or "SNMP Communities."
|
||||
@ -277,6 +283,7 @@ class SecretRole(models.Model):
|
||||
blank=True
|
||||
)
|
||||
|
||||
serializer = 'ipam.api.secrets.SecretSerializer'
|
||||
csv_headers = ['name', 'slug']
|
||||
|
||||
class Meta:
|
||||
@ -304,7 +311,7 @@ class SecretRole(models.Model):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Secret(CreatedUpdatedModel):
|
||||
class Secret(ChangeLoggedModel):
|
||||
"""
|
||||
A Secret stores an AES256-encrypted copy of sensitive data, such as passwords or secret keys. An irreversible
|
||||
SHA-256 hash is stored along with the ciphertext for validation upon decryption. Each Secret is assigned to a
|
||||
@ -340,6 +347,7 @@ class Secret(CreatedUpdatedModel):
|
||||
tags = TaggableManager()
|
||||
|
||||
plaintext = None
|
||||
serializer = 'ipam.api.secrets.SecretSerializer'
|
||||
csv_headers = ['device', 'role', 'name', 'plaintext']
|
||||
|
||||
class Meta:
|
||||
|
35
netbox/tenancy/migrations/0005_change_logging.py
Normal file
35
netbox/tenancy/migrations/0005_change_logging.py
Normal file
@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.12 on 2018-06-13 17:14
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tenancy', '0004_tags'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='tenantgroup',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='tenantgroup',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='tenant',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='tenant',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
]
|
@ -7,11 +7,11 @@ from django.utils.encoding import python_2_unicode_compatible
|
||||
from taggit.managers import TaggableManager
|
||||
|
||||
from extras.models import CustomFieldModel
|
||||
from utilities.models import CreatedUpdatedModel
|
||||
from utilities.models import ChangeLoggedModel
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class TenantGroup(models.Model):
|
||||
class TenantGroup(ChangeLoggedModel):
|
||||
"""
|
||||
An arbitrary collection of Tenants.
|
||||
"""
|
||||
@ -23,9 +23,8 @@ class TenantGroup(models.Model):
|
||||
unique=True
|
||||
)
|
||||
|
||||
csv_headers = ['name', 'slug']
|
||||
|
||||
serializer = 'tenancy.api.serializers.TenantGroupSerializer'
|
||||
csv_headers = ['name', 'slug']
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
@ -44,7 +43,7 @@ class TenantGroup(models.Model):
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Tenant(CreatedUpdatedModel, CustomFieldModel):
|
||||
class Tenant(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
A Tenant represents an organization served by the NetBox owner. This is typically a customer or an internal
|
||||
department.
|
||||
@ -79,9 +78,8 @@ class Tenant(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
tags = TaggableManager()
|
||||
|
||||
csv_headers = ['name', 'slug', 'group', 'description', 'comments']
|
||||
|
||||
serializer = 'tenancy.api.serializers.TenantSerializer'
|
||||
csv_headers = ['name', 'slug', 'group', 'description', 'comments']
|
||||
|
||||
class Meta:
|
||||
ordering = ['group', 'name']
|
||||
|
@ -3,9 +3,21 @@ from __future__ import unicode_literals
|
||||
from django.db import models
|
||||
|
||||
|
||||
class CreatedUpdatedModel(models.Model):
|
||||
created = models.DateField(auto_now_add=True)
|
||||
last_updated = models.DateTimeField(auto_now=True)
|
||||
class ChangeLoggedModel(models.Model):
|
||||
"""
|
||||
An abstract model which adds fields to store the creation and last-updated times for an object. Both fields can be
|
||||
null to facilitate adding these fields to existing instances via a database migration.
|
||||
"""
|
||||
created = models.DateField(
|
||||
auto_now_add=True,
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
last_updated = models.DateTimeField(
|
||||
auto_now=True,
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
55
netbox/virtualization/migrations/0007_change_logging.py
Normal file
55
netbox/virtualization/migrations/0007_change_logging.py
Normal file
@ -0,0 +1,55 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.12 on 2018-06-13 17:14
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('virtualization', '0006_tags'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='clustergroup',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='clustergroup',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='clustertype',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='clustertype',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cluster',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cluster',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='virtualmachine',
|
||||
name='created',
|
||||
field=models.DateField(auto_now_add=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='virtualmachine',
|
||||
name='last_updated',
|
||||
field=models.DateTimeField(auto_now=True, null=True),
|
||||
),
|
||||
]
|
@ -10,7 +10,7 @@ from taggit.managers import TaggableManager
|
||||
|
||||
from dcim.models import Device
|
||||
from extras.models import CustomFieldModel
|
||||
from utilities.models import CreatedUpdatedModel
|
||||
from utilities.models import ChangeLoggedModel
|
||||
from .constants import DEVICE_STATUS_ACTIVE, VM_STATUS_CHOICES, VM_STATUS_CLASSES
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ from .constants import DEVICE_STATUS_ACTIVE, VM_STATUS_CHOICES, VM_STATUS_CLASSE
|
||||
#
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class ClusterType(models.Model):
|
||||
class ClusterType(ChangeLoggedModel):
|
||||
"""
|
||||
A type of Cluster.
|
||||
"""
|
||||
@ -31,6 +31,7 @@ class ClusterType(models.Model):
|
||||
unique=True
|
||||
)
|
||||
|
||||
serializer = 'virtualization.api.serializers.ClusterTypeSerializer'
|
||||
csv_headers = ['name', 'slug']
|
||||
|
||||
class Meta:
|
||||
@ -54,7 +55,7 @@ class ClusterType(models.Model):
|
||||
#
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class ClusterGroup(models.Model):
|
||||
class ClusterGroup(ChangeLoggedModel):
|
||||
"""
|
||||
An organizational group of Clusters.
|
||||
"""
|
||||
@ -66,9 +67,8 @@ class ClusterGroup(models.Model):
|
||||
unique=True
|
||||
)
|
||||
|
||||
csv_headers = ['name', 'slug']
|
||||
|
||||
serializer = 'virtualization.api.serializers.ClusterGroupSerializer'
|
||||
csv_headers = ['name', 'slug']
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
@ -91,7 +91,7 @@ class ClusterGroup(models.Model):
|
||||
#
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Cluster(CreatedUpdatedModel, CustomFieldModel):
|
||||
class Cluster(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
A cluster of VirtualMachines. Each Cluster may optionally be associated with one or more Devices.
|
||||
"""
|
||||
@ -129,9 +129,8 @@ class Cluster(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
tags = TaggableManager()
|
||||
|
||||
csv_headers = ['name', 'type', 'group', 'site', 'comments']
|
||||
|
||||
serializer = 'virtualization.api.serializers.ClusterSerializer'
|
||||
csv_headers = ['name', 'type', 'group', 'site', 'comments']
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
@ -169,7 +168,7 @@ class Cluster(CreatedUpdatedModel, CustomFieldModel):
|
||||
#
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
|
||||
class VirtualMachine(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
A virtual machine which runs inside a Cluster.
|
||||
"""
|
||||
@ -251,12 +250,11 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
tags = TaggableManager()
|
||||
|
||||
serializer = 'virtualization.api.serializers.VirtualMachineSerializer'
|
||||
csv_headers = [
|
||||
'name', 'status', 'role', 'cluster', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments',
|
||||
]
|
||||
|
||||
serializer = 'virtualization.api.serializers.VirtualMachineSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user