Merge "New input field with validation: MACAddressField"
This commit is contained in:
commit
f084006845
@ -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",
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user