Remove router actions from Admin panel
add-interface/set-gateway/create-router actions in Admin Router panel are no longer needed since all of these operations now can be done by regular users. Moreover, there is a bug that admin cannot add an interface of other tenant to a router in Admin Router panel and the behavior is confusing for users. Consindering the above, this commit remove forms create/modifying quantum routers. After the commit admin router panel just provides the list of routers of all tenants and removes them. Fixes bug #1153754 Change-Id: Ie17601b260fc6584ba21cd19dc9492bf16b267c1
This commit is contained in:
parent
ff270d1059
commit
8ac3e38c57
@ -1,71 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012, Nachi Ueno, NTT MCL, 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.
|
||||
|
||||
"""
|
||||
Views for managing Quantum Routers.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import forms
|
||||
from horizon import exceptions
|
||||
from horizon import messages
|
||||
from openstack_dashboard import api
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CreateForm(forms.SelfHandlingForm):
|
||||
name = forms.CharField(max_length="255",
|
||||
label=_("Router Name"),
|
||||
required=False)
|
||||
tenant_id = forms.ChoiceField(label=_("Project"))
|
||||
failure_url = 'horizon:admin:routers:index'
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(CreateForm, self).__init__(request, *args, **kwargs)
|
||||
tenant_choices = [('', _("Select a project"))]
|
||||
try:
|
||||
for tenant in api.keystone.tenant_list(request, admin=True):
|
||||
if tenant.enabled:
|
||||
tenant_choices.append((tenant.id, tenant.name))
|
||||
except:
|
||||
msg = _('Failed to get tenants.')
|
||||
LOG.warn(msg)
|
||||
redirect = reverse(self.failure_url)
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
return
|
||||
|
||||
self.fields['tenant_id'].choices = tenant_choices
|
||||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
params = {}
|
||||
if data.get('tenant_id'):
|
||||
params['tenant_id'] = data['tenant_id']
|
||||
router = api.quantum.router_create(request,
|
||||
name=data['name'], **params)
|
||||
message = 'Creating router "%s"' % data['name']
|
||||
messages.info(request, message)
|
||||
return router
|
||||
except:
|
||||
msg = _('Failed to create router "%s".') % data['name']
|
||||
LOG.warn(msg)
|
||||
redirect = reverse(self.failure_url)
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
return False
|
@ -1,31 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012, Nachi Ueno, NTT MCL, 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.
|
||||
|
||||
import logging
|
||||
|
||||
from openstack_dashboard.dashboards.project.routers.ports import (
|
||||
forms as p_forms)
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AddInterface(p_forms.AddInterface):
|
||||
failure_url = 'horizon:admin:routers:detail'
|
||||
|
||||
|
||||
class SetGatewayForm(p_forms.SetGatewayForm):
|
||||
failure_url = 'horizon:admin:routers:index'
|
@ -21,8 +21,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import tables
|
||||
from openstack_dashboard.dashboards.project.networks.ports.tables import\
|
||||
get_fixed_ips, get_attached
|
||||
from openstack_dashboard.dashboards.project.routers.ports import\
|
||||
tables as r_tables
|
||||
from openstack_dashboard.dashboards.project.routers.ports.tables import\
|
||||
get_device_owner
|
||||
|
||||
@ -30,20 +28,11 @@ from openstack_dashboard.dashboards.project.routers.ports.tables import\
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AddInterface(r_tables.AddInterface):
|
||||
url = "horizon:admin:routers:addinterface"
|
||||
|
||||
|
||||
class RemoveInterface(r_tables.RemoveInterface):
|
||||
failure_url = 'horizon:admin:routers:detail'
|
||||
|
||||
|
||||
class PortsTable(tables.DataTable):
|
||||
name = tables.Column("name",
|
||||
verbose_name=_("Name"),
|
||||
link="horizon:admin:networks:ports:detail")
|
||||
fixed_ips = tables.Column(get_fixed_ips, verbose_name=_("Fixed IPs"))
|
||||
attached = tables.Column(get_attached, verbose_name=_("Device Attached"))
|
||||
status = tables.Column("status", verbose_name=_("Status"))
|
||||
device_owner = tables.Column(get_device_owner,
|
||||
verbose_name=_("Type"))
|
||||
@ -56,5 +45,3 @@ class PortsTable(tables.DataTable):
|
||||
class Meta:
|
||||
name = "interfaces"
|
||||
verbose_name = _("Interfaces")
|
||||
table_actions = (AddInterface, RemoveInterface)
|
||||
row_actions = (RemoveInterface, )
|
||||
|
@ -18,27 +18,11 @@ import logging
|
||||
|
||||
from horizon import tabs
|
||||
from .tabs import PortDetailTabs
|
||||
from .forms import (AddInterface, SetGatewayForm)
|
||||
from openstack_dashboard.dashboards.project.routers.ports import views
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AddInterfaceView(views.AddInterfaceView):
|
||||
form_class = AddInterface
|
||||
template_name = 'admin/routers/ports/create.html'
|
||||
success_url = 'horizon:admin:routers:detail'
|
||||
failure_url = 'horizon:admin:routers:detail'
|
||||
|
||||
|
||||
class SetGatewayView(views.SetGatewayView):
|
||||
form_class = SetGatewayForm
|
||||
template_name = 'admin/routers/ports/setgateway.html'
|
||||
success_url = 'horizon:admin:routers:index'
|
||||
failure_url = 'horizon:admin:routers:index'
|
||||
|
||||
|
||||
class DetailView(tabs.TabView):
|
||||
tab_group_class = PortDetailTabs
|
||||
template_name = 'admin/networks/ports/detail.html'
|
||||
|
@ -30,25 +30,19 @@ LOG = logging.getLogger(__name__)
|
||||
class DeleteRouter(r_tables.DeleteRouter):
|
||||
redirect_url = "horizon:admin:routers:index"
|
||||
|
||||
def delete(self, request, obj_id):
|
||||
search_opts = {'device_owner': 'network:router_interface',
|
||||
'device_id': obj_id}
|
||||
ports = api.quantum.port_list(request, **search_opts)
|
||||
for port in ports:
|
||||
api.quantum.router_remove_interface(request, obj_id,
|
||||
port_id=port.id)
|
||||
super(DeleteRouter, self).delete(request, obj_id)
|
||||
|
||||
def allowed(self, request, router=None):
|
||||
return True
|
||||
|
||||
|
||||
class CreateRouter(tables.LinkAction):
|
||||
name = "create"
|
||||
verbose_name = _("Create Router")
|
||||
url = "horizon:admin:routers:create"
|
||||
classes = ("ajax-modal", "btn-create")
|
||||
|
||||
|
||||
class SetGateway(r_tables.SetGateway):
|
||||
url = "horizon:admin:routers:setgateway"
|
||||
|
||||
|
||||
class ClearGateway(r_tables.ClearGateway):
|
||||
redirect_url = "horizon:admin:routers:index"
|
||||
|
||||
|
||||
class UpdateRow(tables.Row):
|
||||
ajax = True
|
||||
|
||||
@ -77,5 +71,5 @@ class RoutersTable(tables.DataTable):
|
||||
verbose_name = _("Routers")
|
||||
status_columns = ["status"]
|
||||
row_class = UpdateRow
|
||||
table_actions = (CreateRouter, DeleteRouter)
|
||||
row_actions = (SetGateway, ClearGateway, DeleteRouter)
|
||||
table_actions = (DeleteRouter,)
|
||||
row_actions = (DeleteRouter,)
|
||||
|
@ -1,21 +0,0 @@
|
||||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n horizon humanize %}
|
||||
|
||||
{% block form_id %}{% endblock %}
|
||||
{% block form_action %}{% url horizon:admin:routers:create %}?{{ request.GET.urlencode }}{% endblock %}
|
||||
|
||||
{% block modal_id %}create_router_modal{% endblock %}
|
||||
{% block modal-header %}{% trans "Create router" %}{% endblock %}
|
||||
|
||||
{% block modal-body %}
|
||||
<div class="left">
|
||||
<fieldset>
|
||||
{% include "horizon/common/_form_fields.html" %}
|
||||
</fieldset>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block modal-footer %}
|
||||
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Create router" %}" />
|
||||
<a href="{% url horizon:admin:routers:index %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
|
||||
{% endblock %}
|
@ -1,11 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Create Router" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Create a Router") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'admin/routers/_create.html' %}
|
||||
{% endblock %}
|
@ -1,25 +0,0 @@
|
||||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block form_id %}add_interface_form{% endblock %}
|
||||
{% block form_action %}{% url horizon:admin:routers:addinterface router.id %}
|
||||
{% endblock %}
|
||||
|
||||
{% block modal-header %}{% trans "Add Interface" %}{% endblock %}
|
||||
|
||||
{% block modal-body %}
|
||||
<div class="left">
|
||||
<fieldset>
|
||||
{% include "horizon/common/_form_fields.html" %}
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="right">
|
||||
<h3>{% trans "Description" %}:</h3>
|
||||
<p>{% trans "You can connect a specified subnet to the router." %}</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block modal-footer %}
|
||||
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Add interface" %}" />
|
||||
<a href="{% url horizon:admin:routers:detail router.id %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
|
||||
{% endblock %}
|
@ -1,25 +0,0 @@
|
||||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block form_id %}setgateway_form{% endblock %}
|
||||
{% block form_action %}{% url horizon:admin:routers:setgateway router.id %}
|
||||
{% endblock %}
|
||||
|
||||
{% block modal-header %}{% trans "Set Gateway" %}{% endblock %}
|
||||
|
||||
{% block modal-body %}
|
||||
<div class="left">
|
||||
<fieldset>
|
||||
{% include "horizon/common/_form_fields.html" %}
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="right">
|
||||
<h3>{% trans "Description" %}:</h3>
|
||||
<p>{% trans "You can connect a specified external network to the router. The external network is regarded as a default route of the router and the router acts as a gateway for external connectivity." %}</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block modal-footer %}
|
||||
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Set Gateway" %}" />
|
||||
<a href="{% url horizon:admin:routers:detail router.id %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
|
||||
{% endblock %}
|
@ -1,11 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Add Interface" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Add Interface") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
{% include "admin/routers/ports/_create.html" %}
|
||||
{% endblock %}
|
@ -1,11 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Set Gateway" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Set Gateway") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
{% include "admin/routers/ports/_setgateway.html" %}
|
||||
{% endblock %}
|
@ -60,46 +60,3 @@ class RouterTests(test.BaseAdminViewTests, r_test.RouterTests):
|
||||
self.assertTemplateUsed(res, '%s/routers/index.html' % self.DASHBOARD)
|
||||
self.assertEqual(len(res.context['table'].data), 0)
|
||||
self.assertMessageCount(res, error=1)
|
||||
|
||||
@test.create_stubs({api.quantum: ('router_list', 'router_create'),
|
||||
api.keystone: ('tenant_list',)})
|
||||
def test_router_create_post(self):
|
||||
router = self.routers.first()
|
||||
tenants = self.tenants.list()
|
||||
api.quantum.router_create(
|
||||
IsA(http.HttpRequest),
|
||||
name=router.name,
|
||||
tenant_id=router.tenant_id).AndReturn(router)
|
||||
api.keystone.tenant_list(IsA(http.HttpRequest), admin=True)\
|
||||
.AndReturn(tenants)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
form_data = {'name': router.name,
|
||||
'tenant_id': router.tenant_id}
|
||||
url = reverse('horizon:%s:routers:create' % self.DASHBOARD)
|
||||
res = self.client.post(url, form_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, self.INDEX_URL)
|
||||
|
||||
@test.create_stubs({api.quantum: ('router_list', 'router_create'),
|
||||
api.keystone: ('tenant_list',)})
|
||||
def test_router_create_post_exception(self):
|
||||
router = self.routers.first()
|
||||
tenants = self.tenants.list()
|
||||
api.quantum.router_create(
|
||||
IsA(http.HttpRequest),
|
||||
name=router.name,
|
||||
tenant_id=router.tenant_id).AndRaise(self.exceptions.quantum)
|
||||
api.keystone.tenant_list(IsA(http.HttpRequest), admin=True)\
|
||||
.AndReturn(tenants)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
form_data = {'name': router.name,
|
||||
'tenant_id': router.tenant_id}
|
||||
url = reverse('horizon:%s:routers:create' % self.DASHBOARD)
|
||||
res = self.client.post(url, form_data)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertRedirectsNoFollow(res, self.INDEX_URL)
|
||||
|
@ -16,19 +16,12 @@
|
||||
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
from .views import (IndexView, CreateView, DetailView)
|
||||
from .ports.views import (AddInterfaceView, SetGatewayView)
|
||||
from .views import (IndexView, DetailView)
|
||||
|
||||
|
||||
urlpatterns = patterns('horizon.dashboards.admin.routers.views',
|
||||
url(r'^$', IndexView.as_view(), name='index'),
|
||||
url(r'^create/$', CreateView.as_view(), name='create'),
|
||||
url(r'^(?P<router_id>[^/]+)/$',
|
||||
DetailView.as_view(),
|
||||
name='detail'),
|
||||
url(r'^(?P<router_id>[^/]+)/addinterface', AddInterfaceView.as_view(),
|
||||
name='addinterface'),
|
||||
url(r'^(?P<router_id>[^/]+)/setgateway',
|
||||
SetGatewayView.as_view(),
|
||||
name='setgateway'),
|
||||
)
|
||||
|
@ -24,13 +24,11 @@ from django.core.urlresolvers import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.dashboards.admin.networks import views as n_views
|
||||
from openstack_dashboard.dashboards.project.routers import views as r_views
|
||||
|
||||
from .ports.tables import PortsTable
|
||||
from .forms import CreateForm
|
||||
from .tables import RoutersTable
|
||||
|
||||
|
||||
@ -71,9 +69,3 @@ class DetailView(r_views.DetailView):
|
||||
table_classes = (PortsTable, )
|
||||
template_name = 'admin/routers/detail.html'
|
||||
failure_url = reverse_lazy('horizon:admin:routers:index')
|
||||
|
||||
|
||||
class CreateView(forms.ModalFormView):
|
||||
form_class = CreateForm
|
||||
template_name = 'admin/routers/create.html'
|
||||
success_url = reverse_lazy("horizon:admin:routers:index")
|
||||
|
@ -23,14 +23,16 @@ from horizon import exceptions
|
||||
from horizon import tables
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.dashboards.project.networks.ports.tables import\
|
||||
get_fixed_ips, get_attached
|
||||
get_fixed_ips
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_device_owner(port):
|
||||
if port['device_owner'] == 'network:router_gateway':
|
||||
return _('Gateway')
|
||||
return _('External Gateway')
|
||||
elif port['device_owner'] == 'network:router_interface':
|
||||
return _('Internal Interface')
|
||||
else:
|
||||
return ' '
|
||||
|
||||
@ -75,7 +77,6 @@ class PortsTable(tables.DataTable):
|
||||
verbose_name=_("Name"),
|
||||
link="horizon:project:networks:ports:detail")
|
||||
fixed_ips = tables.Column(get_fixed_ips, verbose_name=_("Fixed IPs"))
|
||||
attached = tables.Column(get_attached, verbose_name=_("Device Attached"))
|
||||
status = tables.Column("status", verbose_name=_("Status"))
|
||||
device_owner = tables.Column(get_device_owner,
|
||||
verbose_name=_("Type"))
|
||||
|
@ -104,6 +104,12 @@ class RouterTests(test.TestCase):
|
||||
args=[router.id]))
|
||||
self.assertRedirectsNoFollow(res, self.INDEX_URL)
|
||||
|
||||
|
||||
class RouterActionTests(test.TestCase):
|
||||
DASHBOARD = 'project'
|
||||
INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD)
|
||||
DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD
|
||||
|
||||
@test.create_stubs({api.quantum: ('router_create',)})
|
||||
def test_router_create_post(self):
|
||||
router = self.routers.first()
|
||||
|
@ -82,7 +82,7 @@ def data(TEST):
|
||||
'device_owner': 'network:dhcp',
|
||||
'fixed_ips': [{'ip_address': '10.0.0.3',
|
||||
'subnet_id': subnet_dict['id']}],
|
||||
'id': '3ec7f3db-cb2f-4a34-ab6b-69a64d3f008c',
|
||||
'id': '063cf7f3-ded1-4297-bc4c-31eae876cc91',
|
||||
'mac_address': 'fa:16:3e:9c:d5:7e',
|
||||
'name': '',
|
||||
'network_id': network_dict['id'],
|
||||
@ -197,7 +197,7 @@ def data(TEST):
|
||||
'device_owner': 'network:router_gateway',
|
||||
'fixed_ips': [{'ip_address': '10.0.0.3',
|
||||
'subnet_id': subnet_dict['id']}],
|
||||
'id': '3ec7f3db-cb2f-4a34-ab6b-69a64d3f008c',
|
||||
'id': '44ec6726-4bdc-48c5-94d4-df8d1fbf613b',
|
||||
'mac_address': 'fa:16:3e:9c:d5:7e',
|
||||
'name': '',
|
||||
'network_id': network_dict['id'],
|
||||
@ -213,8 +213,8 @@ def data(TEST):
|
||||
'tenant_id': '1'}
|
||||
TEST.api_routers.add(router_dict)
|
||||
TEST.routers.add(Router(router_dict))
|
||||
router_dict = {'id': '279989f7-54bb-41d9-ba42-0d61f12fda61',
|
||||
'name': 'router1',
|
||||
router_dict = {'id': '10e3dc42-1ce1-4d48-87cf-7fc333055d6c',
|
||||
'name': 'router2',
|
||||
'external_gateway_info':
|
||||
{'network_id': ext_net['id']},
|
||||
'tenant_id': '1'}
|
||||
|
Loading…
x
Reference in New Issue
Block a user