review changes and further cleanup

This commit is contained in:
John Anderson 2018-05-26 17:39:21 -07:00
parent 2d8b15f341
commit 7e01bcad2f
13 changed files with 73 additions and 114 deletions

View File

@ -47,19 +47,19 @@ The webhook POST request is structured as so (assuming `application/json` as the
"event": "created", "event": "created",
"signal_received_timestamp": 1508769597, "signal_received_timestamp": 1508769597,
"model": "Site" "model": "Site"
"instance": { "data": {
... ...
} }
} }
``` ```
`instance` is the serialized representation of the model instance from the event. The same serializers from the NetBox API are used. So an example of the payload for a Site delete event would be: `data` is the serialized representation of the model instance(s) from the event. The same serializers from the NetBox API are used. So an example of the payload for a Site delete event would be:
``` ```
{ {
"event": "deleted", "event": "deleted",
"signal_received_timestamp": 1508781858.544069, "signal_received_timestamp": 1508781858.544069,
"model": "Site", "model": "Site",
"instance": { "data": {
"asn": None, "asn": None,
"comments": "", "comments": "",
"contact_email": "", "contact_email": "",

View File

@ -61,6 +61,8 @@ class Provider(CreatedUpdatedModel, CustomFieldModel):
csv_headers = ['name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments'] csv_headers = ['name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments']
serializer = 'circuits.api.serializers.ProviderSerializer'
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
@ -82,10 +84,6 @@ class Provider(CreatedUpdatedModel, CustomFieldModel):
self.comments, self.comments,
) )
@property
def serializer(self):
return 'circuits.api.serializers.ProviderSerializer'
@python_2_unicode_compatible @python_2_unicode_compatible
class CircuitType(models.Model): class CircuitType(models.Model):
@ -179,6 +177,8 @@ class Circuit(CreatedUpdatedModel, CustomFieldModel):
'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'commit_rate', 'description', 'comments', 'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'commit_rate', 'description', 'comments',
] ]
serializer = 'circuits.api.serializers.CircuitSerializer'
class Meta: class Meta:
ordering = ['provider', 'cid'] ordering = ['provider', 'cid']
unique_together = ['provider', 'cid'] unique_together = ['provider', 'cid']
@ -219,10 +219,6 @@ class Circuit(CreatedUpdatedModel, CustomFieldModel):
def termination_z(self): def termination_z(self):
return self._get_termination('Z') return self._get_termination('Z')
@property
def serializer(self):
return 'circuits.api.serializers.CircuitSerializer'
@python_2_unicode_compatible @python_2_unicode_compatible
class CircuitTermination(models.Model): class CircuitTermination(models.Model):

View File

