Преглед на файлове

Move Floating IPs from Access & Security to panel

This patch makes the Floating IPs tab in Access & Security its own panel
under Project > Network

Change-Id: Ibb83ae5a0448d2824c10f867e620cec8219b7b72
Implements: blueprint reorganise-access-and-security
tags/11.0.0.0rc1
Rob Cresswell преди 3 години
родител
ревизия
99849ad88f
променени са 18 файла, в които са добавени 125 реда и са изтрити 231 реда
  1. +2
    -2
      openstack_dashboard/dashboards/admin/floating_ips/tables.py
  2. +2
    -2
      openstack_dashboard/dashboards/admin/floating_ips/views.py
  3. +1
    -58
      openstack_dashboard/dashboards/project/access_and_security/tabs.py
  4. +0
    -7
      openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html
  5. +4
    -102
      openstack_dashboard/dashboards/project/access_and_security/tests.py
  6. +0
    -3
      openstack_dashboard/dashboards/project/access_and_security/urls.py
  7. +0
    -0
      openstack_dashboard/dashboards/project/floating_ips/__init__.py
  8. +0
    -0
      openstack_dashboard/dashboards/project/floating_ips/forms.py
  9. +27
    -0
      openstack_dashboard/dashboards/project/floating_ips/panel.py
  10. +4
    -4
      openstack_dashboard/dashboards/project/floating_ips/tables.py
  11. +0
    -0
      openstack_dashboard/dashboards/project/floating_ips/templates/floating_ips/_allocate.html
  12. +6
    -0
      openstack_dashboard/dashboards/project/floating_ips/templates/floating_ips/allocate.html
  13. +7
    -35
      openstack_dashboard/dashboards/project/floating_ips/tests.py
  14. +2
    -3
      openstack_dashboard/dashboards/project/floating_ips/urls.py
  15. +58
    -8
      openstack_dashboard/dashboards/project/floating_ips/views.py
  16. +4
    -4
      openstack_dashboard/dashboards/project/floating_ips/workflows.py
  17. +2
    -3
      openstack_dashboard/dashboards/project/instances/tables.py
  18. +6
    -0
      openstack_dashboard/enabled/_1490_project_floating_ips_panel.py

+ 2
- 2
openstack_dashboard/dashboards/admin/floating_ips/tables.py Целия файл

@@ -23,9 +23,9 @@ from horizon import messages
from horizon import tables

from openstack_dashboard import api
from openstack_dashboard.dashboards.project.floating_ips \
import tables as project_tables
from openstack_dashboard import policy
from openstack_dashboard.dashboards.project.access_and_security.\
floating_ips import tables as project_tables
from openstack_dashboard.utils import filters



+ 2
- 2
openstack_dashboard/dashboards/admin/floating_ips/views.py Целия файл

@@ -32,8 +32,8 @@ from openstack_dashboard.dashboards.admin.floating_ips \
import forms as fip_forms
from openstack_dashboard.dashboards.admin.floating_ips \
import tables as fip_tables
from openstack_dashboard.dashboards.project.access_and_security.\
floating_ips import tables as project_tables
from openstack_dashboard.dashboards.project.floating_ips \
import tables as project_tables


def get_floatingip_pools(request):

+ 1
- 58
openstack_dashboard/dashboards/project/access_and_security/tabs.py Целия файл

@@ -25,10 +25,6 @@ from horizon import tabs
from neutronclient.common import exceptions as neutron_exc

from openstack_dashboard.api import network
from openstack_dashboard.api import nova

from openstack_dashboard.dashboards.project.access_and_security.\
floating_ips.tables import FloatingIPsTable
from openstack_dashboard.dashboards.project.access_and_security.\
security_groups.tables import SecurityGroupsTable

@@ -53,60 +49,7 @@ class SecurityGroupsTab(tabs.TableTab):
return sorted(security_groups, key=lambda group: group.name)


class FloatingIPsTab(tabs.TableTab):
table_classes = (FloatingIPsTable,)
name = _("Floating IPs")
slug = "floating_ips_tab"
template_name = "horizon/common/_detail_table.html"
permissions = ('openstack.services.compute',)

