Merge "Group specific fields in horizon.form module"
This commit is contained in:
@@ -30,6 +30,11 @@ from horizon.forms.base import SelfHandlingForm # noqa
|
||||
from horizon.forms.base import SelfHandlingMixin # noqa
|
||||
from horizon.forms.fields import DynamicChoiceField # noqa
|
||||
from horizon.forms.fields import DynamicTypedChoiceField # noqa
|
||||
from horizon.forms.fields import IPField # noqa
|
||||
from horizon.forms.fields import IPv4 # noqa
|
||||
from horizon.forms.fields import IPv6 # noqa
|
||||
from horizon.forms.fields import MultiIPField # noqa
|
||||
from horizon.forms.fields import SelectWidget # noqa
|
||||
from horizon.forms.views import ModalFormMixin # noqa
|
||||
from horizon.forms.views import ModalFormView # noqa
|
||||
|
||||
@@ -42,6 +47,11 @@ __all__ = [
|
||||
"ModalFormMixin",
|
||||
"DynamicTypedChoiceField",
|
||||
"DynamicChoiceField",
|
||||
"IPField",
|
||||
"IPv4",
|
||||
"IPv6",
|
||||
"MultiIPField",
|
||||
"SelectWidget"
|
||||
|
||||
# From django.forms
|
||||
"ValidationError",
|
||||
|
@@ -14,9 +14,153 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import re
|
||||
|
||||
import netaddr
|
||||
|
||||
from django.core.exceptions import ValidationError # noqa
|
||||
from django.core import urlresolvers
|
||||
from django.forms import fields
|
||||
from django.forms import widgets
|
||||
from django.utils.encoding import force_unicode
|
||||
from django.utils.functional import Promise # noqa
|
||||
from django.utils import html
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
ip_allowed_symbols_re = re.compile(r'^[a-fA-F0-9:/\.]+$')
|
||||
IPv4 = 1
|
||||
IPv6 = 2
|
||||
|
||||
|
||||
class IPField(fields.Field):
|
||||
"""Form field for entering IP/range values, with validation.
|
||||
Supports IPv4/IPv6 in the format:
|
||||
.. xxx.xxx.xxx.xxx
|
||||
.. xxx.xxx.xxx.xxx/zz
|
||||
.. ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||
.. ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/zz
|
||||
and all compressed forms. Also the short forms
|
||||
are supported:
|
||||
xxx/yy
|
||||
xxx.xxx/yy
|
||||
|
||||
.. attribute:: version
|
||||
|
||||
Specifies which IP version to validate,
|
||||
valid values are 1 (fields.IPv4), 2 (fields.IPv6) or
|
||||
both - 3 (fields.IPv4 | fields.IPv6).
|
||||
Defaults to IPv4 (1)
|
||||
|
||||
.. attribute:: mask
|
||||
|
||||
Boolean flag to validate subnet masks along with IP address.
|
||||
E.g: 10.0.0.1/32
|
||||
|
||||
.. attribute:: mask_range_from
|
||||
Subnet range limitation, e.g. 16
|
||||
That means the input mask will be checked to be in the range
|
||||
16:max_value. Useful to limit the subnet ranges
|
||||
to A/B/C-class networks.
|
||||
"""
|
||||
invalid_format_message = _("Incorrect format for IP address")
|
||||
invalid_version_message = _("Invalid version for IP address")
|
||||
invalid_mask_message = _("Invalid subnet mask")
|
||||
max_v4_mask = 32
|
||||
max_v6_mask = 128
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.mask = kwargs.pop("mask", None)
|
||||
self.min_mask = kwargs.pop("mask_range_from", 0)
|
||||
self.version = kwargs.pop('version', IPv4)
|
||||
|
||||
super(IPField, self).__init__(*args, **kwargs)
|
||||
|
||||
def validate(self, value):
|
||||
super(IPField, self).validate(value)
|
||||
if not value and not self.required:
|
||||
return
|
||||
|
||||
try:
|
||||
if self.mask:
|
||||
self.ip = netaddr.IPNetwork(value)
|
||||
else:
|
||||
self.ip = netaddr.IPAddress(value)
|
||||
except Exception:
|
||||
raise ValidationError(self.invalid_format_message)
|
||||
|
||||
if not any([self.version & IPv4 > 0 and self.ip.version == 4,
|
||||
self.version & IPv6 > 0 and self.ip.version == 6]):
|
||||
raise ValidationError(self.invalid_version_message)
|
||||
|
||||
if self.mask:
|
||||
if self.ip.version == 4 and \
|
||||
not self.min_mask <= self.ip.prefixlen <= self.max_v4_mask:
|
||||
raise ValidationError(self.invalid_mask_message)
|
||||
|
||||
if self.ip.version == 6 and \
|
||||
not self.min_mask <= self.ip.prefixlen <= self.max_v6_mask:
|
||||
raise ValidationError(self.invalid_mask_message)
|
||||
|
||||
def clean(self, value):
|
||||
super(IPField, self).clean(value)
|
||||
return str(getattr(self, "ip", ""))
|
||||
|
||||
|
||||
class MultiIPField(IPField):
|
||||
"""Extends IPField to allow comma-separated lists of addresses."""
|
||||
def validate(self, value):
|
||||
self.addresses = []
|
||||
if value:
|
||||
addresses = value.split(',')
|
||||
for ip in addresses:
|
||||
super(MultiIPField, self).validate(ip)
|
||||
self.addresses.append(ip)
|
||||
else:
|
||||
super(MultiIPField, self).validate(value)
|
||||
|
||||
def clean(self, value):
|
||||
super(MultiIPField, self).clean(value)
|
||||
return str(','.join(getattr(self, "addresses", [])))
|
||||
|
||||
|
||||
class SelectWidget(widgets.Select):
|
||||
"""Customizable select widget, that allows to render
|
||||
data-xxx attributes from choices.
|
||||
|
||||
.. attribute:: data_attrs
|
||||
|
||||
Specifies object properties to serialize as
|
||||
data-xxx attribute. If passed ('id', ),
|
||||
this will be rendered as:
|
||||
<option data-id="123">option_value</option>
|
||||
where 123 is the value of choice_value.id
|
||||
|
||||
.. attribute:: transform
|
||||
|
||||
A callable used to render the display value
|
||||
from the option object.
|
||||
"""
|
||||
def __init__(self, attrs=None, choices=(), data_attrs=(), transform=None):
|
||||
self.data_attrs = data_attrs
|
||||
self.transform = transform
|
||||
super(SelectWidget, self).__init__(attrs, choices)
|
||||
|
||||
def render_option(self, selected_choices, option_value, option_label):
|
||||
option_value = force_unicode(option_value)
|
||||
other_html = (option_value in selected_choices) and \
|
||||
u' selected="selected"' or ''
|
||||
if not isinstance(option_label, (basestring, Promise)):
|
||||
for data_attr in self.data_attrs:
|
||||
data_value = html.conditional_escape(
|
||||
force_unicode(getattr(option_label,
|
||||
data_attr, "")))
|
||||
other_html += ' data-%s="%s"' % (data_attr, data_value)
|
||||
|
||||
if self.transform:
|
||||
option_label = self.transform(option_label)
|
||||
return u'<option value="%s"%s>%s</option>' % (
|
||||
html.escape(option_value), other_html,
|
||||
html.conditional_escape(force_unicode(option_label)))
|
||||
|
||||
|
||||
class DynamicSelectWidget(widgets.Select):
|
||||
|
@@ -21,8 +21,8 @@ from django.core.exceptions import ValidationError # noqa
|
||||
import django.template
|
||||
from django.template import defaultfilters
|
||||
|
||||
from horizon import forms
|
||||
from horizon.test import helpers as test
|
||||
from horizon.utils import fields
|
||||
from horizon.utils import filters
|
||||
# we have to import the filter in order to register it
|
||||
from horizon.utils.filters import parse_isotime # noqa
|
||||
@@ -56,7 +56,7 @@ class ValidatorsTests(test.TestCase):
|
||||
"fe80::204:61ff:254.157.241.86/0",
|
||||
"2001:0DB8::CD30:0:0:0:0/60",
|
||||
"2001:0DB8::CD30:0/90")
|
||||
ip = fields.IPField(mask=True, version=fields.IPv4)
|
||||
ip = forms.IPField(mask=True, version=forms.IPv4)
|
||||
for cidr in GOOD_CIDRS:
|
||||
self.assertIsNone(ip.validate(cidr))
|
||||
for cidr in BAD_CIDRS:
|
||||
@@ -83,7 +83,7 @@ class ValidatorsTests(test.TestCase):
|
||||
"10.144.11.107/4",
|
||||
"255.255.255.255/0",
|
||||
"0.1.2.3/16")
|
||||
ip = fields.IPField(mask=True, version=fields.IPv6)
|
||||
ip = forms.IPField(mask=True, version=forms.IPv6)
|
||||
for cidr in GOOD_CIDRS:
|
||||
self.assertIsNone(ip.validate(cidr))
|
||||
for cidr in BAD_CIDRS:
|
||||
@@ -112,7 +112,7 @@ class ValidatorsTests(test.TestCase):
|
||||
"127.0.0.1/",
|
||||
"127.0.0.1/33",
|
||||
"127.0.0.1/-1")
|
||||
ip = fields.IPField(mask=True, version=fields.IPv4 | fields.IPv6)
|
||||
ip = forms.IPField(mask=True, version=forms.IPv4 | forms.IPv6)
|
||||
for cidr in GOOD_CIDRS:
|
||||
self.assertIsNone(ip.validate(cidr))
|
||||
for cidr in BAD_CIDRS:
|
||||
@@ -147,10 +147,10 @@ class ValidatorsTests(test.TestCase):
|
||||
"1111:2222::4444:5555:6666::8888",
|
||||
"1111:2222::4444:5555:6666:8888/",
|
||||
"1111:2222::4444:5555:6666::8888/130")
|
||||
ipv4 = fields.IPField(required=True, version=fields.IPv4)
|
||||
ipv6 = fields.IPField(required=False, version=fields.IPv6)
|
||||
ipmixed = fields.IPField(required=False,
|
||||
version=fields.IPv4 | fields.IPv6)
|
||||
ipv4 = forms.IPField(required=True, version=forms.IPv4)
|
||||
ipv6 = forms.IPField(required=False, version=forms.IPv6)
|
||||
ipmixed = forms.IPField(required=False,
|
||||
version=forms.IPv4 | forms.IPv6)
|
||||
|
||||
for ip_addr in GOOD_IPS_V4:
|
||||
self.assertIsNone(ipv4.validate(ip_addr))
|
||||
@@ -170,10 +170,10 @@ class ValidatorsTests(test.TestCase):
|
||||
|
||||
self.assertRaises(ValidationError, ipv4.validate, "") # required=True
|
||||
|
||||
iprange = fields.IPField(required=False,
|
||||
iprange = forms.IPField(required=False,
|
||||
mask=True,
|
||||
mask_range_from=10,
|
||||
version=fields.IPv4 | fields.IPv6)
|
||||
version=forms.IPv4 | forms.IPv6)
|
||||
self.assertRaises(ValidationError, iprange.validate,
|
||||
"fe80::204:61ff:254.157.241.86/6")
|
||||
self.assertRaises(ValidationError, iprange.validate,
|
||||
@@ -188,7 +188,7 @@ class ValidatorsTests(test.TestCase):
|
||||
"1.2.3.4.5/41 0.0.0.0/99",
|
||||
"192.168.1.1/16 192.0.0.1/17")
|
||||
|
||||
ip = fields.MultiIPField(mask=True, version=fields.IPv4)
|
||||
ip = forms.MultiIPField(mask=True, version=forms.IPv4)
|
||||
for cidr in GOOD_CIDRS_INPUT:
|
||||
self.assertIsNone(ip.validate(cidr))
|
||||
for cidr in BAD_CIDRS_INPUT:
|
||||
|
@@ -1,157 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.core.exceptions import ValidationError # noqa
|
||||
from django.forms import forms
|
||||
from django.forms import widgets
|
||||
from django.utils.encoding import force_unicode
|
||||
from django.utils.functional import Promise # noqa
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.html import escape
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import netaddr
|
||||
import re
|
||||
|
||||
ip_allowed_symbols_re = re.compile(r'^[a-fA-F0-9:/\.]+$')
|
||||
IPv4 = 1
|
||||
IPv6 = 2
|
||||
|
||||
|
||||
class IPField(forms.Field):
|
||||
"""Form field for entering IP/range values, with validation.
|
||||
Supports IPv4/IPv6 in the format:
|
||||
.. xxx.xxx.xxx.xxx
|
||||
.. xxx.xxx.xxx.xxx/zz
|
||||
.. ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||
.. ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/zz
|
||||
and all compressed forms. Also the short forms
|
||||
are supported:
|
||||
xxx/yy
|
||||
xxx.xxx/yy
|
||||
|
||||
.. attribute:: version
|
||||
|
||||
Specifies which IP version to validate,
|
||||
valid values are 1 (fields.IPv4), 2 (fields.IPv6) or
|
||||
both - 3 (fields.IPv4 | fields.IPv6).
|
||||
Defaults to IPv4 (1)
|
||||
|
||||
.. attribute:: mask
|
||||
|
||||
Boolean flag to validate subnet masks along with IP address.
|
||||
E.g: 10.0.0.1/32
|
||||
|
||||
.. attribute:: mask_range_from
|
||||
Subnet range limitation, e.g. 16
|
||||
That means the input mask will be checked to be in the range
|
||||
16:max_value. Useful to limit the subnet ranges
|
||||
to A/B/C-class networks.
|
||||
"""
|
||||
invalid_format_message = _("Incorrect format for IP address")
|
||||
invalid_version_message = _("Invalid version for IP address")
|
||||
invalid_mask_message = _("Invalid subnet mask")
|
||||
max_v4_mask = 32
|
||||
max_v6_mask = 128
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.mask = kwargs.pop("mask", None)
|
||||
self.min_mask = kwargs.pop("mask_range_from", 0)
|
||||
self.version = kwargs.pop('version', IPv4)
|
||||
|
||||
super(IPField, self).__init__(*args, **kwargs)
|
||||
|
||||
def validate(self, value):
|
||||
super(IPField, self).validate(value)
|
||||
if not value and not self.required:
|
||||
return
|
||||
|
||||
try:
|
||||
if self.mask:
|
||||
self.ip = netaddr.IPNetwork(value)
|
||||
else:
|
||||
self.ip = netaddr.IPAddress(value)
|
||||
except Exception:
|
||||
raise ValidationError(self.invalid_format_message)
|
||||
|
||||
if not any([self.version & IPv4 > 0 and self.ip.version == 4,
|
||||
self.version & IPv6 > 0 and self.ip.version == 6]):
|
||||
raise ValidationError(self.invalid_version_message)
|
||||
|
||||
if self.mask:
|
||||
if self.ip.version == 4 and \
|
||||
not self.min_mask <= self.ip.prefixlen <= self.max_v4_mask:
|
||||
raise ValidationError(self.invalid_mask_message)
|
||||
|
||||
if self.ip.version == 6 and \
|
||||
not self.min_mask <= self.ip.prefixlen <= self.max_v6_mask:
|
||||
raise ValidationError(self.invalid_mask_message)
|
||||
|
||||
def clean(self, value):
|
||||
super(IPField, self).clean(value)
|
||||
return str(getattr(self, "ip", ""))
|
||||
|
||||
|
||||
class MultiIPField(IPField):
|
||||
"""Extends IPField to allow comma-separated lists of addresses."""
|
||||
def validate(self, value):
|
||||
self.addresses = []
|
||||
if value:
|
||||
addresses = value.split(',')
|
||||
for ip in addresses:
|
||||
super(MultiIPField, self).validate(ip)
|
||||
self.addresses.append(ip)
|
||||
else:
|
||||
super(MultiIPField, self).validate(value)
|
||||
|
||||
def clean(self, value):
|
||||
super(MultiIPField, self).clean(value)
|
||||
return str(','.join(getattr(self, "addresses", [])))
|
||||
|
||||
|
||||
class SelectWidget(widgets.Select):
|
||||
"""Customizable select widget, that allows to render
|
||||
data-xxx attributes from choices.
|
||||
|
||||
.. attribute:: data_attrs
|
||||
|
||||
Specifies object properties to serialize as
|
||||
data-xxx attribute. If passed ('id', ),
|
||||
this will be rendered as:
|
||||
<option data-id="123">option_value</option>
|
||||
where 123 is the value of choice_value.id
|
||||
|
||||
.. attribute:: transform
|
||||
|
||||
A callable used to render the display value
|
||||
from the option object.
|
||||
"""
|
||||
def __init__(self, attrs=None, choices=(), data_attrs=(), transform=None):
|
||||
self.data_attrs = data_attrs
|
||||
self.transform = transform
|
||||
super(SelectWidget, self).__init__(attrs, choices)
|
||||
|
||||
def render_option(self, selected_choices, option_value, option_label):
|
||||
option_value = force_unicode(option_value)
|
||||
other_html = (option_value in selected_choices) and \
|
||||
u' selected="selected"' or ''
|
||||
if not isinstance(option_label, (basestring, Promise)):
|
||||
for data_attr in self.data_attrs:
|
||||
data_value = conditional_escape(
|
||||
force_unicode(getattr(option_label,
|
||||
data_attr, "")))
|
||||
other_html += ' data-%s="%s"' % (data_attr, data_value)
|
||||
|
||||
if self.transform:
|
||||
option_label = self.transform(option_label)
|
||||
return u'<option value="%s"%s>%s</option>' % (
|
||||
escape(option_value), other_html,
|
||||
conditional_escape(force_unicode(option_label)))
|
@@ -29,7 +29,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
from horizon.utils import fields
|
||||
from horizon.utils import validators as utils_validators
|
||||
|
||||
from openstack_dashboard import api
|
||||
@@ -204,12 +203,12 @@ class AddRule(forms.SelfHandlingForm):
|
||||
'class': 'switchable',
|
||||
'data-slug': 'remote'}))
|
||||
|
||||
cidr = fields.IPField(label=_("CIDR"),
|
||||
cidr = forms.IPField(label=_("CIDR"),
|
||||
required=False,
|
||||
initial="0.0.0.0/0",
|
||||
help_text=_("Classless Inter-Domain Routing "
|
||||
"(e.g. 192.168.0.0/24)"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
mask=True,
|
||||
widget=forms.TextInput(
|
||||
attrs={'class': 'switched',
|
||||
|
@@ -23,7 +23,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
from horizon.utils import fields
|
||||
from horizon.utils import validators
|
||||
|
||||
from openstack_dashboard import api
|
||||
@@ -44,14 +43,14 @@ class UpdateRule(forms.SelfHandlingForm):
|
||||
action = forms.ChoiceField(
|
||||
label=_("Action"), required=False,
|
||||
help_text=_('Action for the firewall rule'))
|
||||
source_ip_address = fields.IPField(
|
||||
source_ip_address = forms.IPField(
|
||||
label=_("Source IP Address/Subnet"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
required=False, mask=True,
|
||||
help_text=_('Source IP address or subnet'))
|
||||
destination_ip_address = fields.IPField(
|
||||
destination_ip_address = forms.IPField(
|
||||
label=_('Destination IP Address/Subnet'),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
required=False, mask=True,
|
||||
help_text=_('Destination IP address or subnet'))
|
||||
source_port = forms.CharField(
|
||||
|
@@ -19,7 +19,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon.utils import fields
|
||||
from horizon.utils import validators
|
||||
from horizon import workflows
|
||||
|
||||
@@ -47,13 +46,13 @@ class AddRuleAction(workflows.Action):
|
||||
label=_("Action"),
|
||||
choices=[('allow', _('ALLOW')),
|
||||
('deny', _('DENY'))],)
|
||||
source_ip_address = fields.IPField(
|
||||
source_ip_address = forms.IPField(
|
||||
label=_("Source IP Address/Subnet"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
required=False, mask=True)
|
||||
destination_ip_address = fields.IPField(
|
||||
destination_ip_address = forms.IPField(
|
||||
label=_("Destination IP Address/Subnet"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
required=False, mask=True)
|
||||
source_port = forms.CharField(
|
||||
max_length=80,
|
||||
|
@@ -23,7 +23,6 @@ from django.views.decorators.debug import sensitive_variables # noqa
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
from horizon.utils import fields
|
||||
from horizon.utils import validators
|
||||
|
||||
from openstack_dashboard import api
|
||||
@@ -37,8 +36,9 @@ def _image_choice_title(img):
|
||||
|
||||
class RebuildInstanceForm(forms.SelfHandlingForm):
|
||||
instance_id = forms.CharField(widget=forms.HiddenInput())
|
||||
|
||||
image = forms.ChoiceField(label=_("Select Image"),
|
||||
widget=fields.SelectWidget(attrs={'class': 'image-selector'},
|
||||
widget=forms.SelectWidget(attrs={'class': 'image-selector'},
|
||||
data_attrs=('size', 'display-name'),
|
||||
transform=_image_choice_title))
|
||||
password = forms.RegexField(label=_("Rebuild Password"),
|
||||
|
@@ -29,7 +29,6 @@ from django.views.decorators.debug import sensitive_variables # noqa
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon.utils import fields
|
||||
from horizon.utils import functions
|
||||
from horizon.utils import validators
|
||||
from horizon import workflows
|
||||
@@ -106,7 +105,7 @@ class SetInstanceDetailsAction(workflows.Action):
|
||||
image_id = forms.ChoiceField(
|
||||
label=_("Image Name"),
|
||||
required=False,
|
||||
widget=fields.SelectWidget(
|
||||
widget=forms.SelectWidget(
|
||||
data_attrs=('volume_size',),
|
||||
transform=lambda x: ("%s (%s)" % (x.name,
|
||||
filesizeformat(x.bytes)))))
|
||||
|
@@ -18,7 +18,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon.utils import fields
|
||||
from horizon.utils import validators
|
||||
from horizon import workflows
|
||||
|
||||
@@ -155,9 +154,9 @@ class AddVipAction(workflows.Action):
|
||||
label=_("VIP Address from Floating IPs"),
|
||||
widget=forms.Select(attrs={'disabled': 'disabled'}),
|
||||
required=False)
|
||||
other_address = fields.IPField(required=False,
|
||||
other_address = forms.IPField(required=False,
|
||||
initial="",
|
||||
version=fields.IPv4,
|
||||
version=forms.IPv4,
|
||||
mask=False)
|
||||
protocol_port = forms.IntegerField(label=_("Protocol Port"), min_value=1,
|
||||
help_text=_("Enter an integer value "
|
||||
|
@@ -21,7 +21,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon.utils import fields
|
||||
from horizon import workflows
|
||||
|
||||
from openstack_dashboard import api
|
||||
@@ -80,14 +79,14 @@ class CreateSubnet(network_workflows.CreateNetwork):
|
||||
|
||||
|
||||
class UpdateSubnetInfoAction(CreateSubnetInfoAction):
|
||||
cidr = fields.IPField(label=_("Network Address"),
|
||||
cidr = forms.IPField(label=_("Network Address"),
|
||||
required=False,
|
||||
initial="",
|
||||
widget=forms.TextInput(
|
||||
attrs={'readonly': 'readonly'}),
|
||||
help_text=_("Network address in CIDR format "
|
||||
"(e.g. 192.168.0.0/24)"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
mask=True)
|
||||
# NOTE(amotoki): When 'disabled' attribute is set for the ChoiceField
|
||||
# and ValidationError is raised for POST request, the initial value of
|
||||
@@ -103,7 +102,7 @@ class UpdateSubnetInfoAction(CreateSubnetInfoAction):
|
||||
widget=forms.HiddenInput(),
|
||||
label=_("IP Version"))
|
||||
|
||||
gateway_ip = fields.IPField(
|
||||
gateway_ip = forms.IPField(
|
||||
label=_("Gateway IP (optional)"),
|
||||
required=False,
|
||||
initial="",
|
||||
@@ -112,7 +111,7 @@ class UpdateSubnetInfoAction(CreateSubnetInfoAction):
|
||||
"to set the gateway. "
|
||||
"If you want to use no gateway, "
|
||||
"check 'Disable Gateway' below."),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
mask=False)
|
||||
no_gateway = forms.BooleanField(label=_("Disable Gateway"),
|
||||
initial=False, required=False)
|
||||
|
@@ -24,7 +24,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
from horizon.utils import fields
|
||||
from horizon import workflows
|
||||
|
||||
from openstack_dashboard import api
|
||||
@@ -87,16 +86,16 @@ class CreateSubnetInfoAction(workflows.Action):
|
||||
subnet_name = forms.CharField(max_length=255,
|
||||
label=_("Subnet Name"),
|
||||
required=False)
|
||||
cidr = fields.IPField(label=_("Network Address"),
|
||||
cidr = forms.IPField(label=_("Network Address"),
|
||||
required=False,
|
||||
initial="",
|
||||
help_text=_("Network address in CIDR format "
|
||||
"(e.g. 192.168.0.0/24)"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
mask=True)
|
||||
ip_version = forms.ChoiceField(choices=[(4, 'IPv4'), (6, 'IPv6')],
|
||||
label=_("IP Version"))
|
||||
gateway_ip = fields.IPField(
|
||||
gateway_ip = forms.IPField(
|
||||
label=_("Gateway IP"),
|
||||
required=False,
|
||||
initial="",
|
||||
@@ -107,7 +106,7 @@ class CreateSubnetInfoAction(workflows.Action):
|
||||
"If you use the default, leave blank. "
|
||||
"If you want to use no gateway, "
|
||||
"check 'Disable Gateway' below."),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
mask=False)
|
||||
no_gateway = forms.BooleanField(label=_("Disable Gateway"),
|
||||
initial=False, required=False)
|
||||
|
@@ -23,14 +23,13 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
from horizon.utils import fields
|
||||
from openstack_dashboard.dashboards.project.routers.extensions.routerrules\
|
||||
import rulemanager
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RuleCIDRField(fields.IPField):
|
||||
class RuleCIDRField(forms.IPField):
|
||||
"""Extends IPField to allow ('any','external') keywords and requires CIDR
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -53,7 +52,7 @@ class AddRouterRule(forms.SelfHandlingForm):
|
||||
destination = RuleCIDRField(label=_("Destination CIDR"),
|
||||
widget=forms.TextInput(), required=True)
|
||||
action = forms.ChoiceField(label=_("Action"), required=True)
|
||||
nexthops = fields.MultiIPField(label=_("Optional: Next Hop "
|
||||
nexthops = forms.MultiIPField(label=_("Optional: Next Hop "
|
||||
"Addresses (comma delimited)"),
|
||||
widget=forms.TextInput(), required=False)
|
||||
router_id = forms.CharField(label=_("Router ID"),
|
||||
|
@@ -22,7 +22,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
from horizon.utils import fields
|
||||
from openstack_dashboard import api
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@@ -30,11 +29,11 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
class AddInterface(forms.SelfHandlingForm):
|
||||
subnet_id = forms.ChoiceField(label=_("Subnet"))
|
||||
ip_address = fields.IPField(
|
||||
ip_address = forms.IPField(
|
||||
label=_("IP Address (optional)"), required=False, initial="",
|
||||
help_text=_("You can specify an IP address of the interface "
|
||||
"created if you want (e.g. 192.168.0.254)."),
|
||||
version=fields.IPv4 | fields.IPv6, mask=False)
|
||||
version=forms.IPv4 | forms.IPv6, mask=False)
|
||||
router_name = forms.CharField(label=_("Router Name"),
|
||||
widget=forms.TextInput(
|
||||
attrs={'readonly': 'readonly'}))
|
||||
|
@@ -28,7 +28,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
from horizon.utils import fields
|
||||
from horizon.utils import functions
|
||||
from horizon.utils.memoized import memoized # noqa
|
||||
|
||||
@@ -55,21 +54,21 @@ class CreateForm(forms.SelfHandlingForm):
|
||||
'data-slug': 'source'}))
|
||||
snapshot_source = forms.ChoiceField(
|
||||
label=_("Use snapshot as a source"),
|
||||
widget=fields.SelectWidget(
|
||||
widget=forms.SelectWidget(
|
||||
attrs={'class': 'snapshot-selector'},
|
||||
data_attrs=('size', 'name'),
|
||||
transform=lambda x: "%s (%sGB)" % (x.name, x.size)),
|
||||
required=False)
|
||||
image_source = forms.ChoiceField(
|
||||
label=_("Use image as a source"),
|
||||
widget=fields.SelectWidget(
|
||||
widget=forms.SelectWidget(
|
||||
attrs={'class': 'image-selector'},
|
||||
data_attrs=('size', 'name', 'min_disk'),
|
||||
transform=lambda x: "%s (%s)" % (x.name, filesizeformat(x.bytes))),
|
||||
required=False)
|
||||
volume_source = forms.ChoiceField(
|
||||
label=_("Use a volume as source"),
|
||||
widget=fields.SelectWidget(
|
||||
widget=forms.SelectWidget(
|
||||
attrs={'class': 'image-selector'},
|
||||
data_attrs=('size', 'name'),
|
||||
transform=lambda x: "%s (%s)" % (x.name,
|
||||
|
@@ -24,7 +24,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
from horizon.utils import fields
|
||||
|
||||
from openstack_dashboard import api
|
||||
|
||||
@@ -211,25 +210,25 @@ class UpdateIPSecSiteConnection(forms.SelfHandlingForm):
|
||||
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
|
||||
description = forms.CharField(
|
||||
required=False, max_length=80, label=_("Description"))
|
||||
peer_address = fields.IPField(
|
||||
peer_address = forms.IPField(
|
||||
label=_("Peer gateway public IPv4/IPv6 Address or FQDN"),
|
||||
help_text=_("Peer gateway public IPv4/IPv6 address or FQDN for "
|
||||
"the VPN Connection"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
mask=False)
|
||||
peer_id = fields.IPField(
|
||||
peer_id = forms.IPField(
|
||||
label=_("Peer router identity for authentication (Peer ID)"),
|
||||
help_text=_("Peer router identity for authentication. "
|
||||
"Can be IPv4/IPv6 address, e-mail, key ID, or FQDN"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
mask=False)
|
||||
peer_cidrs = fields.MultiIPField(
|
||||
peer_cidrs = forms.MultiIPField(
|
||||
label=_("Remote peer subnet(s)"),
|
||||
help_text=_("Remote peer subnet(s) address(es) "
|
||||
"with mask(s) in CIDR format "
|
||||
"separated with commas if needed "
|
||||
"(e.g. 20.1.0.0/24, 21.1.0.0/24)"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
mask=True)
|
||||
psk = forms.CharField(
|
||||
max_length=80, label=_("Pre-Shared Key (PSK) string"))
|
||||
|
@@ -20,7 +20,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon.utils import fields
|
||||
from horizon import workflows
|
||||
|
||||
from openstack_dashboard import api
|
||||
@@ -316,25 +315,25 @@ class AddIPSecSiteConnectionAction(workflows.Action):
|
||||
label=_("IKE Policy associated with this connection"))
|
||||
ipsecpolicy_id = forms.ChoiceField(
|
||||
label=_("IPSec Policy associated with this connection"))
|
||||
peer_address = fields.IPField(
|
||||
peer_address = forms.IPField(
|
||||
label=_("Peer gateway public IPv4/IPv6 Address or FQDN"),
|
||||
help_text=_("Peer gateway public IPv4/IPv6 address or FQDN for "
|
||||
"the VPN Connection"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
mask=False)
|
||||
peer_id = fields.IPField(
|
||||
peer_id = forms.IPField(
|
||||
label=_("Peer router identity for authentication (Peer ID)"),
|
||||
help_text=_("Peer router identity for authentication. "
|
||||
"Can be IPv4/IPv6 address, e-mail, key ID, or FQDN"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
mask=False)
|
||||
peer_cidrs = fields.MultiIPField(
|
||||
peer_cidrs = forms.MultiIPField(
|
||||
label=_("Remote peer subnet(s)"),
|
||||
help_text=_("Remote peer subnet(s) address(es) "
|
||||
"with mask(s) in CIDR format "
|
||||
"separated with commas if needed "
|
||||
"(e.g. 20.1.0.0/24, 21.1.0.0/24)"),
|
||||
version=fields.IPv4 | fields.IPv6,
|
||||
version=forms.IPv4 | forms.IPv6,
|
||||
mask=True)
|
||||
psk = forms.CharField(max_length=80,
|
||||
label=_("Pre-Shared Key (PSK) string"))
|
||||
|
Reference in New Issue
Block a user