Implement RestrictedQuerySet as a manager

This commit is contained in:
Jeremy Stretch 2020-05-29 16:27:36 -04:00
parent 5b6a6fb63e
commit e23b2c4c4f
16 changed files with 118 additions and 21 deletions

View File

@ -8,6 +8,7 @@ from dcim.fields import ASNField
from dcim.models import CableTermination from dcim.models import CableTermination
from extras.models import CustomFieldModel, ObjectChange, TaggedItem from extras.models import CustomFieldModel, ObjectChange, TaggedItem
from extras.utils import extras_features from extras.utils import extras_features
from utilities.querysets import RestrictedQuerySet
from utilities.models import ChangeLoggedModel from utilities.models import ChangeLoggedModel
from utilities.utils import serialize_object from utilities.utils import serialize_object
from .choices import * from .choices import *
@ -66,9 +67,10 @@ class Provider(ChangeLoggedModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = [ csv_headers = [
'name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments', 'name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments',
] ]
@ -115,6 +117,8 @@ class CircuitType(ChangeLoggedModel):
blank=True, blank=True,
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'description'] csv_headers = ['name', 'slug', 'description']
class Meta: class Meta:
@ -300,6 +304,8 @@ class CircuitTermination(CableTermination):
blank=True blank=True
) )
objects = RestrictedQuerySet.as_manager()
class Meta: class Meta:
ordering = ['circuit', 'term_side'] ordering = ['circuit', 'term_side']
unique_together = ['circuit', 'term_side'] unique_together = ['circuit', 'term_side']

View File

@ -1,7 +1,9 @@
from django.db.models import OuterRef, QuerySet, Subquery from django.db.models import OuterRef, Subquery
from utilities.querysets import RestrictedQuerySet
class CircuitQuerySet(QuerySet): class CircuitQuerySet(RestrictedQuerySet):
def annotate_sites(self): def annotate_sites(self):
""" """

View File