@ -169,6 +169,8 @@ class Site(CreatedUpdatedModel, CustomFieldModel):
'shipping_address', 'contact_name', 'contact_phone', 'contact_email', 'comments', 'shipping_address', 'contact_name', 'contact_phone', 'contact_email', 'comments',
] ]
serializer = 'dcim.api.serializers.SiteSerializer'
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
@ -220,10 +222,6 @@ class Site(CreatedUpdatedModel, CustomFieldModel):
def count_circuits(self): def count_circuits(self):
return Circuit.objects.filter(terminations__site=self).count() return Circuit.objects.filter(terminations__site=self).count()
@property
def serializer(self):
return 'dcim.api.serializers.SiteSerializer'
@property @property
def count_vms(self): def count_vms(self):
from virtualization.models import VirtualMachine from virtualization.models import VirtualMachine
@ -253,6 +251,8 @@ class RackGroup(models.Model):
csv_headers = ['site', 'name', 'slug'] csv_headers = ['site', 'name', 'slug']
serializer = 'dcim.api.serializers.RackGroupSerializer'
class Meta: class Meta:
ordering = ['site', 'name'] ordering = ['site', 'name']
unique_together = [ unique_together = [
@ -273,10 +273,6 @@ class RackGroup(models.Model):
self.slug, self.slug,
) )
@property
def serializer(self):
return 'dcim.api.serializers.RackGroupSerializer'
@python_2_unicode_compatible @python_2_unicode_compatible
class RackRole(models.Model): class RackRole(models.Model):
@ -405,6 +401,8 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
'desc_units', 'comments', 'desc_units', 'comments',
] ]
serializer = 'dcim.api.serializers.RackSerializer'
class Meta: class Meta:
ordering = ['site', 'group', 'name'] ordering = ['site', 'group', 'name']
unique_together = [ unique_together = [
@ -574,10 +572,6 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
u_available = len(self.get_available_units()) u_available = len(self.get_available_units())
return int(float(self.u_height - u_available) / self.u_height * 100) return int(float(self.u_height - u_available) / self.u_height * 100)
@property
def serializer(self):
return 'dcim.api.serializers.RackSerializer'
@python_2_unicode_compatible @python_2_unicode_compatible
class RackReservation(models.Model): class RackReservation(models.Model):
@ -1255,6 +1249,8 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
'site', 'rack_group', 'rack_name', 'position', 'face', 'comments', 'site', 'rack_group', 'rack_name', 'position', 'face', 'comments',
] ]
serializer = 'dcim.api.serializers.DeviceSerializer'
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
unique_together = [ unique_together = [
@ -1491,10 +1487,6 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
return None return None
return RPC_CLIENTS.get(self.platform.rpc_client) return RPC_CLIENTS.get(self.platform.rpc_client)
@property
def serializer(self):
return 'dcim.api.serializers.DeviceSerializer'
# #
# Console ports # Console ports
@ -1784,6 +1776,8 @@ class Interface(models.Model):
objects = InterfaceQuerySet.as_manager() objects = InterfaceQuerySet.as_manager()
serializer = 'dcim.api.serializers.InterfaceSerializer'
class Meta: class Meta:
ordering = ['device', 'name'] ordering = ['device', 'name']
unique_together = ['device', 'name'] unique_together = ['device', 'name']
@ -1914,10 +1908,6 @@ class Interface(models.Model):
pass pass
return None return None
@property
def serializer(self):
return 'dcim.api.serializers.InterfaceSerializer'
class InterfaceConnection(models.Model): class InterfaceConnection(models.Model):
""" """

View File

@ -40,8 +40,8 @@ class WebhookForm(forms.ModelForm):
@admin.register(Webhook) @admin.register(Webhook)
class WebhookAdmin(admin.ModelAdmin): class WebhookAdmin(admin.ModelAdmin):
list_display = [ list_display = [
'name', 'models', 'payload_url', 'content_type', 'type_create', 'type_update', 'type_delete', 'name', 'models', 'payload_url', 'http_content_type', 'enabled', 'type_create', 'type_update',
'secret', 'enabled', 'insecure_ssl', 'type_delete', 'ssl_verification',
] ]
form = WebhookForm form = WebhookForm

View File

@ -17,15 +17,15 @@ class Migration(migrations.Migration):
name='Webhook', name='Webhook',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50, unique=True)), ('name', models.CharField(max_length=150, unique=True)),
('type_create', models.BooleanField(default=False, help_text='A POST will be sent to the URL when the object type(s) is created.')), ('type_create', models.BooleanField(default=False, help_text='A POST will be sent to the URL when the object type(s) is created.')),
('type_update', models.BooleanField(default=False, help_text='A POST will be sent to the URL when the object type(s) is updated.')), ('type_update', models.BooleanField(default=False, help_text='A POST will be sent to the URL when the object type(s) is updated.')),
('type_delete', models.BooleanField(default=False, help_text='A POST will be sent to the URL when the object type(s) is deleted.')), ('type_delete', models.BooleanField(default=False, help_text='A POST will be sent to the URL when the object type(s) is deleted.')),
('payload_url', models.CharField(max_length=500, verbose_name='A POST will be sent to this URL based on the webhook criteria.')), ('payload_url', models.CharField(max_length=500, verbose_name='A POST will be sent to this URL based on the webhook criteria.')),
('content_type', models.PositiveSmallIntegerField(choices=[(1, 'application/json'), (2, 'application/x-www-form-urlencoded')], default=1)), ('http_content_type', models.PositiveSmallIntegerField(choices=[(1, 'application/json'), (2, 'application/x-www-form-urlencoded')], default=1)),
('secret', models.CharField(blank=True, help_text="When provided the request will include a 'X-Hook-Signature' header which is a HMAC hex digest of the payload body using the secret as the key. The secret is not transmitted in the request.", max_length=255)), ('secret', models.CharField(blank=True, help_text="When provided the request will include a 'X-Hook-Signature' header which is a HMAC hex digest of the payload body using the secret as the key. The secret is not transmitted in the request.", max_length=255)),
('enabled', models.BooleanField(default=True)), ('enabled', models.BooleanField(default=True)),
('insecure_ssl', models.BooleanField(default=False, help_text='When enabled, secure SSL verification will be ignored. Use with caution!')), ('ssl_verification', models.BooleanField(default=True, help_text='By default, use of proper SSL is verified. Disable with caution!')),
('obj_type', models.ManyToManyField(help_text='The object(s) to which this Webhook applies.', related_name='webhooks', to='contenttypes.ContentType', verbose_name='Object(s)')), ('obj_type', models.ManyToManyField(help_text='The object(s) to which this Webhook applies.', related_name='webhooks', to='contenttypes.ContentType', verbose_name='Object(s)')),
], ],
), ),

