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">×</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() {