blob: d45f55ddb28bd63a4f59871f0f85156c211da3ee [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">
Ievgeniia Zadorozhna33d5c9a2025-09-04 17:36:55 +0200253 <div class="label">k0rdent release:</div>
254 <div class="text">{{ k0rdent_release }}</div>
Alex836fac82019-08-22 13:36:16 -0500255 <div class="label">RAM % Warning/Critical:</div>
256 <div class="text">{{ const['ram_warn'] }}/{{ const['ram_critical'] }}</div>
257 <div class="label">Disk % Warning/Critical:</div>
258 <div class="text">{{ const['disk_warn'] }}/{{ const['disk_critical'] }}</div>
Alex41485522019-04-12 17:26:18 -0500259 <div class="label date">generated on: {{ gen_date }}</div>
260</div>
261
262<div class="bar">
263 <button class="bar-item" onclick="openBar(event, 'nodes')">Nodes</button>
264 <button class="bar-item" onclick="openBar(event, 'networks')">Networks</button>
Alex41485522019-04-12 17:26:18 -0500265</div>
266
267{% macro nodes_page(nodes, id_label) %}
268<div id="{{ id_label }}" class="barcontent">
269 <h5>{{ caller() }}</h5>
270 <hr>
271 <table class="cluster_nodes">
Alex836fac82019-08-22 13:36:16 -0500272 <tr class="node">
273 <td class="status_none"></td>
274 <td class="head col_name">Name</td>
275 <td class="head col_role">Role</td>
276 <td class="head col_vendor">Virtual</td>
277 <td class="head col_release">Linux</td>
278 <td class="head col_kernel">Kernel</td>
279
280 <td class="head col_vcpu">
281 <div class="meters vcpu">
282 <div class="meter cpu">vCPU</div>
283 </div>
284 </td>
Alex1839bbf2019-08-22 17:17:21 -0500285 <td class="head col_net">
Alexe9908f72020-05-19 16:04:53 -0500286 <div class="net_group">
287 <div class="item net">vCpu</div>
288 <div class="item net">Total</div>
289 <div class="item net">Drop</div>
290 <div class="item net">Sq.</div>
291 <div class="item net">Cl.</div>
Alex1839bbf2019-08-22 17:17:21 -0500292 </div>
293 </td>
Alex836fac82019-08-22 13:36:16 -0500294 <td class="head col_ram">
Alexe9908f72020-05-19 16:04:53 -0500295 <div class="ram_group">
296 <div class="item ram">Total</div>
297 <div class="item ram">Used</div>
298 <div class="item ram">Free</div>
299 <div class="item ram">Avail.</div>
Alex836fac82019-08-22 13:36:16 -0500300 </div>
301 </td>
302 <td class="head col_disk">
Alexe9908f72020-05-19 16:04:53 -0500303 <div class="disk_group">
304 <div class="item disk path">Device path</div>
305 <div class="item disk">Total</div>
306 <div class="item disk">Used</div>
307 <div class="item disk">Free</div>
308 <div class="item disk">%</div>
Alex836fac82019-08-22 13:36:16 -0500309 </div>
310 </td>
311 </tr>
Alex41485522019-04-12 17:26:18 -0500312 {% for node in nodes.keys() | sort %}
313 {% set _ndat = nodes[node] %}
Alexe9908f72020-05-19 16:04:53 -0500314 {% set _status = _ndat['status'] | node_status_class %}
315 {% if _status == 'down' %}
316 <tr class="node down">
317 <td class="status_{{ _status }}">.</td>
318 <td class="head col_name">{{ _ndat['shortname'] }}</td>
319 <td class="head col_role">{{ _ndat['role'] }}</td>
320 <td class="head col_down" colspan="7"> ...no data collected: node is down</td>
321 </tr>
322 {% elif _status == 'skip' %}
323 <tr class="node skip">
324 <td class="status_{{ _status }}">.</td>
325 <td class="head col_name">{{ _ndat['shortname'] }}</td>
326 <td class="head col_role">{{ _ndat['role'] }}</td>
327 <td class="head col_skip" colspan="7"> ...no skipped from processing</td>
328 </tr>
329 {% else %}
Alex836fac82019-08-22 13:36:16 -0500330 <tr class="node" onclick="toggleClassByID('info_{{ node }}')" id='info_{{ node }}_button'>
331 <td class="status_{{ _ndat['status'] | node_status_class }}">.</td>
Alexe9908f72020-05-19 16:04:53 -0500332 <td class="head col_name">{{ _ndat['shortname'] }}</td>
Alex836fac82019-08-22 13:36:16 -0500333 <td class="head col_role">{{ _ndat['role'] }}</td>
Alex1839bbf2019-08-22 17:17:21 -0500334 <td class="head col_vendor">{{ _ndat['node_type'] }}</td>
Alex836fac82019-08-22 13:36:16 -0500335 <td class="head col_release">{{ _ndat['linux_arch'] }}/{{ _ndat['linux_codename'] }}</td>
336 <td class="head col_kernel">{{ _ndat['kernel'] }}</td>
337 <td class="head col_vcpu">
338 <div class="meters vcpu">
Alex1839bbf2019-08-22 17:17:21 -0500339 <div class="meter cpu">{{ _ndat['lscpu']['cpus'] }}</div>
340 </div>
341 </td>
342 <td class="head col_net">
343 <div class="net_group">
Alexe9908f72020-05-19 16:04:53 -0500344 <div class="item net">All</div>
Alex1839bbf2019-08-22 17:17:21 -0500345 <div class="item net">{{ _ndat['net_stats']['total'][0] }}</div>
346 <div class="item net">{{ _ndat['net_stats']['total'][1] }}</div>
347 <div class="item net">{{ _ndat['net_stats']['total'][2] }}</div>
348 <div class="item net">{{ _ndat['net_stats']['total'][3] }}</div>
Alex836fac82019-08-22 13:36:16 -0500349 </div>
350 </td>
351 <td class="head col_ram">
352 <div class="ram_group">
Alex1839bbf2019-08-22 17:17:21 -0500353 <div class="item ram">{{ _ndat['ram']['total'] }}</div>
354 <div class="item ram">{{ _ndat['ram']['used'] }}</div>
355 <div class="item ram">{{ _ndat['ram']['free'] }}</div>
356 <div class="item ram {{ _ndat['ram']['status'] }}">{{ _ndat['ram']['available'] }}</div>
Alex836fac82019-08-22 13:36:16 -0500357 </div>
358 </td>
359 <td class="head col_disk">
360 <div class="disk_group">
Alexe9908f72020-05-19 16:04:53 -0500361 <div class="item disk path">{{ _ndat['disk_max_dev'] }}</div>
Alex836fac82019-08-22 13:36:16 -0500362 {% for val in _ndat['disk'][_ndat['disk_max_dev']]['v'] %}
363 <div class="item disk {{ _ndat['disk'][_ndat['disk_max_dev']]['f'] }}">{{ val }}</div>
364 {% endfor %}
365 </div>
366 </td>
367 </tr>
368 <tr class="collapsable" id="info_{{ node }}">
369 <td class="status_none"></td>
Alex1839bbf2019-08-22 17:17:21 -0500370 <td class="col_node_notes" colspan="2">
371 {% if 'virsh' in _ndat %}
372 <div class="kvm_group">
373 {% for kvm_node in _ndat['virsh'].keys() | sort %}
374 <div class="item kvm_id">{{ _ndat['virsh'][kvm_node]['id'] }}</div>
375 <div class="item kvm_node">{{ kvm_node }}</div>
376 <div class="item kvm_status">{{ _ndat['virsh'][kvm_node]['status'] }}</div>
377 {% endfor %}
378 </div>
379 {% endif %}
380 </td>
381 <td class="col_cpu_notes smallgreytext" colspan="2">
382 CPU Model: {{ _ndat['lscpu']['model_name'] }} at {{ _ndat['lscpu']['cpu_mhz'] }}Mhz<br>
383 Virtualization: {{ _ndat['lscpu']['virtualization'] }}
384 </td>
Alex836fac82019-08-22 13:36:16 -0500385 <td class="col_kernel"></td>
386 <td class="col_vcpu"></td>
Alex1839bbf2019-08-22 17:17:21 -0500387 <td class="col_net">
388 <div class="net_group">
389 {% for cpu in _ndat['net_stats'].keys() | sort %}
390 <div class="item net">{{ cpu }}</div>
391 {% for val in _ndat['net_stats'][cpu] %}
392 <div class="item net">{{ val }}</div>
393 {% endfor %}
394 {% endfor %}
395 </div>
396 </td>
Alex836fac82019-08-22 13:36:16 -0500397 <td class="col_ram"></td>
398 <td class="col_disk">
399 <div class="disk_group">
400 {% for dev in _ndat['disk'].keys() | sort %}
Alexe9908f72020-05-19 16:04:53 -0500401 <div class="item disk path">{{ dev }}</div>
Alex836fac82019-08-22 13:36:16 -0500402 {% for val in _ndat['disk'][dev]['v'] %}
403 <div class="item disk {{ _ndat['disk'][dev]['f'] }}">{{ val }}</div>
404 {% endfor %}
405 {% endfor %}
406 </div>
407 </td>
Alex41485522019-04-12 17:26:18 -0500408 </tr>
Alexe9908f72020-05-19 16:04:53 -0500409 {% endif %}
Alex41485522019-04-12 17:26:18 -0500410 {% endfor %}
411 </table>
412 <hr>
413</div>
414{% endmacro %}
415
416{% macro networks_page(networks, id_label) %}
417<div id="{{ id_label }}" class="barcontent">
418 <h5>{{ caller() }}</h5>
419 <hr>
420 <table class="networks">
Alex836fac82019-08-22 13:36:16 -0500421 {% for net in map.keys() %}
422 <tr class="subnet" onclick="toggleClassByID('net_{{ net }}')" id="{{ net }}_net_button">
423 <td>{{ net }}</td>
Alex41485522019-04-12 17:26:18 -0500424 </tr>
Alex836fac82019-08-22 13:36:16 -0500425 <tr class="collapsable" id="net_{{ net }}"><td>
426 <div class="map_grid">
427 {% for node in map[net].keys() | sort %}
428 {% for d in map[net][node] %}
429 <div class="map_item name">{{ node }}</div>
430 <div class="map_item interface {{ d['interface_error'] }}">{{ d['interface'] }}</div>
Alex1839bbf2019-08-22 17:17:21 -0500431 <div class="map_item note"><pre>{{ d['interface_map'] | linebreaks }}</pre></div>
Alex836fac82019-08-22 13:36:16 -0500432 <div class="map_item ipaddr">{{ d['ip_address'] }}</div>
433 <div class="map_item ipaddr_type">{{ d['address_type'] }}</div>
434 <div class="map_item mtu {{ d['mtu_error'] }}">{{ d['rt_mtu'] }}</div>
435 <div class="map_item status {{ d['status_error'] }}">{{ d['status'] }}</div>
436 <div class="map_item gate {{ d['subnet_gateway_error'] }}">{{ d['subnet_gateway'] }}</div>
437 <div class="map_item gate">{{ d['default_gateway'] }}</div>
438 <div class="map_item error_note">{{ d['error_note'] }}</div>
439 {% endfor %}
440 {% endfor %}
441 </div>
442 </td></tr>
443 {% endfor %}
Alex41485522019-04-12 17:26:18 -0500444 </table>
445 <hr>
446</div>
447{% endmacro %}
448
449{% macro services_page(services, id_label) %}
450<div id="{{ id_label }}" class="barcontent">
451 <h5>{{ caller() }}</h5>
452 <hr>
Alex836fac82019-08-22 13:36:16 -0500453 <div class="services">
454 {% for node in nodes.keys() | sort %}
Alex1839bbf2019-08-22 17:17:21 -0500455 <div class="service_node" onclick="toggleClassByID('svc_{{ node }}')" id="svc_{{ node }}_button">
456 <div class="node_name">{{ node }}</div>
457 {% for service in nodes[node]['services'].keys() | sort -%}
458 {% if service in const['services'] %}
459 {% if not nodes[node]['services'][service] %}
460 <div class="service_name fail">{{ service }}</div>
461 {% endif %}
462 {% endif%}
463 {% endfor%}
464 </div>
Alex836fac82019-08-22 13:36:16 -0500465 <div class="collapsable" id="svc_{{ node }}">
466 <div class="service_grid">
467 {% for service in nodes[node]['services'].keys() | sort -%}
Alex1839bbf2019-08-22 17:17:21 -0500468 {% if service in const['services'] %}
Alex836fac82019-08-22 13:36:16 -0500469 {% if nodes[node]['services'][service] %}
Alex1839bbf2019-08-22 17:17:21 -0500470 <div class="service on">{{ service }}</div>
Alex836fac82019-08-22 13:36:16 -0500471 {% else %}
Alex1839bbf2019-08-22 17:17:21 -0500472 <div class="service fail">{{ service }}</div>
473 {% endif %}
474 {% endif%}
475 {% endfor %}
476 <div class="service"># Other services</div>
477 {% for service in nodes[node]['services'].keys() | sort -%}
478 {% if service not in const['services'] %}
479 {% if nodes[node]['services'][service] %}
480 <div class="service on">{{ service }}</div>
481 {% else %}
482 <div class="service off">{{ service }}</div>
483 {% endif %}
Alex836fac82019-08-22 13:36:16 -0500484 {% endif %}
485 {% endfor %}
486 </div>
487 </div>
488 {% endfor %}
489 </div>
490 <hr>
Alex41485522019-04-12 17:26:18 -0500491</div>
492{% endmacro %}
493
494<!-- Cluster nodes page -->
495{% call nodes_page(nodes, "nodes") %}
Ievgeniia Zadorozhna33d5c9a2025-09-04 17:36:55 +0200496 Cluster nodes status and simple metrics
Alex41485522019-04-12 17:26:18 -0500497{% endcall %}
498
499<!-- Cluster nodes page -->
500{% call networks_page(networks, "networks") %}
501 Networks in the cluster
502{% endcall %}
503
504<!-- Cluster nodes page -->
505{% call services_page(services, "services") %}
506 Services status in the cluster
507{% endcall %}
508
Alex Savatieiev9b2f6512019-02-20 18:05:00 -0600509</body>
510</html>