Additions and fixes to network check

- Per interface tree maps
- proper virtial nodes detection
- KVM nodes listing
- CPU count fix
- Basic service fail check (wip)

Change-Id: I62b68793404eeff957ef70468c954df2fda869a5
Related-PROD: PROD-38972
diff --git a/templates/network_check_tmpl.j2 b/templates/network_check_tmpl.j2
index c26a115..a2b17a9 100644
--- a/templates/network_check_tmpl.j2
+++ b/templates/network_check_tmpl.j2
@@ -41,6 +41,13 @@
             padding: 1px;
             margin: 2px;
         }
+        td > .kvm_group {
+            display: grid;
+            grid-template-columns: auto auto auto;
+            padding-left: 0px;
+            padding-right: 0px;
+            margin: 1px;
+        }
         td > .disk_group {
             display: grid;
             grid-template-columns: auto auto auto auto auto;
@@ -48,13 +55,20 @@
             padding-right: 0px;
             margin: 1px;
         }
-        td > .ram_group {
+        td > .ram_group, td > .net_group {
             display: grid;
             grid-template-columns: auto auto auto auto;
             padding-left: 0px;
             padding-right: 0px;
             margin: 1px;
         }
+        td > .net_group {
+            display: grid;
+            grid-template-columns: auto auto auto auto auto;
+            padding-left: 0px;
+            padding-right: 0px;
+            margin: 1px;
+        }
         td > .vcpu_group {
             display: grid;
             grid-template-columns: auto;
@@ -82,10 +96,13 @@
         .col_release { width: 100px; }
         .col_kernel { min-width: 100px; }
         .col_vcpu { min-width: 40px; }
+        .col_net { min-width: 150px; }
         .col_ram { min-width: 150px; }
         .col_disk { min-width: 200px; }
         
-        .col_notes { width: 618px; }
+        .col_node_notes { width: 400px; }
+        .col_cpu_notes { width: 218px; }
+
         .meters {
             display: inline-block;
             margin: 1px;
@@ -99,6 +116,13 @@
             padding: 0px 1px 0px 1px;
             
         }
+        .kvm_id, .kvm_node, .kvm_status {
+            border-width: 0px;
+            background-color: #f0f0f0;
+        }
+        .kvm_id, .kvm_status {
+            text-align: center;
+        }
         .meters > .ok, .disk_group > .ok, .ram_group > .ok{
 			border-color: #80a080;
 			background-color: #efe;
@@ -112,7 +136,8 @@
 			background-color: rgb(250, 135, 135);
         }
         .cpu { border-color: #a0c0a0; background-color: rgb(252, 248, 248); }
-        .ram { border-color: #c0c0a0; background-color: rgb(255, 255, 251); }
+        .net { border-color: #c0c0a0; background-color: rgb(255, 255, 251); text-align: right; }
+        .ram { border-color: #a0c0c0; background-color: rgb(255, 250, 250); }
         .disk { border-color: #cedfdf; background-color: rgb(237, 241, 243); }
 
         .map_grid {
@@ -149,8 +174,20 @@
 			background-color: white;
         }
         .service_node {
-            background-color: #ddd;
             margin-bottom: 2px;
+            display: flex;
+        }
+        .service_name, .node_name {
+            text-align: center;
+            border-width: 0px;
+			border-style: solid;
+			margin: 1px 1px 1px 1px;
+            padding: 0px 1px 0px 1px;
+            min-width: 250px;
+            border-radius: 10px;
+        }
+        .node_name {
+            background-color: #ddd;
         }
         .service_grid {
             display: grid;
@@ -174,13 +211,13 @@
             border-radius: 10px;
         }
 
-        .service_grid > .on {
+        .service_grid > .on, .service_node > .ok {
             background-color: #8c8;
         }
-        .service_grid > .off {
+        .service_grid > .off, .service_node > .off{
             background-color: #9aa;
         }
-        .service_grid > .fail {
+        .service_grid > .fail, .service_node > .fail {
             background-color: rgb(250, 135, 135);
         }
 
@@ -203,7 +240,7 @@
 <div class="bar">
     <button class="bar-item" onclick="openBar(event, 'nodes')">Nodes</button>
     <button class="bar-item" onclick="openBar(event, 'networks')">Networks</button>
-    <button class="bar-item" onclick="openBar(event, 'services')">Other</button>
+    <button class="bar-item" onclick="openBar(event, 'services')">Services</button>
 </div>
 
 {% macro nodes_page(nodes, id_label) %}
@@ -224,6 +261,14 @@
                     <div class="meter cpu">vCPU</div>
                 </div>
             </td>
+            <td class="head col_net">
+                <div class="meters net">
+                    <div class="meter net">Total</div>
+                    <div class="meter net">Dropped</div>
+                    <div class="meter net">Squeeze</div>
+                    <div class="meter net">Collide</div>
+                </div>
+            </td>
             <td class="head col_ram">
                 <div class="meters">
                     <div class="meter ram">Total</div>
@@ -248,20 +293,28 @@
             <td class="status_{{ _ndat['status'] | node_status_class }}">.</td>
             <td class="head col_name">{{ node }}</td>
             <td class="head col_role">{{ _ndat['role'] }}</td>
-            <td class="head col_vendor">{{ _ndat['virt_vendor'] }}/{{ _ndat['virt_mode'] }}/{{ _ndat['virt_type'] }}</td>
+            <td class="head col_vendor">{{ _ndat['node_type'] }}</td>
             <td class="head col_release">{{ _ndat['linux_arch'] }}/{{ _ndat['linux_codename'] }}</td>
             <td class="head col_kernel">{{ _ndat['kernel'] }}</td>
             <td class="head col_vcpu">
                 <div class="meters vcpu">
-                    <div class="meter cpu">{{ _ndat['cpus'] }}</div>
+                    <div class="meter cpu">{{ _ndat['lscpu']['cpus'] }}</div>
+                </div>
+            </td>
+            <td class="head col_net">
+                <div class="net_group">
+                    <div class="item net">{{ _ndat['net_stats']['total'][0] }}</div>
+                    <div class="item net">{{ _ndat['net_stats']['total'][1] }}</div>
+                    <div class="item net">{{ _ndat['net_stats']['total'][2] }}</div>
+                    <div class="item net">{{ _ndat['net_stats']['total'][3] }}</div>
                 </div>
             </td>
             <td class="head col_ram">
                 <div class="ram_group">
-                    <div class="item ram">{{ _ndat['ram_total'] }}</div>
-                    <div class="item ram">{{ _ndat['ram_used'] }}</div>
-                    <div class="item ram">{{ _ndat['ram_free'] }}</div>
-                    <div class="item ram {{ _ndat['ram_status'] }}">{{ _ndat['ram_available'] }}</div>
+                    <div class="item ram">{{ _ndat['ram']['total'] }}</div>
+                    <div class="item ram">{{ _ndat['ram']['used'] }}</div>
+                    <div class="item ram">{{ _ndat['ram']['free'] }}</div>
+                    <div class="item ram {{ _ndat['ram']['status'] }}">{{ _ndat['ram']['available'] }}</div>
                 </div>
             </td>
             <td class="head col_disk">
@@ -275,9 +328,33 @@
         </tr>
         <tr class="collapsable" id="info_{{ node }}">
             <td class="status_none"></td>
-            <td class="col_notes" colspan="4">.</td>
+            <td class="col_node_notes" colspan="2">
+                {% if 'virsh' in _ndat %}
+                <div class="kvm_group">
+                {% for kvm_node in _ndat['virsh'].keys() | sort %}
+                    <div class="item kvm_id">{{ _ndat['virsh'][kvm_node]['id'] }}</div>
+                    <div class="item kvm_node">{{ kvm_node }}</div>
+                    <div class="item kvm_status">{{ _ndat['virsh'][kvm_node]['status'] }}</div>
+                {% endfor %}
+                </div>
+                {% endif %}
+            </td>
+            <td class="col_cpu_notes smallgreytext" colspan="2">
+                CPU Model: {{ _ndat['lscpu']['model_name'] }} at {{ _ndat['lscpu']['cpu_mhz'] }}Mhz<br>
+                Virtualization: {{ _ndat['lscpu']['virtualization'] }}
+            </td>
             <td class="col_kernel"></td>
             <td class="col_vcpu"></td>
+            <td class="col_net">
+                <div class="net_group">
+                    {% for cpu in _ndat['net_stats'].keys() | sort %}
+                    <div class="item net">{{ cpu }}</div>
+                    {% for val in _ndat['net_stats'][cpu] %}
+                    <div class="item net">{{ val }}</div>
+                    {% endfor %}
+                    {% endfor %}
+                </div>
+            </td>
             <td class="col_ram"></td>
             <td class="col_disk">
                 <div class="disk_group">
@@ -311,7 +388,7 @@
         {% for d in map[net][node] %}
                 <div class="map_item name">{{ node }}</div>
                 <div class="map_item interface {{ d['interface_error'] }}">{{ d['interface'] }}</div>
-                <div class="map_item note">{{ d['interface_note'] }}</div>
+                <div class="map_item note"><pre>{{ d['interface_map'] | linebreaks }}</pre></div>
                 <div class="map_item ipaddr">{{ d['ip_address'] }}</div>
                 <div class="map_item ipaddr_type">{{ d['address_type'] }}</div>
                 <div class="map_item mtu {{ d['mtu_error'] }}">{{ d['rt_mtu'] }}</div>
@@ -335,14 +412,35 @@
     <hr>
     <div class="services">
             {% for node in nodes.keys() | sort %}
-            <div class="service_node" onclick="toggleClassByID('svc_{{ node }}')" id="svc_{{ node }}_button">{{ node }}</div>
+            <div class="service_node" onclick="toggleClassByID('svc_{{ node }}')" id="svc_{{ node }}_button">
+                <div class="node_name">{{ node }}</div>
+                {% for service in nodes[node]['services'].keys() | sort -%}            
+                {% if service in const['services'] %}
+                {% if not nodes[node]['services'][service] %}
+                    <div class="service_name fail">{{ service }}</div>
+                {% endif %}
+                {% endif%}
+                {% endfor%}
+            </div>
             <div class="collapsable" id="svc_{{ node }}">
                 <div class="service_grid">
             {% for service in nodes[node]['services'].keys() | sort -%}            
+                {% if service in const['services'] %}
                 {% if nodes[node]['services'][service] %}
-                    <div class="service name on">{{ service }}</div>
+                    <div class="service on">{{ service }}</div>
                 {% else %}
-                    <div class="service name off">{{ service }}</div>
+                    <div class="service fail">{{ service }}</div>
+                {% endif %}
+                {% endif%}
+            {% endfor %}
+                    <div class="service"># Other services</div>
+            {% for service in nodes[node]['services'].keys() | sort -%}            
+                {% if service not in const['services'] %}
+                {% if nodes[node]['services'][service] %}
+                    <div class="service on">{{ service }}</div>
+                {% else %}
+                    <div class="service off">{{ service }}</div>
+                {% endif %}
                 {% endif %}
             {% endfor %}
                 </div>