View File

@ -39,7 +39,7 @@ class Webhook(models.Model):
help_text="The object(s) to which this Webhook applies." help_text="The object(s) to which this Webhook applies."
) )
name = models.CharField( name = models.CharField(
max_length=50, max_length=150,
unique=True unique=True
) )
type_create = models.BooleanField( type_create = models.BooleanField(
@ -58,7 +58,7 @@ class Webhook(models.Model):
max_length=500, max_length=500,
verbose_name="A POST will be sent to this URL based on the webhook criteria." verbose_name="A POST will be sent to this URL based on the webhook criteria."
) )
content_type = models.PositiveSmallIntegerField( http_content_type = models.PositiveSmallIntegerField(
choices=WEBHOOK_CT_CHOICES, choices=WEBHOOK_CT_CHOICES,
default=WEBHOOK_CT_JSON default=WEBHOOK_CT_JSON
) )
@ -73,10 +73,9 @@ class Webhook(models.Model):
enabled = models.BooleanField( enabled = models.BooleanField(
default=True default=True
) )
insecure_ssl = models.BooleanField( ssl_verification = models.BooleanField(
default=False, default=True,
help_text="When enabled, secure SSL verification will be ignored. Use with " help_text="By default, use of proper SSL is verified. Disable with caution!"
"caution!"
) )
class Meta: class Meta:
@ -95,11 +94,6 @@ class Webhook(models.Model):
"You must select at least one type. Either create, update, or delete." "You must select at least one type. Either create, update, or delete."
) )
if self.insecure_ssl and not self.payload_url.startswith("https"):
raise ValidationError({
'insecure_ssl': 'Only applies to HTTPS payload urls.'
})
# #
# Custom fields # Custom fields

View File

@ -122,7 +122,7 @@ def bulk_operation_receiver(sender, **kwargs):
enqueue_webhooks(webhooks, sender, list(kwargs['instances']), event, signal_received_timestamp) enqueue_webhooks(webhooks, sender, list(kwargs['instances']), event, signal_received_timestamp)
# the bulk operation signal is used to overcome signals not being send for bulk model changes # the bulk operation signal is used to overcome signals not being sent for bulk model changes
bulk_operation_signal = Signal(providing_args=["instances", "event"]) bulk_operation_signal = Signal(providing_args=["instances", "event"])
bulk_operation_signal.connect(bulk_operation_receiver) bulk_operation_signal.connect(bulk_operation_receiver)

