diff --git a/CHANGELOG.md b/CHANGELOG.md index db5120ead..8105e0006 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ v2.4.5 (FUTURE) ## Bug Fixes * [#2406](https://github.com/digitalocean/netbox/issues/2406) - Remove hard-coded limit of 1000 objects from API-populated form fields +* [#2443](https://github.com/digitalocean/netbox/issues/2443) - Enforce JSON object format when creating config contexts +* [#2444](https://github.com/digitalocean/netbox/issues/2444) - Improve validation of interface MAC addresses --- diff --git a/netbox/dcim/fields.py b/netbox/dcim/fields.py index 22e0be581..4f38ec24e 100644 --- a/netbox/dcim/fields.py +++ b/netbox/dcim/fields.py @@ -1,13 +1,11 @@ from __future__ import unicode_literals -from netaddr import EUI, mac_unix_expanded +from netaddr import AddrFormatError, EUI, mac_unix_expanded from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator, MaxValueValidator from django.db import models -from .formfields import MACAddressFormField - class ASNField(models.BigIntegerField): description = "32-bit ASN field" @@ -35,7 +33,7 @@ class MACAddressField(models.Field): return value try: return EUI(value, version=48, dialect=mac_unix_expanded_uppercase) - except ValueError as e: + except AddrFormatError as e: raise ValidationError(e) def db_type(self, connection): @@ -45,11 +43,3 @@ class MACAddressField(models.Field): if not value: return None return str(self.to_python(value)) - - def form_class(self): - return MACAddressFormField - - def formfield(self, **kwargs): - defaults = {'form_class': self.form_class()} - defaults.update(kwargs) - return super(MACAddressField, self).formfield(**defaults) diff --git a/netbox/dcim/formfields.py b/netbox/dcim/formfields.py deleted file mode 100644 index 804c2c956..000000000 --- a/netbox/dcim/formfields.py +++ /dev/null @@ -1,27 +0,0 @@ -from __future__ import unicode_literals - -from django import forms -from django.core.exceptions import ValidationError -from netaddr import EUI, AddrFormatError - - -# -# Form fields -# - -class MACAddressFormField(forms.Field): - default_error_messages = { - 'invalid': "Enter a valid MAC address.", - } - - def to_python(self, value): - if not value: - return None - - if isinstance(value, EUI): - return value - - try: - return EUI(value, version=48) - except AddrFormatError: - raise ValidationError("Please specify a valid MAC address.") diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 333e90548..cec2fafad 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -27,7 +27,6 @@ from .constants import ( RACK_TYPE_CHOICES, RACK_WIDTH_CHOICES, RACK_WIDTH_19IN, RACK_WIDTH_23IN, SITE_STATUS_CHOICES, SUBDEVICE_ROLE_CHILD, SUBDEVICE_ROLE_PARENT, SUBDEVICE_ROLE_CHOICES, ) -from .formfields import MACAddressFormField from .models import ( DeviceBay, DeviceBayTemplate, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceRole, DeviceType, Interface, InterfaceConnection, InterfaceTemplate, Manufacturer, InventoryItem, @@ -1857,7 +1856,7 @@ class InterfaceCreateForm(ComponentForm, forms.Form): enabled = forms.BooleanField(required=False) lag = forms.ModelChoiceField(queryset=Interface.objects.all(), required=False, label='Parent LAG') mtu = forms.IntegerField(required=False, min_value=1, max_value=32767, label='MTU') - mac_address = MACAddressFormField(required=False, label='MAC Address') + mac_address = forms.CharField(required=False, label='MAC Address') mgmt_only = forms.BooleanField( required=False, label='OOB Management', diff --git a/netbox/extras/models.py b/netbox/extras/models.py index 2ccb7cdf1..de3edca9b 100644 --- a/netbox/extras/models.py +++ b/netbox/extras/models.py @@ -700,6 +700,14 @@ class ConfigContext(models.Model): def get_absolute_url(self): return reverse('extras:configcontext', kwargs={'pk': self.pk}) + def clean(self): + + # Verify that JSON data is provided as an object + if type(self.data) is not dict: + raise ValidationError( + {'data': 'JSON data must be in object form. Example: {"foo": 123}'} + ) + class ConfigContextModel(models.Model): diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index 9853157d8..ee1007be3 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -8,7 +8,6 @@ from taggit.forms import TagField from dcim.constants import IFACE_FF_VIRTUAL, IFACE_MODE_ACCESS, IFACE_MODE_TAGGED_ALL from dcim.forms import INTERFACE_MODE_HELP_TEXT -from dcim.formfields import MACAddressFormField from dcim.models import Device, DeviceRole, Interface, Platform, Rack, Region, Site from extras.forms import AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldForm, CustomFieldFilterForm from ipam.models import IPAddress @@ -461,7 +460,7 @@ class InterfaceCreateForm(ComponentForm): form_factor = forms.ChoiceField(choices=VIFACE_FF_CHOICES, initial=IFACE_FF_VIRTUAL, widget=forms.HiddenInput()) enabled = forms.BooleanField(required=False) mtu = forms.IntegerField(required=False, min_value=1, max_value=32767, label='MTU') - mac_address = MACAddressFormField(required=False, label='MAC Address') + mac_address = forms.CharField(required=False, label='MAC Address') description = forms.CharField(max_length=100, required=False) def __init__(self, *args, **kwargs):