def get_floating_ips_data(self):
try:
floating_ips = network.tenant_floating_ip_list(self.request)
except neutron_exc.ConnectionFailed:
floating_ips = []
exceptions.handle(self.request)
except Exception:
floating_ips = []
exceptions.handle(self.request,
_('Unable to retrieve floating IP addresses.'))

try:
floating_ip_pools = network.floating_ip_pools_list(self.request)
except neutron_exc.ConnectionFailed:
floating_ip_pools = []
exceptions.handle(self.request)
except Exception:
floating_ip_pools = []
exceptions.handle(self.request,
_('Unable to retrieve floating IP pools.'))
pool_dict = dict([(obj.id, obj.name) for obj in floating_ip_pools])

attached_instance_ids = [ip.instance_id for ip in floating_ips
if ip.instance_id is not None]
if attached_instance_ids:
instances = []
try:
# TODO(tsufiev): we should pass attached_instance_ids to
# nova.server_list as soon as Nova API allows for this
instances, has_more = nova.server_list(self.request)
except Exception:
exceptions.handle(self.request,
_('Unable to retrieve instance list.'))

instances_dict = dict([(obj.id, obj.name) for obj in instances])

for ip in floating_ips:
ip.instance_name = instances_dict.get(ip.instance_id)
ip.pool_name = pool_dict.get(ip.pool, ip.pool)

return floating_ips

def allowed(self, request):
return network.floating_ip_supported(request)


class AccessAndSecurityTabs(tabs.TabGroup):
slug = "access_security_tabs"
tabs = (SecurityGroupsTab, FloatingIPsTab)
tabs = (SecurityGroupsTab,)
sticky = True

+ 0
- 7
openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html Целия файл

@@ -1,7 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Allocate Floating IP" %}{% endblock %}

{% block main %}
{% include 'project/access_and_security/floating_ips/_allocate.html' %}
{% endblock %}

+ 4
- 102
openstack_dashboard/dashboards/project/access_and_security/tests.py Целия файл

@@ -23,7 +23,6 @@ from django import http
from mox3.mox import IsA # noqa
import six

from horizon.workflows import views
from openstack_dashboard import api
from openstack_dashboard.test import helpers as test
from openstack_dashboard.usage import quotas
@@ -35,32 +34,14 @@ class AccessAndSecurityTests(test.TestCase):
def setUp(self):
super(AccessAndSecurityTests, self).setUp()

