blob: ff8f613e2c1666d9aec1ada6ff8073750480940d [file] [log] [blame]
Alexb78191f2021-11-02 16:35:46 -05001<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>cfg-checker agent</title>
6 {% include 'common_styles.j2' %}
7 {% include 'common_scripts.j2' %}
8 <script language="JavaScript">
9 const getJSON = async url => {
10 const response = await fetch(url);
11 if(!response.ok) // check if response worked (no 404 errors etc...)
12 throw new Error(response.statusText);
13
14 const data = response.json(); // get JSON from the response
15 return data; // returns a promise, which resolves to this data value
16 }
17
18 function qStatus(uri, tagId) {
19 var dt, el;
20
21 el = document.getElementById(tagId);
22 el.innerHTML = "calling " + uri;
23
24 getJSON(uri).then(data => {
25 el.innerHTML = "<pre>" + JSON.stringify(data, null, ' ') + "</pre>";
26 }).catch(error => {
27 el.innerHTML = JSON.stringify(error, null, ' ');
28 });
29 };
30
31 function updateModules() {
32 var _n, _v, _hc, _s, _phead, _p;
33
34 let mods = [];
35 // Jinja populated list
36 {% for mod in modules %}
37 mods.push("{{ mod }}");
38 {% endfor %}
39
40 mods.forEach((mod) => {
41 // get all ids needed to fill
42 _n = document.getElementById(mod + "_name");
43 _v = document.getElementById(mod + "_version");
44 _hc = document.getElementById(mod + "_healthcheck");
45 _s = document.getElementById(mod + "_status");
46 _phead = document.getElementById(mod + "_progress_head");
47 _p = document.getElementById(mod + "_progress");
48
49 // Fill
50 _n.innerHTML = mod;
51 // get status
52 getJSON("api/" + mod).then(data => {
53 _v.innerHTML = data['healthcheck']['version'];
54 _hc.innerHTML = data['healthcheck']['ready'];
55 _s.innerHTML = data['status'];
56 if ((data['status'] == "idle") || (data['status'] == "finished")) {
57 if (_phead.className.indexOf("idle") < 0) {
58 _phead.className += " idle";
59 }
60 }
61 else if (data['status'] == "running") {
62 _phead.className = _phead.className.replace(" idle", "");
63 }
64 _p.style.width = data['progress'] + "%";
65 }).catch(error => {
66 _v.innerHTML = "?";
67 _hc.innerHTML = "No response";
68 _s.innerHTML = "Unknown";
69 _phead.className = _phead.className.replace(" idle", "");
70 // set bar status to red later
71 //_p.style.width = "100%";
72 });
73 })
74 };
75 var interval = 500;
76 setInterval(updateModules, interval);
77 </script>
78 <style>
79 .barcontent {
80 margin: auto;
81 width: 1350px;
82 padding: 10px;
83 }
84 .bar-centered {
85 float: none;
86 transform: translate(25%);
87 }
88 .agent_labels {
89 display: inline-block;
90 margin: 0px;
91 margin-right: 5px;
92
93 }
94 .info_label {
95 font-family: "LaoSangamMN", Monaco, monospace;
96 display: block;
97 float: left;
98 box-sizing: content-box;
99 background: #262;
100 color: white;
101 border-radius: 5px;
102 text-align: center;
103 padding: 0px 5px 5px 5px;
104 height: 14px;
105 margin: 5px 2px 5px 2px;
106 }
107 .gray_bg { background: #444; }
108 .section_head { font-size: 0.8em; color: Navy; padding-left: 2px; }
109 .row_button {
110 background-color: #468;
111 color: #fff;
112 cursor: pointer;
113 padding: 5px;
114 width: 100%;
115 border: none;
116 text-align: left;
117 outline: none;
118 font-size: 13px;
119 }
120 .row_button:after {
121 content: '\02795'; /* Unicode character for "plus" sign (+) */
122 font-size: 13px;
123 color: white;
124 float: left;
125 margin-left: 5px;
126 }
127
128 .row_active:after {
129 content: "\2796"; /* Unicode character for "minus" sign (-) */
130 color: white
131 }
132
133 .row_active, .row_button:hover {
134 background-color: #68a;
135 color: white
136 }
137
138 .cell_button {
139 color: darkgreen;
140 cursor: pointer;
141 padding: 5px;
142 width: 100%;
143 border: none;
144 text-align: center;
145 outline: none;
146 }
147 .cell_button:hover {
148 background-color: gray;
149 }
150
151 .tooltiptext {
152 transform: translate(100px);
153 }
154
155 .console {
156 background-color: black;
157 font-family: "Lucida Console", Monaco, monospace;
158 font-size: 0.5em;
159 width: auto;
160 color: #fff;
161 border-radius: 6px;
162 padding: 5px 5px;
163 }
164
165 .progress {
166 box-sizing: content-box;
167 height: 10px; /* Can be anything */
168 position: relative;
169 background: #aaa;
170 border-radius: 5px;
171 padding: 5px;
172 box-shadow: inset 0 -1px 1px rgba(255, 255, 255, 0.3);
173 }
174 .progress > span {
175 display: block;
176 height: 100%;
177 border-top-right-radius: 3px;
178 border-bottom-right-radius: 3px;
179 border-top-left-radius: 5px;
180 border-bottom-left-radius: 5px;
181 background-color: rgb(43, 194, 83);
182 background-image: linear-gradient(
183 center bottom,
184 rgb(43, 194, 83) 37%,
185 rgb(84, 240, 84) 69%
186 );
187 position: relative;
188 overflow: hidden;
189 }
190 .progress > span:after,
191 .animate > span > span {
192 content: "";
193 position: absolute;
194 top: 0;
195 left: 0;
196 bottom: 0;
197 right: 0;
198 background-image: linear-gradient(
199 -45deg,
200 rgba(255, 255, 255, 0.1) 25%,
201 transparent 25%,
202 transparent 50%,
203 rgba(255, 255, 255, 0.1) 50%,
204 rgba(255, 255, 255, 0.1) 75%,
205 transparent 75%,
206 transparent
207 );
208 z-index: 1;
209 background-size: 50px 50px;
210 animation: move 2s linear infinite;
211 border-top-right-radius: 8px;
212 border-bottom-right-radius: 8px;
213 border-top-left-radius: 20px;
214 border-bottom-left-radius: 20px;
215 overflow: hidden;
216 }
217
218 .animate > span:after {
219 display: none;
220 }
221
222 @keyframes move {
223 0% {
224 background-position: 0 0;
225 }
226 100% {
227 background-position: 50px 50px;
228 }
229 }
230
231 .bluewish > span {
232 background-image: linear-gradient(#3d52b1, #3052b1);
233 }
234 .idle > span > span,
235 .idle > span::after {
236 background-image: none;
237 }
238 </style>
239</head>
240<body onload="init()">
241
242<div class="header">
243 <div class="label date">generated on: {{ gen_date }}</div>
244</div>
245
246<div class="bar">
247 <div class="bar-centered">
248 <button class="bar-item" onclick="openBar(event, 'status')">Status</button>
249 </div>
250</div>
251
252{% macro status_page(info, id_label) %}
253<div id="{{ id_label }}" class="barcontent">
254 <h5>{{ caller() }}</h5>
255 <hr>
256 <div class="agent_labels">
257 <div class="info_label" onclick="updateModules()">{{ hostname }}</div>
258 <div class="info_label">{{ system }}</div>
259 <div class="info_label">{{ release }}</div>
260 <div class="info_label gray_bg">Started: {{ agent['started'] }}</div>
261 </div>
262 <hr>
263 {% for mod in modules %}
264 <div class="agent_labels">
265 <div class="info_label" id="{{ mod }}_name">{{ mod }}</div>
266 <div class="info_label" id="{{ mod }}_version">unknown</div>
267 <div class="info_label" id="{{ mod }}_healthcheck">unknown</div>
268 <div class="info_label" id="{{ mod }}_status">unknown</div>
269 </div>
270 <div class="progress bluewish idle" id="{{ mod }}_progress_head">
271 <span style="width: 0%" id="{{ mod }}_progress"></span>
272 </div>
273 <hr>
274 {% endfor %}
275 <div class="section_head">REST Api help:</div>
276 {% for uri, ops in help.items() %}
277 <div class="console">
278 <div class="">{{ uri | escape }}</div>
279 {% for op, op_help in ops.items() %}
280 <div class="">{{ op }}: {{ op_help | escape }}</div>
281 {% endfor %}
282 </div>
283 <br>
284 {% endfor %}
285 <div class="section_head">Available modules: {{ modules | join(", ")}}</div>
286 <div class="section_head">Agent:</div>
287 <div class="console" onclick="qStatus('api/','agent')">
288 <div class="" id="agent"></div>
289 </div>
290
291 <div class="section_head">Status json:</div>
292 <div class="console" onclick="qStatus('api/{{ modules[0] }}','fio')">
293 <div class="" id="fio"></div>
294 </div>
295
296
297</div>
298{% endmacro %}
299
300
301{% call status_page(info, "status") %}
302 Agent status
303{% endcall %}
304</body>
305</html>