Ensure only one prompt for cidr and gateway_ip

This commit makes 3 changes:
 - There should be only one prompt for field self. But required check
   in method clean checks the cleaned data, instead of the original value.
   So this commit set the fields required and remove the prompt when
   unnecessary.
 - According to below code [1], we know that initial equals context,
   and hidden with_subnet under subnet tab will conflict with
   the one under networks tab.
   So, this commit get with_subnet from initial, instead of cleaned_data.
 - Even with_subnet is False, the field checks are also valid and prevent
   the submitting. So, this commit remove erros for there fields.

[1] 3730ec164e/horizon/workflows/base.py (L157)

Change-Id: I8fd14861c33e60cba90d4193ce8953a3b27bbe26
Closes-Bug: #1812142
This commit is contained in:
Wangliangyu 2019-01-17 11:28:18 +08:00 committed by Akihiro Motoki
parent 37aec60a8f
commit 2bbd0e2509
2 changed files with 47 additions and 29 deletions

View File

@ -32,6 +32,19 @@ LOG = logging.getLogger(__name__)
class CreateSubnetInfoAction(network_workflows.CreateSubnetInfoAction):
with_subnet = forms.BooleanField(initial=True, required=False,
widget=forms.HiddenInput())
cidr = forms.IPField(label=_("Network Address"),
initial="",
error_messages={
'required': _("Specify network address")},
widget=forms.TextInput(attrs={
'class': 'switched',
'data-switch-on': 'source',
'data-source-manual': _("Network Address"),
}),
help_text=_("Network address in CIDR format "
"(e.g. 192.168.0.0/24, 2001:DB8::/48)"),
version=forms.IPv4 | forms.IPv6,
mask=True)
class Meta(object):
name = _("Subnet")
@ -41,7 +54,7 @@ class CreateSubnetInfoAction(network_workflows.CreateSubnetInfoAction):
def clean(self):
cleaned_data = workflows.Action.clean(self)
self._check_subnet_data(cleaned_data, with_network_form=False)
self._check_subnet_data(cleaned_data)
return cleaned_data
@ -105,6 +118,23 @@ class UpdateSubnetInfoAction(CreateSubnetInfoAction):
ip_version = forms.ThemableChoiceField(choices=[(4, 'IPv4'), (6, 'IPv6')],
widget=forms.HiddenInput(),
label=_("IP Version"))
gateway_ip = forms.IPField(
label=_("Gateway IP"),
widget=forms.TextInput(attrs={
'class': 'switched',
'data-switch-on': 'gateway_ip',
'data-source-manual': _("Gateway IP")
}),
initial="",
error_messages={
'required': _('Specify IP address of gateway or '
'check "Disable Gateway" checkbox.')
},
help_text=_("IP address of Gateway (e.g. 192.168.0.254) "
"If you do not want to use a gateway, "
"check 'Disable Gateway' below."),
version=forms.IPv4 | forms.IPv6,
mask=False)
class Meta(object):
name = _("Subnet")
@ -114,8 +144,7 @@ class UpdateSubnetInfoAction(CreateSubnetInfoAction):
def clean(self):
cleaned_data = workflows.Action.clean(self)
self._check_subnet_data(cleaned_data, is_create=False,
with_network_form=False)
self._check_subnet_data(cleaned_data)
return cleaned_data

View File

@ -139,11 +139,13 @@ class CreateSubnetInfoAction(workflows.Action):
required=False)
cidr = forms.IPField(label=_("Network Address"),
required=False,
initial="",
error_messages={
'required': _('Specify "Network Address" or '
'clear "Create Subnet" checkbox '
'in previous step.')},
widget=forms.TextInput(attrs={
'class': 'switched',
'data-required-when-shown': 'true',
'data-switch-on': 'source',
'data-source-manual': _("Network Address"),
}),
@ -202,13 +204,6 @@ class CreateSubnetInfoAction(workflows.Action):
def __init__(self, request, context, *args, **kwargs):
super(CreateSubnetInfoAction, self).__init__(request, context, *args,
**kwargs)
if 'with_subnet' in context:
self.fields['with_subnet'] = forms.BooleanField(
initial=context['with_subnet'],
required=False,
widget=forms.HiddenInput()
)
if not getattr(settings, 'OPENSTACK_NEUTRON_NETWORK',
{}).get('enable_ipv6', True):
self.fields['ip_version'].widget = forms.HiddenInput()
@ -279,8 +274,7 @@ class CreateSubnetInfoAction(workflows.Action):
'allowed': range_str})
raise forms.ValidationError(msg)
def _check_subnet_data(self, cleaned_data, is_create=True,
with_network_form=True):
def _check_subnet_data(self, cleaned_data):
cidr = cleaned_data.get('cidr')
ip_version = int(cleaned_data.get('ip_version'))
gateway_ip = cleaned_data.get('gateway_ip')
@ -293,14 +287,9 @@ class CreateSubnetInfoAction(workflows.Action):
'"Enter Network Address manually" and specify '
'"Network Address".')
raise forms.ValidationError(msg)
if not cidr and address_source != 'subnetpool':
if with_network_form:
msg = _('Specify "Network Address" or '
'clear "Create Subnet" checkbox in previous step.')
else:
msg = _("Specify network address")
raise forms.ValidationError(msg)
if cidr:
if address_source == 'subnetpool' and 'cidr' in self._errors:
del self._errors['cidr']
elif cidr:
subnet = netaddr.IPNetwork(cidr)
if subnet.version != ip_version:
msg = _('Network Address and IP version are inconsistent.')
@ -316,18 +305,18 @@ class CreateSubnetInfoAction(workflows.Action):
if netaddr.IPAddress(gateway_ip).version is not ip_version:
msg = _('Gateway IP and IP version are inconsistent.')
raise forms.ValidationError(msg)
if not is_create and not no_gateway and not gateway_ip:
msg = _('Specify IP address of gateway or '
'check "Disable Gateway" checkbox.')
raise forms.ValidationError(msg)
if no_gateway and 'gateway_ip' in self._errors:
del self._errors['gateway_ip']
def _remove_fields_errors(self):
self._errors = {}
def clean(self):
cleaned_data = super(CreateSubnetInfoAction, self).clean()
with_subnet = cleaned_data.get('with_subnet')
with_subnet = self.initial.get('with_subnet')
if not with_subnet:
return cleaned_data
self._remove_fields_errors()
return None
cleaned_data = super(CreateSubnetInfoAction, self).clean()
self._check_subnet_data(cleaned_data)
return cleaned_data