@ -25,7 +25,9 @@ from extras.models import ConfigContextModel, CustomFieldModel, ObjectChange, Ta
from extras.utils import extras_features from extras.utils import extras_features
from utilities.choices import ColorChoices from utilities.choices import ColorChoices
from utilities.fields import ColorField, NaturalOrderingField from utilities.fields import ColorField, NaturalOrderingField
from utilities.querysets import RestrictedQuerySet
from utilities.models import ChangeLoggedModel from utilities.models import ChangeLoggedModel
from utilities.mptt import TreeManager
from utilities.utils import serialize_object, to_meters from utilities.utils import serialize_object, to_meters
from utilities.validators import ExclusionValidator from utilities.validators import ExclusionValidator
from .device_component_templates import ( from .device_component_templates import (
@ -103,6 +105,8 @@ class Region(MPTTModel, ChangeLoggedModel):
blank=True blank=True
) )
objects = TreeManager()
csv_headers = ['name', 'slug', 'parent', 'description'] csv_headers = ['name', 'slug', 'parent', 'description']
class MPTTMeta: class MPTTMeta:
@ -244,6 +248,8 @@ class Site(ChangeLoggedModel, CustomFieldModel):
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = [ csv_headers = [
'name', 'slug', 'status', 'region', 'tenant', 'facility', 'asn', 'time_zone', 'description', 'physical_address', 'name', 'slug', 'status', 'region', 'tenant', 'facility', 'asn', 'time_zone', 'description', 'physical_address',
'shipping_address', 'latitude', 'longitude', 'contact_name', 'contact_phone', 'contact_email', 'comments', 'shipping_address', 'latitude', 'longitude', 'contact_name', 'contact_phone', 'contact_email', 'comments',
@ -326,6 +332,8 @@ class RackGroup(MPTTModel, ChangeLoggedModel):
blank=True blank=True
) )
objects = TreeManager()
csv_headers = ['site', 'parent', 'name', 'slug', 'description'] csv_headers = ['site', 'parent', 'name', 'slug', 'description']
class Meta: class Meta:
@ -388,6 +396,8 @@ class RackRole(ChangeLoggedModel):
blank=True, blank=True,
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'color', 'description'] csv_headers = ['name', 'slug', 'color', 'description']
class Meta: class Meta:
@ -526,6 +536,8 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = [ csv_headers = [
'site', 'group', 'name', 'facility_id', 'tenant', 'status', 'role', 'type', 'serial', 'asset_tag', 'width', 'site', 'group', 'name', 'facility_id', 'tenant', 'status', 'role', 'type', 'serial', 'asset_tag', 'width',
'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'comments', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'comments',
@ -821,6 +833,8 @@ class RackReservation(ChangeLoggedModel):
max_length=200 max_length=200
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['site', 'rack_group', 'rack', 'units', 'tenant', 'user', 'description'] csv_headers = ['site', 'rack_group', 'rack', 'units', 'tenant', 'user', 'description']
class Meta: class Meta:
@ -900,6 +914,8 @@ class Manufacturer(ChangeLoggedModel):
blank=True blank=True
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'description'] csv_headers = ['name', 'slug', 'description']
class Meta: class Meta:
@ -982,9 +998,10 @@ class DeviceType(ChangeLoggedModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
clone_fields = [ clone_fields = [
'manufacturer', 'u_height', 'is_full_depth', 'subdevice_role', 'manufacturer', 'u_height', 'is_full_depth', 'subdevice_role',
] ]
@ -1206,6 +1223,8 @@ class DeviceRole(ChangeLoggedModel):
blank=True, blank=True,
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'color', 'vm_role', 'description'] csv_headers = ['name', 'slug', 'color', 'vm_role', 'description']
class Meta: class Meta:
@ -1263,6 +1282,8 @@ class Platform(ChangeLoggedModel):
blank=True blank=True
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_args', 'description'] csv_headers = ['name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_args', 'description']
class Meta: class Meta:
@ -1429,6 +1450,8 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = [ csv_headers = [
'name', 'device_role', 'tenant', 'manufacturer', 'device_type', 'platform', 'serial', 'asset_tag', 'status', 'name', 'device_role', 'tenant', 'manufacturer', 'device_type', 'platform', 'serial', 'asset_tag', 'status',
'site', 'rack_group', 'rack_name', 'position', 'face', 'comments', 'site', 'rack_group', 'rack_name', 'position', 'face', 'comments',
@ -1741,9 +1764,10 @@ class VirtualChassis(ChangeLoggedModel):
max_length=30, max_length=30,
blank=True blank=True
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = ['master', 'domain'] csv_headers = ['master', 'domain']
class Meta: class Meta:
@ -1813,6 +1837,8 @@ class PowerPanel(ChangeLoggedModel):
max_length=50 max_length=50
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['site', 'rack_group', 'name'] csv_headers = ['site', 'rack_group', 'name']
class Meta: class Meta:
@ -1916,9 +1942,10 @@ class PowerFeed(ChangeLoggedModel, CableTermination, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = [ csv_headers = [
'site', 'power_panel', 'rack_group', 'rack', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'site', 'power_panel', 'rack_group', 'rack', 'name', 'status', 'type', 'supply', 'phase', 'voltage',
'amperage', 'max_utilization', 'comments', 'amperage', 'max_utilization', 'comments',
@ -2084,6 +2111,8 @@ class Cable(ChangeLoggedModel):
null=True null=True
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = [ csv_headers = [
'termination_a_type', 'termination_a_id', 'termination_b_type', 'termination_b_id', 'type', 'status', 'label', 'termination_a_type', 'termination_a_id', 'termination_b_type', 'termination_b_id', 'type', 'status', 'label',
'color', 'length', 'length_unit', 'color', 'length', 'length_unit',

View File

@ -6,6 +6,7 @@ from dcim.choices import *
from dcim.constants import * from dcim.constants import *
from extras.models import ObjectChange from extras.models import ObjectChange
from utilities.fields import NaturalOrderingField from utilities.fields import NaturalOrderingField
from utilities.querysets import RestrictedQuerySet
from utilities.ordering import naturalize_interface from utilities.ordering import naturalize_interface
from utilities.utils import serialize_object from utilities.utils import serialize_object
from .device_components import ( from .device_components import (
@ -26,6 +27,7 @@ __all__ = (
class ComponentTemplateModel(models.Model): class ComponentTemplateModel(models.Model):
objects = RestrictedQuerySet.as_manager()
class Meta: class Meta:
abstract = True abstract = True

View File

@ -16,6 +16,7 @@ from extras.models import ObjectChange, TaggedItem
from extras.utils import extras_features from extras.utils import extras_features
from utilities.fields import NaturalOrderingField from utilities.fields import NaturalOrderingField
from utilities.ordering import naturalize_interface from utilities.ordering import naturalize_interface
from utilities.querysets import RestrictedQuerySet
from utilities.query_functions import CollateAsChar from utilities.query_functions import CollateAsChar
from utilities.utils import serialize_object from utilities.utils import serialize_object
from virtualization.choices import VMInterfaceTypeChoices from virtualization.choices import VMInterfaceTypeChoices
@ -41,6 +42,8 @@ class ComponentModel(models.Model):
blank=True blank=True
) )
objects = RestrictedQuerySet.as_manager()
class Meta: class Meta:
abstract = True abstract = True

View File

@ -12,6 +12,7 @@ from django.template import Template, Context
from django.urls import reverse from django.urls import reverse
from rest_framework.utils.encoders import JSONEncoder from rest_framework.utils.encoders import JSONEncoder
from utilities.querysets import RestrictedQuerySet
from utilities.utils import deepmerge, render_jinja2 from utilities.utils import deepmerge, render_jinja2
from extras.choices import * from extras.choices import *
from extras.constants import * from extras.constants import *
@ -670,6 +671,8 @@ class ObjectChange(models.Model):
editable=False editable=False
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = [ csv_headers = [
'time', 'user', 'user_name', 'request_id', 'action', 'changed_object_type', 'changed_object_id', 'time', 'user', 'user_name', 'request_id', 'action', 'changed_object_type', 'changed_object_id',
'related_object_type', 'related_object_id', 'object_repr', 'object_data', 'related_object_type', 'related_object_id', 'object_repr', 'object_data',

View File

@ -6,6 +6,7 @@ from taggit.models import TagBase, GenericTaggedItemBase
from utilities.choices import ColorChoices from utilities.choices import ColorChoices
from utilities.fields import ColorField from utilities.fields import ColorField
from utilities.models import ChangeLoggedModel from utilities.models import ChangeLoggedModel
from utilities.querysets import RestrictedQuerySet
# #
@ -21,6 +22,8 @@ class Tag(TagBase, ChangeLoggedModel):
blank=True, blank=True,
) )
objects = RestrictedQuerySet.as_manager()
def get_absolute_url(self): def get_absolute_url(self):
return reverse('extras:tag', args=[self.slug]) return reverse('extras:tag', args=[self.slug])

View File

@ -2,6 +2,8 @@ from collections import OrderedDict
from django.db.models import Q, QuerySet from django.db.models import Q, QuerySet
from utilities.querysets import RestrictedQuerySet
class CustomFieldQueryset: class CustomFieldQueryset:
""" """
@ -19,7 +21,7 @@ class CustomFieldQueryset:
yield obj yield obj
class ConfigContextQuerySet(QuerySet): class ConfigContextQuerySet(RestrictedQuerySet):
def get_for_object(self, obj): def get_for_object(self, obj):
""" """

View File

@ -1,6 +1,7 @@
from django.db import models from django.db import models
from ipam.lookups import Host, Inet from ipam.lookups import Host, Inet
from utilities.querysets import RestrictedQuerySet
class IPAddressManager(models.Manager): class IPAddressManager(models.Manager):
@ -13,5 +14,5 @@ class IPAddressManager(models.Manager):
then re-cast this value to INET() so that records will be ordered properly. We are essentially re-casting each then re-cast this value to INET() so that records will be ordered properly. We are essentially re-casting each
IP address as a /32 or /128. IP address as a /32 or /128.
""" """
qs = super().get_queryset() qs = RestrictedQuerySet(self.model, using=self._db)
return qs.order_by(Inet(Host('address'))) return qs.order_by(Inet(Host('address')))

View File

@ -12,6 +12,7 @@ from dcim.models import Device, Interface
from extras.models import CustomFieldModel, ObjectChange, TaggedItem from extras.models import CustomFieldModel, ObjectChange, TaggedItem
from extras.utils import extras_features from extras.utils import extras_features
from utilities.models import ChangeLoggedModel from utilities.models import ChangeLoggedModel
from utilities.querysets import RestrictedQuerySet
from utilities.utils import serialize_object from utilities.utils import serialize_object
from virtualization.models import VirtualMachine from virtualization.models import VirtualMachine
from .choices import * from .choices import *
@ -74,9 +75,10 @@ class VRF(ChangeLoggedModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'rd', 'tenant', 'enforce_unique', 'description'] csv_headers = ['name', 'rd', 'tenant', 'enforce_unique', 'description']
clone_fields = [ clone_fields = [
'tenant', 'enforce_unique', 'description', 'tenant', 'enforce_unique', 'description',
@ -131,6 +133,8 @@ class RIR(ChangeLoggedModel):
blank=True blank=True
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'is_private', 'description'] csv_headers = ['name', 'slug', 'is_private', 'description']
class Meta: class Meta:
@ -179,9 +183,10 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = ['prefix', 'rir', 'date_added', 'description'] csv_headers = ['prefix', 'rir', 'date_added', 'description']
clone_fields = [ clone_fields = [
'rir', 'date_added', 'description', 'rir', 'date_added', 'description',
@ -274,6 +279,8 @@ class Role(ChangeLoggedModel):
blank=True, blank=True,
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'weight', 'description'] csv_headers = ['name', 'slug', 'weight', 'description']
class Meta: class Meta:
@ -360,9 +367,9 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem)
objects = PrefixQuerySet.as_manager() objects = PrefixQuerySet.as_manager()
tags = TaggableManager(through=TaggedItem)
csv_headers = [ csv_headers = [
'prefix', 'vrf', 'tenant', 'site', 'vlan_group', 'vlan', 'status', 'role', 'is_pool', 'description', 'prefix', 'vrf', 'tenant', 'site', 'vlan_group', 'vlan', 'status', 'role', 'is_pool', 'description',
@ -631,9 +638,9 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem)
objects = IPAddressManager() objects = IPAddressManager()
tags = TaggableManager(through=TaggedItem)
csv_headers = [ csv_headers = [
'address', 'vrf', 'tenant', 'status', 'role', 'device', 'virtual_machine', 'interface', 'is_primary', 'address', 'vrf', 'tenant', 'status', 'role', 'device', 'virtual_machine', 'interface', 'is_primary',
@ -828,6 +835,8 @@ class VLANGroup(ChangeLoggedModel):
blank=True blank=True
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'site', 'description'] csv_headers = ['name', 'slug', 'site', 'description']
class Meta: class Meta:
@ -923,9 +932,10 @@ class VLAN(ChangeLoggedModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = ['site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description'] csv_headers = ['site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description']
clone_fields = [ clone_fields = [
'site', 'group', 'tenant', 'status', 'role', 'description', 'site', 'group', 'tenant', 'status', 'role', 'description',
@ -1039,9 +1049,10 @@ class Service(ChangeLoggedModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = ['device', 'virtual_machine', 'name', 'protocol', 'port', 'description'] csv_headers = ['device', 'virtual_machine', 'name', 'protocol', 'port', 'description']
class Meta: class Meta:

View File

@ -1,7 +1,7 @@
from django.db.models import QuerySet from utilities.querysets import RestrictedQuerySet
class PrefixQuerySet(QuerySet): class PrefixQuerySet(RestrictedQuerySet):
def annotate_depth(self, limit=None): def annotate_depth(self, limit=None):
""" """

View File

@ -17,6 +17,7 @@ from dcim.models import Device
from extras.models import CustomFieldModel, TaggedItem from extras.models import CustomFieldModel, TaggedItem
from extras.utils import extras_features from extras.utils import extras_features
from utilities.models import ChangeLoggedModel from utilities.models import ChangeLoggedModel
from utilities.querysets import RestrictedQuerySet
from .exceptions import InvalidKey from .exceptions import InvalidKey
from .hashers import SecretValidationHasher from .hashers import SecretValidationHasher
from .querysets import UserKeyQuerySet from .querysets import UserKeyQuerySet
@ -268,6 +269,8 @@ class SecretRole(ChangeLoggedModel):
blank=True blank=True
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'description'] csv_headers = ['name', 'slug', 'description']
class Meta: class Meta:
@ -333,9 +336,10 @@ class Secret(ChangeLoggedModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
plaintext = None plaintext = None
csv_headers = ['device', 'role', 'name', 'plaintext'] csv_headers = ['device', 'role', 'name', 'plaintext']

View File

@ -7,6 +7,8 @@ from taggit.managers import TaggableManager
from extras.models import CustomFieldModel, ObjectChange, TaggedItem from extras.models import CustomFieldModel, ObjectChange, TaggedItem
from extras.utils import extras_features from extras.utils import extras_features
from utilities.models import ChangeLoggedModel from utilities.models import ChangeLoggedModel
from utilities.mptt import TreeManager
from utilities.querysets import RestrictedQuerySet
from utilities.utils import serialize_object from utilities.utils import serialize_object
@ -40,6 +42,8 @@ class TenantGroup(MPTTModel, ChangeLoggedModel):
blank=True blank=True
) )
objects = TreeManager()
csv_headers = ['name', 'slug', 'parent', 'description'] csv_headers = ['name', 'slug', 'parent', 'description']
class Meta: class Meta:
@ -104,9 +108,10 @@ class Tenant(ChangeLoggedModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'group', 'description', 'comments'] csv_headers = ['name', 'slug', 'group', 'description', 'comments']
clone_fields = [ clone_fields = [
'group', 'description', 'group', 'description',

19
netbox/utilities/mptt.py Normal file
View File

@ -0,0 +1,19 @@
from mptt.managers import TreeManager as TreeManager_
from mptt.querysets import TreeQuerySet as TreeQuerySet_
from django.db.models import Manager
from .querysets import RestrictedQuerySet
class TreeQuerySet(TreeQuerySet_, RestrictedQuerySet):
"""
Mate django-mptt's TreeQuerySet with our RestrictedQuerySet for permissions enforcement.
"""
pass
class TreeManager(Manager.from_queryset(TreeQuerySet), TreeManager_):
"""
Extend django-mptt's TreeManager to incorporate RestrictedQuerySet().
"""
pass

View File

@ -27,7 +27,7 @@ class RestrictedQuerySet(QuerySet):
# Determine what constraints (if any) have been placed on this user for this action and model # Determine what constraints (if any) have been placed on this user for this action and model
# TODO: Find a better way to ensure permissions are cached # TODO: Find a better way to ensure permissions are cached
if not hasattr(user, '_object_perm_cache'): if not hasattr(user, '_object_perm_cache'):
user.get_all_permisisons() user.get_all_permissions()
obj_perm_attrs = user._object_perm_cache[permission_required] obj_perm_attrs = user._object_perm_cache[permission_required]
# Filter the queryset to include only objects with allowed attributes # Filter the queryset to include only objects with allowed attributes

View File

@ -9,6 +9,7 @@ from dcim.models import Device
from extras.models import ConfigContextModel, CustomFieldModel, TaggedItem from extras.models import ConfigContextModel, CustomFieldModel, TaggedItem
from extras.utils import extras_features from extras.utils import extras_features
from utilities.models import ChangeLoggedModel from utilities.models import ChangeLoggedModel
from utilities.querysets import RestrictedQuerySet
from .choices import * from .choices import *
@ -40,6 +41,8 @@ class ClusterType(ChangeLoggedModel):
blank=True blank=True
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'description'] csv_headers = ['name', 'slug', 'description']
class Meta: class Meta:
@ -79,6 +82,8 @@ class ClusterGroup(ChangeLoggedModel):
blank=True blank=True
) )
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'slug', 'description'] csv_headers = ['name', 'slug', 'description']
class Meta: class Meta:
@ -145,9 +150,10 @@ class Cluster(ChangeLoggedModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = ['name', 'type', 'group', 'site', 'comments'] csv_headers = ['name', 'type', 'group', 'site', 'comments']
clone_fields = [ clone_fields = [
'type', 'group', 'tenant', 'site', 'type', 'group', 'tenant', 'site',
@ -269,9 +275,10 @@ class VirtualMachine(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
content_type_field='obj_type', content_type_field='obj_type',
object_id_field='obj_id' object_id_field='obj_id'
) )
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()
csv_headers = [ csv_headers = [
'name', 'status', 'role', 'cluster', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments', 'name', 'status', 'role', 'cluster', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments',
] ]