@test.create_stubs({api.network: ('floating_ip_supported',
'tenant_floating_ip_list',
'floating_ip_pools_list',
'security_group_list',),
api.nova: ('server_list',),
@test.create_stubs({api.network: ('security_group_list',),
api.base: ('is_service_enabled',),
quotas: ('tenant_quota_usages',)})
def _test_index(self, instanceless_ips=False):
def _test_index(self):
sec_groups = self.security_groups.list()
floating_ips = self.floating_ips.list()
floating_pools = self.pools.list()
if instanceless_ips:
for fip in floating_ips:
fip.instance_id = None
quota_data = self.quota_usages.first()
quota_data['security_groups']['available'] = 10

api.network.floating_ip_supported(IsA(http.HttpRequest)) \
.AndReturn(True)
if not instanceless_ips:
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn([self.servers.list(), False])
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(floating_ips)
api.network.floating_ip_pools_list(IsA(http.HttpRequest)) \
.AndReturn(floating_pools)
api.network.security_group_list(IsA(http.HttpRequest)) \
.AndReturn(sec_groups)
quotas.tenant_quota_usages(IsA(http.HttpRequest)).MultipleTimes() \
@@ -74,8 +55,6 @@ class AccessAndSecurityTests(test.TestCase):
res = self.client.get(INDEX_URL)

self.assertTemplateUsed(res, 'project/access_and_security/index.html')
self.assertItemsEqual(res.context['floating_ips_table'].data,
floating_ips)

# Security groups
sec_groups_from_ctx = res.context['security_groups_table'].data
@@ -93,81 +72,22 @@ class AccessAndSecurityTests(test.TestCase):
def test_index(self):
self._test_index()

def test_index_with_instanceless_fips(self):
self._test_index(instanceless_ips=True)

@test.create_stubs({api.network: ('floating_ip_target_list',
'tenant_floating_ip_list',)})
def test_association(self):
servers = [api.nova.Server(s, self.request)
for s in self.servers.list()]
# Add duplicate instance name to test instance name with [ID]
# Change id and private IP
server3 = api.nova.Server(self.servers.first(), self.request)
server3.id = 101
server3.addresses = deepcopy(server3.addresses)
server3.addresses['private'][0]['addr'] = "10.0.0.5"
servers.append(server3)

targets = [api.nova.FloatingIpTarget(s) for s in servers]

api.network.tenant_floating_ip_list(
IsA(http.HttpRequest)) \
.AndReturn(self.floating_ips.list())
api.network.floating_ip_target_list(
IsA(http.HttpRequest)) \
.AndReturn(targets)

self.mox.ReplayAll()

res = self.client.get(reverse("horizon:project:access_and_security:"
"floating_ips:associate"))

self.assertTemplateUsed(res, views.WorkflowView.template_name)
self.assertContains(res, '<option value="1">server_1 (1)</option>')
self.assertContains(res, '<option value="101">server_1 (101)</option>')
self.assertContains(res, '<option value="2">server_2 (2)</option>')


class AccessAndSecurityNeutronProxyTests(AccessAndSecurityTests):
def setUp(self):
super(AccessAndSecurityNeutronProxyTests, self).setUp()
self.floating_ips = self.floating_ips_uuid


class SecurityGroupTabTests(test.TestCase):
def setUp(self):
super(SecurityGroupTabTests, self).setUp()

@test.create_stubs({api.network: ('floating_ip_supported',
'tenant_floating_ip_list',
'security_group_list',
'floating_ip_pools_list',),
api.nova: ('server_list',),
@test.create_stubs({api.network: ('security_group_list',),
quotas: ('tenant_quota_usages',),
api.base: ('is_service_enabled',)})
def test_create_button_attributes(self):
floating_ips = self.floating_ips.list()
floating_pools = self.pools.list()
sec_groups = self.security_groups.list()
quota_data = self.quota_usages.first()
quota_data['security_groups']['available'] = 10

api.network.floating_ip_supported(
IsA(http.HttpRequest)) \
.AndReturn(True)
api.network.tenant_floating_ip_list(
IsA(http.HttpRequest)) \
.AndReturn(floating_ips)
api.network.floating_ip_pools_list(
IsA(http.HttpRequest)) \
.AndReturn(floating_pools)
api.network.security_group_list(
IsA(http.HttpRequest)) \
.AndReturn(sec_groups)
api.nova.server_list(
IsA(http.HttpRequest)) \
.AndReturn([self.servers.list(), False])
quotas.tenant_quota_usages(
IsA(http.HttpRequest)).MultipleTimes() \
.AndReturn(quota_data)
@@ -195,36 +115,18 @@ class SecurityGroupTabTests(test.TestCase):
url = 'horizon:project:access_and_security:security_groups:create'
self.assertEqual(url, create_action.url)

@test.create_stubs({api.network: ('floating_ip_supported',
'tenant_floating_ip_list',
'security_group_list',
'floating_ip_pools_list',),
api.nova: ('server_list',),
@test.create_stubs({api.network: ('security_group_list',),
quotas: ('tenant_quota_usages',),
api.base: ('is_service_enabled',)})
def _test_create_button_disabled_when_quota_exceeded(self,
network_enabled):
floating_ips = self.floating_ips.list()
floating_pools = self.pools.list()
sec_groups = self.security_groups.list()
quota_data = self.quota_usages.first()
quota_data['security_groups']['available'] = 0

api.network.floating_ip_supported(
IsA(http.HttpRequest)) \
.AndReturn(True)
api.network.tenant_floating_ip_list(
IsA(http.HttpRequest)) \
.AndReturn(floating_ips)
api.network.floating_ip_pools_list(
IsA(http.HttpRequest)) \
.AndReturn(floating_pools)
api.network.security_group_list(
IsA(http.HttpRequest)) \
.AndReturn(sec_groups)
api.nova.server_list(
IsA(http.HttpRequest)) \
.AndReturn([self.servers.list(), False])
quotas.tenant_quota_usages(
IsA(http.HttpRequest)).MultipleTimes() \
.AndReturn(quota_data)

+ 0
- 3
openstack_dashboard/dashboards/project/access_and_security/urls.py Целия файл

@@ -19,8 +19,6 @@
from django.conf.urls import include
from django.conf.urls import url

from openstack_dashboard.dashboards.project.access_and_security.\
floating_ips import urls as fip_urls
from openstack_dashboard.dashboards.project.access_and_security.\
security_groups import urls as sec_group_urls
from openstack_dashboard.dashboards.project.access_and_security import views
@@ -28,7 +26,6 @@ from openstack_dashboard.dashboards.project.access_and_security import views

urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'floating_ips/', include(fip_urls, namespace='floating_ips')),
url(r'security_groups/',
include(sec_group_urls, namespace='security_groups')),
]

openstack_dashboard/dashboards/project/access_and_security/floating_ips/__init__.py → openstack_dashboard/dashboards/project/floating_ips/__init__.py Целия файл


openstack_dashboard/dashboards/project/access_and_security/floating_ips/forms.py → openstack_dashboard/dashboards/project/floating_ips/forms.py Целия файл


+ 27
- 0
openstack_dashboard/dashboards/project/floating_ips/panel.py Целия файл

@@ -0,0 +1,27 @@
# Copyright 2017 Cisco Systems, 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.conf import settings
from django.utils.translation import ugettext_lazy as _
import horizon


class FloatingIps(horizon.Panel):
name = _("Floating IPs")
slug = 'floating_ips'

@staticmethod
def can_register():
network_config = getattr(settings, 'OPENSTACK_NEUTRON_NETWORK', {})
return network_config.get('enable_router', True)

openstack_dashboard/dashboards/project/access_and_security/floating_ips/tables.py → openstack_dashboard/dashboards/project/floating_ips/tables.py Целия файл

@@ -41,10 +41,10 @@ class AllocateIP(tables.LinkAction):
verbose_name = _("Allocate IP To Project")
classes = ("ajax-modal",)
icon = "link"
url = "horizon:project:access_and_security:floating_ips:allocate"
url = "horizon:project:floating_ips:allocate"

def single(self, data_table, request, *args):
return shortcuts.redirect('horizon:project:access_and_security:index')
return shortcuts.redirect('horizon:project:floating_ips:index')

def allowed(self, request, fip=None):
usages = quotas.tenant_quota_usages(request)
@@ -106,7 +106,7 @@ class ReleaseIPs(tables.BatchAction):
class AssociateIP(tables.LinkAction):
name = "associate"
verbose_name = _("Associate")
url = "horizon:project:access_and_security:floating_ips:associate"
url = "horizon:project:floating_ips:associate"
classes = ("ajax-modal",)
icon = "link"

@@ -152,7 +152,7 @@ class DisassociateIP(tables.Action):
except Exception:
exceptions.handle(request,
_('Unable to disassociate floating IP.'))
return shortcuts.redirect('horizon:project:access_and_security:index')
return shortcuts.redirect('horizon:project:floating_ips:index')


def get_instance_info(fip):

openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html → openstack_dashboard/dashboards/project/floating_ips/templates/floating_ips/_allocate.html Целия файл


+ 6
- 0
openstack_dashboard/dashboards/project/floating_ips/templates/floating_ips/allocate.html Целия файл

@@ -0,0 +1,6 @@
{% extends 'base.html' %}
{% load i18n %}

{% block main %}
{% include 'project/floating_ips/_allocate.html' %}
{% endblock %}

openstack_dashboard/dashboards/project/access_and_security/floating_ips/tests.py → openstack_dashboard/dashboards/project/floating_ips/tests.py Целия файл

@@ -31,8 +31,8 @@ from openstack_dashboard.usage import quotas
from horizon.workflows import views


INDEX_URL = reverse('horizon:project:access_and_security:index')
NAMESPACE = "horizon:project:access_and_security:floating_ips"
INDEX_URL = reverse('horizon:project:floating_ips:index')
NAMESPACE = "horizon:project:floating_ips"


class FloatingIpViewTests(test.TestCase):
@@ -167,7 +167,6 @@ class FloatingIpViewTests(test.TestCase):

@test.create_stubs({api.nova: ('server_list',),
api.network: ('floating_ip_disassociate',
'floating_ip_supported',
'tenant_floating_ip_get',
'tenant_floating_ip_list',),
api.neutron: ('is_extension_supported',)})
@@ -176,8 +175,6 @@ class FloatingIpViewTests(test.TestCase):

api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn([self.servers.list(), False])
api.network.floating_ip_supported(IsA(http.HttpRequest)) \
.AndReturn(True)
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(self.floating_ips.list())
api.neutron.is_extension_supported(IsA(http.HttpRequest),
@@ -194,7 +191,6 @@ class FloatingIpViewTests(test.TestCase):

@test.create_stubs({api.nova: ('server_list',),
api.network: ('floating_ip_disassociate',
'floating_ip_supported',
'tenant_floating_ip_get',
'tenant_floating_ip_list',),
api.neutron: ('is_extension_supported',)})
@@ -203,8 +199,6 @@ class FloatingIpViewTests(test.TestCase):

api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn([self.servers.list(), False])
api.network.floating_ip_supported(IsA(http.HttpRequest)) \
.AndReturn(True)
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(self.floating_ips.list())
api.neutron.is_extension_supported(IsA(http.HttpRequest),
@@ -220,9 +214,7 @@ class FloatingIpViewTests(test.TestCase):
res = self.client.post(INDEX_URL, {"action": action})
self.assertRedirectsNoFollow(res, INDEX_URL)

@test.create_stubs({api.network: ('floating_ip_supported',
'tenant_floating_ip_list',
'security_group_list',
@test.create_stubs({api.network: ('tenant_floating_ip_list',
'floating_ip_pools_list',),
api.nova: ('server_list',),
quotas: ('tenant_quota_usages',),
@@ -232,17 +224,10 @@ class FloatingIpViewTests(test.TestCase):
floating_pools = self.pools.list()
quota_data = self.quota_usages.first()
quota_data['floating_ips']['available'] = 10
sec_groups = self.security_groups.list()

api.network.floating_ip_supported(
IsA(http.HttpRequest)) \
.AndReturn(True)
api.network.tenant_floating_ip_list(
IsA(http.HttpRequest)) \
.AndReturn(floating_ips)
api.network.security_group_list(
IsA(http.HttpRequest)).MultipleTimes()\
.AndReturn(sec_groups)
api.network.floating_ip_pools_list(
IsA(http.HttpRequest)) \
.AndReturn(floating_pools)
@@ -252,7 +237,6 @@ class FloatingIpViewTests(test.TestCase):
quotas.tenant_quota_usages(
IsA(http.HttpRequest)).MultipleTimes() \
.AndReturn(quota_data)

api.base.is_service_enabled(
IsA(http.HttpRequest),
'network').MultipleTimes() \
@@ -260,8 +244,7 @@ class FloatingIpViewTests(test.TestCase):

self.mox.ReplayAll()

res = self.client.get(INDEX_URL +
"?tab=access_security_tabs__floating_ips_tab")
res = self.client.get(INDEX_URL)

allocate_action = self.getAndAssertTableAction(res, 'floating_ips',
'allocate')
@@ -270,12 +253,10 @@ class FloatingIpViewTests(test.TestCase):
six.text_type(allocate_action.verbose_name))
self.assertIsNone(allocate_action.policy_rules)

url = 'horizon:project:access_and_security:floating_ips:allocate'
url = 'horizon:project:floating_ips:allocate'
self.assertEqual(url, allocate_action.url)

@test.create_stubs({api.network: ('floating_ip_supported',
'tenant_floating_ip_list',
'security_group_list',
@test.create_stubs({api.network: ('tenant_floating_ip_list',
'floating_ip_pools_list',),
api.nova: ('server_list',),
quotas: ('tenant_quota_usages',),
@@ -285,17 +266,10 @@ class FloatingIpViewTests(test.TestCase):
floating_pools = self.pools.list()
quota_data = self.quota_usages.first()
quota_data['floating_ips']['available'] = 0
sec_groups = self.security_groups.list()

api.network.floating_ip_supported(
IsA(http.HttpRequest)) \
.AndReturn(True)
api.network.tenant_floating_ip_list(
IsA(http.HttpRequest)) \
.AndReturn(floating_ips)
api.network.security_group_list(
IsA(http.HttpRequest)).MultipleTimes()\
.AndReturn(sec_groups)
api.network.floating_ip_pools_list(
IsA(http.HttpRequest)) \
.AndReturn(floating_pools)
@@ -305,7 +279,6 @@ class FloatingIpViewTests(test.TestCase):
quotas.tenant_quota_usages(
IsA(http.HttpRequest)).MultipleTimes() \
.AndReturn(quota_data)

api.base.is_service_enabled(
IsA(http.HttpRequest),
'network').MultipleTimes() \
@@ -313,8 +286,7 @@ class FloatingIpViewTests(test.TestCase):

self.mox.ReplayAll()

res = self.client.get(INDEX_URL +
"?tab=access_security_tabs__floating_ips_tab")
res = self.client.get(INDEX_URL)

allocate_action = self.getAndAssertTableAction(res, 'floating_ips',
'allocate')

openstack_dashboard/dashboards/project/access_and_security/floating_ips/urls.py → openstack_dashboard/dashboards/project/floating_ips/urls.py Целия файл

@@ -18,11 +18,10 @@

from django.conf.urls import url

from openstack_dashboard.dashboards.project.access_and_security.\
floating_ips import views

from openstack_dashboard.dashboards.project.floating_ips import views

urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^associate/$', views.AssociateView.as_view(), name='associate'),
url(r'^allocate/$', views.AllocateView.as_view(), name='allocate'),
]

openstack_dashboard/dashboards/project/access_and_security/floating_ips/views.py → openstack_dashboard/dashboards/project/floating_ips/views.py Целия файл

@@ -28,15 +28,18 @@ from neutronclient.common import exceptions as neutron_exc

from horizon import exceptions
from horizon import forms
from horizon import tables
from horizon import workflows

from openstack_dashboard import api
from openstack_dashboard.usage import quotas

from openstack_dashboard.dashboards.project.access_and_security.\
floating_ips import forms as project_forms
from openstack_dashboard.dashboards.project.access_and_security.\
floating_ips import workflows as project_workflows
from openstack_dashboard.dashboards.project.floating_ips \
import forms as project_forms
from openstack_dashboard.dashboards.project.floating_ips \
import tables as project_tables
from openstack_dashboard.dashboards.project.floating_ips \
import workflows as project_workflows


class AssociateView(workflows.WorkflowView):
@@ -47,11 +50,10 @@ class AllocateView(forms.ModalFormView):
form_class = project_forms.FloatingIpAllocate
form_id = "associate_floating_ip_form"
page_title = _("Allocate Floating IP")
template_name = 'project/access_and_security/floating_ips/allocate.html'
template_name = 'project/floating_ips/allocate.html'
submit_label = _("Allocate IP")
submit_url = reverse_lazy(
"horizon:project:access_and_security:floating_ips:allocate")
success_url = reverse_lazy('horizon:project:access_and_security:index')
submit_url = reverse_lazy("horizon:project:floating_ips:allocate")
success_url = reverse_lazy('horizon:project:floating_ips:index')

def get_object_display(self, obj):
return obj.ip
@@ -78,3 +80,51 @@ class AllocateView(forms.ModalFormView):
if not pool_list:
pool_list = [(None, _("No floating IP pools available"))]
return {'pool_list': pool_list}


class IndexView(tables.DataTableView):
table_class = project_tables.FloatingIPsTable
page_title = _("Floating IPs")

def get_data(self):
try:
floating_ips = api.network.tenant_floating_ip_list(self.request)
except neutron_exc.ConnectionFailed:
floating_ips = []
exceptions.handle(self.request)
except Exception:
floating_ips = []
exceptions.handle(self.request,
_('Unable to retrieve floating IP addresses.'))

try:
floating_ip_pools = \
api.network.floating_ip_pools_list(self.request)
except neutron_exc.ConnectionFailed:
floating_ip_pools = []
exceptions.handle(self.request)
except Exception:
floating_ip_pools = []
exceptions.handle(self.request,
_('Unable to retrieve floating IP pools.'))
pool_dict = dict([(obj.id, obj.name) for obj in floating_ip_pools])

attached_instance_ids = [ip.instance_id for ip in floating_ips
if ip.instance_id is not None]
if attached_instance_ids:
instances = []
try:
# TODO(tsufiev): we should pass attached_instance_ids to
# nova.server_list as soon as Nova API allows for this
instances, has_more = api.nova.server_list(self.request)
except Exception:
exceptions.handle(self.request,
_('Unable to retrieve instance list.'))

instances_dict = dict([(obj.id, obj.name) for obj in instances])

for ip in floating_ips:
ip.instance_name = instances_dict.get(ip.instance_id)
ip.pool_name = pool_dict.get(ip.pool, ip.pool)

return floating_ips

openstack_dashboard/dashboards/project/access_and_security/floating_ips/workflows.py → openstack_dashboard/dashboards/project/floating_ips/workflows.py Целия файл

@@ -26,7 +26,7 @@ from openstack_dashboard import api
from openstack_dashboard.utils import filters


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


class AssociateIPAction(workflows.Action):
@@ -72,7 +72,7 @@ class AssociateIPAction(workflows.Action):

def populate_ip_id_choices(self, request, context):
ips = []
redirect = reverse('horizon:project:access_and_security:index')
redirect = reverse('horizon:project:floating_ips:index')
try:
ips = api.network.tenant_floating_ip_list(self.request)
except neutron_exc.ConnectionFailed:
@@ -95,7 +95,7 @@ class AssociateIPAction(workflows.Action):
try:
targets = api.network.floating_ip_target_list(self.request)
except Exception:
redirect = reverse('horizon:project:access_and_security:index')
redirect = reverse('horizon:project:floating_ips:index')
exceptions.handle(self.request,
_('Unable to retrieve instance list.'),
redirect=redirect)
@@ -146,7 +146,7 @@ class IPAssociationWorkflow(workflows.Workflow):
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"
success_url = "horizon:project:floating_ips:index"
default_steps = (AssociateIP,)

def format_status_message(self, message):

+ 2
- 3
openstack_dashboard/dashboards/project/instances/tables.py Целия файл

@@ -36,8 +36,7 @@ from horizon.templatetags import sizeformat
from horizon.utils import filters

from openstack_dashboard import api
from openstack_dashboard.dashboards.project.access_and_security.floating_ips \
import workflows
from openstack_dashboard.dashboards.project.floating_ips import workflows
from openstack_dashboard.dashboards.project.instances import tabs
from openstack_dashboard.dashboards.project.instances.workflows \
import resize_instance
@@ -617,7 +616,7 @@ class DecryptInstancePassword(tables.LinkAction):
class AssociateIP(policy.PolicyTargetMixin, tables.LinkAction):
name = "associate"
verbose_name = _("Associate Floating IP")
url = "horizon:project:access_and_security:floating_ips:associate"
url = "horizon:project:floating_ips:associate"
classes = ("ajax-modal",)
icon = "link"
policy_rules = (("compute", "network:associate_floating_ip"),)

+ 6
- 0
openstack_dashboard/enabled/_1490_project_floating_ips_panel.py Целия файл

@@ -0,0 +1,6 @@
PANEL_DASHBOARD = 'project'
PANEL_GROUP = 'network'
PANEL = 'floating_ips'

ADD_PANEL = \
'openstack_dashboard.dashboards.project.floating_ips.panel.FloatingIps'

Loading…
Отказ
Запис