blob: 4057a22bc2bd4f6c7d221a515c07a5a80fda65e7 [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 {
Alexc96fdd32019-10-15 12:48:59 -050010 width: 98%;
11 margin-left: 1%;
12 margin-right: 1%;
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 }
Alex1839bbf2019-08-22 17:17:21 -050044 td > .kvm_group {
45 display: grid;
46 grid-template-columns: auto auto auto;
47 padding-left: 0px;
48 padding-right: 0px;
49 margin: 1px;
50 }
Alex836fac82019-08-22 13:36:16 -050051 td > .disk_group {
52 display: grid;
Alexe9908f72020-05-19 16:04:53 -050053 grid-template-columns: 170px 40px 40px 40px 40px;
Alex836fac82019-08-22 13:36:16 -050054 padding-left: 0px;
55 padding-right: 0px;
56 margin: 1px;
Alex Savatieiev9b2f6512019-02-20 18:05:00 -060057 }
Alexe9908f72020-05-19 16:04:53 -050058 td > .ram_group {
Alex836fac82019-08-22 13:36:16 -050059 display: grid;
Alexe9908f72020-05-19 16:04:53 -050060 grid-template-columns: 40px 40px 40px 40px;
Alex836fac82019-08-22 13:36:16 -050061 padding-left: 0px;
62 padding-right: 0px;
63 margin: 1px;
64 }
Alex1839bbf2019-08-22 17:17:21 -050065 td > .net_group {
66 display: grid;
Alexe9908f72020-05-19 16:04:53 -050067 grid-template-columns: 50px 50px 40px 40px 40px;
Alex1839bbf2019-08-22 17:17:21 -050068 padding-left: 0px;
69 padding-right: 0px;
70 margin: 1px;
71 }
Alex836fac82019-08-22 13:36:16 -050072 td > .vcpu_group {
73 display: grid;
74 grid-template-columns: auto;
75 padding-left: 0px;
76 padding-right: 0px;
77 margin: 1px;
78 }
79
80 .item {
81 display: inline-grid;
82 border-width: 1px;
83 border-style: solid;
84 margin: 1px 1px 1px 1px;
85 padding: 0px 1px 0px 1px;
86 }
87
88 .status_none { border-radius: 10px; width: 8px; }
89 .status_up { border-radius: 10px; width: 8px; background-color: #393; color: #393; }
Alexe9908f72020-05-19 16:04:53 -050090 .status_down { border-radius: 10px; width: 8px; background-color: #933; color: #933; }
91 .status_skip { border-radius: 10px; width: 8px; background-color: #aaa; color: #aaa; }
92
93 .down > .col_name, .down > .col_role, .down > .col_down {
94 background-color: #fee;
95 background-image: linear-gradient(white, #fee, #fee, white);
96 margin: 0px;
97 }
98 .skip > .col_name, .skip > .col_role, .skip > .col_skip {
99 background-color: #eee;
100 background-image: linear-gradient(white, #eee, #eee, white);
101 margin: 0px;
102 }
103 .down > .col_name, .skip > .col_name { padding-left: 3px; }
104 .down > .col_role, .skip > .col_role { padding-left: 5px; }
105
Alex836fac82019-08-22 13:36:16 -0500106 .head { height: 18px; }
Alexe9908f72020-05-19 16:04:53 -0500107 .col_name { width: 90px; }
Alexc96fdd32019-10-15 12:48:59 -0500108 .col_role { width: 130px; }
109 .col_vendor { width: 70px; }
Alex836fac82019-08-22 13:36:16 -0500110 .col_release { width: 100px; }
111 .col_kernel { min-width: 100px; }
112 .col_vcpu { min-width: 40px; }
Alex1839bbf2019-08-22 17:17:21 -0500113 .col_net { min-width: 150px; }
Alexe9908f72020-05-19 16:04:53 -0500114 .col_ram { min-width: 162px; }
115 .col_disk { min-width: 290px; }
116
117 .col_down, .col_skip {
118 min-width: 1020px;
119 text-align: left;
120 font-style: italic;
121 padding-left: 50px !important;
122 color: gray;
123 }
Alex836fac82019-08-22 13:36:16 -0500124
Alexe9908f72020-05-19 16:04:53 -0500125 .col_node_notes { width: 225px; }
Alexc96fdd32019-10-15 12:48:59 -0500126 .col_cpu_notes { width: 177px; }
Alex1839bbf2019-08-22 17:17:21 -0500127
Alex836fac82019-08-22 13:36:16 -0500128 .meters {
129 display: inline-block;
130 margin: 1px;
131 }
132 .meters > .meter {
Alex41485522019-04-12 17:26:18 -0500133 display: block;
134 float: left;
Alex836fac82019-08-22 13:36:16 -0500135 border-width: 1px;
136 border-style: solid;
137 margin: 0px 1px 0px 1px;
138 padding: 0px 1px 0px 1px;
139
Alex Savatieiev9b2f6512019-02-20 18:05:00 -0600140 }
Alex1839bbf2019-08-22 17:17:21 -0500141 .kvm_id, .kvm_node, .kvm_status {
142 border-width: 0px;
143 background-color: #f0f0f0;
144 }
145 .kvm_id, .kvm_status {
146 text-align: center;
147 }
Alex836fac82019-08-22 13:36:16 -0500148 .meters > .ok, .disk_group > .ok, .ram_group > .ok{
149 border-color: #80a080;
150 background-color: #efe;
151 }
152 .meters > .warn, .disk_group > .warn, .ram_group > .warn {
153 border-color: #d3a200;
154 background-color: rgb(255, 216, 133);
155 }
156 .meters > .fail, .disk_group > .fail, .ram_group > .fail {
157 border-color: #bb0000;
158 background-color: rgb(250, 135, 135);
159 }
160 .cpu { border-color: #a0c0a0; background-color: rgb(252, 248, 248); }
Alex1839bbf2019-08-22 17:17:21 -0500161 .net { border-color: #c0c0a0; background-color: rgb(255, 255, 251); text-align: right; }
Alexe9908f72020-05-19 16:04:53 -0500162 .ram { border-color: #a0c0c0; background-color: rgb(255, 250, 250); text-align: right; }
163 .disk { border-color: #cedfdf; background-color: rgb(237, 241, 243); text-align: right; }
164 .disk_group > .path {
165 text-align: left;
166 }
Alex836fac82019-08-22 13:36:16 -0500167 .map_grid {
168 display: grid;
169 grid-template-columns: auto auto auto auto auto auto auto auto auto auto;
170 grid-column-gap: 20px;
171 padding-left: 0px;
172 padding-right: 0px;
173 margin: 1px;
174 margin-left: 20px;
175
176 }
177 .map_item {
178 display: inline-grid;
179 border-width: 0px;
180 border-style: solid;
181 margin: 1px 1px 1px 1px;
182 padding: 0px 1px 0px 1px;
183 }
184
185 .map_grid > .ok {
186 color: #80a080;
187 }
188 .map_grid > .warn {
189 color: #d3a200;
190 }
191 .map_grid > .fail {
192 color: #bb0000;
193 }
194
195 .services {
196 font-family: "LaoSangamMN", Monaco, monospace;
197 font-size: 1.1em;
198 background-color: white;
199 }
200 .service_node {
Alex836fac82019-08-22 13:36:16 -0500201 margin-bottom: 2px;
Alex1839bbf2019-08-22 17:17:21 -0500202 display: flex;
203 }
204 .service_name, .node_name {
205 text-align: center;
206 border-width: 0px;
207 border-style: solid;
208 margin: 1px 1px 1px 1px;
209 padding: 0px 1px 0px 1px;
210 min-width: 250px;
211 border-radius: 10px;
212 }
213 .node_name {
214 background-color: #ddd;
Alex836fac82019-08-22 13:36:16 -0500215 }
216 .service_grid {
217 display: grid;
218 grid-template-columns: repeat(8, auto);
219 grid-template-rows: repeat(10, auto);
220 grid-auto-flow: column;
221 grid-column-gap: 20px;
222 padding-left: 0px;
223 padding-right: 0px;
224 margin: 1px;
225 margin-left: 20px;
226 }
227 .service {
228 display: inline-grid;
229 text-align: center;
230 border-width: 0px;
231 border-style: solid;
232 margin: 1px 1px 1px 1px;
233 padding: 0px 1px 0px 1px;
234 min-width: 150px;
235 border-radius: 10px;
236 }
237
Alex1839bbf2019-08-22 17:17:21 -0500238 .service_grid > .on, .service_node > .ok {
Alex836fac82019-08-22 13:36:16 -0500239 background-color: #8c8;
240 }
Alex1839bbf2019-08-22 17:17:21 -0500241 .service_grid > .off, .service_node > .off{
Alex836fac82019-08-22 13:36:16 -0500242 background-color: #9aa;
243 }
Alex1839bbf2019-08-22 17:17:21 -0500244 .service_grid > .fail, .service_node > .fail {
Alex836fac82019-08-22 13:36:16 -0500245 background-color: rgb(250, 135, 135);
246 }
247
Alex Savatieiev9b2f6512019-02-20 18:05:00 -0600248 </style>
Alex Savatieiev9b2f6512019-02-20 18:05:00 -0600249</head>
250<body onload="init()">
251
Alex41485522019-04-12 17:26:18 -0500252<div class="header">
253 <div class="label">OpenStack release:</div>
254 <div class="text">{{ openstack_release }}</div>
255 <div class="label">MCP Version:</div>
256 <div class="text">{{ mcp_release }}</div>
Alex836fac82019-08-22 13:36:16 -0500257 <div class="label">RAM % Warning/Critical:</div>
258 <div class="text">{{ const['ram_warn'] }}/{{ const['ram_critical'] }}</div>
259 <div class="label">Disk % Warning/Critical:</div>
260 <div class="text">{{ const['disk_warn'] }}/{{ const['disk_critical'] }}</div>
Alex41485522019-04-12 17:26:18 -0500261 <div class="label date">generated on: {{ gen_date }}</div>
262</div>
263
264<div class="bar">
265 <button class="bar-item" onclick="openBar(event, 'nodes')">Nodes</button>
266 <button class="bar-item" onclick="openBar(event, 'networks')">Networks</button>
Alex1839bbf2019-08-22 17:17:21 -0500267 <button class="bar-item" onclick="openBar(event, 'services')">Services</button>
Alex41485522019-04-12 17:26:18 -0500268</div>
269
270{% macro nodes_page(nodes, id_label) %}
271<div id="{{ id_label }}" class="barcontent">
272 <h5>{{ caller() }}</h5>
273 <hr>
274 <table class="cluster_nodes">
Alex836fac82019-08-22 13:36:16 -0500275 <tr class="node">
276 <td class="status_none"></td>
277 <td class="head col_name">Name</td>
278 <td class="head col_role">Role</td>
279 <td class="head col_vendor">Virtual</td>
280 <td class="head col_release">Linux</td>
281 <td class="head col_kernel">Kernel</td>
282
283 <td class="head col_vcpu">
284 <div class="meters vcpu">
285 <div class="meter cpu">vCPU</div>
286 </div>
287 </td>
Alex1839bbf2019-08-22 17:17:21 -0500288 <td class="head col_net">
Alexe9908f72020-05-19 16:04:53 -0500289 <div class="net_group">
290 <div class="item net">vCpu</div>
291 <div class="item net">Total</div>
292 <div class="item net">Drop</div>
293 <div class="item net">Sq.</div>
294 <div class="item net">Cl.</div>
Alex1839bbf2019-08-22 17:17:21 -0500295 </div>
296 </td>
Alex836fac82019-08-22 13:36:16 -0500297 <td class="head col_ram">
Alexe9908f72020-05-19 16:04:53 -0500298 <div class="ram_group">
299 <div class="item ram">Total</div>
300 <div class="item ram">Used</div>
301 <div class="item ram">Free</div>
302 <div class="item ram">Avail.</div>
Alex836fac82019-08-22 13:36:16 -0500303 </div>
304 </td>
305 <td class="head col_disk">
Alexe9908f72020-05-19 16:04:53 -0500306 <div class="disk_group">
307 <div class="item disk path">Device path</div>
308 <div class="item disk">Total</div>
309 <div class="item disk">Used</div>
310 <div class="item disk">Free</div>
311 <div class="item disk">%</div>
Alex836fac82019-08-22 13:36:16 -0500312 </div>
313 </td>
314 </tr>
Alex41485522019-04-12 17:26:18 -0500315 {% for node in nodes.keys() | sort %}
316 {% set _ndat = nodes[node] %}
Alexe9908f72020-05-19 16:04:53 -0500317 {% set _status = _ndat['status'] | node_status_class %}
318 {% if _status == 'down' %}
319 <tr class="node down">
320 <td class="status_{{ _status }}">.</td>
321 <td class="head col_name">{{ _ndat['shortname'] }}</td>
322 <td class="head col_role">{{ _ndat['role'] }}</td>
323 <td class="head col_down" colspan="7"> ...no data collected: node is down</td>
324 </tr>
325 {% elif _status == 'skip' %}
326 <tr class="node skip">
327 <td class="status_{{ _status }}">.</td>
328 <td class="head col_name">{{ _ndat['shortname'] }}</td>
329 <td class="head col_role">{{ _ndat['role'] }}</td>
330 <td class="head col_skip" colspan="7"> ...no skipped from processing</td>
331 </tr>
332 {% else %}
Alex836fac82019-08-22 13:36:16 -0500333 <tr class="node" onclick="toggleClassByID('info_{{ node }}')" id='info_{{ node }}_button'>
334 <td class="status_{{ _ndat['status'] | node_status_class }}">.</td>
Alexe9908f72020-05-19 16:04:53 -0500335 <td class="head col_name">{{ _ndat['shortname'] }}</td>
Alex836fac82019-08-22 13:36:16 -0500336 <td class="head col_role">{{ _ndat['role'] }}</td>
Alex1839bbf2019-08-22 17:17:21 -0500337 <td class="head col_vendor">{{ _ndat['node_type'] }}</td>
Alex836fac82019-08-22 13:36:16 -0500338 <td class="head col_release">{{ _ndat['linux_arch'] }}/{{ _ndat['linux_codename'] }}</td>
339 <td class="head col_kernel">{{ _ndat['kernel'] }}</td>
340 <td class="head col_vcpu">
341 <div class="meters vcpu">
Alex1839bbf2019-08-22 17:17:21 -0500342 <div class="meter cpu">{{ _ndat['lscpu']['cpus'] }}</div>
343 </div>
344 </td>
345 <td class="head col_net">
346 <div class="net_group">
Alexe9908f72020-05-19 16:04:53 -0500347 <div class="item net">All</div>
Alex1839bbf2019-08-22 17:17:21 -0500348 <div class="item net">{{ _ndat['net_stats']['total'][0] }}</div>
349 <div class="item net">{{ _ndat['net_stats']['total'][1] }}</div>
350 <div class="item net">{{ _ndat['net_stats']['total'][2] }}</div>
351 <div class="item net">{{ _ndat['net_stats']['total'][3] }}</div>
Alex836fac82019-08-22 13:36:16 -0500352 </div>
353 </td>
354 <td class="head col_ram">
355 <div class="ram_group">
Alex1839bbf2019-08-22 17:17:21 -0500356 <div class="item ram">{{ _ndat['ram']['total'] }}</div>
357 <div class="item ram">{{ _ndat['ram']['used'] }}</div>
358 <div class="item ram">{{ _ndat['ram']['free'] }}</div>
359 <div class="item ram {{ _ndat['ram']['status'] }}">{{ _ndat['ram']['available'] }}</div>
Alex836fac82019-08-22 13:36:16 -0500360 </div>
361 </td>
362 <td class="head col_disk">
363 <div class="disk_group">
Alexe9908f72020-05-19 16:04:53 -0500364 <div class="item disk path">{{ _ndat['disk_max_dev'] }}</div>
Alex836fac82019-08-22 13:36:16 -0500365 {% for val in _ndat['disk'][_ndat['disk_max_dev']]['v'] %}
366 <div class="item disk {{ _ndat['disk'][_ndat['disk_max_dev']]['f'] }}">{{ val }}</div>
367 {% endfor %}
368 </div>
369 </td>
370 </tr>
371 <tr class="collapsable" id="info_{{ node }}">
372 <td class="status_none"></td>
Alex1839bbf2019-08-22 17:17:21 -0500373 <td class="col_node_notes" colspan="2">
374 {% if 'virsh' in _ndat %}
375 <div class="kvm_group">
376 {% for kvm_node in _ndat['virsh'].keys() | sort %}
377 <div class="item kvm_id">{{ _ndat['virsh'][kvm_node]['id'] }}</div>
378 <div class="item kvm_node">{{ kvm_node }}</div>
379 <div class="item kvm_status">{{ _ndat['virsh'][kvm_node]['status'] }}</div>
380 {% endfor %}
381 </div>
382 {% endif %}
383 </td>
384 <td class="col_cpu_notes smallgreytext" colspan="2">
385 CPU Model: {{ _ndat['lscpu']['model_name'] }} at {{ _ndat['lscpu']['cpu_mhz'] }}Mhz<br>
386 Virtualization: {{ _ndat['lscpu']['virtualization'] }}
387 </td>
Alex836fac82019-08-22 13:36:16 -0500388 <td class="col_kernel"></td>
389 <td class="col_vcpu"></td>
Alex1839bbf2019-08-22 17:17:21 -0500390 <td class="col_net">
391 <div class="net_group">
392 {% for cpu in _ndat['net_stats'].keys() | sort %}
393 <div class="item net">{{ cpu }}</div>
394 {% for val in _ndat['net_stats'][cpu] %}
395 <div class="item net">{{ val }}</div>
396 {% endfor %}
397 {% endfor %}
398 </div>
399 </td>
Alex836fac82019-08-22 13:36:16 -0500400 <td class="col_ram"></td>
401 <td class="col_disk">
402 <div class="disk_group">
403 {% for dev in _ndat['disk'].keys() | sort %}
Alexe9908f72020-05-19 16:04:53 -0500404 <div class="item disk path">{{ dev }}</div>
Alex836fac82019-08-22 13:36:16 -0500405 {% for val in _ndat['disk'][dev]['v'] %}
406 <div class="item disk {{ _ndat['disk'][dev]['f'] }}">{{ val }}</div>
407 {% endfor %}
408 {% endfor %}
409 </div>
410 </td>
Alex41485522019-04-12 17:26:18 -0500411 </tr>
Alexe9908f72020-05-19 16:04:53 -0500412 {% endif %}
Alex41485522019-04-12 17:26:18 -0500413 {% endfor %}
414 </table>
415 <hr>
416</div>
417{% endmacro %}
418
419{% macro networks_page(networks, id_label) %}
420<div id="{{ id_label }}" class="barcontent">
421 <h5>{{ caller() }}</h5>
422 <hr>
423 <table class="networks">
Alex836fac82019-08-22 13:36:16 -0500424 {% for net in map.keys() %}
425 <tr class="subnet" onclick="toggleClassByID('net_{{ net }}')" id="{{ net }}_net_button">
426 <td>{{ net }}</td>
Alex41485522019-04-12 17:26:18 -0500427 </tr>
Alex836fac82019-08-22 13:36:16 -0500428 <tr class="collapsable" id="net_{{ net }}"><td>
429 <div class="map_grid">
430 {% for node in map[net].keys() | sort %}
431 {% for d in map[net][node] %}
432 <div class="map_item name">{{ node }}</div>
433 <div class="map_item interface {{ d['interface_error'] }}">{{ d['interface'] }}</div>
Alex1839bbf2019-08-22 17:17:21 -0500434 <div class="map_item note"><pre>{{ d['interface_map'] | linebreaks }}</pre></div>
Alex836fac82019-08-22 13:36:16 -0500435 <div class="map_item ipaddr">{{ d['ip_address'] }}</div>
436 <div class="map_item ipaddr_type">{{ d['address_type'] }}</div>
437 <div class="map_item mtu {{ d['mtu_error'] }}">{{ d['rt_mtu'] }}</div>
438 <div class="map_item status {{ d['status_error'] }}">{{ d['status'] }}</div>
439 <div class="map_item gate {{ d['subnet_gateway_error'] }}">{{ d['subnet_gateway'] }}</div>
440 <div class="map_item gate">{{ d['default_gateway'] }}</div>
441 <div class="map_item error_note">{{ d['error_note'] }}</div>
442 {% endfor %}
443 {% endfor %}
444 </div>
445 </td></tr>
446 {% endfor %}
Alex41485522019-04-12 17:26:18 -0500447 </table>
448 <hr>
449</div>
450{% endmacro %}
451
452{% macro services_page(services, id_label) %}
453<div id="{{ id_label }}" class="barcontent">
454 <h5>{{ caller() }}</h5>
455 <hr>
Alex836fac82019-08-22 13:36:16 -0500456 <div class="services">
457 {% for node in nodes.keys() | sort %}
Alex1839bbf2019-08-22 17:17:21 -0500458 <div class="service_node" onclick="toggleClassByID('svc_{{ node }}')" id="svc_{{ node }}_button">
459 <div class="node_name">{{ node }}</div>
460 {% for service in nodes[node]['services'].keys() | sort -%}
461 {% if service in const['services'] %}
462 {% if not nodes[node]['services'][service] %}
463 <div class="service_name fail">{{ service }}</div>
464 {% endif %}
465 {% endif%}
466 {% endfor%}
467 </div>
Alex836fac82019-08-22 13:36:16 -0500468 <div class="collapsable" id="svc_{{ node }}">
469 <div class="service_grid">
470 {% for service in nodes[node]['services'].keys() | sort -%}
Alex1839bbf2019-08-22 17:17:21 -0500471 {% if service in const['services'] %}
Alex836fac82019-08-22 13:36:16 -0500472 {% if nodes[node]['services'][service] %}
Alex1839bbf2019-08-22 17:17:21 -0500473 <div class="service on">{{ service }}</div>
Alex836fac82019-08-22 13:36:16 -0500474 {% else %}
Alex1839bbf2019-08-22 17:17:21 -0500475 <div class="service fail">{{ service }}</div>
476 {% endif %}
477 {% endif%}
478 {% endfor %}
479 <div class="service"># Other services</div>
480 {% for service in nodes[node]['services'].keys() | sort -%}
481 {% if service not in const['services'] %}
482 {% if nodes[node]['services'][service] %}
483 <div class="service on">{{ service }}</div>
484 {% else %}
485 <div class="service off">{{ service }}</div>
486 {% endif %}
Alex836fac82019-08-22 13:36:16 -0500487 {% endif %}
488 {% endfor %}
489 </div>
490 </div>
491 {% endfor %}
492 </div>
493 <hr>
Alex41485522019-04-12 17:26:18 -0500494</div>
495{% endmacro %}
496
497<!-- Cluster nodes page -->
498{% call nodes_page(nodes, "nodes") %}
Alexe9908f72020-05-19 16:04:53 -0500499 Cluster nodes status and simple meterings in *.{{ domain }}
Alex41485522019-04-12 17:26:18 -0500500{% endcall %}
501
502<!-- Cluster nodes page -->
503{% call networks_page(networks, "networks") %}
504 Networks in the cluster
505{% endcall %}
506
507<!-- Cluster nodes page -->
508{% call services_page(services, "services") %}
509 Services status in the cluster
510{% endcall %}
511
Alex Savatieiev9b2f6512019-02-20 18:05:00 -0600512</body>
513</html>