mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-08 16:48:16 -06:00
review changes and further cleanup
This commit is contained in:
parent
2d8b15f341
commit
7e01bcad2f
@ -47,19 +47,19 @@ The webhook POST request is structured as so (assuming `application/json` as the
|
||||
"event": "created",
|
||||
"signal_received_timestamp": 1508769597,
|
||||
"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",
|
||||
"signal_received_timestamp": 1508781858.544069,
|
||||
"model": "Site",
|
||||
"instance": {
|
||||
"data": {
|
||||
"asn": None,
|
||||
"comments": "",
|
||||
"contact_email": "",
|
||||
|
@ -61,6 +61,8 @@ class Provider(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
csv_headers = ['name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments']
|
||||
|
||||
serializer = 'circuits.api.serializers.ProviderSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
|
||||
@ -82,10 +84,6 @@ class Provider(CreatedUpdatedModel, CustomFieldModel):
|
||||
self.comments,
|
||||
)
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'circuits.api.serializers.ProviderSerializer'
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class CircuitType(models.Model):
|
||||
@ -179,6 +177,8 @@ class Circuit(CreatedUpdatedModel, CustomFieldModel):
|
||||
'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']
|
||||
@ -219,10 +219,6 @@ class Circuit(CreatedUpdatedModel, CustomFieldModel):
|
||||
def termination_z(self):
|
||||
return self._get_termination('Z')
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'circuits.api.serializers.CircuitSerializer'
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class CircuitTermination(models.Model):
|
||||
|
@ -169,6 +169,8 @@ class Site(CreatedUpdatedModel, CustomFieldModel):
|
||||
'shipping_address', 'contact_name', 'contact_phone', 'contact_email', 'comments',
|
||||
]
|
||||
|
||||
serializer = 'dcim.api.serializers.SiteSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
|
||||
@ -220,10 +222,6 @@ class Site(CreatedUpdatedModel, CustomFieldModel):
|
||||
def count_circuits(self):
|
||||
return Circuit.objects.filter(terminations__site=self).count()
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'dcim.api.serializers.SiteSerializer'
|
||||
|
||||
@property
|
||||
def count_vms(self):
|
||||
from virtualization.models import VirtualMachine
|
||||
@ -253,6 +251,8 @@ class RackGroup(models.Model):
|
||||
|
||||
csv_headers = ['site', 'name', 'slug']
|
||||
|
||||
serializer = 'dcim.api.serializers.RackGroupSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['site', 'name']
|
||||
unique_together = [
|
||||
@ -273,10 +273,6 @@ class RackGroup(models.Model):
|
||||
self.slug,
|
||||
)
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'dcim.api.serializers.RackGroupSerializer'
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class RackRole(models.Model):
|
||||
@ -405,6 +401,8 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
|
||||
'desc_units', 'comments',
|
||||
]
|
||||
|
||||
serializer = 'dcim.api.serializers.RackSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['site', 'group', 'name']
|
||||
unique_together = [
|
||||
@ -574,10 +572,6 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
|
||||
u_available = len(self.get_available_units())
|
||||
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
|
||||
class RackReservation(models.Model):
|
||||
@ -1255,6 +1249,8 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
|
||||
'site', 'rack_group', 'rack_name', 'position', 'face', 'comments',
|
||||
]
|
||||
|
||||
serializer = 'dcim.api.serializers.DeviceSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
unique_together = [
|
||||
@ -1491,10 +1487,6 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
|
||||
return None
|
||||
return RPC_CLIENTS.get(self.platform.rpc_client)
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'dcim.api.serializers.DeviceSerializer'
|
||||
|
||||
|
||||
#
|
||||
# Console ports
|
||||
@ -1784,6 +1776,8 @@ class Interface(models.Model):
|
||||
|
||||
objects = InterfaceQuerySet.as_manager()
|
||||
|
||||
serializer = 'dcim.api.serializers.InterfaceSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['device', 'name']
|
||||
unique_together = ['device', 'name']
|
||||
@ -1914,10 +1908,6 @@ class Interface(models.Model):
|
||||
pass
|
||||
return None
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'dcim.api.serializers.InterfaceSerializer'
|
||||
|
||||
|
||||
class InterfaceConnection(models.Model):
|
||||
"""
|
||||
|
@ -40,8 +40,8 @@ class WebhookForm(forms.ModelForm):
|
||||
@admin.register(Webhook)
|
||||
class WebhookAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
'name', 'models', 'payload_url', 'content_type', 'type_create', 'type_update', 'type_delete',
|
||||
'secret', 'enabled', 'insecure_ssl',
|
||||
'name', 'models', 'payload_url', 'http_content_type', 'enabled', 'type_create', 'type_update',
|
||||
'type_delete', 'ssl_verification',
|
||||
]
|
||||
form = WebhookForm
|
||||
|
||||
|
@ -17,15 +17,15 @@ class Migration(migrations.Migration):
|
||||
name='Webhook',
|
||||
fields=[
|
||||
('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_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.')),
|
||||
('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)),
|
||||
('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)')),
|
||||
],
|
||||
),
|
@ -39,7 +39,7 @@ class Webhook(models.Model):
|
||||
help_text="The object(s) to which this Webhook applies."
|
||||
)
|
||||
name = models.CharField(
|
||||
max_length=50,
|
||||
max_length=150,
|
||||
unique=True
|
||||
)
|
||||
type_create = models.BooleanField(
|
||||
@ -58,7 +58,7 @@ class Webhook(models.Model):
|
||||
max_length=500,
|
||||
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,
|
||||
default=WEBHOOK_CT_JSON
|
||||
)
|
||||
@ -73,10 +73,9 @@ class Webhook(models.Model):
|
||||
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!"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@ -95,11 +94,6 @@ class Webhook(models.Model):
|
||||
"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
|
||||
|
@ -122,7 +122,7 @@ def bulk_operation_receiver(sender, **kwargs):
|
||||
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.connect(bulk_operation_receiver)
|
||||
|
||||
|
@ -9,18 +9,18 @@ from extras.constants import WEBHOOK_CT_JSON, WEBHOOK_CT_X_WWW_FORM_ENCODED
|
||||
|
||||
|
||||
@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
|
||||
"""
|
||||
payload = {
|
||||
'event': event,
|
||||
'signal_received_timestamp': signal_received_timestamp,
|
||||
'timestamp': timestamp,
|
||||
'model': model_class.__name__,
|
||||
'data': data
|
||||
}
|
||||
headers = {
|
||||
'Content-Type': webhook.get_content_type_display(),
|
||||
'Content-Type': webhook.get_http_content_type_display(),
|
||||
}
|
||||
params = {
|
||||
'method': 'POST',
|
||||
@ -28,9 +28,9 @@ def process_webhook(webhook, data, model_class, event, signal_received_timestamp
|
||||
'headers': headers
|
||||
}
|
||||
|
||||
if webhook.content_type == WEBHOOK_CT_JSON:
|
||||
if webhook.http_content_type == WEBHOOK_CT_JSON:
|
||||
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})
|
||||
|
||||
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()
|
||||
|
||||
with requests.Session() as session:
|
||||
session.very = not webhook.insecure_ssl
|
||||
session.verify = webhook.ssl_verification
|
||||
response = session.send(prepared_request)
|
||||
|
||||
if response.status_code >= 200 and response.status_code <= 299:
|
||||
|
@ -61,6 +61,8 @@ class VRF(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
csv_headers = ['name', 'rd', 'tenant', 'enforce_unique', 'description']
|
||||
|
||||
serializer = 'ipam.api.serializers.VRFSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['name', 'rd']
|
||||
verbose_name = 'VRF'
|
||||
@ -87,10 +89,6 @@ class VRF(CreatedUpdatedModel, CustomFieldModel):
|
||||
return "{} ({})".format(self.name, self.rd)
|
||||
return None
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'ipam.api.serializers.VRFSerializer'
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class RIR(models.Model):
|
||||
@ -166,6 +164,8 @@ class Aggregate(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
csv_headers = ['prefix', 'rir', 'date_added', 'description']
|
||||
|
||||
serializer = 'ipam.api.serializers.AggregateSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['family', 'prefix']
|
||||
|
||||
@ -226,10 +226,6 @@ class Aggregate(CreatedUpdatedModel, CustomFieldModel):
|
||||
child_prefixes = netaddr.IPSet([p.prefix for p in queryset])
|
||||
return int(float(child_prefixes.size) / self.prefix.size * 100)
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'ipam.api.serializers.AggregateSerializer'
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
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',
|
||||
]
|
||||
|
||||
serializer = 'ipam.api.serializers.PrefixSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['vrf', 'family', 'prefix']
|
||||
verbose_name_plural = 'prefixes'
|
||||
@ -499,10 +497,6 @@ class Prefix(CreatedUpdatedModel, CustomFieldModel):
|
||||
return netaddr.IPNetwork('{}/{}'.format(self.prefix.network, self.prefix.prefixlen + 1))
|
||||
return None
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'ipam.api.serializers.PrefixSerializer'
|
||||
|
||||
|
||||
class IPAddressManager(models.Manager):
|
||||
|
||||
@ -599,6 +593,8 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
|
||||
'description',
|
||||
]
|
||||
|
||||
serializer = 'ipam.api.serializers.IPAddressSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['family', 'address']
|
||||
verbose_name = 'IP address'
|
||||
@ -672,10 +668,6 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
|
||||
def get_status_class(self):
|
||||
return STATUS_CHOICE_CLASSES[self.status]
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'ipam.api.serializers.IPAddressSerializer'
|
||||
|
||||
def get_role_class(self):
|
||||
return ROLE_CHOICE_CLASSES[self.role]
|
||||
|
||||
@ -699,6 +691,8 @@ class VLANGroup(models.Model):
|
||||
|
||||
csv_headers = ['name', 'slug', 'site']
|
||||
|
||||
serializer = 'ipam.api.serializers.VLANGroupSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['site', 'name']
|
||||
unique_together = [
|
||||
@ -731,10 +725,6 @@ class VLANGroup(models.Model):
|
||||
return i
|
||||
return None
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'ipam.api.serializers.VLANGroupSerializer'
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class VLAN(CreatedUpdatedModel, CustomFieldModel):
|
||||
@ -800,6 +790,8 @@ class VLAN(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
csv_headers = ['site', 'group_name', 'vid', 'name', 'tenant', 'status', 'role', 'description']
|
||||
|
||||
serializer = 'ipam.api.serializers.VLANSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['site', 'group', 'vid']
|
||||
unique_together = [
|
||||
@ -851,10 +843,6 @@ class VLAN(CreatedUpdatedModel, CustomFieldModel):
|
||||
Q(tagged_vlans=self.pk)
|
||||
)
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'ipam.api.serializers.VLANSerializer'
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Service(CreatedUpdatedModel):
|
||||
@ -898,6 +886,8 @@ class Service(CreatedUpdatedModel):
|
||||
blank=True
|
||||
)
|
||||
|
||||
serializer = 'ipam.api.serializers.ServiceSerializer'
|
||||
|
||||
class Meta:
|
||||
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.")
|
||||
if not self.device and not self.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'
|
||||
|
@ -122,13 +122,15 @@ PREFER_IPV4 = False
|
||||
# on first enabling the required components for the webhook backend.
|
||||
WEBHOOK_BACKEND_ENABLED = False
|
||||
|
||||
# Redis settings. Redis is used in webhook backend so WEBHOOK_BACKEND_ENABLED must be enabled for these mean anything.
|
||||
# Please refer to the netbox documentation on the webhook backend.
|
||||
REDIS_HOST = 'localhost'
|
||||
REDIS_PORT = 6379
|
||||
REDIS_DEFAULT_TIMEOUT = 300
|
||||
REDIS_PASSWORD = ''
|
||||
REDIS_DB = 0
|
||||
# Redis settings. Redis is used in webhook backend so WEBHOOK_BACKEND_ENABLED must be enabled for these
|
||||
# to mean anything. Please refer to the netbox documentation on the webhook backend.
|
||||
REDIS = {
|
||||
'HOST': 'localhost',
|
||||
'PORT': 6379,
|
||||
'DEFAULT_TIMEOUT': 300,
|
||||
'PASSWORD': '',
|
||||
'DB': 0,
|
||||
}
|
||||
|
||||
# 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.
|
||||
|
@ -65,11 +65,12 @@ PAGINATE_COUNT = getattr(configuration, 'PAGINATE_COUNT', 50)
|
||||
PREFER_IPV4 = getattr(configuration, 'PREFER_IPV4', False)
|
||||
REPORTS_ROOT = getattr(configuration, 'REPORTS_ROOT', os.path.join(BASE_DIR, 'reports')).rstrip('/')
|
||||
WEBHOOK_BACKEND_ENABLED = getattr(configuration, 'WEBHOOK_BACKEND_ENABLED', False)
|
||||
REDIS_HOST = getattr(configuration, 'REDIS_HOST', 'localhost')
|
||||
REDIS_PORT = getattr(configuration, 'REDIS_PORT', 6379)
|
||||
REDIS_DEFAULT_TIMEOUT = getattr(configuration, 'REDIS_DEFAULT_TIMEOUT', 300)
|
||||
REDIS_PASSWORD = getattr(configuration, 'REDIS_PASSWORD', '')
|
||||
REDIS_DB = getattr(configuration, 'REDIS_DB', 0)
|
||||
REDIS = getattr(configuration, 'REDIS', {})
|
||||
REDIS_HOST = REDIS.get('REDIS_HOST', 'localhost')
|
||||
REDIS_PORT = REDIS.get('REDIS_PORT', 6379)
|
||||
REDIS_DEFAULT_TIMEOUT = REDIS.get('REDIS_DEFAULT_TIMEOUT', 300)
|
||||
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_DATETIME_FORMAT = getattr(configuration, 'SHORT_DATETIME_FORMAT', 'Y-m-d H:i')
|
||||
SHORT_TIME_FORMAT = getattr(configuration, 'SHORT_TIME_FORMAT', 'H:i:s')
|
||||
|
@ -25,6 +25,8 @@ class TenantGroup(models.Model):
|
||||
|
||||
csv_headers = ['name', 'slug']
|
||||
|
||||
serializer = 'tenancy.api.serializers.TenantGroupSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
|
||||
@ -40,10 +42,6 @@ class TenantGroup(models.Model):
|
||||
self.slug,
|
||||
)
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'tenancy.api.serializers.TenantGroupSerializer'
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Tenant(CreatedUpdatedModel, CustomFieldModel):
|
||||
@ -83,6 +81,8 @@ class Tenant(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
csv_headers = ['name', 'slug', 'group', 'description', 'comments']
|
||||
|
||||
serializer = 'tenancy.api.serializers.TenantSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['group', 'name']
|
||||
|
||||
@ -100,7 +100,3 @@ class Tenant(CreatedUpdatedModel, CustomFieldModel):
|
||||
self.description,
|
||||
self.comments,
|
||||
)
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'tenancy.api.serializers.TenantSerializer'
|
||||
|
@ -68,6 +68,8 @@ class ClusterGroup(models.Model):
|
||||
|
||||
csv_headers = ['name', 'slug']
|
||||
|
||||
serializer = 'virtualization.api.serializers.ClusterGroupSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
|
||||
@ -83,10 +85,6 @@ class ClusterGroup(models.Model):
|
||||
self.slug,
|
||||
)
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'virtualization.api.serializers.ClusterGroupSerializer'
|
||||
|
||||
|
||||
#
|
||||
# Clusters
|
||||
@ -133,6 +131,8 @@ class Cluster(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
csv_headers = ['name', 'type', 'group', 'site', 'comments']
|
||||
|
||||
serializer = 'virtualization.api.serializers.ClusterSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
|
||||
@ -163,10 +163,6 @@ class Cluster(CreatedUpdatedModel, CustomFieldModel):
|
||||
self.comments,
|
||||
)
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'virtualization.api.serializers.ClusterSerializer'
|
||||
|
||||
|
||||
#
|
||||
# Virtual machines
|
||||
@ -259,6 +255,8 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
|
||||
'name', 'status', 'role', 'cluster', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments',
|
||||
]
|
||||
|
||||
serializer = 'virtualization.api.serializers.VirtualMachineSerializer'
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
|
||||
@ -285,10 +283,6 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
|
||||
def get_status_class(self):
|
||||
return VM_STATUS_CLASSES[self.status]
|
||||
|
||||
@property
|
||||
def serializer(self):
|
||||
return 'virtualization.api.serializers.VirtualMachineSerializer'
|
||||
|
||||
@property
|
||||
def primary_ip(self):
|
||||
if settings.PREFER_IPV4 and self.primary_ip4:
|
||||
|
Loading…
Reference in New Issue
Block a user