Source code for openstack_dashboard.dashboards.project.access_and_security.floating_ips.workflows

# Copyright 2012 Nebula, Inc.

#    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.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _

from neutronclient.common import exceptions as neutron_exc

from horizon import exceptions
from horizon import forms
from horizon.utils import memoized
from horizon import workflows

from openstack_dashboard import api
from openstack_dashboard.utils import filters


ALLOCATE_URL = "horizon:project:access_and_security:floating_ips:allocate"


[docs]class AssociateIPAction(workflows.Action): ip_id = forms.ThemableDynamicTypedChoiceField( label=_("IP Address"), coerce=filters.get_int_or_uuid, empty_value=None, add_item_link=ALLOCATE_URL) instance_id = forms.ThemableChoiceField(label=_("Instance")) class Meta(object): name = _("IP Address") help_text = _("Select the IP address you wish to associate with " "the selected instance or port.") def __init__(self, *args, **kwargs): super(AssociateIPAction, self).__init__(*args, **kwargs) if api.base.is_service_enabled(self.request, 'network'): label = _("Port to be associated") else: label = _("Instance to be associated") self.fields['instance_id'].label = label # If AssociateIP is invoked from instance menu, instance_id parameter # is passed in URL. In Neutron based Floating IP implementation # an association target is not an instance but a port, so we need # to get an association target based on a received instance_id # and set the initial value of instance_id ChoiceField. q_instance_id = self.request.GET.get('instance_id') q_port_id = self.request.GET.get('port_id') if q_instance_id: targets = self._get_target_list() target_id = api.network.floating_ip_target_get_by_instance( self.request, q_instance_id, targets) self.initial['instance_id'] = target_id elif q_port_id: targets = self._get_target_list() for target in targets: if (hasattr(target, 'port_id') and target.port_id == q_port_id): self.initial['instance_id'] = target.id break
[docs] def populate_ip_id_choices(self, request, context): ips = [] redirect = reverse('horizon:project:access_and_security:index') try: ips = api.network.tenant_floating_ip_list(self.request) except neutron_exc.ConnectionFailed: exceptions.handle(self.request, redirect=redirect) except Exception: exceptions.handle(self.request, _('Unable to retrieve floating IP addresses.'), redirect=redirect) options = sorted([(ip.id, ip.ip) for ip in ips if not ip.port_id]) if options: options.insert(0, ("", _("Select an IP address"))) else: options = [("", _("No floating IP addresses allocated"))] return options
@memoized.memoized_method def _get_target_list(self): targets = [] try: targets = api.network.floating_ip_target_list(self.request) except Exception: redirect = reverse('horizon:project:access_and_security:index') exceptions.handle(self.request, _('Unable to retrieve instance list.'), redirect=redirect) return targets
[docs] def populate_instance_id_choices(self, request, context): targets = self._get_target_list() instances = [] for target in targets: instances.append((target.id, target.name)) # Sort instances for easy browsing instances = sorted(instances, key=lambda x: x[1]) neutron_enabled = api.base.is_service_enabled(request, 'network') if instances: if neutron_enabled: label = _("Select a port") else: label = _("Select an instance") instances.insert(0, ("", label)) else: if neutron_enabled: label = _("No ports available") else: label = _("No instances available") instances = (("", label),) return instances
[docs]class AssociateIP(workflows.Step): action_class = AssociateIPAction contributes = ("ip_id", "instance_id", "ip_address")
[docs] def contribute(self, data, context): context = super(AssociateIP, self).contribute(data, context) ip_id = data.get('ip_id', None) if ip_id: ip_choices = dict(self.action.fields['ip_id'].choices) context["ip_address"] = ip_choices.get(ip_id, None) return context
[docs]class IPAssociationWorkflow(workflows.Workflow): slug = "ip_association" name = _("Manage Floating IP Associations") finalize_button_name = _("Associate") success_message = _('IP address %s associated.') failure_message = _('Unable to associate IP address %s.') success_url = "horizon:project:access_and_security:index" default_steps = (AssociateIP,)
[docs] def format_status_message(self, message): if "%s" in message: return message % self.context.get('ip_address', _('unknown IP address')) else: return message
[docs] def handle(self, request, data): try: api.network.floating_ip_associate(request, data['ip_id'], data['instance_id']) except neutron_exc.Conflict: msg = _('The requested instance port is already' ' associated with another floating IP.') exceptions.handle(request, msg) self.failure_message = msg return False except Exception: exceptions.handle(request) return False return True

Project Source