View File

@ -9,18 +9,18 @@ from extras.constants import WEBHOOK_CT_JSON, WEBHOOK_CT_X_WWW_FORM_ENCODED
@job('default') @job('default')
def process_webhook(webhook, data, model_class, event, signal_received_timestamp): def process_webhook(webhook, data, model_class, event, timestamp):
""" """
Make a POST request to the defined Webhook Make a POST request to the defined Webhook
""" """
payload = { payload = {
'event': event, 'event': event,
'signal_received_timestamp': signal_received_timestamp, 'timestamp': timestamp,
'model': model_class.__name__, 'model': model_class.__name__,
'data': data 'data': data
} }
headers = { headers = {
'Content-Type': webhook.get_content_type_display(), 'Content-Type': webhook.get_http_content_type_display(),
} }
params = { params = {
'method': 'POST', 'method': 'POST',
@ -28,9 +28,9 @@ def process_webhook(webhook, data, model_class, event, signal_received_timestamp
'headers': headers 'headers': headers
} }
if webhook.content_type == WEBHOOK_CT_JSON: if webhook.http_content_type == WEBHOOK_CT_JSON:
params.update({'json': payload}) params.update({'json': payload})
elif webhook.content_type == WEBHOOK_CT_X_WWW_FORM_ENCODED: elif webhook.http_content_type == WEBHOOK_CT_X_WWW_FORM_ENCODED:
params.update({'data': payload}) params.update({'data': payload})
prepared_request = requests.Request(**params).prepare() prepared_request = requests.Request(**params).prepare()
@ -41,7 +41,7 @@ def process_webhook(webhook, data, model_class, event, signal_received_timestamp
prepared_request.headers['X-Hook-Signature'] = hmac_prep.hexdigest() prepared_request.headers['X-Hook-Signature'] = hmac_prep.hexdigest()
with requests.Session() as session: with requests.Session() as session:
session.very = not webhook.insecure_ssl session.verify = webhook.ssl_verification
response = session.send(prepared_request) response = session.send(prepared_request)
if response.status_code >= 200 and response.status_code <= 299: if response.status_code >= 200 and response.status_code <= 299:

View File

@ -61,6 +61,8 @@ class VRF(CreatedUpdatedModel, CustomFieldModel):
csv_headers = ['name', 'rd', 'tenant', 'enforce_unique', 'description'] csv_headers = ['name', 'rd', 'tenant', 'enforce_unique', 'description']
serializer = 'ipam.api.serializers.VRFSerializer'
class Meta: class Meta:
ordering = ['name', 'rd'] ordering = ['name', 'rd']
verbose_name = 'VRF' verbose_name = 'VRF'
@ -87,10 +89,6 @@ class VRF(CreatedUpdatedModel, CustomFieldModel):
return "{} ({})".format(self.name, self.rd) return "{} ({})".format(self.name, self.rd)
return None return None
@property
def serializer(self):
return 'ipam.api.serializers.VRFSerializer'
@python_2_unicode_compatible @python_2_unicode_compatible
class RIR(models.Model): class RIR(models.Model):
@ -166,6 +164,8 @@ class Aggregate(CreatedUpdatedModel, CustomFieldModel):
csv_headers = ['prefix', 'rir', 'date_added', 'description'] csv_headers = ['prefix', 'rir', 'date_added', 'description']
serializer = 'ipam.api.serializers.AggregateSerializer'
class Meta: class Meta:
ordering = ['family', 'prefix'] ordering = ['family', 'prefix']
@ -226,10 +226,6 @@ class Aggregate(CreatedUpdatedModel, CustomFieldModel):
child_prefixes = netaddr.IPSet([p.prefix for p in queryset]) child_prefixes = netaddr.IPSet([p.prefix for p in queryset])
return int(float(child_prefixes.size) / self.prefix.size * 100) return int(float(child_prefixes.size) / self.prefix.size * 100)
@property
def serializer(self):
return 'ipam.api.serializers.AggregateSerializer'
@python_2_unicode_compatible @python_2_unicode_compatible
class Role(models.Model): class Role(models.Model):
@ -344,6 +340,8 @@ class Prefix(CreatedUpdatedModel, CustomFieldModel):
'prefix', 'vrf', 'tenant', 'site', 'vlan_group', 'vlan_vid', 'status', 'role', 'is_pool', 'description', 'prefix', 'vrf', 'tenant', 'site', 'vlan_group', 'vlan_vid', 'status', 'role', 'is_pool', 'description',
] ]
serializer = 'ipam.api.serializers.PrefixSerializer'
class Meta: class Meta:
ordering = ['vrf', 'family', 'prefix'] ordering = ['vrf', 'family', 'prefix']
verbose_name_plural = 'prefixes' verbose_name_plural = 'prefixes'
@ -499,10 +497,6 @@ class Prefix(CreatedUpdatedModel, CustomFieldModel):
return netaddr.IPNetwork('{}/{}'.format(self.prefix.network, self.prefix.prefixlen + 1)) return netaddr.IPNetwork('{}/{}'.format(self.prefix.network, self.prefix.prefixlen + 1))
return None return None
@property
def serializer(self):
return 'ipam.api.serializers.PrefixSerializer'
class IPAddressManager(models.Manager): class IPAddressManager(models.Manager):
@ -599,6 +593,8 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
'description', 'description',
] ]
serializer = 'ipam.api.serializers.IPAddressSerializer'
class Meta: class Meta:
ordering = ['family', 'address'] ordering = ['family', 'address']
verbose_name = 'IP address' verbose_name = 'IP address'
@ -672,10 +668,6 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
def get_status_class(self): def get_status_class(self):
return STATUS_CHOICE_CLASSES[self.status] return STATUS_CHOICE_CLASSES[self.status]
@property
def serializer(self):
return 'ipam.api.serializers.IPAddressSerializer'
def get_role_class(self): def get_role_class(self):
return ROLE_CHOICE_CLASSES[self.role] return ROLE_CHOICE_CLASSES[self.role]
@ -699,6 +691,8 @@ class VLANGroup(models.Model):
csv_headers = ['name', 'slug', 'site'] csv_headers = ['name', 'slug', 'site']
serializer = 'ipam.api.serializers.VLANGroupSerializer'
class Meta: class Meta:
ordering = ['site', 'name'] ordering = ['site', 'name']
unique_together = [ unique_together = [
@ -731,10 +725,6 @@ class VLANGroup(models.Model):
return i return i
return None return None
@property
def serializer(self):
return 'ipam.api.serializers.VLANGroupSerializer'
@python_2_unicode_compatible @python_2_unicode_compatible
class VLAN(CreatedUpdatedModel, CustomFieldModel): class VLAN(CreatedUpdatedModel, CustomFieldModel):
@ -800,6 +790,8 @@ class VLAN(CreatedUpdatedModel, CustomFieldModel):
csv_headers = ['site', 'group_name', 'vid', 'name', 'tenant', 'status', 'role', 'description'] csv_headers = ['site', 'group_name', 'vid', 'name', 'tenant', 'status', 'role', 'description']
serializer = 'ipam.api.serializers.VLANSerializer'
class Meta: class Meta:
ordering = ['site', 'group', 'vid'] ordering = ['site', 'group', 'vid']
unique_together = [ unique_together = [
@ -851,10 +843,6 @@ class VLAN(CreatedUpdatedModel, CustomFieldModel):
Q(tagged_vlans=self.pk) Q(tagged_vlans=self.pk)
) )
@property
def serializer(self):
return 'ipam.api.serializers.VLANSerializer'
@python_2_unicode_compatible @python_2_unicode_compatible
class Service(CreatedUpdatedModel): class Service(CreatedUpdatedModel):
@ -898,6 +886,8 @@ class Service(CreatedUpdatedModel):
blank=True blank=True
) )
serializer = 'ipam.api.serializers.ServiceSerializer'
class Meta: class Meta:
ordering = ['protocol', 'port'] ordering = ['protocol', 'port']
@ -915,7 +905,3 @@ class Service(CreatedUpdatedModel):
raise ValidationError("A service cannot be associated with both a device and a virtual machine.") raise ValidationError("A service cannot be associated with both a device and a virtual machine.")
if not self.device and not self.virtual_machine: if not self.device and not self.virtual_machine:
raise ValidationError("A service must be associated with either a device or a virtual machine.") raise ValidationError("A service must be associated with either a device or a virtual machine.")
@property
def serializer(self):
return 'ipam.api.serializers.ServiceSerializer'

