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