blob: c26a115a70925c8643db9a980fc0bea65201be0c [file] [log] [blame]
Alex Savatieiev9b2f6512019-02-20 18:05:00 -06001<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
Alex41485522019-04-12 17:26:18 -05005 <title>Nodes and Networks report</title>
6 {% include 'common_styles.j2' %}
7 {% include 'common_scripts.j2' %}
Alex Savatieiev9b2f6512019-02-20 18:05:00 -06008 <style>
Alex41485522019-04-12 17:26:18 -05009 table.cluster_nodes {
10 width: 90%;
11 margin-left: 5%;
12 margin-right: 5%;
Alex Savatieiev9b2f6512019-02-20 18:05:00 -060013 }
Alex41485522019-04-12 17:26:18 -050014
15 /* Node rows*/
16 .node {
Alex836fac82019-08-22 13:36:16 -050017 font-family: "LaoSangamMN", Monaco, monospace;
18 font-size: 0.8em;
Alex41485522019-04-12 17:26:18 -050019 display: inline-block;
20 background-color: white;
21 }
Alex836fac82019-08-22 13:36:16 -050022 .collapsable {
23 font-family: "LaoSangamMN", Monaco, monospace;
24 font-size: 0.8em;
25 display: none;
26 background-color: white;
27 visibility: hidden;
28 }
29 .collapsable.in {
30 visibility: visible;
31 display: inline-block;
32 }
33
34 div.services > .collapsable.in {
35 display: table-row;
36 }
Alex41485522019-04-12 17:26:18 -050037
Alex836fac82019-08-22 13:36:16 -050038 tr.node > td, tr.collapsable > td {
Alex Savatieiev9b2f6512019-02-20 18:05:00 -060039 display: block;
Alex Savatieiev9b2f6512019-02-20 18:05:00 -060040 float: left;
Alex41485522019-04-12 17:26:18 -050041 padding: 1px;
Alex41485522019-04-12 17:26:18 -050042 margin: 2px;
Alex Savatieiev9b2f6512019-02-20 18:05:00 -060043 }
Alex836fac82019-08-22 13:36:16 -050044 td > .disk_group {
45 display: grid;
46 grid-template-columns: auto auto auto auto auto;
47 padding-left: 0px;
48 padding-right: 0px;
49 margin: 1px;
Alex Savatieiev9b2f6512019-02-20 18:05:00 -060050 }
Alex836fac82019-08-22 13:36:16 -050051 td > .ram_group {
52 display: grid;
53 grid-template-columns: auto auto auto auto;
54 padding-left: 0px;
55 padding-right: 0px;
56 margin: 1px;
57 }
58 td > .vcpu_group {
59 display: grid;
60 grid-template-columns: auto;
61 padding-left: 0px;
62 padding-right: 0px;
63 margin: 1px;
64 }
65
66 .item {
67 display: inline-grid;
68 border-width: 1px;
69 border-style: solid;
70 margin: 1px 1px 1px 1px;
71 padding: 0px 1px 0px 1px;
72 }
73
74 .status_none { border-radius: 10px; width: 8px; }
75 .status_up { border-radius: 10px; width: 8px; background-color: #393; color: #393; }
76 .status_down { border-radius: 10px; width: 8px; background-color: #933; color: #933; }
Alex41485522019-04-12 17:26:18 -050077
Alex836fac82019-08-22 13:36:16 -050078 .head { height: 18px; }
79 .col_name { width: 250px; }
80 .col_role { width: 150px; }
81 .col_vendor { width: 100px; }
82 .col_release { width: 100px; }
83 .col_kernel { min-width: 100px; }
84 .col_vcpu { min-width: 40px; }
85 .col_ram { min-width: 150px; }
86 .col_disk { min-width: 200px; }
87
88 .col_notes { width: 618px; }
89 .meters {
90 display: inline-block;
91 margin: 1px;
92 }
93 .meters > .meter {
Alex41485522019-04-12 17:26:18 -050094 display: block;
95 float: left;
Alex836fac82019-08-22 13:36:16 -050096 border-width: 1px;
97 border-style: solid;
98 margin: 0px 1px 0px 1px;
99 padding: 0px 1px 0px 1px;
100
Alex Savatieiev9b2f6512019-02-20 18:05:00 -0600101 }
Alex836fac82019-08-22 13:36:16 -0500102 .meters > .ok, .disk_group > .ok, .ram_group > .ok{
103 border-color: #80a080;
104 background-color: #efe;
105 }
106 .meters > .warn, .disk_group > .warn, .ram_group > .warn {
107 border-color: #d3a200;
108 background-color: rgb(255, 216, 133);
109 }
110 .meters > .fail, .disk_group > .fail, .ram_group > .fail {
111 border-color: #bb0000;
112 background-color: rgb(250, 135, 135);
113 }
114 .cpu { border-color: #a0c0a0; background-color: rgb(252, 248, 248); }
115 .ram { border-color: #c0c0a0; background-color: rgb(255, 255, 251); }
116 .disk { border-color: #cedfdf; background-color: rgb(237, 241, 243); }
117
118 .map_grid {
119 display: grid;
120 grid-template-columns: auto auto auto auto auto auto auto auto auto auto;
121 grid-column-gap: 20px;
122 padding-left: 0px;
123 padding-right: 0px;
124 margin: 1px;
125 margin-left: 20px;
126
127 }
128 .map_item {
129 display: inline-grid;
130 border-width: 0px;
131 border-style: solid;
132 margin: 1px 1px 1px 1px;
133 padding: 0px 1px 0px 1px;
134 }
135
136 .map_grid > .ok {
137 color: #80a080;
138 }
139 .map_grid > .warn {
140 color: #d3a200;
141 }
142 .map_grid > .fail {
143 color: #bb0000;
144 }
145
146 .services {
147 font-family: "LaoSangamMN", Monaco, monospace;
148 font-size: 1.1em;
149 background-color: white;
150 }
151 .service_node {
152 background-color: #ddd;
153 margin-bottom: 2px;
154 }
155 .service_grid {
156 display: grid;
157 grid-template-columns: repeat(8, auto);
158 grid-template-rows: repeat(10, auto);
159 grid-auto-flow: column;
160 grid-column-gap: 20px;
161 padding-left: 0px;
162 padding-right: 0px;
163 margin: 1px;
164 margin-left: 20px;
165 }
166 .service {
167 display: inline-grid;
168 text-align: center;
169 border-width: 0px;
170 border-style: solid;
171 margin: 1px 1px 1px 1px;
172 padding: 0px 1px 0px 1px;
173 min-width: 150px;
174 border-radius: 10px;
175 }
176
177 .service_grid > .on {
178 background-color: #8c8;
179 }
180 .service_grid > .off {
181 background-color: #9aa;
182 }
183 .service_grid > .fail {
184 background-color: rgb(250, 135, 135);
185 }
186
Alex Savatieiev9b2f6512019-02-20 18:05:00 -0600187 </style>
Alex Savatieiev9b2f6512019-02-20 18:05:00 -0600188</head>
189<body onload="init()">
190
Alex41485522019-04-12 17:26:18 -0500191<div class="header">
192 <div class="label">OpenStack release:</div>
193 <div class="text">{{ openstack_release }}</div>
194 <div class="label">MCP Version:</div>
195 <div class="text">{{ mcp_release }}</div>
Alex836fac82019-08-22 13:36:16 -0500196 <div class="label">RAM % Warning/Critical:</div>
197 <div class="text">{{ const['ram_warn'] }}/{{ const['ram_critical'] }}</div>
198 <div class="label">Disk % Warning/Critical:</div>
199 <div class="text">{{ const['disk_warn'] }}/{{ const['disk_critical'] }}</div>
Alex41485522019-04-12 17:26:18 -0500200 <div class="label date">generated on: {{ gen_date }}</div>
201</div>
202
203<div class="bar">
204 <button class="bar-item" onclick="openBar(event, 'nodes')">Nodes</button>
205 <button class="bar-item" onclick="openBar(event, 'networks')">Networks</button>
206 <button class="bar-item" onclick="openBar(event, 'services')">Other</button>
207</div>
208
209{% macro nodes_page(nodes, id_label) %}
210<div id="{{ id_label }}" class="barcontent">
211 <h5>{{ caller() }}</h5>
212 <hr>
213 <table class="cluster_nodes">
Alex836fac82019-08-22 13:36:16 -0500214 <tr class="node">
215 <td class="status_none"></td>
216 <td class="head col_name">Name</td>
217 <td class="head col_role">Role</td>
218 <td class="head col_vendor">Virtual</td>
219 <td class="head col_release">Linux</td>
220 <td class="head col_kernel">Kernel</td>
221
222 <td class="head col_vcpu">
223 <div class="meters vcpu">
224 <div class="meter cpu">vCPU</div>
225 </div>
226 </td>
227 <td class="head col_ram">
228 <div class="meters">
229 <div class="meter ram">Total</div>
230 <div class="meter ram">Used</div>
231 <div class="meter ram">Free</div>
232 <div class="meter ram">Available</div>
233 </div>
234 </td>
235 <td class="head col_disk">
236 <div class="meters">
237 <div class="meter disk">device</div>
238 <div class="meter disk">total</div>
239 <div class="meter disk">used</div>
240 <div class="meter disk">free</div>
241 <div class="meter disk">percent</div>
242 </div>
243 </td>
244 </tr>
Alex41485522019-04-12 17:26:18 -0500245 {% for node in nodes.keys() | sort %}
246 {% set _ndat = nodes[node] %}
Alex836fac82019-08-22 13:36:16 -0500247 <tr class="node" onclick="toggleClassByID('info_{{ node }}')" id='info_{{ node }}_button'>
248 <td class="status_{{ _ndat['status'] | node_status_class }}">.</td>
249 <td class="head col_name">{{ node }}</td>
250 <td class="head col_role">{{ _ndat['role'] }}</td>
251 <td class="head col_vendor">{{ _ndat['virt_vendor'] }}/{{ _ndat['virt_mode'] }}/{{ _ndat['virt_type'] }}</td>
252 <td class="head col_release">{{ _ndat['linux_arch'] }}/{{ _ndat['linux_codename'] }}</td>
253 <td class="head col_kernel">{{ _ndat['kernel'] }}</td>
254 <td class="head col_vcpu">
255 <div class="meters vcpu">
256 <div class="meter cpu">{{ _ndat['cpus'] }}</div>
257 </div>
258 </td>
259 <td class="head col_ram">
260 <div class="ram_group">
261 <div class="item ram">{{ _ndat['ram_total'] }}</div>
262 <div class="item ram">{{ _ndat['ram_used'] }}</div>
263 <div class="item ram">{{ _ndat['ram_free'] }}</div>
264 <div class="item ram {{ _ndat['ram_status'] }}">{{ _ndat['ram_available'] }}</div>
265 </div>
266 </td>
267 <td class="head col_disk">
268 <div class="disk_group">
269 <div class="item disk">{{ _ndat['disk_max_dev'] }}</div>
270 {% for val in _ndat['disk'][_ndat['disk_max_dev']]['v'] %}
271 <div class="item disk {{ _ndat['disk'][_ndat['disk_max_dev']]['f'] }}">{{ val }}</div>
272 {% endfor %}
273 </div>
274 </td>
275 </tr>
276 <tr class="collapsable" id="info_{{ node }}">
277 <td class="status_none"></td>
278 <td class="col_notes" colspan="4">.</td>
279 <td class="col_kernel"></td>
280 <td class="col_vcpu"></td>
281 <td class="col_ram"></td>
282 <td class="col_disk">
283 <div class="disk_group">
284 {% for dev in _ndat['disk'].keys() | sort %}
285 <div class="item disk">{{ dev }}</div>
286 {% for val in _ndat['disk'][dev]['v'] %}
287 <div class="item disk {{ _ndat['disk'][dev]['f'] }}">{{ val }}</div>
288 {% endfor %}
289 {% endfor %}
290 </div>
291 </td>
Alex41485522019-04-12 17:26:18 -0500292 </tr>
293 {% endfor %}
294 </table>
295 <hr>
296</div>
297{% endmacro %}
298
299{% macro networks_page(networks, id_label) %}
300<div id="{{ id_label }}" class="barcontent">
301 <h5>{{ caller() }}</h5>
302 <hr>
303 <table class="networks">
Alex836fac82019-08-22 13:36:16 -0500304 {% for net in map.keys() %}
305 <tr class="subnet" onclick="toggleClassByID('net_{{ net }}')" id="{{ net }}_net_button">
306 <td>{{ net }}</td>
Alex41485522019-04-12 17:26:18 -0500307 </tr>
Alex836fac82019-08-22 13:36:16 -0500308 <tr class="collapsable" id="net_{{ net }}"><td>
309 <div class="map_grid">
310 {% for node in map[net].keys() | sort %}
311 {% for d in map[net][node] %}
312 <div class="map_item name">{{ node }}</div>
313 <div class="map_item interface {{ d['interface_error'] }}">{{ d['interface'] }}</div>
314 <div class="map_item note">{{ d['interface_note'] }}</div>
315 <div class="map_item ipaddr">{{ d['ip_address'] }}</div>
316 <div class="map_item ipaddr_type">{{ d['address_type'] }}</div>
317 <div class="map_item mtu {{ d['mtu_error'] }}">{{ d['rt_mtu'] }}</div>
318 <div class="map_item status {{ d['status_error'] }}">{{ d['status'] }}</div>
319 <div class="map_item gate {{ d['subnet_gateway_error'] }}">{{ d['subnet_gateway'] }}</div>
320 <div class="map_item gate">{{ d['default_gateway'] }}</div>
321 <div class="map_item error_note">{{ d['error_note'] }}</div>
322 {% endfor %}
323 {% endfor %}
324 </div>
325 </td></tr>
326 {% endfor %}
Alex41485522019-04-12 17:26:18 -0500327 </table>
328 <hr>
329</div>
330{% endmacro %}
331
332{% macro services_page(services, id_label) %}
333<div id="{{ id_label }}" class="barcontent">
334 <h5>{{ caller() }}</h5>
335 <hr>
Alex836fac82019-08-22 13:36:16 -0500336 <div class="services">
337 {% for node in nodes.keys() | sort %}
338 <div class="service_node" onclick="toggleClassByID('svc_{{ node }}')" id="svc_{{ node }}_button">{{ node }}</div>
339 <div class="collapsable" id="svc_{{ node }}">
340 <div class="service_grid">
341 {% for service in nodes[node]['services'].keys() | sort -%}
342 {% if nodes[node]['services'][service] %}
343 <div class="service name on">{{ service }}</div>
344 {% else %}
345 <div class="service name off">{{ service }}</div>
346 {% endif %}
347 {% endfor %}
348 </div>
349 </div>
350 {% endfor %}
351 </div>
352 <hr>
Alex41485522019-04-12 17:26:18 -0500353</div>
354{% endmacro %}
355
356<!-- Cluster nodes page -->
357{% call nodes_page(nodes, "nodes") %}
358 Cluster nodes status and simple meterings
359{% endcall %}
360
361<!-- Cluster nodes page -->
362{% call networks_page(networks, "networks") %}
363 Networks in the cluster
364{% endcall %}
365
366<!-- Cluster nodes page -->
367{% call services_page(services, "services") %}
368 Services status in the cluster
369{% endcall %}
370
Alex Savatieiev9b2f6512019-02-20 18:05:00 -0600371</body>
372</html>