Merge "Improve style of network topology"
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
horizon.network_topology = {
|
horizon.network_topology = {
|
||||||
model: null,
|
model: null,
|
||||||
network_margin: 270,
|
network_margin: 270,
|
||||||
|
topologyCanvas_padding: 120,
|
||||||
min_network_height:500,
|
min_network_height:500,
|
||||||
port_margin: 20,
|
port_margin: 20,
|
||||||
device_initial_position : 40,
|
device_initial_position : 40,
|
||||||
@@ -20,15 +21,16 @@ horizon.network_topology = {
|
|||||||
var self = this;
|
var self = this;
|
||||||
$("#topologyCanvas").spin(horizon.conf.spinner_options.modal);
|
$("#topologyCanvas").spin(horizon.conf.spinner_options.modal);
|
||||||
self.retrieve_network_info();
|
self.retrieve_network_info();
|
||||||
setInterval(horizon.network_topology.retrieve_network_info,
|
setInterval(function(){
|
||||||
horizon.network_topology.reload_duration);
|
self.retrieve_network_info();
|
||||||
|
}, self.reload_duration);
|
||||||
},
|
},
|
||||||
retrieve_network_info: function(){
|
retrieve_network_info: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
if($("#networktopology").length === 0) {
|
if($("#networktopology").length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.getJSON($("#networktopology").data('networktopology'),
|
$.getJSON($("#networktopology").data("networktopology"),
|
||||||
function(data) {
|
function(data) {
|
||||||
self.draw_graph(data);
|
self.draw_graph(data);
|
||||||
}
|
}
|
||||||
@@ -40,19 +42,27 @@ horizon.network_topology = {
|
|||||||
draw_graph: function(data){
|
draw_graph: function(data){
|
||||||
var canvas = $("#topologyCanvas");
|
var canvas = $("#topologyCanvas");
|
||||||
var networks = $("#topologyCanvas > .networks");
|
var networks = $("#topologyCanvas > .networks");
|
||||||
|
var nodata = $("#topologyCanvas > .nodata");
|
||||||
|
networks.show();
|
||||||
|
nodata.hide();
|
||||||
canvas.spin(false);
|
canvas.spin(false);
|
||||||
networks.empty();
|
networks.empty();
|
||||||
this.model = data;
|
this.model = data;
|
||||||
this.device_last_position = this.device_initial_position;
|
this.device_last_position = this.device_initial_position;
|
||||||
this.draw_networks();
|
var network_elements = this.draw_networks();
|
||||||
this.draw_routers();
|
var router_elements = this.draw_routers();
|
||||||
this.draw_servers();
|
var server_elements = this.draw_servers();
|
||||||
canvas.height(
|
if ((network_elements + router_elements + server_elements) <= 0){
|
||||||
Math.max(this.device_last_position,this.min_network_height)
|
networks.hide();
|
||||||
);
|
nodata.show();
|
||||||
networks.width(
|
} else {
|
||||||
this.model.networks.length * this.network_margin
|
canvas.height(
|
||||||
);
|
Math.max(this.device_last_position + this.topologyCanvas_padding, this.min_network_height)
|
||||||
|
);
|
||||||
|
networks.width(
|
||||||
|
this.model.networks.length * this.network_margin
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
network_color: function(network_id){
|
network_color: function(network_id){
|
||||||
var max_hue = 360;
|
var max_hue = 360;
|
||||||
@@ -115,18 +125,24 @@ horizon.network_topology = {
|
|||||||
if(network['router:external']){
|
if(network['router:external']){
|
||||||
label += " (external) ";
|
label += " (external) ";
|
||||||
}
|
}
|
||||||
label += self.select_cidr(network.id);
|
|
||||||
self.network_index[network.id] = index;
|
self.network_index[network.id] = index;
|
||||||
var network_html = $("<div class='network' />").attr("id", network.id);
|
var network_html = $("<div class='network' />").attr("id", network.id);
|
||||||
var nicname_html = $("<div class='nicname'><h3>" + label + "</h3></div>");
|
var nicname_html = $("<div class='nicname'><h3>" + label +
|
||||||
|
"</h3><span class='ip'>" + self.select_cidr(network.id) + "</span></div>");
|
||||||
|
if (network.url == undefined) {
|
||||||
|
nicname_html.addClass("nourl");
|
||||||
|
} else {
|
||||||
|
nicname_html.click(function (){
|
||||||
|
window.location.href = network.url;
|
||||||
|
});
|
||||||
|
}
|
||||||
nicname_html
|
nicname_html
|
||||||
.click(function (){
|
|
||||||
window.location.href = network.url;})
|
|
||||||
.css (
|
.css (
|
||||||
{'background-color':self.network_color(network.id)})
|
{'background-color':self.network_color(network.id)})
|
||||||
.appendTo(network_html);
|
.appendTo(network_html);
|
||||||
networks.append(network_html);
|
networks.append(network_html);
|
||||||
});
|
});
|
||||||
|
return self.model.networks.length;
|
||||||
},
|
},
|
||||||
select_cidr:function(network_id){
|
select_cidr:function(network_id){
|
||||||
var cidr = "";
|
var cidr = "";
|
||||||
@@ -134,13 +150,13 @@ horizon.network_topology = {
|
|||||||
if(subnet.network_id != network_id){
|
if(subnet.network_id != network_id){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cidr += " <span class=\"ip\">[ " + subnet.cidr + " ]</span>";
|
cidr += subnet.cidr;
|
||||||
});
|
});
|
||||||
return cidr;
|
return cidr;
|
||||||
},
|
},
|
||||||
draw_devices: function(type){
|
draw_devices: function(type){
|
||||||
var self = this;
|
var self = this;
|
||||||
$.each(self.model[type + 's'], function(index, device){
|
$.each(self.model[type + 's'], function(index, device){
|
||||||
var id = device.id;
|
var id = device.id;
|
||||||
var name = (device.name != "")? device.name : device.id;
|
var name = (device.name != "")? device.name : device.id;
|
||||||
var ports = self.select_port(id);
|
var ports = self.select_port(id);
|
||||||
@@ -176,6 +192,7 @@ horizon.network_topology = {
|
|||||||
self.device_last_position += device_html.height() + self.device_margin;
|
self.device_last_position += device_html.height() + self.device_margin;
|
||||||
$("#" + parent_network).append(device_html);
|
$("#" + parent_network).append(device_html);
|
||||||
});
|
});
|
||||||
|
return self.model[type + 's'].length;
|
||||||
},
|
},
|
||||||
sum_port_length: function(network_id, ports){
|
sum_port_length: function(network_id, ports){
|
||||||
var self = this;
|
var self = this;
|
||||||
@@ -200,10 +217,10 @@ horizon.network_topology = {
|
|||||||
return ports[main_port_index];
|
return ports[main_port_index];
|
||||||
},
|
},
|
||||||
draw_routers: function(){
|
draw_routers: function(){
|
||||||
this.draw_devices('router');
|
return this.draw_devices('router');
|
||||||
},
|
},
|
||||||
draw_servers: function(){
|
draw_servers: function(){
|
||||||
this.draw_devices('server');
|
return this.draw_devices('server');
|
||||||
},
|
},
|
||||||
select_port: function(device_id){
|
select_port: function(device_id){
|
||||||
return $.map(this.model.ports,function(port, index){
|
return $.map(this.model.ports,function(port, index){
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ div.network .device:hover div.port {
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<noscript>
|
<noscript>
|
||||||
{%trans "This pane needs javascript support." %}
|
{% trans "This pane needs javascript support." %}
|
||||||
</noscript>
|
</noscript>
|
||||||
<div class="launchButtons">
|
<div class="launchButtons">
|
||||||
<a href="{% url horizon:project:instances:launch %}" id="instances__action_launch" class="btn btn-small btn-launch ajax-modal">{%trans "Launch Instance" %}</a>
|
<a href="{% url horizon:project:instances:launch %}" id="instances__action_launch" class="btn btn-small btn-launch ajax-modal">{%trans "Launch Instance" %}</a>
|
||||||
@@ -30,6 +30,7 @@ div.network .device:hover div.port {
|
|||||||
|
|
||||||
<div id="topologyCanvas">
|
<div id="topologyCanvas">
|
||||||
<div class="networks"></div>
|
<div class="networks"></div>
|
||||||
|
<div class="nodata">{% blocktrans %}There are no networks, routers, or connected instances to display. {% endblocktrans %}</div>
|
||||||
</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>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -33,7 +33,11 @@ class NetworkTopology(TemplateView):
|
|||||||
|
|
||||||
class JSONView(View):
|
class JSONView(View):
|
||||||
def add_resource_url(self, view, resources):
|
def add_resource_url(self, view, resources):
|
||||||
|
tenant_id = self.request.user.tenant_id
|
||||||
for resource in resources:
|
for resource in resources:
|
||||||
|
if (resource.get('tenant_id')
|
||||||
|
and tenant_id != resource.get('tenant_id')):
|
||||||
|
continue
|
||||||
resource['url'] = reverse(view, None, [str(resource['id'])])
|
resource['url'] = reverse(view, None, [str(resource['id'])])
|
||||||
|
|
||||||
def _select_port_by_network_id(self, ports, network_id):
|
def _select_port_by_network_id(self, ports, network_id):
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -1834,6 +1834,13 @@ label.log-length {
|
|||||||
padding: 25px;
|
padding: 25px;
|
||||||
padding-left: 50px;
|
padding-left: 50px;
|
||||||
background: #efefef;
|
background: #efefef;
|
||||||
|
div.nodata {
|
||||||
|
font-size: 150%;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 200px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
div.networks {
|
div.networks {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -1863,12 +1870,18 @@ div.network {
|
|||||||
background-image: linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15));
|
background-image: linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15));
|
||||||
background-size: 10px 10px;
|
background-size: 10px 10px;
|
||||||
}
|
}
|
||||||
|
&.nourl {
|
||||||
|
cursor: auto;
|
||||||
|
&:hover {
|
||||||
|
background-image:none;
|
||||||
|
}
|
||||||
|
}
|
||||||
h3 {
|
h3 {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
top:60%;
|
top:55%;
|
||||||
color:#fff;
|
color:#fff;
|
||||||
left:-1px;
|
left:-1px;
|
||||||
letter-spacing: 0.2em;
|
letter-spacing: 0.2em;
|
||||||
@@ -1877,71 +1890,83 @@ div.network {
|
|||||||
-ms-transform: rotate(-90deg);
|
-ms-transform: rotate(-90deg);
|
||||||
-o-transform: rotate(-90deg);
|
-o-transform: rotate(-90deg);
|
||||||
transform: rotate(-90deg);
|
transform: rotate(-90deg);
|
||||||
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-shadow: 0px 0px 5px #000;
|
text-shadow: 0px 0px 5px #000;
|
||||||
span.ip {
|
}
|
||||||
margin-left: 0.5em;
|
span.ip {
|
||||||
color: #000;
|
position: absolute;
|
||||||
font-weight: normal;
|
bottom:-10px;
|
||||||
font-size: 90%;
|
left:20px;
|
||||||
text-shadow: 0px 0px 0px #000;
|
color: #000;
|
||||||
}
|
display: block;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 90%;
|
||||||
|
letter-spacing: 0.2em;
|
||||||
|
-webkit-transform: rotate(-90deg);
|
||||||
|
-moz-transform: rotate(-90deg);
|
||||||
|
-ms-transform: rotate(-90deg);
|
||||||
|
-o-transform: rotate(-90deg);
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
-webkit-transform-origin: 0% 0%;
|
||||||
|
-moz-transform-origin: 0% 0%;
|
||||||
|
-ms-transform-origin: 0% 0%;
|
||||||
|
-o-transform-origin: 0% 0%;
|
||||||
|
transform-origin: 0% 0%;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-shadow: 0px 0px 2px #fff,0px 0px 2px #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.router, .server, .device {
|
.router, .server, .device {
|
||||||
.box-sizing();
|
.box-sizing();
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 90px;
|
width: 90px;
|
||||||
border: 3px solid #666;
|
border: 3px solid #444;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top:30px;
|
top:30px;
|
||||||
left:90px;
|
left:90px;
|
||||||
|
color:#fff;
|
||||||
padding: 0 3px;
|
padding: 0 3px;
|
||||||
background: #666;
|
background: #666;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
&:before,&:after {
|
border-radius: 8px;
|
||||||
|
&:before {
|
||||||
content: "";
|
content: "";
|
||||||
width: 90px;
|
width: 20px;
|
||||||
height: 34px;
|
height: 20px;
|
||||||
text-align: center;
|
border: 2px solid #444;
|
||||||
|
line-height: 1.2;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border: 3px solid #666;
|
border-radius: 20px;
|
||||||
.box-sizing();
|
top:-10px;
|
||||||
background: #fff;
|
left:-10px;
|
||||||
border-radius:50%;
|
background:#fff url(/static/dashboard/img/router.png) no-repeat center center;
|
||||||
top:-19px;
|
background-size: 16px 16px;
|
||||||
left:-3px;
|
|
||||||
}
|
}
|
||||||
&:after {
|
&:after {
|
||||||
content:"";
|
content: "";
|
||||||
|
width: 100%;
|
||||||
|
line-height: 1.2;
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 0;
|
||||||
|
background: #444;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background:#666;
|
|
||||||
border-radius:50%;
|
|
||||||
top:auto;
|
|
||||||
bottom:-19px;
|
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
line-height: 30px;
|
height: 1.5em;
|
||||||
|
bottom:0px;
|
||||||
|
left: 0px;
|
||||||
}
|
}
|
||||||
span.devicename {
|
span.devicename {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
bottom: -10px;
|
bottom: 0px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
left:-4px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
z-index:300;
|
z-index:300;
|
||||||
i {
|
left:-2px;
|
||||||
display: inline-block;
|
|
||||||
width: 14px;
|
|
||||||
height:14px;
|
|
||||||
background: #fff url(/static/dashboard/img/router.png) no-repeat center center;
|
|
||||||
background-size: 12px 12px;
|
|
||||||
margin-right: 3px;
|
|
||||||
vertical-align: middle;
|
|
||||||
border-radius: 20px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
span.name {
|
span.name {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -1952,7 +1977,7 @@ div.network {
|
|||||||
position: relative;
|
position: relative;
|
||||||
z-index:10;
|
z-index:10;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
top:-10px;
|
top:4px;
|
||||||
padding: 0 3px;
|
padding: 0 3px;
|
||||||
}
|
}
|
||||||
div.port {
|
div.port {
|
||||||
@@ -1972,6 +1997,7 @@ div.network {
|
|||||||
z-index:100;
|
z-index:100;
|
||||||
span.ip {
|
span.ip {
|
||||||
.box-sizing();
|
.box-sizing();
|
||||||
|
color: #333;
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
text-shadow: 0px -1px #fff;
|
text-shadow: 0px -1px #fff;
|
||||||
@@ -2010,14 +2036,10 @@ div.network {
|
|||||||
animation: progress-bar-stripes 0.3s linear infinite;
|
animation: progress-bar-stripes 0.3s linear infinite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
background-color: #444;
|
border-color: #222;
|
||||||
border-color: #444;
|
|
||||||
&:before {
|
|
||||||
border-color: #444;
|
|
||||||
}
|
|
||||||
&:after {
|
&:after {
|
||||||
background-color: #444;
|
background-color: #222;
|
||||||
border-color: #444;
|
border-color: #222;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2026,48 +2048,12 @@ div.network {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
.server {
|
.server {
|
||||||
border-radius: 5px;
|
|
||||||
background: #fff;
|
|
||||||
span.devicename {
|
|
||||||
bottom: 0px;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 14px;
|
|
||||||
left:-4px;
|
|
||||||
i {
|
|
||||||
display: inline-block;
|
|
||||||
width: 14px;
|
|
||||||
height:14px;
|
|
||||||
background: url(/static/dashboard/img/server.png) no-repeat center center;
|
|
||||||
background-size: 12px 12px;
|
|
||||||
margin-right: 3px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
span.name {
|
|
||||||
top:5px;
|
|
||||||
padding: 0 3px;
|
|
||||||
}
|
|
||||||
&:before {
|
&:before {
|
||||||
border:none;
|
background:#fff url(/static/dashboard/img/server.png) no-repeat center center;
|
||||||
background: transparent;
|
background-size: 14px 14px;
|
||||||
}
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
width: 100%;
|
|
||||||
line-height: 1.2;
|
|
||||||
position: absolute;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 0;
|
|
||||||
background: #666;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 11px;
|
|
||||||
height: 1.5em;
|
|
||||||
bottom:0px;
|
|
||||||
left: 0px;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
background: #fff;
|
|
||||||
}
|
}
|
||||||
|
background: #fff;
|
||||||
|
color:#333;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user