Loading data/admin.html +25 −1 Original line number Diff line number Diff line Loading @@ -1047,12 +1047,36 @@ function loadClusterStatus() { html += '</table>'; } html += '<p style="margin-top:1em"><a class="button" href="#" onclick="loadClusterStatus(); return false;">Refresh</a></p>'; html += '<p style="margin-top:1em">'; html += '<a class="button" href="#" onclick="loadClusterStatus(); return false;">Refresh</a> '; html += '<a class="button" href="#" onclick="clusterScrub(); return false;">Scrub</a> '; html += '<a class="button" href="#" onclick="clusterRebalance(); return false;">Rebalance</a>'; html += '</p>'; setContent(html); }); }); } function clusterScrub() { ajaxGet("/settings/" + currentDomain + "/api/clusterscrub", function(err, data) { if (err) { showError(err); return; } alert('Scrub complete: checked=' + data.groups_checked + ' repaired=' + data.groups_repaired + ' failed=' + data.groups_failed); loadClusterStatus(); }); } function clusterRebalance() { ajaxGet("/settings/" + currentDomain + "/api/clusterrebalance", function(err, data) { if (err) { showError(err); return; } alert('Rebalance complete: rebalanced=' + data.rebalanced + ' already_ok=' + data.already_ok + ' failed=' + data.failed); loadClusterStatus(); }); } /* ---- Logout ---- */ function doLogout() { ajaxPost("/settings/api/logout", {}, function(err, data) { Loading src/admin.cpp +41 −0 Original line number Diff line number Diff line Loading @@ -715,6 +715,45 @@ namespace authdb { json_object_put(jobj); } /* ---- JSON API: Cluster Rebalance ---- */ void apiClusterRebalance(libhttppp::HttpRequest &curreq) { json_object *jobj = json_object_new_object(); if (!g_Cluster || !g_Cluster->isRunning()) { json_object_object_add(jobj, "status", json_object_new_string("error")); json_object_object_add(jobj, "message", json_object_new_string("cluster not running")); sendJson(curreq, jobj); json_object_put(jobj); return; } if (g_Cluster->isCritical()) { json_object_object_add(jobj, "status", json_object_new_string("error")); json_object_object_add(jobj, "message", json_object_new_string("cluster is critical — need more nodes online")); sendJson(curreq, jobj); json_object_put(jobj); return; } auto &client = g_Cluster->getClient(); if (!client) { json_object_object_add(jobj, "status", json_object_new_string("error")); json_object_object_add(jobj, "message", json_object_new_string("no parity client")); sendJson(curreq, jobj); json_object_put(jobj); return; } auto rb = client->rebalance(); json_object_object_add(jobj, "status", json_object_new_string("ok")); json_object_object_add(jobj, "rebalanced", json_object_new_int(static_cast<int>(rb.rebalanced))); json_object_object_add(jobj, "already_ok", json_object_new_int(static_cast<int>(rb.already_ok))); json_object_object_add(jobj, "failed", json_object_new_int(static_cast<int>(rb.failed))); sendJson(curreq, jobj); json_object_put(jobj); } /* ---- JSON API: List Domains ---- */ void apiListDomains(libhttppp::HttpRequest &curreq) { json_object *jobj = json_object_new_object(); Loading Loading @@ -2152,6 +2191,8 @@ namespace authdb { apiClusterSync(curreq); } else if (strcmp(apiurl, "clusterscrub") == 0) { apiClusterScrub(curreq); } else if (strcmp(apiurl, "clusterrebalance") == 0) { apiClusterRebalance(curreq); } else { sendJsonError(curreq, "Unknown API endpoint", 404); } Loading Loading
data/admin.html +25 −1 Original line number Diff line number Diff line Loading @@ -1047,12 +1047,36 @@ function loadClusterStatus() { html += '</table>'; } html += '<p style="margin-top:1em"><a class="button" href="#" onclick="loadClusterStatus(); return false;">Refresh</a></p>'; html += '<p style="margin-top:1em">'; html += '<a class="button" href="#" onclick="loadClusterStatus(); return false;">Refresh</a> '; html += '<a class="button" href="#" onclick="clusterScrub(); return false;">Scrub</a> '; html += '<a class="button" href="#" onclick="clusterRebalance(); return false;">Rebalance</a>'; html += '</p>'; setContent(html); }); }); } function clusterScrub() { ajaxGet("/settings/" + currentDomain + "/api/clusterscrub", function(err, data) { if (err) { showError(err); return; } alert('Scrub complete: checked=' + data.groups_checked + ' repaired=' + data.groups_repaired + ' failed=' + data.groups_failed); loadClusterStatus(); }); } function clusterRebalance() { ajaxGet("/settings/" + currentDomain + "/api/clusterrebalance", function(err, data) { if (err) { showError(err); return; } alert('Rebalance complete: rebalanced=' + data.rebalanced + ' already_ok=' + data.already_ok + ' failed=' + data.failed); loadClusterStatus(); }); } /* ---- Logout ---- */ function doLogout() { ajaxPost("/settings/api/logout", {}, function(err, data) { Loading
src/admin.cpp +41 −0 Original line number Diff line number Diff line Loading @@ -715,6 +715,45 @@ namespace authdb { json_object_put(jobj); } /* ---- JSON API: Cluster Rebalance ---- */ void apiClusterRebalance(libhttppp::HttpRequest &curreq) { json_object *jobj = json_object_new_object(); if (!g_Cluster || !g_Cluster->isRunning()) { json_object_object_add(jobj, "status", json_object_new_string("error")); json_object_object_add(jobj, "message", json_object_new_string("cluster not running")); sendJson(curreq, jobj); json_object_put(jobj); return; } if (g_Cluster->isCritical()) { json_object_object_add(jobj, "status", json_object_new_string("error")); json_object_object_add(jobj, "message", json_object_new_string("cluster is critical — need more nodes online")); sendJson(curreq, jobj); json_object_put(jobj); return; } auto &client = g_Cluster->getClient(); if (!client) { json_object_object_add(jobj, "status", json_object_new_string("error")); json_object_object_add(jobj, "message", json_object_new_string("no parity client")); sendJson(curreq, jobj); json_object_put(jobj); return; } auto rb = client->rebalance(); json_object_object_add(jobj, "status", json_object_new_string("ok")); json_object_object_add(jobj, "rebalanced", json_object_new_int(static_cast<int>(rb.rebalanced))); json_object_object_add(jobj, "already_ok", json_object_new_int(static_cast<int>(rb.already_ok))); json_object_object_add(jobj, "failed", json_object_new_int(static_cast<int>(rb.failed))); sendJson(curreq, jobj); json_object_put(jobj); } /* ---- JSON API: List Domains ---- */ void apiListDomains(libhttppp::HttpRequest &curreq) { json_object *jobj = json_object_new_object(); Loading Loading @@ -2152,6 +2191,8 @@ namespace authdb { apiClusterSync(curreq); } else if (strcmp(apiurl, "clusterscrub") == 0) { apiClusterScrub(curreq); } else if (strcmp(apiurl, "clusterrebalance") == 0) { apiClusterRebalance(curreq); } else { sendJsonError(curreq, "Unknown API endpoint", 404); } Loading