View File

@ -122,13 +122,15 @@ PREFER_IPV4 = False
# on first enabling the required components for the webhook backend. # on first enabling the required components for the webhook backend.
WEBHOOK_BACKEND_ENABLED = False WEBHOOK_BACKEND_ENABLED = False
# Redis settings. Redis is used in webhook backend so WEBHOOK_BACKEND_ENABLED must be enabled for these mean anything. # Redis settings. Redis is used in webhook backend so WEBHOOK_BACKEND_ENABLED must be enabled for these
# Please refer to the netbox documentation on the webhook backend. # to mean anything. Please refer to the netbox documentation on the webhook backend.
REDIS_HOST = 'localhost' REDIS = {
REDIS_PORT = 6379 'HOST': 'localhost',
REDIS_DEFAULT_TIMEOUT = 300 'PORT': 6379,
REDIS_PASSWORD = '' 'DEFAULT_TIMEOUT': 300,
REDIS_DB = 0 'PASSWORD': '',
'DB': 0,
}
# The file path where custom reports will be stored. A trailing slash is not needed. Note that the default value of # The file path where custom reports will be stored. A trailing slash is not needed. Note that the default value of
# this setting is derived from the installed location. # this setting is derived from the installed location.

View File

@ -65,11 +65,12 @@ PAGINATE_COUNT = getattr(configuration, 'PAGINATE_COUNT', 50)
PREFER_IPV4 = getattr(configuration, 'PREFER_IPV4', False) PREFER_IPV4 = getattr(configuration, 'PREFER_IPV4', False)
REPORTS_ROOT = getattr(configuration, 'REPORTS_ROOT', os.path.join(BASE_DIR, 'reports')).rstrip('/') REPORTS_ROOT = getattr(configuration, 'REPORTS_ROOT', os.path.join(BASE_DIR, 'reports')).rstrip('/')
WEBHOOK_BACKEND_ENABLED = getattr(configuration, 'WEBHOOK_BACKEND_ENABLED', False) WEBHOOK_BACKEND_ENABLED = getattr(configuration, 'WEBHOOK_BACKEND_ENABLED', False)
REDIS_HOST = getattr(configuration, 'REDIS_HOST', 'localhost') REDIS = getattr(configuration, 'REDIS', {})
REDIS_PORT = getattr(configuration, 'REDIS_PORT', 6379) REDIS_HOST = REDIS.get('REDIS_HOST', 'localhost')
REDIS_DEFAULT_TIMEOUT = getattr(configuration, 'REDIS_DEFAULT_TIMEOUT', 300) REDIS_PORT = REDIS.get('REDIS_PORT', 6379)
REDIS_PASSWORD = getattr(configuration, 'REDIS_PASSWORD', '') REDIS_DEFAULT_TIMEOUT = REDIS.get('REDIS_DEFAULT_TIMEOUT', 300)
REDIS_DB = getattr(configuration, 'REDIS_DB', 0) REDIS_PASSWORD = REDIS.get('REDIS_PASSWORD', '')
REDIS_DB = REDIS.get('REDIS_DB', 0)
SHORT_DATE_FORMAT = getattr(configuration, 'SHORT_DATE_FORMAT', 'Y-m-d') SHORT_DATE_FORMAT = getattr(configuration, 'SHORT_DATE_FORMAT', 'Y-m-d')
SHORT_DATETIME_FORMAT = getattr(configuration, 'SHORT_DATETIME_FORMAT', 'Y-m-d H:i') SHORT_DATETIME_FORMAT = getattr(configuration, 'SHORT_DATETIME_FORMAT', 'Y-m-d H:i')
SHORT_TIME_FORMAT = getattr(configuration, 'SHORT_TIME_FORMAT', 'H:i:s') SHORT_TIME_FORMAT = getattr(configuration, 'SHORT_TIME_FORMAT', 'H:i:s')

