workflows.py (horizon-18.6.2) | : | workflows.py (horizon-18.6.3) | ||
---|---|---|---|---|
skipping to change at line 38 | skipping to change at line 38 | |||
ALLOCATE_URL = "horizon:project:floating_ips:allocate" | ALLOCATE_URL = "horizon:project:floating_ips:allocate" | |||
class AssociateIPAction(workflows.Action): | class AssociateIPAction(workflows.Action): | |||
use_required_attribute = False | use_required_attribute = False | |||
ip_id = forms.ThemableDynamicTypedChoiceField( | ip_id = forms.ThemableDynamicTypedChoiceField( | |||
label=_("IP Address"), | label=_("IP Address"), | |||
coerce=filters.get_int_or_uuid, | coerce=filters.get_int_or_uuid, | |||
empty_value=None | empty_value=None | |||
) | ) | |||
instance_id = forms.ThemableChoiceField( | instance_id = forms.CharField( | |||
widget=forms.widgets.HiddenInput(), | ||||
required=False, | ||||
) | ||||
port_id = forms.ThemableChoiceField( | ||||
label=_("Port to be associated") | label=_("Port to be associated") | |||
) | ) | |||
class Meta(object): | class Meta(object): | |||
name = _("IP Address") | name = _("IP Address") | |||
help_text = _("Select the IP address you wish to associate with " | help_text = _("Select the IP address you wish to associate with " | |||
"the selected instance or port.") | "the selected instance or port.") | |||
def __init__(self, *args, **kwargs): | def __init__(self, *args, **kwargs): | |||
super(AssociateIPAction, self).__init__(*args, **kwargs) | super(AssociateIPAction, self).__init__(*args, **kwargs) | |||
# If AssociateIP is invoked from instance menu, instance_id parameter | # If AssociateIP is invoked from instance menu, instance_id parameter | |||
# is passed in URL. In Neutron based Floating IP implementation | # is passed in URL. In Neutron based Floating IP implementation | |||
# an association target is not an instance but a port, so we need | # an association target is not an instance but a port, so we need | |||
# to get an association target based on a received instance_id | # to get an association target based on a received instance_id | |||
# and set the initial value of instance_id ChoiceField. | # and set the initial value of instance_id ChoiceField. | |||
q_instance_id = self.request.GET.get('instance_id') | q_instance_id = self.data.get('instance_id', | |||
self.request.GET.get('instance_id')) | ||||
q_port_id = self.request.GET.get('port_id') | q_port_id = self.request.GET.get('port_id') | |||
if policy.check((("network", "create_floatingip"),), | if policy.check((("network", "create_floatingip"),), | |||
request=self.request): | request=self.request): | |||
self.fields['ip_id'].widget.add_item_link = ALLOCATE_URL | self.fields['ip_id'].widget.add_item_link = ALLOCATE_URL | |||
if q_instance_id: | if q_instance_id: | |||
self.initial['instance_id'] = q_instance_id | ||||
targets = self._get_target_list(q_instance_id) | targets = self._get_target_list(q_instance_id) | |||
# Setting the initial value here is required to avoid a situation | # Setting the initial value here is required to avoid a situation | |||
# where instance_id passed in the URL is used as the initial value | # where instance_id passed in the URL is used as the initial value | |||
# unexpectedly. (This always happens if the form is invoked from | # unexpectedly. (This always happens if the form is invoked from | |||
# the instance table.) | # the instance table.) | |||
if targets: | if targets: | |||
self.initial['instance_id'] = targets[0].id | self.initial['port_id'] = targets[0].id | |||
else: | else: | |||
self.initial['instance_id'] = '' | self.initial['port_id'] = '' | |||
elif q_port_id: | elif q_port_id: | |||
targets = self._get_target_list() | targets = self._get_target_list() | |||
for target in targets: | for target in targets: | |||
if target.port_id == q_port_id: | if target.port_id == q_port_id: | |||
self.initial['instance_id'] = target.id | self.initial['port_id'] = target.id | |||
break | break | |||
def populate_ip_id_choices(self, request, context): | def populate_ip_id_choices(self, request, context): | |||
ips = [] | ips = [] | |||
redirect = reverse('horizon:project:floating_ips:index') | redirect = reverse('horizon:project:floating_ips:index') | |||
try: | try: | |||
ips = api.neutron.tenant_floating_ip_list(self.request) | ips = api.neutron.tenant_floating_ip_list(self.request) | |||
except neutron_exc.ConnectionFailed: | except neutron_exc.ConnectionFailed: | |||
exceptions.handle(self.request, redirect=redirect) | exceptions.handle(self.request, redirect=redirect) | |||
except Exception: | except Exception: | |||
skipping to change at line 114 | skipping to change at line 120 | |||
self.request, instance_id) | self.request, instance_id) | |||
else: | else: | |||
targets = api.neutron.floating_ip_target_list(self.request) | targets = api.neutron.floating_ip_target_list(self.request) | |||
except Exception: | except Exception: | |||
redirect = reverse('horizon:project:floating_ips:index') | redirect = reverse('horizon:project:floating_ips:index') | |||
exceptions.handle(self.request, | exceptions.handle(self.request, | |||
_('Unable to retrieve instance list.'), | _('Unable to retrieve instance list.'), | |||
redirect=redirect) | redirect=redirect) | |||
return targets | return targets | |||
# TODO(amotoki): [drop-nova-network] Rename instance_id to port_id | def populate_port_id_choices(self, request, context): | |||
def populate_instance_id_choices(self, request, context): | q_instance_id = self.data.get('instance_id', | |||
q_instance_id = self.request.GET.get('instance_id') | self.initial.get('instance_id')) | |||
# The reason of specifying an empty tuple when q_instance_id is None | # The reason of specifying an empty tuple when q_instance_id is None | |||
# is to make memoized_method _get_target_list work. Two calls of | # is to make memoized_method _get_target_list work. Two calls of | |||
# _get_target_list from here and __init__ must have a same arguments. | # _get_target_list from here and __init__ must have a same arguments. | |||
params = (q_instance_id, ) if q_instance_id else () | params = (q_instance_id, ) if q_instance_id else () | |||
targets = self._get_target_list(*params) | targets = self._get_target_list(*params) | |||
instances = sorted([(target.id, target.name) for target in targets], | instances = sorted([(target.id, target.name) for target in targets], | |||
# Sort FIP targets by server name for easy browsing | # Sort FIP targets by server name for easy browsing | |||
key=lambda x: x[1]) | key=lambda x: x[1]) | |||
if instances: | if instances: | |||
instances.insert(0, ("", _("Select a port"))) | instances.insert(0, ("", _("Select a port"))) | |||
else: | else: | |||
instances = (("", _("No ports available")),) | instances = (("", _("No ports available")),) | |||
return instances | return instances | |||
class AssociateIP(workflows.Step): | class AssociateIP(workflows.Step): | |||
action_class = AssociateIPAction | action_class = AssociateIPAction | |||
contributes = ("ip_id", "instance_id", "ip_address") | contributes = ("ip_id", "instance_id", "ip_address", "port_id") | |||
def contribute(self, data, context): | def contribute(self, data, context): | |||
context = super(AssociateIP, self).contribute(data, context) | context = super(AssociateIP, self).contribute(data, context) | |||
ip_id = data.get('ip_id', None) | ip_id = data.get('ip_id', None) | |||
if ip_id: | if ip_id: | |||
ip_choices = dict(self.action.fields['ip_id'].choices) | ip_choices = dict(self.action.fields['ip_id'].choices) | |||
context["ip_address"] = ip_choices.get(ip_id, None) | context["ip_address"] = ip_choices.get(ip_id, None) | |||
return context | return context | |||
class IPAssociationWorkflow(workflows.Workflow): | class IPAssociationWorkflow(workflows.Workflow): | |||
skipping to change at line 163 | skipping to change at line 169 | |||
if "%s" in message: | if "%s" in message: | |||
return message % self.context.get('ip_address', | return message % self.context.get('ip_address', | |||
_('unknown IP address')) | _('unknown IP address')) | |||
else: | else: | |||
return message | return message | |||
def handle(self, request, data): | def handle(self, request, data): | |||
try: | try: | |||
api.neutron.floating_ip_associate(request, | api.neutron.floating_ip_associate(request, | |||
data['ip_id'], | data['ip_id'], | |||
data['instance_id']) | data['port_id']) | |||
except neutron_exc.Conflict: | except neutron_exc.Conflict: | |||
msg = _('The requested instance port is already' | msg = _('The requested instance port is already' | |||
' associated with another floating IP.') | ' associated with another floating IP.') | |||
exceptions.handle(request, msg) | exceptions.handle(request, msg) | |||
self.failure_message = msg | self.failure_message = msg | |||
return False | return False | |||
except Exception: | except Exception: | |||
exceptions.handle(request) | exceptions.handle(request) | |||
return False | return False | |||
End of changes. 9 change blocks. | ||||
10 lines changed or deleted | 16 lines changed or added |