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:
parent
e0c43a488a
commit
13e5c15387
@ -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
|
||||
}
|
||||
|
@ -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')
|
||||
|
@ -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 %}
|
||||
|
@ -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)
|
||||
|
@ -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__))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user