View File

@ -25,6 +25,8 @@ class TenantGroup(models.Model):
csv_headers = ['name', 'slug'] csv_headers = ['name', 'slug']
serializer = 'tenancy.api.serializers.TenantGroupSerializer'
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
@ -40,10 +42,6 @@ class TenantGroup(models.Model):
self.slug, self.slug,
) )
@property
def serializer(self):
return 'tenancy.api.serializers.TenantGroupSerializer'
@python_2_unicode_compatible @python_2_unicode_compatible
class Tenant(CreatedUpdatedModel, CustomFieldModel): class Tenant(CreatedUpdatedModel, CustomFieldModel):
@ -83,6 +81,8 @@ class Tenant(CreatedUpdatedModel, CustomFieldModel):
csv_headers = ['name', 'slug', 'group', 'description', 'comments'] csv_headers = ['name', 'slug', 'group', 'description', 'comments']
serializer = 'tenancy.api.serializers.TenantSerializer'
class Meta: class Meta:
ordering = ['group', 'name'] ordering = ['group', 'name']
@ -100,7 +100,3 @@ class Tenant(CreatedUpdatedModel, CustomFieldModel):
self.description, self.description,
self.comments, self.comments,
) )
@property
def serializer(self):
return 'tenancy.api.serializers.TenantSerializer'

