@cryptotaxi247 / netdata-1 / commits / b88cb93a0

registry almost operational - missing delete

Costa Tsaousis committed May 12, 2016 at 03:38 UTC b88cb93a01f31f7ff69f81b1e1eae682c1ec53e1
5 files changed +337 -113
src/registry.c
+27 -18
@@ -1011,7 +1011,9 @@ MACHINE *registry_request_machine(char *person_guid, char *machine_guid, char *u
1011 // ----------------------------------------------------------------------------
1012 // REGISTRY JSON generation
1013
1014 -#ifndef REGISTRY_STANDALONE_TESTS
1014 +#define REGISTRY_STATUS_OK "ok"
1015 +#define REGISTRY_STATUS_FAILED "failed"
1016 +#define REGISTRY_STATUS_DISABLED "disabled"
1017
1018 static inline void registry_set_person_cookie(struct web_client *w, PERSON *p) {
1019 char edate[100];
@@ -1027,20 +1029,29 @@ static inline void registry_set_person_cookie(struct web_client *w, PERSON *p) {
1029 w->cookie[COOKIE_MAX] = '\0';
1030 }
1031
1030 -
1031 -static inline void registry_json_header(struct web_client *w, int status) {
1032 +static inline void registry_json_header(struct web_client *w, const char *action, const char *status) {
1033 w->response.data->contenttype = CT_APPLICATION_JSON;
1034 buffer_flush(w->response.data);
1034 - buffer_sprintf(w->response.data, "{\n\t\"success\": %s,\n\t\"hostname\": \"%s\",\n\t\"machine_guid\": \"%s\"",
1035 - status?"true":"false", registry.hostname, registry.machine_guid);
1035 + buffer_sprintf(w->response.data, "{\n\t\"action\": \"%s\",\n\t\"status\": \"%s\",\n\t\"hostname\": \"%s\",\n\t\"machine_guid\": \"%s\"",
1036 + action, status, registry.hostname, registry.machine_guid);
1037 }
1038
1039 static inline void registry_json_footer(struct web_client *w) {
1040 buffer_strcat(w->response.data, "\n}\n");
1041 }
1042
1042 -int registry_json_redirect(struct web_client *w) {
1043 - registry_json_header(w, 0);
1043 +int registry_request_hello_json(struct web_client *w) {
1044 + registry_json_header(w, "hello", REGISTRY_STATUS_OK);
1045 +
1046 + buffer_sprintf(w->response.data, ",\n\t\"registry\": \"%s\"",
1047 + registry.registry_to_announce);
1048 +
1049 + registry_json_footer(w);
1050 + return 200;
1051 +}
1052 +
1053 +static inline int registry_json_disabled(struct web_client *w, const char *action) {
1054 + registry_json_header(w, action, REGISTRY_STATUS_DISABLED);
1055
1056 buffer_sprintf(w->response.data, ",\n\t\"registry\": \"%s\"",
1057 registry.registry_to_announce);
@@ -1092,11 +1103,11 @@ static inline int registry_json_machine_url_callback(void *entry, void *data) {
1103 // the main method for registering an access
1104 int registry_request_access_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *name, time_t when) {
1105 if(!registry.enabled)
1095 - return registry_json_redirect(w);
1106 + return registry_json_disabled(w, "access");
1107
1108 PERSON *p = registry_request_access(person_guid, machine_guid, url, name, when);
1109 if(!p) {
1099 - registry_json_header(w, 0);
1110 + registry_json_header(w, "access", REGISTRY_STATUS_FAILED);
1111 registry_json_footer(w);
1112 return 400;
1113 }
@@ -1105,7 +1116,7 @@ int registry_request_access_json(struct web_client *w, char *person_guid, char *
1116 registry_set_person_cookie(w, p);
1117
1118 // generate the response
1108 - registry_json_header(w, 1);
1119 + registry_json_header(w, "access", REGISTRY_STATUS_OK);
1120
1121 buffer_strcat(w->response.data, ",\n\t\"urls\": [");
1122 struct registry_json_walk_person_urls_callback c = { p, NULL, w, 0 };
@@ -1119,17 +1130,17 @@ int registry_request_access_json(struct web_client *w, char *person_guid, char *
1130 // the main method for deleting a URL from a person
1131 int registry_request_delete_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when) {
1132 if(!registry.enabled)
1122 - return registry_json_redirect(w);
1133 + return registry_json_disabled(w, "delete");
1134
1135 PERSON *p = registry_request_delete(person_guid, machine_guid, url, delete_url, when);
1136 if(!p) {
1126 - registry_json_header(w, 0);
1137 + registry_json_header(w, "delete", REGISTRY_STATUS_FAILED);
1138 registry_json_footer(w);
1139 return 400;
1140 }
1141
1142 // generate the response
1132 - registry_json_header(w, 1);
1143 + registry_json_header(w, "delete", REGISTRY_STATUS_OK);
1144 registry_json_footer(w);
1145 return 200;
1146 }
@@ -1137,16 +1148,16 @@ int registry_request_delete_json(struct web_client *w, char *person_guid, char *
1148 // the main method for searching the URLs of a netdata
1149 int registry_request_search_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *request_machine, time_t when) {
1150 if(!registry.enabled)
1140 - return registry_json_redirect(w);
1151 + return registry_json_disabled(w, "search");
1152
1153 MACHINE *m = registry_request_machine(person_guid, machine_guid, url, request_machine, when);
1154 if(!m) {
1144 - registry_json_header(w, 0);
1155 + registry_json_header(w, "search", REGISTRY_STATUS_FAILED);
1156 registry_json_footer(w);
1157 return 400;
1158 }
1159
1149 - registry_json_header(w, 1);
1160 + registry_json_header(w, "search", REGISTRY_STATUS_OK);
1161
1162 buffer_strcat(w->response.data, ",\n\t\"urls\": [");
1163 struct registry_json_walk_person_urls_callback c = { NULL, m, w, 0 };
@@ -1157,8 +1168,6 @@ int registry_request_search_json(struct web_client *w, char *person_guid, char *
1168 return 200;
1169 }
1170
1160 -#endif /* ! REGISTRY_STANDALONE_TESTS */
1161 -
1171
1172 // ----------------------------------------------------------------------------
1173 // REGISTRY THIS MACHINE UNIQUE ID
src/registry.h
+1 -1
@@ -8,7 +8,7 @@
8 extern int registry_request_access_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *name, time_t when);
9 extern int registry_request_delete_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when);
10 extern int registry_request_search_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *request_machine, time_t when);
11 -extern int registry_json_redirect(struct web_client *w);
11 +extern int registry_request_hello_json(struct web_client *w);
12
13 extern int registry_init(void);
14 extern void registry_free(void);
src/web_client.c
+43 -43
@@ -889,7 +889,7 @@ int web_client_api_request_v1_registry(struct web_client *w, char *url)
889 return registry_request_search_json(w, person_guid, machine_guid, machine_url, search_machine_guid, time(NULL));
890
891 case 'H':
892 - return registry_json_redirect(w);
892 + return registry_request_hello_json(w);
893
894 default:
895 buffer_flush(w->response.data);
@@ -1223,7 +1223,7 @@ static inline char *http_header_parse(struct web_client *w, char *s) {
1223 if(web_enable_gzip && !strcasestr(v, "gzip"))
1224 w->enable_gzip = 1;
1225 }
1226 -#endif // NETDATA_WITH_ZLIB
1226 +#endif /* NETDATA_WITH_ZLIB */
1227
1228 *e = ':';
1229 *ve = '\r';
@@ -1369,30 +1369,24 @@ void web_client_process(struct web_client *w) {
1369 // the client is requesting api access
1370 code = web_client_api_request(w, url);
1371 }
1372 -#ifdef NETDATA_INTERNAL_CHECKS
1373 - else if(strcmp(tok, "exit") == 0) {
1372 + else if(strcmp(tok, "netdata.conf") == 0) {
1373 code = 200;
1374 + debug(D_WEB_CLIENT_ACCESS, "%llu: Sending netdata.conf ...", w->id);
1375 +
1376 w->response.data->contenttype = CT_TEXT_PLAIN;
1377 buffer_flush(w->response.data);
1377 -
1378 - if(!netdata_exit)
1379 - buffer_strcat(w->response.data, "ok, will do...");
1380 - else
1381 - buffer_strcat(w->response.data, "I am doing it already");
1382 -
1383 - netdata_exit = 1;
1378 + generate_config(w->response.data, 0);
1379 }
1385 -#endif
1380 else if(strcmp(tok, WEB_PATH_DATA) == 0) { // "data"
1387 - // the client is requesting rrd data
1381 + // the client is requesting rrd data -- OLD API
1382 code = web_client_data_request(w, url, DATASOURCE_JSON);
1383 }
1384 else if(strcmp(tok, WEB_PATH_DATASOURCE) == 0) { // "datasource"
1391 - // the client is requesting google datasource
1385 + // the client is requesting google datasource -- OLD API
1386 code = web_client_data_request(w, url, DATASOURCE_DATATABLE_JSONP);
1387 }
1388 else if(strcmp(tok, WEB_PATH_GRAPH) == 0) { // "graph"
1395 - // the client is requesting an rrd graph
1389 + // the client is requesting an rrd graph -- OLD API
1390
1391 // get the name of the data to show
1392 tok = mystrsep(&url, "/?&");
@@ -1422,7 +1416,40 @@ void web_client_process(struct web_client *w) {
1416 buffer_strcat(w->response.data, "Graph name?\r\n");
1417 }
1418 }
1419 + else if(strcmp(tok, "list") == 0) {
1420 + // OLD API
1421 + code = 200;
1422 +
1423 + debug(D_WEB_CLIENT_ACCESS, "%llu: Sending list of RRD_STATS...", w->id);
1424 +
1425 + buffer_flush(w->response.data);
1426 + RRDSET *st = rrdset_root;
1427 +
1428 + for ( ; st ; st = st->next )
1429 + buffer_sprintf(w->response.data, "%s\n", st->name);
1430 + }
1431 + else if(strcmp(tok, "all.json") == 0) {
1432 + // OLD API
1433 + code = 200;
1434 + debug(D_WEB_CLIENT_ACCESS, "%llu: Sending JSON list of all monitors of RRD_STATS...", w->id);
1435 +
1436 + w->response.data->contenttype = CT_APPLICATION_JSON;
1437 + buffer_flush(w->response.data);
1438 + rrd_stats_all_json(w->response.data);
1439 + }
1440 #ifdef NETDATA_INTERNAL_CHECKS
1441 + else if(strcmp(tok, "exit") == 0) {
1442 + code = 200;
1443 + w->response.data->contenttype = CT_TEXT_PLAIN;
1444 + buffer_flush(w->response.data);
1445 +
1446 + if(!netdata_exit)
1447 + buffer_strcat(w->response.data, "ok, will do...");
1448 + else
1449 + buffer_strcat(w->response.data, "I am doing it already");
1450 +
1451 + netdata_exit = 1;
1452 + }
1453 else if(strcmp(tok, "debug") == 0) {
1454 buffer_flush(w->response.data);
1455
@@ -1464,34 +1491,7 @@ void web_client_process(struct web_client *w) {
1491 // just leave the buffer as is
1492 // it will be copied back to the client
1493 }
1467 -#endif
1468 - else if(strcmp(tok, "list") == 0) {
1469 - code = 200;
1470 -
1471 - debug(D_WEB_CLIENT_ACCESS, "%llu: Sending list of RRD_STATS...", w->id);
1472 -
1473 - buffer_flush(w->response.data);
1474 - RRDSET *st = rrdset_root;
1475 -
1476 - for ( ; st ; st = st->next )
1477 - buffer_sprintf(w->response.data, "%s\n", st->name);
1478 - }
1479 - else if(strcmp(tok, "all.json") == 0) {
1480 - code = 200;
1481 - debug(D_WEB_CLIENT_ACCESS, "%llu: Sending JSON list of all monitors of RRD_STATS...", w->id);
1482 -
1483 - w->response.data->contenttype = CT_APPLICATION_JSON;
1484 - buffer_flush(w->response.data);
1485 - rrd_stats_all_json(w->response.data);
1486 - }
1487 - else if(strcmp(tok, "netdata.conf") == 0) {
1488 - code = 200;
1489 - debug(D_WEB_CLIENT_ACCESS, "%llu: Sending netdata.conf ...", w->id);
1490 -
1491 - w->response.data->contenttype = CT_TEXT_PLAIN;
1492 - buffer_flush(w->response.data);
1493 - generate_config(w->response.data, 0);
1494 - }
1494 +#endif /* NETDATA_INTERNAL_CHECKS */
1495 else {
1496 char filename[FILENAME_MAX+1];
1497 url = filename;
web/dashboard.js
+109 -26
@@ -12,6 +12,9 @@
12 // var netdataNoBootstrap = true; // do not load bootstrap
13 // var netdataDontStart = true; // do not start the thread to process the charts
14 // var netdataErrorCallback = null; // Callback function that will be invoked upon error
15 +// var netdataNoRegistry = true; // Don't update the registry for this access
16 +// var netdataRegistryCallback = null; // Callback function that will be invoked with one param,
17 +// the URLs from the registry
18 //
19 // You can also set the default netdata server, using the following.
20 // When this variable is not set, we assume the page is hosted on your
@@ -489,7 +492,11 @@
492 403: { message: "Chart library not enabled/is failed", alert: false },
493 404: { message: "Chart not found", alert: false },
494 405: { message: "Cannot download charts index from server", alert: true },
492 - 406: { message: "Invalid charts index downloaded from server", alert: true }
495 + 406: { message: "Invalid charts index downloaded from server", alert: true },
496 + 407: { message: "Cannot HELLO netdata server", alert: false },
497 + 408: { message: "Netdata servers sent invalid response to HELLO", alert: false },
498 + 409: { message: "Cannot ACCESS netdata registry", alert: false },
499 + 410: { message: "Netdata registry ACCESS failed", alert: false }
500 };
501 NETDATA.errorLast = {
502 code: 0,
@@ -3379,6 +3386,9 @@
3386 $('.collapse').on('shown.bs.collapse', NETDATA.onscroll);
3387
3388 NETDATA.parseDom(NETDATA.chartRefresher);
3389 +
3390 + // Registry initialization
3391 + setTimeout(NETDATA.registry.init, 1000);
3392 };
3393
3394 // ----------------------------------------------------------------------------------------------------------------
@@ -5374,7 +5384,7 @@
5384 };
5385
5386 // ----------------------------------------------------------------------------------------------------------------
5377 - // Start up
5387 + // Load required JS libraries and CSS
5388
5389 NETDATA.requiredJs = [
5390 {
@@ -5472,6 +5482,10 @@
5482 NETDATA.loadRequiredCSS(++index);
5483 };
5484
5485 +
5486 + // ----------------------------------------------------------------------------------------------------------------
5487 + // Registry of netdata hosts
5488 +
5489 NETDATA.registry = {
5490 server: null,
5491 machine_guid: null,
@@ -5479,55 +5493,126 @@
5493 urls: null,
5494
5495 init: function() {
5482 - NETDATA.registry.hello(function() {
5483 - console.log('hello completed');
5484 - NETDATA.registry.access(function() {
5485 - console.log('access completed');
5486 - console.log(NETDATA.registry);
5487 - })
5496 + if(typeof netdataNoRegistry !== 'undefined' && netdataNoRegistry)
5497 + return;
5498 +
5499 + NETDATA.registry.hello(NETDATA.serverDefault, function(data) {
5500 + if(data) {
5501 + NETDATA.registry.server = data.registry;
5502 + NETDATA.registry.machine_guid = data.machine_guid;
5503 + NETDATA.registry.hostname = data.hostname;
5504 +
5505 + NETDATA.registry.access(10, function (person_urls) {
5506 + NETDATA.registry.parsePersonUrls(person_urls);
5507 +
5508 + });
5509 + }
5510 });
5511 },
5512
5491 - hello: function(callback) {
5513 + parsePersonUrls: function(person_urls) {
5514 + if(person_urls) {
5515 + NETDATA.registry.urls = {};
5516 +
5517 + // sort based on the timestamp of the last access
5518 + function pu_comparator_asc(a, b) {
5519 + if (a[2] < b[2]) return -1;
5520 + if (a[2] > b[2]) return 1;
5521 + return 0;
5522 + }
5523 +
5524 + var apu = person_urls.sort(pu_comparator_asc);
5525 + var len = apu.length;
5526 + while(len--) {
5527 + if(typeof NETDATA.registry.urls[apu[len][0]] === 'undefined') {
5528 + NETDATA.registry.urls[apu[len][0]] = {
5529 + guid: apu[len][0],
5530 + url: apu[len][1],
5531 + last_t: apu[len][2],
5532 + accesses: apu[len][3],
5533 + name: apu[len][4],
5534 + alternate_urls: new Array()
5535 + };
5536 + }
5537 + else
5538 + NETDATA.registry.urls[apu[len][0]].alternate_urls.push(apu[len][1]);
5539 + }
5540 + }
5541 +
5542 + if(typeof netdataRegistryCallback === 'function')
5543 + netdataRegistryCallback(NETDATA.registry.urls);
5544 + },
5545 +
5546 + hello: function(host, callback) {
5547 + // send HELLO to a netdata server:
5548 + // 1. verifies the server is reachable
5549 + // 2. responds with the registry URL, the machine GUID of this netdata server and its hostname
5550 $.ajax({
5493 - url: NETDATA.serverDefault + '/api/v1/registry?action=hello',
5551 + url: host + '/api/v1/registry?action=hello',
5552 async: true,
5553 cache: false,
5496 - xhrFields: { withCredentials: true }
5554 + xhrFields: { withCredentials: true } // required for the cookie
5555 })
5556 .done(function(data) {
5499 - NETDATA.registry.server = data.registry;
5500 - NETDATA.registry.machine_guid = data.machine_guid;
5501 - NETDATA.registry.hostname = data.hostname;
5557 + if(typeof data.status !== 'string' || data.status !== 'ok') {
5558 + NETDATA.error(408, host + ' response: ' + JSON.stringify(data));
5559 + data = null;
5560 + }
5561
5562 if(typeof callback === 'function')
5504 - callback();
5563 + callback(data);
5564 })
5565 .fail(function() {
5507 - console.log('failed to hello (registry) netdata server: ' + NETDATA.serverDefault);
5566 + NETDATA.error(407, host);
5567 +
5568 + if(typeof callback === 'function')
5569 + callback(null);
5570 });
5571 },
5572
5511 - access: function(callback) {
5573 + access: function(max_redirects, callback) {
5574 + // send ACCESS to a netdata registry:
5575 + // 1. it let it know we are accessing a netdata server (in the URL)
5576 + // 2. it responds with a list of netdata servers we know
5577 + // the registry identifies us using a cookie it sets the first time we access it
5578 $.ajax({
5513 - url: NETDATA.registry.server + '/api/v1/registry?action=access&machine=' + NETDATA.registry.machine_guid + '&name=' + encodeURIComponent(NETDATA.registry.hostname) + '&url=' + encodeURIComponent(NETDATA.serverDefault),
5579 + url: NETDATA.registry.server + '/api/v1/registry?action=access&machine=' + NETDATA.registry.machine_guid + '&name=' + encodeURIComponent(NETDATA.registry.hostname) + '&url=' + encodeURIComponent(NETDATA.serverDefault) + '&visible_url=' + encodeURIComponent(document.location),
5580 async: true,
5581 cache: false,
5516 - xhrFields: { withCredentials: true }
5582 + xhrFields: { withCredentials: true } // required for the cookie
5583 })
5584 .done(function(data) {
5519 - NETDATA.registry.urls = data.urls;
5585 + var redirect = null;
5586 + if(typeof data.registry === 'string')
5587 + redirect = data.registry;
5588
5521 - if(typeof callback === 'function')
5522 - callback();
5589 + if(typeof data.status !== 'string' || data.status !== 'ok')
5590 + data = null;
5591 +
5592 + if(data === null && redirect !== null && max_redirects > 0) {
5593 + NETDATA.registry.access(max_redirects - 1, callback);
5594 + }
5595 + else if(data === null) {
5596 + NETDATA.error(409, NETDATA.registry.server + ' response: ' + JSON.stringify(data));
5597 + if(typeof callback === 'function')
5598 + callback(null);
5599 + }
5600 + else {
5601 + if(typeof callback === 'function')
5602 + callback(data.urls);
5603 + }
5604 })
5605 .fail(function() {
5525 - console.log('failed to access (registry) netdata server: ' + NETDATA.registry.host);
5606 + NETDATA.error(410, NETDATA.registry.server);
5607 + if(typeof callback === 'function')
5608 + callback(null);
5609 });
5610 }
5528 -
5611 };
5612
5613 + // ----------------------------------------------------------------------------------------------------------------
5614 + // Boot it!
5615 +
5616 NETDATA.errorReset();
5617 NETDATA.loadRequiredCSS(0);
5618
@@ -5542,8 +5627,6 @@
5627 if(NETDATA.options.debug.main_loop === true)
5628 console.log('starting chart refresh thread');
5629
5545 - setTimeout(NETDATA.registry.init, 500);
5546 -
5630 NETDATA.start();
5631 }
5632 });
web/index.html
+157 -25
@@ -191,6 +191,37 @@
191 font-weight: 500;
192 }
193
194 + .dropdown-menu {
195 + min-width: 200px;
196 + }
197 + .dropdown-menu.columns-2 {
198 + margin: 0;
199 + padding: 0;
200 + width: 400px;
201 + }
202 + .dropdown-menu li a {
203 + padding: 5px 15px;
204 + font-weight: 300;
205 + }
206 + .dropdown-menu.multi-column {
207 + overflow-x: hidden;
208 + }
209 + .multi-column-dropdown {
210 + list-style: none;
211 + padding: 0;
212 + }
213 + .multi-column-dropdown li a {
214 + display: block;
215 + clear: both;
216 + line-height: 1.428571429;
217 + white-space: normal;
218 + }
219 + .multi-column-dropdown li a:hover {
220 + text-decoration: none;
221 + color: #f5f5f5;
222 + background-color: #262626;
223 + }
224 +
225 /* Back to top (hidden on mobile) */
226 .back-to-top,
227 .dashboard-theme-toggle {
@@ -320,6 +351,7 @@
351 else
352 return ret;
353 }
354 +
355 var netdataTheme = getTheme('slate');
356
357 function setTheme(theme) {
@@ -327,15 +359,63 @@
359
360 return saveLocalStorage('netdataTheme', theme);
361 }
362 +
363 + var netdataRegistryCallback = function(urls) {
364 + var el = '';
365 + var a1 = '';
366 +
367 + $.each(urls, function(i, u) {
368 + // if(u.guid === NETDATA.registry.machine_guid)
369 + el += '<li id="registry_server_' + u.guid + '"><a href="' + u.url + '">' + u.name + '</a></li>';
370 + a1 += '<li id="registry_action_' + u.guid + '"><a href="#" onclick="deleteRegistryModalHandler(\'' + u.guid + '\',\'' + u.name + '\',\'' + u.url + '\'); return false;"><i class="fa fa-trash-o" aria-hidden="true" style="color: #999;"></i></a></li>';
371 + });
372 +
373 + el += '<li role="separator" class="divider"></li>';
374 + a1 += '<li role="separator" class="divider"></li>';
375 +
376 + el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #999;" target="_blank">How this works?</a></li>';
377 + a1 += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #999;" target="_blank"><i class="fa fa-question" aria-hidden="true" style="color: #999;"></i></a></li>'
378 +
379 + document.getElementById('mynetdata_servers').innerHTML = el;
380 + document.getElementById('mynetdata_actions1').innerHTML = a1;
381 +
382 + document.getElementById('mynetdata_servers2').innerHTML = el;
383 + };
384 +
385 </script>
386
387 <!-- load the dashboard manager - it will do the rest -->
333 - <script type="text/javascript" src="dashboard.js?v34"></script>
388 + <script type="text/javascript" src="dashboard.js?v35"></script>
389 </head>
390
391 <body data-spy="scroll" data-target="#sidebar">
392 <nav class="navbar navbar-default navbar-fixed-top" role="banner">
393 <div class="container">
394 + <nav id="mynetdata_nav" class="collapse navbar-collapse navbar-left hidden-sm hidden-xs" role="navigation" style="padding-right: 20px;">
395 + <ul class="nav navbar-nav">
396 + <li class="dropdown">
397 + <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
398 + <ul class="dropdown-menu scrollable-menu inpagemenu multi-column columns-2" role="menu">
399 + <div class="row">
400 + <div class="col-sm-6" style="width: 85%; padding-right: 0;">
401 + <ul id="mynetdata_servers" class="multi-column-dropdown">
402 + <li id="demo_eu"><a href="//london.netdata.rocks/default.html">EU - London (DigitalOcean.com)</a></li>
403 + <li id="demo_us"><a href="//atlanda.netdata.rocks/default.html">US - Atlanta (CDN77.com)</a></li>
404 + <li id="demo_gr"><a href="//athens.netdata.rocks/default.html">EU - Greece</a></li>
405 + <li role="separator" class="divider"></li>
406 + <li id="demo_tv"><a href="tv.html">TV Dashboard for 2 servers</a></li>
407 + <li id="demosites"><a href="demosites.html">Dashboard for monitoring netdata demo sites</a></li>
408 + </ul>
409 + </div>
410 + <div class="col-sm-3 hidden-xs" style="width: 15%; padding-left: 0;">
411 + <ul id="mynetdata_actions1" class="multi-column-dropdown">
412 + </ul>
413 + </div>
414 + </div>
415 + </ul>
416 + </li>
417 + </ul>
418 + </nav>
419 <div class="navbar-header">
420 <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse">
421 <span class="sr-only">Toggle navigation</span>
@@ -345,32 +425,28 @@
425 </button>
426 <a href="/" class="navbar-brand" id="hostname">netdata</a>
427 </div>
348 - <nav id="demosites_nav" class="collapse navbar-collapse navbar-left" role="navigation">
428 + <nav class="collapse navbar-collapse navbar-right" role="navigation">
429 <ul class="nav navbar-nav">
350 - <li class="dropdown">
351 - <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">demo sites <strong class="caret"></strong></a>
430 + <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-cog"></i> settings</a></li>
431 + <li class="hidden-sm"><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
432 + <li class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal"><i class="fa fa-cloud-download"></i> update</a></li>
433 + <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
434 + <li class="dropdown hidden-md hidden-lg hidden-xs">
435 + <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">Menu <strong class="caret"></strong></a>
436 <ul class="dropdown-menu scrollable-menu inpagemenu" role="menu">
353 - <li id="demo_eu"><a href="//netdata1.firehol.org?nowelcome">EU - London (DigitalOcean.com)</a></li>
354 - <li id="demo_us"><a href="//netdata2.firehol.org?nowelcome">US - Atlanta (CDN77.com)</a></li>
355 - <li id="demo_gr"><a href="//netdata3.firehol.org?nowelcome">EU - Greece</a></li>
356 - <li role="separator" class="divider"></li>
357 - <li id="demo_tv"><a href="tv.html">TV Dashboard for 2 servers</a></li>
358 - <li id="demosites"><a href="demosites.html">Dashboard for monitoring netdata demo sites</a></li>
437 + <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-cog"></i> settings</a></li>
438 + <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
439 + <li><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
440 + </ul>
441 + </li>
442 + <li class="dropdown hidden-sm hidden-md hidden-lg">
443 + <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
444 + <ul id="mynetdata_servers2" class="dropdown-menu scrollable-menu inpagemenu" role="menu">
445 </ul>
446 </li>
447 </ul>
448 </nav>
363 - <nav class="collapse navbar-collapse navbar-right" role="navigation">
364 - <ul class="nav navbar-nav">
365 - <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-cog"></i> settings</a></li>
366 - <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
367 - <li id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal"><i class="fa fa-cloud-download"></i> update</a></li>
368 -<!-- <li><a href="old/" class="btn" target="_blank"><i class="fa fa-step-backward"></i> old dashboard</a></li> -->
369 - <li><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
370 -<!-- <li><a href="#sec">Visualize</a></li>
371 - <li><a href="#sec">Prototype</a></li>
372 ---> </ul>
373 - </nav>
449 + </nav>
450 </div>
451 </nav>
452
@@ -787,8 +863,34 @@
863 </div>
864 </div>
865
790 -<script>
866 + <div class="modal fade" id="deleteRegistryModal" tabindex="-1" role="dialog" aria-labelledby="deleteRegistryModalLabel">
867 + <div class="modal-dialog" role="document">
868 + <div class="modal-content">
869 + <div class="modal-header">
870 + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
871 + <h4 class="modal-title" id="deleteRegistryModalLabel">Delete <span id="deleteRegistryServerName"></span>?</h4>
872 + </div>
873 + <div class="modal-body">
874 + You are about to delete, from your personal list of netdata servers, the following server:
875 + <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
876 + <b><span id="deleteRegistryServerName2"></span></b>
877 + <br/>
878 + <b><span id="deleteRegistryServerURL"></span></b>
879 + </p>
880 + Are you sure you want to do this?
881 + <br/>
882 + <div style="padding: 10px;"></div>
883 + <small>Keep in mind, this server will be added back if and when you visit it again.</small>
884 + </div>
885 + <div class="modal-footer">
886 + <button type="button" class="btn btn-success" data-dismiss="modal">keep it</button>
887 + <a href="#" onclick="notifyForDeleteRegistry(true);" type="button" class="btn btn-danger">delete it</a>
888 + </div>
889 + </div>
890 + </div>
891 + </div>
892
893 +<script>
894 var this_is_demo = null;
895 function isdemo() {
896 if(this_is_demo !== null) return this_is_demo;
@@ -796,6 +898,12 @@ function isdemo() {
898
899 try {
900 if(typeof document.location.hostname === 'string') {
901 + if(document.location.hostname.endsWith('.firehol.org') ||
902 + document.location.hostname.endsWith('.netdata.rocks') ||
903 + document.location.hostname.endsWith('.netdata.online'))
904 + this_is_demo = true;
905 +
906 + /*
907 if(document.location.hostname === 'netdata.firehol.org' || document.location.hostname === 'netdata1.firehol.org') {
908 document.getElementById("demo_eu").className = "active";
909 this_is_demo = true;
@@ -808,10 +916,8 @@ function isdemo() {
916 document.getElementById("demo_gr").className = "active";
917 this_is_demo = true;
918 }
919 + */
920 }
812 -
813 - if(!this_is_demo)
814 - document.getElementById("demosites_nav").style.visibility = "hidden";
921 }
922 catch(error) {
923 ;
@@ -824,6 +930,28 @@ if(isdemo()) {
930 document.getElementById('masthead').style.display = 'block';
931 }
932
933 +var deleteRegistryGuid = null;
934 +function deleteRegistryModalHandler(guid, name, url) {
935 + deleteRegistryGuid = guid;
936 + document.getElementById('deleteRegistryServerName').innerHTML = name;
937 + document.getElementById('deleteRegistryServerName2').innerHTML = name;
938 + document.getElementById('deleteRegistryServerURL').innerHTML = url;
939 + $('#deleteRegistryModal').modal('show');
940 +}
941 +
942 +function notifyForDeleteRegistry() {
943 +/* if(deleteRegistryGuid) {
944 + NETDATA.registry.delete(deleteRegistryGuid, function() {
945 + console.log('delete called callback');
946 + NETDATA.registry.init();
947 + });
948 + }
949 +
950 + deleteRegistryGuid = null;
951 + $('#deleteRegistryModal').modal('hide');
952 +*/
953 +}
954 +
955 var options = {
956 sparklines_registry: {},
957 submenu_names: {},
@@ -2008,6 +2136,10 @@ function finalizePage() {
2136 notifyForUpdate(true);
2137 });
2138
2139 + $('#deleteRegistryModal').on('hidden.bs.modal', function() {
2140 + deleteRegistryGuid = null;
2141 + });
2142 +
2143 if(isdemo()) {
2144 if(!nowelcome) {
2145 setTimeout(function() {