Add Curvature topology
Replace the current network topology with the visualisation from the Curvature user interface Implements: blueprint curvature-network-topology Change-Id: I4435ab9b54ce51540c3346aa709f0fa8bbcb87b4
This commit is contained in:
parent
d83de86ab8
commit
e0ac95be33
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright 2015 Cisco Systems.
|
||||||
|
#
|
||||||
|
# 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.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from openstack_dashboard.dashboards.project.networks import tables
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteNetwork(tables.DeleteNetwork):
|
||||||
|
redirect_url = "horizon:project:network_topology:network"
|
||||||
|
|
||||||
|
|
||||||
|
class NetworksTable(tables.NetworksTable):
|
||||||
|
class Meta(object):
|
||||||
|
name = "networks"
|
||||||
|
verbose_name = _("Networks")
|
||||||
|
table_actions = (DeleteNetwork,)
|
||||||
|
row_actions = (DeleteNetwork,)
|
@ -0,0 +1,30 @@
|
|||||||
|
# Copyright 2015 Cisco Systems.
|
||||||
|
#
|
||||||
|
# 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.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from openstack_dashboard.dashboards.project.networks.subnets import tables
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteSubnet(tables.DeleteSubnet):
|
||||||
|
failure_url = 'horizon:project:network_topology:network'
|
||||||
|
|
||||||
|
|
||||||
|
class SubnetsTable(tables.SubnetsTable):
|
||||||
|
class Meta(object):
|
||||||
|
name = "subnets"
|
||||||
|
verbose_name = _("Subnets")
|
||||||
|
row_actions = (DeleteSubnet, )
|
||||||
|
table_actions = (DeleteSubnet, )
|
@ -1,222 +0,0 @@
|
|||||||
{% load i18n %}
|
|
||||||
<style type="text/css">
|
|
||||||
svg#topology_canvas {
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .network-rect {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .network-rect.nourl {
|
|
||||||
cursor: auto;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .network-name {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 12px;
|
|
||||||
fill: #fff;
|
|
||||||
text-anchor: middle;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .network-cidr {
|
|
||||||
font-size: 11px;
|
|
||||||
text-anchor: end;
|
|
||||||
}
|
|
||||||
svg#topology_canvas text.network-type {
|
|
||||||
font-family: FontAwesome;
|
|
||||||
text-anchor: end;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .port_text {
|
|
||||||
font-size: 9px;
|
|
||||||
fill: #666;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .port_text.left {
|
|
||||||
text-anchor: end;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .base_bg_normal {
|
|
||||||
fill: #333;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .loading_bg_normal {
|
|
||||||
fill: #555;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .base_bg_small,
|
|
||||||
svg#topology_canvas .loading_bg_small {
|
|
||||||
fill: #fff;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .active {
|
|
||||||
fill: #45B035;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .icon polygon {
|
|
||||||
fill: #333;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .instance_small .frame,
|
|
||||||
svg#topology_canvas .router_small .frame {
|
|
||||||
fill: url(#device_small_bg);
|
|
||||||
stroke: #333;
|
|
||||||
stroke-width: 3;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .instance_small .port_text,
|
|
||||||
svg#topology_canvas .router_small .port_text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .router_normal .frame,
|
|
||||||
svg#topology_canvas .instance_normal .frame {
|
|
||||||
fill: #fff;
|
|
||||||
stroke: #333;
|
|
||||||
stroke-width: 4;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .router_normal .icon_bg,
|
|
||||||
svg#topology_canvas .instance_normal .icon_bg {
|
|
||||||
fill: #fff;
|
|
||||||
stroke: #333;
|
|
||||||
stroke-width: 4;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .router_normal .texts_bg,
|
|
||||||
svg#topology_canvas .instance_normal .texts_bg {
|
|
||||||
fill: url('#device_normal_bg');
|
|
||||||
}
|
|
||||||
svg#topology_canvas .router_normal .texts .name,
|
|
||||||
svg#topology_canvas .instance_normal .texts .name {
|
|
||||||
text-anchor: middle;
|
|
||||||
fill: #333;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .router_normal .texts .type,
|
|
||||||
svg#topology_canvas .instance_normal .texts .type {
|
|
||||||
text-anchor: middle;
|
|
||||||
fill: #fff;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
svg#topology_canvas .router_normal .instance_bg,
|
|
||||||
svg#topology_canvas .instance_normal .instance_bg {
|
|
||||||
fill: #333;
|
|
||||||
}
|
|
||||||
svg#topology_canvas g.loading .active {
|
|
||||||
fill: #555;
|
|
||||||
}
|
|
||||||
svg#topology_canvas g.loading .icon polygon {
|
|
||||||
fill: #555;
|
|
||||||
}
|
|
||||||
svg#topology_canvas g.loading .instance_bg {
|
|
||||||
fill: #555;
|
|
||||||
}
|
|
||||||
svg#topology_canvas g.loading .instance_small .frame,
|
|
||||||
svg#topology_canvas g.loading .router_small .frame {
|
|
||||||
stroke: #555;
|
|
||||||
fill: url(#device_small_bg_loading);
|
|
||||||
}
|
|
||||||
svg#topology_canvas g.loading .router_normal .frame,
|
|
||||||
svg#topology_canvas g.loading .instance_normal .frame {
|
|
||||||
stroke: #555;
|
|
||||||
}
|
|
||||||
svg#topology_canvas g.loading .router_normal .name,
|
|
||||||
svg#topology_canvas g.loading .instance_normal .name {
|
|
||||||
fill: #999;
|
|
||||||
}
|
|
||||||
svg#topology_canvas g.loading .router_normal .texts_bg,
|
|
||||||
svg#topology_canvas g.loading .instance_normal .texts_bg {
|
|
||||||
fill: url(#device_normal_bg_loading);
|
|
||||||
}
|
|
||||||
svg#topology_canvas g.loading .router_normal .icon_bg,
|
|
||||||
svg#topology_canvas g.loading .instance_normal .icon_bg {
|
|
||||||
stroke: #555;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<svg width="400" height="400" id="topology_canvas">
|
|
||||||
<defs>
|
|
||||||
<pattern id="device_normal_bg" patternUnits="userSpaceOnUse" x="0" y="0" width="20" height="20">
|
|
||||||
<g>
|
|
||||||
<rect width="20" height="20" class="base_bg_normal"></rect>
|
|
||||||
</g>
|
|
||||||
</pattern>
|
|
||||||
<pattern id="device_normal_bg_loading" patternUnits="userSpaceOnUse" x="0" y="0" width="20" height="20">
|
|
||||||
<g>
|
|
||||||
<rect width="20" height="20" class="loading_bg_normal"></rect>
|
|
||||||
<path d='M0 20L20 0ZM22 18L18 22ZM-2 2L2 -2Z' stroke-linecap="square" stroke='rgba(0, 0, 0, 0.3)' stroke-width="7"></path>
|
|
||||||
</g>
|
|
||||||
<animate attributeName="x" attributeType="XML" begin="0s" dur="0.5s" from="0" to="-20" repeatCount="indefinite"></animate>
|
|
||||||
</pattern>
|
|
||||||
<pattern id="device_small_bg" patternUnits="userSpaceOnUse" x="0" y="0" width="20" height="20">
|
|
||||||
<g>
|
|
||||||
<rect width="20" height="20" class="base_bg_small"></rect>
|
|
||||||
</g>
|
|
||||||
</pattern>
|
|
||||||
<pattern id="device_small_bg_loading" patternUnits="userSpaceOnUse" x="0" y="0" width="5" height="5">
|
|
||||||
<g>
|
|
||||||
<rect width="5" height="5" class="loading_bg_small"></rect>
|
|
||||||
<path d='M0 5L5 0ZM6 4L4 6ZM-1 1L1 -1Z' stroke-linecap="square" stroke='rgba(0, 0, 0, 0.4)' stroke-width="1.5"></path>
|
|
||||||
</g>
|
|
||||||
<animate attributeName="x" attributeType="XML" begin="0s" dur="0.5s" from="0" to="-5" repeatCount="indefinite"></animate>
|
|
||||||
</pattern>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
<svg id="topology_template" display="none">
|
|
||||||
<g class="router_small device_body">
|
|
||||||
<g class="ports" pointer-events="none"></g>
|
|
||||||
<rect rx="3" ry="3" width="20" height="20" class="frame"></rect>
|
|
||||||
<g transform="translate(3.5,3)" class="icon">
|
|
||||||
<polygon points="12.51,4.23 12.51,0.49 8.77,0.49 9.68,1.4 6.92,4.16 8.84,6.08 11.6,3.32 "></polygon>
|
|
||||||
<polygon points="0.49,8.77 0.49,12.51 4.23,12.51 3.32,11.6 6.08,8.83 4.17,6.92 1.4,9.68 "></polygon>
|
|
||||||
<polygon points="1.85,5.59 5.59,5.59 5.59,1.85 4.68,2.76 1.92,0 0,1.92 2.76,4.68 "></polygon>
|
|
||||||
<polygon points="11.15,7.41 7.41,7.41 7.41,11.15 8.32,10.24 11.08,13 13,11.08 10.24,8.32 "></polygon>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="instance_small device_body">
|
|
||||||
<g class="ports" pointer-events="none"></g>
|
|
||||||
<rect rx="3" ry="3" width="20" height="20" class="frame"></rect>
|
|
||||||
<g transform="translate(5,3)" class="icon">
|
|
||||||
<rect class="instance_bg" width="10" height="13"></rect>
|
|
||||||
<rect x="2" y="1" fill="#FFFFFF" width="6" height="2"></rect>
|
|
||||||
<rect x="2" y="4" fill="#FFFFFF" width="6" height="2"></rect>
|
|
||||||
<circle class="active" cx="3" cy="10" r="1.3"></circle>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="network_container_small">
|
|
||||||
<rect rx="7" ry="7" width="15" height="200" style="fill: #8541B5;" class="network-rect"></rect>
|
|
||||||
<text x="250" y="-3" class="network-name" transform="rotate(90 0 0)" pointer-events="none">Network</text>
|
|
||||||
<text x="0" y="-20" class="network-cidr" transform="rotate(90 0 0)">0.0.0.0</text>
|
|
||||||
<text x="0" y="-20" class="network-type" transform="rotate(90 0 0)"
|
|
||||||
data-toggle="tooltip" data-placement="bottom" title="{% trans 'External Network' %}"></text>
|
|
||||||
</g>
|
|
||||||
<g class="router_normal device_body">
|
|
||||||
<g class="ports" pointer-events="none"></g>
|
|
||||||
<rect class="frame" x="0" y="0" rx="6" ry="6" width="90" height="50"></rect>
|
|
||||||
<g class="texts" pointer-events="none">
|
|
||||||
<rect class="texts_bg" x="1.5" y="32" width="87" height="17"></rect>
|
|
||||||
<text x="45" y="46" class="type">{% trans "Router" %}</text>
|
|
||||||
<text x="45" y="22" class="name">router</text>
|
|
||||||
</g>
|
|
||||||
<g class="icon" transform="translate(6,6)" pointer-events="none">
|
|
||||||
<circle class="icon_bg" cx="0" cy="0" r="12"></circle>
|
|
||||||
<g transform="translate(-6.5,-6.5)">
|
|
||||||
<polygon points="12.51,4.23 12.51,0.49 8.77,0.49 9.68,1.4 6.92,4.16 8.84,6.08 11.6,3.32 "></polygon>
|
|
||||||
<polygon points="0.49,8.77 0.49,12.51 4.23,12.51 3.32,11.6 6.08,8.83 4.17,6.92 1.4,9.68 "></polygon>
|
|
||||||
<polygon points="1.85,5.59 5.59,5.59 5.59,1.85 4.68,2.76 1.92,0 0,1.92 2.76,4.68 "></polygon>
|
|
||||||
<polygon points="11.15,7.41 7.41,7.41 7.41,11.15 8.32,10.24 11.08,13 13,11.08 10.24,8.32 "></polygon>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="instance_normal device_body">
|
|
||||||
<g class="ports" pointer-events="none"></g>
|
|
||||||
<rect class="frame" x="0" y="0" rx="6" ry="6" width="90" height="50"></rect>
|
|
||||||
<g class="texts">
|
|
||||||
<rect class="texts_bg" x="1.5" y="32" width="87" height="17"></rect>
|
|
||||||
<text x="45" y="46" class="type">{% trans "Instance" %}</text>
|
|
||||||
<text x="45" y="22" class="name">instance</text>
|
|
||||||
</g>
|
|
||||||
<g class="icon" transform="translate(6,6)">
|
|
||||||
<circle class="icon_bg" cx="0" cy="0" r="12"></circle>
|
|
||||||
<g transform="translate(-5,-6.5)">
|
|
||||||
<rect class="instance_bg" width="10" height="13"></rect>
|
|
||||||
<rect x="2" y="1" fill="#FFFFFF" width="6" height="2"></rect>
|
|
||||||
<rect x="2" y="4" fill="#FFFFFF" width="6" height="2"></rect>
|
|
||||||
<circle class="active" cx="3" cy="10" r="1.3"></circle>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="network_container_normal">
|
|
||||||
<rect rx="9" ry="9" width="17" height="500" style="fill: #8541B5;" class="network-rect"></rect>
|
|
||||||
<text x="250" y="-4" class="network-name" transform="rotate(90 0 0)" pointer-events="none">Network</text>
|
|
||||||
<text x="490" y="-20" class="network-cidr" transform="rotate(90 0 0)">0.0.0.0</text>
|
|
||||||
<text x="490" y="-20" class="network-type" transform="rotate(90 0 0)"
|
|
||||||
data-toggle="tooltip" data-placement="bottom" title="{% trans 'External Network' %}"></text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
@ -22,9 +22,11 @@
|
|||||||
[[/console_id]]
|
[[/console_id]]
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
[[#type]]
|
||||||
<div class="cell delete">
|
<div class="cell delete">
|
||||||
<button class="delete-device btn btn-danger btn-xs [[type]]" data-type="[[type]]" data-device-id="[[id]]">[[delete_label]]</button>
|
<button class="delete-device btn btn-danger btn-xs [[type]]" data-type="[[type]]" data-device-id="[[id]]">[[delete_label]]</button>
|
||||||
</div>
|
</div>
|
||||||
|
[[/type]]
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
{% extends "horizon/client_side/template.html" %}
|
||||||
|
{% load horizon %}
|
||||||
|
|
||||||
|
{% block id %}balloon_instance{% endblock %}
|
||||||
|
|
||||||
|
{% block template %}
|
||||||
|
{% jstemplate %}
|
||||||
|
<div class="portTableHeader">
|
||||||
|
<div class="title">[[ips_label]]</div>
|
||||||
|
</div>
|
||||||
|
<table class="detailInfoTable">
|
||||||
|
<caption></caption>
|
||||||
|
<tbody>
|
||||||
|
[[#ips]]
|
||||||
|
<tr>
|
||||||
|
<th>[[ip_address]]</th>
|
||||||
|
<td>[[subnet_id]]</td>
|
||||||
|
</tr>
|
||||||
|
[[/ips]]
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endjstemplate %}
|
||||||
|
{% endblock %}
|
@ -0,0 +1,38 @@
|
|||||||
|
{% extends "horizon/client_side/template.html" %}
|
||||||
|
{% load horizon %}
|
||||||
|
|
||||||
|
{% block id %}balloon_net{% endblock %}
|
||||||
|
|
||||||
|
{% block template %}
|
||||||
|
{% jstemplate %}
|
||||||
|
<div class="portTableHeader">
|
||||||
|
<div class="title">[[subnets_label]]</div>
|
||||||
|
<div class="action">
|
||||||
|
<a class="add-subnet btn btn-default btn-xs ajax-modal [[type]]" href="[[add_subnet_url]]">
|
||||||
|
<span class="fa fa-plus"></span>
|
||||||
|
[[add_subnet_label]]
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<table class="detailInfoTable">
|
||||||
|
<caption></caption>
|
||||||
|
<tbody>
|
||||||
|
[[#subnet]]
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<span title="[[id]]">
|
||||||
|
<a href="[[url]]">[[id]]</a>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<td>[[cidr]]</td>
|
||||||
|
<td class="delete">
|
||||||
|
<button class="delete-port btn btn-danger btn-xs"
|
||||||
|
data-router-id="[[router_id]]" data-network-id="[[network_id]]"
|
||||||
|
data-port-id="[[id]]">[[delete_subnet_label]]</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
[[/subnet]]
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endjstemplate %}
|
||||||
|
{% endblock %}
|
@ -31,7 +31,9 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="delete">
|
<td class="delete">
|
||||||
[[#is_interface]]
|
[[#is_interface]]
|
||||||
<button class="delete-port btn btn-danger btn-xs" data-router-id="[[router_id]]" data-port-id="[[id]]">[[delete_interface_label]]</button>
|
<button class="delete-port btn btn-danger btn-xs"
|
||||||
|
data-router-id="[[router_id]]" data-network-id="[[network_id]]"
|
||||||
|
data-port-id="[[id]]">[[delete_interface_label]]</button>
|
||||||
[[/is_interface]]
|
[[/is_interface]]
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% include "horizon/_messages.html" %}
|
{% include "horizon/_messages.html" %}
|
||||||
{% firstof table.render interfaces_table.render tab_group.render %}
|
{% firstof subnets_table.render table.render interfaces_table.render tab_group.render %}
|
||||||
{% include "project/network_topology/_post_massage.html" %}
|
{% include "project/network_topology/_post_massage.html" %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -12,19 +12,20 @@
|
|||||||
{% include "project/network_topology/client_side/_balloon_container.html" %}
|
{% include "project/network_topology/client_side/_balloon_container.html" %}
|
||||||
{% include "project/network_topology/client_side/_balloon_device.html" %}
|
{% include "project/network_topology/client_side/_balloon_device.html" %}
|
||||||
{% include "project/network_topology/client_side/_balloon_port.html" %}
|
{% include "project/network_topology/client_side/_balloon_port.html" %}
|
||||||
|
{% include "project/network_topology/client_side/_balloon_net.html" %}
|
||||||
|
{% include "project/network_topology/client_side/_balloon_instance.html" %}
|
||||||
|
<div class='description'>
|
||||||
|
{% blocktrans %}
|
||||||
|
Resize the canvas by scrolling up/down with your mouse/trackpad on the topology.
|
||||||
|
Pan around the canvas by clicking and dragging the space behind the topology.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</div>
|
||||||
<div class="topologyNavi">
|
<div class="topologyNavi">
|
||||||
<div class="toggleView btn-group" data-toggle="buttons">
|
<div class="toggleView btn-group" data-toggle="buttons-radio">
|
||||||
<label class="btn btn-default" data-value="small">
|
<button type="button" class="btn btn-default" id="toggle_labels"><span class="fa
|
||||||
<input type="radio" name="options" id="option1" checked>
|
fa-th-large"></span> {%trans "Toggle labels" %}</button>
|
||||||
<span class="fa fa-th"></span>
|
<button type="button" class="btn btn-default" id="toggle_networks"><span class="fa
|
||||||
{% trans "Small" %}
|
fa-th"></span> {%trans "Toggle Network Collapse" %}</button>
|
||||||
</label>
|
|
||||||
<label class="btn btn-default" data-value="normal">
|
|
||||||
<input type="radio" name="options" id="option2">
|
|
||||||
<span class="fa fa-th-large"></span>
|
|
||||||
{% trans "Normal" %}
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="launchButtons">
|
<div class="launchButtons">
|
||||||
{% if launch_instance_allowed %}
|
{% if launch_instance_allowed %}
|
||||||
@ -47,7 +48,6 @@
|
|||||||
|
|
||||||
<div id="topologyCanvasContainer">
|
<div id="topologyCanvasContainer">
|
||||||
<div class="nodata">{% blocktrans %}There are no networks, routers, or connected instances to display.{% endblocktrans %}</div>
|
<div class="nodata">{% blocktrans %}There are no networks, routers, or connected instances to display.{% endblocktrans %}</div>
|
||||||
{% include "project/network_topology/_svg_element.html" %}
|
|
||||||
</div>
|
</div>
|
||||||
<span data-networktopology="{% url 'horizon:project:network_topology:json' %}" id="networktopology"></span>
|
<span data-networktopology="{% url 'horizon:project:network_topology:json' %}" id="networktopology"></span>
|
||||||
<div id="topologyMessages"></div>
|
<div id="topologyMessages"></div>
|
||||||
|
@ -110,17 +110,22 @@ class NetworkTopologyTests(test.TestCase):
|
|||||||
expect_net_urls = []
|
expect_net_urls = []
|
||||||
if router_enable:
|
if router_enable:
|
||||||
expect_net_urls += [{'id': net.id,
|
expect_net_urls += [{'id': net.id,
|
||||||
'url': None,
|
'url': '/project/networks/%s/detail' % net.id,
|
||||||
'name': net.name,
|
'name': net.name,
|
||||||
'router:external': net.router__external,
|
'router:external': net.router__external,
|
||||||
'subnets': [{'cidr': subnet.cidr}
|
'status': net.status,
|
||||||
for subnet in net.subnets]}
|
'subnets': []}
|
||||||
for net in external_networks]
|
for net in external_networks]
|
||||||
expect_net_urls += [{'id': net.id,
|
expect_net_urls += [{'id': net.id,
|
||||||
'url': '/project/networks/%s/detail' % net.id,
|
'url': '/project/networks/%s/detail' % net.id,
|
||||||
'name': net.name,
|
'name': net.name,
|
||||||
'router:external': net.router__external,
|
'router:external': net.router__external,
|
||||||
'subnets': [{'cidr': subnet.cidr}
|
'status': net.status,
|
||||||
|
'subnets': [{'cidr': subnet.cidr,
|
||||||
|
'id': subnet.id,
|
||||||
|
'url':
|
||||||
|
'/project/networks/subnets/%s/detail'
|
||||||
|
% subnet.id}
|
||||||
for subnet in net.subnets]}
|
for subnet in net.subnets]}
|
||||||
for net in tenant_networks]
|
for net in tenant_networks]
|
||||||
for exp_net in expect_net_urls:
|
for exp_net in expect_net_urls:
|
||||||
|
@ -27,9 +27,16 @@ urlpatterns = patterns(
|
|||||||
'openstack_dashboard.dashboards.project.network_topology.views',
|
'openstack_dashboard.dashboards.project.network_topology.views',
|
||||||
url(r'^$', views.NetworkTopologyView.as_view(), name='index'),
|
url(r'^$', views.NetworkTopologyView.as_view(), name='index'),
|
||||||
url(r'^router$', views.RouterView.as_view(), name='router'),
|
url(r'^router$', views.RouterView.as_view(), name='router'),
|
||||||
|
url(r'^network$', views.NetworkView.as_view(), name='network'),
|
||||||
url(r'^instance$', views.InstanceView.as_view(), name='instance'),
|
url(r'^instance$', views.InstanceView.as_view(), name='instance'),
|
||||||
url(r'^router/(?P<router_id>[^/]+)/$', views.RouterDetailView.as_view(),
|
url(r'^router/(?P<router_id>[^/]+)/$', views.RouterDetailView.as_view(),
|
||||||
name='detail'),
|
name='detail'),
|
||||||
|
url(r'^router/(?P<router_id>[^/]+)/addinterface$',
|
||||||
|
views.NTAddInterfaceView.as_view(), name='interface'),
|
||||||
|
url(r'^network/(?P<network_id>[^/]+)/$', views.NetworkDetailView.as_view(),
|
||||||
|
name='detail'),
|
||||||
|
url(r'^network/(?P<network_id>[^/]+)/subnet/create$',
|
||||||
|
views.NTCreateSubnetView.as_view(), name='subnet'),
|
||||||
url(r'^json$', views.JSONView.as_view(), name='json'),
|
url(r'^json$', views.JSONView.as_view(), name='json'),
|
||||||
url(r'^launchinstance$', views.NTLaunchInstanceView.as_view(),
|
url(r'^launchinstance$', views.NTLaunchInstanceView.as_view(),
|
||||||
name='launchinstance'),
|
name='launchinstance'),
|
||||||
|
@ -33,10 +33,14 @@ from openstack_dashboard.usage import quotas
|
|||||||
|
|
||||||
from openstack_dashboard.dashboards.project.network_topology.instances \
|
from openstack_dashboard.dashboards.project.network_topology.instances \
|
||||||
import tables as instances_tables
|
import tables as instances_tables
|
||||||
|
from openstack_dashboard.dashboards.project.network_topology.networks \
|
||||||
|
import tables as networks_tables
|
||||||
from openstack_dashboard.dashboards.project.network_topology.ports \
|
from openstack_dashboard.dashboards.project.network_topology.ports \
|
||||||
import tables as ports_tables
|
import tables as ports_tables
|
||||||
from openstack_dashboard.dashboards.project.network_topology.routers \
|
from openstack_dashboard.dashboards.project.network_topology.routers \
|
||||||
import tables as routers_tables
|
import tables as routers_tables
|
||||||
|
from openstack_dashboard.dashboards.project.network_topology.subnets \
|
||||||
|
import tables as subnets_tables
|
||||||
|
|
||||||
from openstack_dashboard.dashboards.project.instances import\
|
from openstack_dashboard.dashboards.project.instances import\
|
||||||
console as i_console
|
console as i_console
|
||||||
@ -44,14 +48,33 @@ from openstack_dashboard.dashboards.project.instances import\
|
|||||||
views as i_views
|
views as i_views
|
||||||
from openstack_dashboard.dashboards.project.instances.workflows import\
|
from openstack_dashboard.dashboards.project.instances.workflows import\
|
||||||
create_instance as i_workflows
|
create_instance as i_workflows
|
||||||
|
from openstack_dashboard.dashboards.project.networks.subnets import\
|
||||||
|
views as s_views
|
||||||
|
from openstack_dashboard.dashboards.project.networks.subnets import\
|
||||||
|
workflows as s_workflows
|
||||||
from openstack_dashboard.dashboards.project.networks import\
|
from openstack_dashboard.dashboards.project.networks import\
|
||||||
views as n_views
|
views as n_views
|
||||||
from openstack_dashboard.dashboards.project.networks import\
|
from openstack_dashboard.dashboards.project.networks import\
|
||||||
workflows as n_workflows
|
workflows as n_workflows
|
||||||
|
from openstack_dashboard.dashboards.project.routers.ports import\
|
||||||
|
views as p_views
|
||||||
from openstack_dashboard.dashboards.project.routers import\
|
from openstack_dashboard.dashboards.project.routers import\
|
||||||
views as r_views
|
views as r_views
|
||||||
|
|
||||||
|
|
||||||
|
class NTAddInterfaceView(p_views.AddInterfaceView):
|
||||||
|
success_url = "horizon:project:network_topology:index"
|
||||||
|
failure_url = "horizon:project:network_topology:index"
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse("horizon:project:network_topology:index")
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(NTAddInterfaceView, self).get_context_data(**kwargs)
|
||||||
|
context['form_url'] = 'horizon:project:network_topology:interface'
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class NTCreateRouterView(r_views.CreateView):
|
class NTCreateRouterView(r_views.CreateView):
|
||||||
template_name = 'project/network_topology/create_router.html'
|
template_name = 'project/network_topology/create_router.html'
|
||||||
success_url = reverse_lazy("horizon:project:network_topology:index")
|
success_url = reverse_lazy("horizon:project:network_topology:index")
|
||||||
@ -78,6 +101,18 @@ class NTLaunchInstanceView(i_views.LaunchInstanceView):
|
|||||||
workflow_class = NTLaunchInstance
|
workflow_class = NTLaunchInstance
|
||||||
|
|
||||||
|
|
||||||
|
class NTCreateSubnet(s_workflows.CreateSubnet):
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse("horizon:project:network_topology:index")
|
||||||
|
|
||||||
|
def get_failure_url(self):
|
||||||
|
return reverse("horizon:project:network_topology:index")
|
||||||
|
|
||||||
|
|
||||||
|
class NTCreateSubnetView(s_views.CreateView):
|
||||||
|
workflow_class = NTCreateSubnet
|
||||||
|
|
||||||
|
|
||||||
class InstanceView(i_views.IndexView):
|
class InstanceView(i_views.IndexView):
|
||||||
table_class = instances_tables.InstancesTable
|
table_class = instances_tables.InstancesTable
|
||||||
template_name = 'project/network_topology/iframe.html'
|
template_name = 'project/network_topology/iframe.html'
|
||||||
@ -88,6 +123,11 @@ class RouterView(r_views.IndexView):
|
|||||||
template_name = 'project/network_topology/iframe.html'
|
template_name = 'project/network_topology/iframe.html'
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkView(n_views.IndexView):
|
||||||
|
table_class = networks_tables.NetworksTable
|
||||||
|
template_name = 'project/network_topology/iframe.html'
|
||||||
|
|
||||||
|
|
||||||
class RouterDetailView(r_views.DetailView):
|
class RouterDetailView(r_views.DetailView):
|
||||||
table_classes = (ports_tables.PortsTable, )
|
table_classes = (ports_tables.PortsTable, )
|
||||||
template_name = 'project/network_topology/iframe.html'
|
template_name = 'project/network_topology/iframe.html'
|
||||||
@ -96,6 +136,11 @@ class RouterDetailView(r_views.DetailView):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkDetailView(n_views.DetailView):
|
||||||
|
table_classes = (subnets_tables.SubnetsTable, )
|
||||||
|
template_name = 'project/network_topology/iframe.html'
|
||||||
|
|
||||||
|
|
||||||
class NetworkTopologyView(views.HorizonTemplateView):
|
class NetworkTopologyView(views.HorizonTemplateView):
|
||||||
template_name = 'project/network_topology/index.html'
|
template_name = 'project/network_topology/index.html'
|
||||||
page_title = _("Network Topology")
|
page_title = _("Network Topology")
|
||||||
@ -197,14 +242,18 @@ class JSONView(View):
|
|||||||
request.user.tenant_id)
|
request.user.tenant_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
neutron_networks = []
|
neutron_networks = []
|
||||||
networks = [{'name': network.name,
|
networks = []
|
||||||
|
for network in neutron_networks:
|
||||||
|
obj = {'name': network.name,
|
||||||
'id': network.id,
|
'id': network.id,
|
||||||
'subnets': [{'cidr': subnet.cidr}
|
'subnets': [{'id': subnet.id,
|
||||||
|
'cidr': subnet.cidr}
|
||||||
for subnet in network.subnets],
|
for subnet in network.subnets],
|
||||||
|
'status': network.status,
|
||||||
'router:external': network['router:external']}
|
'router:external': network['router:external']}
|
||||||
for network in neutron_networks]
|
self.add_resource_url('horizon:project:networks:subnets:detail',
|
||||||
self.add_resource_url('horizon:project:networks:detail',
|
obj['subnets'])
|
||||||
networks)
|
networks.append(obj)
|
||||||
|
|
||||||
# Add public networks to the networks list
|
# Add public networks to the networks list
|
||||||
if self.is_router_enabled:
|
if self.is_router_enabled:
|
||||||
@ -219,16 +268,25 @@ class JSONView(View):
|
|||||||
if publicnet.id in my_network_ids:
|
if publicnet.id in my_network_ids:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
subnets = [{'cidr': subnet.cidr}
|
subnets = []
|
||||||
for subnet in publicnet.subnets]
|
for subnet in publicnet.subnets:
|
||||||
|
snet = {'id': subnet.id,
|
||||||
|
'cidr': subnet.cidr}
|
||||||
|
self.add_resource_url(
|
||||||
|
'horizon:project:networks:subnets:detail', snet)
|
||||||
|
subnets.append(snet)
|
||||||
except Exception:
|
except Exception:
|
||||||
subnets = []
|
subnets = []
|
||||||
networks.append({
|
networks.append({
|
||||||
'name': publicnet.name,
|
'name': publicnet.name,
|
||||||
'id': publicnet.id,
|
'id': publicnet.id,
|
||||||
'subnets': subnets,
|
'subnets': subnets,
|
||||||
|
'status': publicnet.status,
|
||||||
'router:external': publicnet['router:external']})
|
'router:external': publicnet['router:external']})
|
||||||
|
|
||||||
|
self.add_resource_url('horizon:project:networks:detail',
|
||||||
|
networks)
|
||||||
|
|
||||||
return sorted(networks,
|
return sorted(networks,
|
||||||
key=lambda x: x.get('router:external'),
|
key=lambda x: x.get('router:external'),
|
||||||
reverse=True)
|
reverse=True)
|
||||||
|
@ -52,6 +52,7 @@ class AddInterfaceView(forms.ModalFormView):
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(AddInterfaceView, self).get_context_data(**kwargs)
|
context = super(AddInterfaceView, self).get_context_data(**kwargs)
|
||||||
context['router'] = self.get_object()
|
context['router'] = self.get_object()
|
||||||
|
context['form_url'] = 'horizon:project:routers:addinterface'
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
{% load url from future %}
|
{% load url from future %}
|
||||||
|
|
||||||
{% block form_id %}add_interface_form{% endblock %}
|
{% block form_id %}add_interface_form{% endblock %}
|
||||||
{% block form_action %}{% url 'horizon:project:routers:addinterface' router.id %}
|
{% block form_action %}{% url form_url router.id %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block modal-header %}{% trans "Add Interface" %}{% endblock %}
|
{% block modal-header %}{% trans "Add Interface" %}{% endblock %}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
height: auto;
|
height: auto;
|
||||||
padding: 25px;
|
padding: 25px;
|
||||||
padding-left: 50px;
|
padding-left: 50px;
|
||||||
background: #efefef;
|
background: #ffffff;
|
||||||
min-height: 400px;
|
min-height: 400px;
|
||||||
div.nodata {
|
div.nodata {
|
||||||
font-size: 150%;
|
font-size: 150%;
|
||||||
|
Loading…
Reference in New Issue
Block a user