Adds a "simplified" floating IP management option.

Provides one-click associate and disassociated actions when in
"simple" floating IP management mode. Complex floating IP
management is still allowed via the access & security panel,
but in general it's not necessary except when managing multiple
floating IP pools or with complex network requirements.

Implements blueprint associate-ip-one-click.

Change-Id: Iaa9333b4f9a0c1590fcee50d1e56fcbaa21a84dc
This commit is contained in:
Gabriel Hurley 2012-12-10 00:27:29 -08:00
parent e0c43a488a
commit 13e5c15387
5 changed files with 84 additions and 8 deletions

View File

@ -26,5 +26,8 @@ HORIZON_CONFIG = {
# Password configuration.
'password_validator': {'regex': '.*',
'help_text': _("Password is not accepted")}
'help_text': _("Password is not accepted")},
# Enable or disable simplified floating IP address management.
'simple_ip_management': True
}

View File

@ -524,7 +524,7 @@ class BatchAction(Action):
action_failure.append(datum_display)
exceptions.handle(request, ignore=ignore)
#Begin with success message class, downgrade to info if problems
# Begin with success message class, downgrade to info if problems.
success_message_level = messages.success
if action_not_allowed:
msg = _('You do not have permission to %(action)s: %(objs)s')

View File

@ -7,10 +7,6 @@
{% endblock page_header %}
{% block main %}
<div id="floating_ips">
{{ floating_ips_table.render }}
</div>
<div id="security_groups">
{{ security_groups_table.render }}
</div>
@ -18,4 +14,8 @@
<div id="keypairs">
{{ keypairs_table.render }}
</div>
<div id="floating_ips">
{{ floating_ips_table.render }}
</div>
{% endblock %}

View File

@ -16,12 +16,16 @@
import logging
from django import shortcuts
from django import template
from django.core import urlresolvers
from django.template.defaultfilters import title
from django.utils.http import urlencode
from django.utils.translation import ugettext_lazy as _
from horizon.conf import HORIZON_CONFIG
from horizon import exceptions
from horizon import messages
from horizon import tables
from horizon.templatetags import sizeformat
from horizon.utils.filters import replace_underscores
@ -221,6 +225,8 @@ class AssociateIP(tables.LinkAction):
classes = ("ajax-modal", "btn-associate")
def allowed(self, request, instance):
if HORIZON_CONFIG["simple_ip_management"]:
return False
return not _is_deleting(instance)
def get_link_url(self, datum):
@ -232,6 +238,68 @@ class AssociateIP(tables.LinkAction):
return "?".join([base_url, params])
class SimpleAssociateIP(tables.Action):
name = "associate"
verbose_name = _("Associate Floating IP")
classes = ("btn-associate",)
def allowed(self, request, instance):
if not HORIZON_CONFIG["simple_ip_management"]:
return False
return not _is_deleting(instance)
def single(self, table, request, instance):
try:
fip = api.nova.tenant_floating_ip_allocate(request)
api.nova.server_add_floating_ip(request, instance, fip.id)
messages.success(request,
_("Successfully associated floating IP: %s")
% fip.ip)
except:
exceptions.handle(request,
_("Unable to associate floating IP."))
return shortcuts.redirect("horizon:project:instances:index")
if HORIZON_CONFIG["simple_ip_management"]:
CurrentAssociateIP = SimpleAssociateIP
else:
CurrentAssociateIP = AssociateIP
class SimpleDisassociateIP(tables.Action):
name = "disassociate"
verbose_name = _("Disassociate Floating IP")
classes = ("btn-danger", "btn-disassociate",)
def allowed(self, request, instance):
if not HORIZON_CONFIG["simple_ip_management"]:
return False
return not _is_deleting(instance)
def single(self, table, request, instance_id):
try:
fips = [fip for fip in api.nova.tenant_floating_ip_list(request)
if fip.instance_id == instance_id]
# Removing multiple floating IPs at once doesn't work, so this pops
# off the first one.
if fips:
fip = fips.pop()
api.nova.server_remove_floating_ip(request,
instance_id,
fip.id)
api.nova.tenant_floating_ip_release(request, fip.id)
messages.success(request,
_("Successfully disassociated "
"floating IP: %s") % fip.ip)
else:
messages.info(request, _("No floating IPs to disassociate."))
except:
exceptions.handle(request,
_("Unable to disassociate floating IP."))
return shortcuts.redirect("horizon:project:instances:index")
class UpdateRow(tables.Row):
ajax = True
@ -314,6 +382,7 @@ class InstancesTable(tables.DataTable):
status_columns = ["status", "task"]
row_class = UpdateRow
table_actions = (LaunchLink, TerminateInstance)
row_actions = (CreateSnapshot, AssociateIP, EditInstance, ConsoleLink,
row_actions = (CreateSnapshot, CurrentAssociateIP,
SimpleDisassociateIP, EditInstance, ConsoleLink,
LogLink, TogglePause, ToggleSuspend, RebootInstance,
TerminateInstance)

View File

@ -30,7 +30,11 @@ HORIZON_CONFIG = {
# HORIZON_CONFIG["password_validator"] = {
# "regex": '.*',
# "help_text": _("Your password does not meet the requirements.")
# },
# }
# Disable simplified floating IP address management for deployments with
# multiple floating IP pools or complex network requirements.
# HORIZON_CONFIG["simple_ip_management"] = False
LOCAL_PATH = os.path.dirname(os.path.abspath(__file__))