View File

@ -68,6 +68,8 @@ class ClusterGroup(models.Model):
csv_headers = ['name', 'slug'] csv_headers = ['name', 'slug']
serializer = 'virtualization.api.serializers.ClusterGroupSerializer'
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
@ -83,10 +85,6 @@ class ClusterGroup(models.Model):
self.slug, self.slug,
) )
@property
def serializer(self):
return 'virtualization.api.serializers.ClusterGroupSerializer'
# #
# Clusters # Clusters
@ -133,6 +131,8 @@ class Cluster(CreatedUpdatedModel, CustomFieldModel):
csv_headers = ['name', 'type', 'group', 'site', 'comments'] csv_headers = ['name', 'type', 'group', 'site', 'comments']
serializer = 'virtualization.api.serializers.ClusterSerializer'
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
@ -163,10 +163,6 @@ class Cluster(CreatedUpdatedModel, CustomFieldModel):
self.comments, self.comments,
) )
@property
def serializer(self):
return 'virtualization.api.serializers.ClusterSerializer'
# #
# Virtual machines # Virtual machines
@ -259,6 +255,8 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
'name', 'status', 'role', 'cluster', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments', 'name', 'status', 'role', 'cluster', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments',
] ]
serializer = 'virtualization.api.serializers.VirtualMachineSerializer'
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
@ -285,10 +283,6 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
def get_status_class(self): def get_status_class(self):
return VM_STATUS_CLASSES[self.status] return VM_STATUS_CLASSES[self.status]
@property
def serializer(self):
return 'virtualization.api.serializers.VirtualMachineSerializer'
@property @property
def primary_ip(self): def primary_ip(self):
if settings.PREFER_IPV4 and self.primary_ip4: if settings.PREFER_IPV4 and self.primary_ip4: