Merge "New input field with validation: MACAddressField"

This commit is contained in:
Jenkins 2017-03-22 17:30:42 +00:00 committed by Gerrit Code Review
commit f084006845
4 changed files with 56 additions and 9 deletions

View File

@ -33,6 +33,7 @@ from horizon.forms.fields import ExternalUploadMeta
from horizon.forms.fields import IPField
from horizon.forms.fields import IPv4
from horizon.forms.fields import IPv6
from horizon.forms.fields import MACAddressField
from horizon.forms.fields import MultiIPField
from horizon.forms.fields import SelectWidget
from horizon.forms.fields import ThemableCheckboxInput
@ -64,6 +65,7 @@ __all__ = [
"IPField",
"IPv4",
"IPv6",
"MACAddressField",
"MultiIPField",
"SelectWidget",

View File

@ -129,6 +129,33 @@ class MultiIPField(IPField):
return str(','.join(getattr(self, "addresses", [])))
class MACAddressField(fields.Field):
"""Form field for entering a MAC address with validation.
Supports all formats known by netaddr.EUI(), for example:
.. xx:xx:xx:xx:xx:xx
.. xx-xx-xx-xx-xx-xx
.. xxxx.xxxx.xxxx
"""
def validate(self, value):
super(MACAddressField, self).validate(value)
if not value:
return
try:
self.mac_address = netaddr.EUI(value)
# NOTE(rubasov): Normalize MAC address to the most usual format.
self.mac_address.dialect = netaddr.mac_unix_expanded
except Exception:
raise ValidationError(_("Invalid MAC Address format"),
code="invalid_mac")
def clean(self, value):
super(MACAddressField, self).clean(value)
return str(getattr(self, "mac_address", ""))
class SelectWidget(widgets.Select):
"""Customizable select widget, that allows to render
data-xxx attributes from choices. This widget also

View File

@ -194,6 +194,30 @@ class ValidatorsTests(test.TestCase):
for cidr in BAD_CIDRS_INPUT:
self.assertRaises(ValidationError, ip.validate, cidr)
def test_mac_address_validator(self):
GOOD_MAC_ADDRESSES = (
"00:11:88:99:Aa:Ff",
"00-11-88-99-Aa-Ff",
"0011.8899.AaFf",
"00118899AaFf",
)
BAD_MAC_ADDRESSES = (
"not a mac",
"11:22:33:44:55",
"zz:11:22:33:44:55",
)
field = forms.MACAddressField()
for input in GOOD_MAC_ADDRESSES:
self.assertIsNone(field.validate(input))
for input in BAD_MAC_ADDRESSES:
self.assertRaises(ValidationError, field.validate, input)
def test_mac_address_normal_form(self):
field = forms.MACAddressField()
field.validate("00-11-88-99-Aa-Ff")
self.assertEqual(field.mac_address, "00:11:88:99:aa:ff")
def test_port_validator(self):
VALID_PORTS = (1, 65535)
INVALID_PORTS = (-1, 65536)

View File

@ -16,7 +16,6 @@
import logging
from django.core.urlresolvers import reverse
from django.core import validators
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
@ -27,20 +26,15 @@ from openstack_dashboard import api
LOG = logging.getLogger(__name__)
validate_mac = validators.RegexValidator(r'([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}',
_("Invalid MAC Address format"),
code="invalid_mac")
class AddAllowedAddressPairForm(forms.SelfHandlingForm):
ip = forms.IPField(label=_("IP Address or CIDR"),
help_text=_("A single IP Address or CIDR"),
version=forms.IPv4 | forms.IPv6,
mask=True)
mac = forms.CharField(label=_("MAC Address"),
help_text=_("A valid MAC Address"),
validators=[validate_mac],
required=False)
mac = forms.MACAddressField(label=_("MAC Address"),
help_text=_("A valid MAC Address"),
required=False)
failure_url = 'horizon:project:networks:ports:detail'
def clean(self):