gan.html 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <div id="ganetWindow" class="standardContainer">
  2. <div class="ui basic segment">
  3. <h2>Global Area Network</h2>
  4. <p>Virtual Network Hub that allows all networked devices to communicate as if they all reside in the same physical data center or cloud region</p>
  5. </div>
  6. <div class="gansnetworks">
  7. <div class="ganstats ui basic segment">
  8. <div style="float: right; max-width: 300px; margin-top: 0.4em;">
  9. <h1 class="ui header" style="text-align: right;">
  10. <span class="ganControllerID"></span>
  11. <div class="sub header">Network Controller ID</div>
  12. </h1>
  13. </div>
  14. <div class="ui list">
  15. <div class="item">
  16. <i class="exchange icon"></i>
  17. <div class="content">
  18. <div class="header" style="font-size: 1.2em;" id="ganetCount">0</div>
  19. <div class="description">Networks</div>
  20. </div>
  21. </div>
  22. <div class="item">
  23. <i class="desktop icon"></i>
  24. <div class="content">
  25. <div class="header" style="font-size: 1.2em;" id="ganodeCount">0</div>
  26. <div class="description">Connected Nodes</div>
  27. </div>
  28. </div>
  29. </div>
  30. </div>
  31. <div class="ganlist">
  32. <button class="ui basic orange button" onclick="addGANet();">Create New Network</button>
  33. <div class="ui divider"></div>
  34. <div class="ui icon input" style="margin-bottom: 1em;">
  35. <input type="text" placeholder="Search a Network">
  36. <i class="circular search link icon"></i>
  37. </div>
  38. <div style="width: 100%; overflow-x: auto;">
  39. <table class="ui celled basic unstackable striped table">
  40. <thead>
  41. <tr>
  42. <th>Network ID</th>
  43. <th>Name</th>
  44. <th>Description</th>
  45. <th>Subnet (Assign Range)</th>
  46. <th>Nodes</th>
  47. <th>Actions</th>
  48. </tr>
  49. </thead>
  50. <tbody id="GANetList">
  51. <tr>
  52. <td colspan="6"><i class="ui green circle check icon"></i> No Global Area Network Found on this host</td>
  53. </tr>
  54. </tbody>
  55. </table>
  56. </div>
  57. </div>
  58. </div>
  59. </div>
  60. <script>
  61. /*
  62. Network Management Functions
  63. */
  64. function handleAddNetwork(){
  65. let networkName = $("#networkName").val().trim();
  66. if (networkName == ""){
  67. msgbox("Network name cannot be empty", false, 5000);
  68. return;
  69. }
  70. //Add network with default settings
  71. addGANet(networkName, "192.168.196.0/24");
  72. $("#networkName").val("");
  73. }
  74. function initGANetID(){
  75. $.get("/api/gan/network/info", function(data){
  76. if (data.error !== undefined){
  77. msgbox(data.error, false, 5000)
  78. }else{
  79. if (data != ""){
  80. $(".ganControllerID").text(data);
  81. }
  82. }
  83. })
  84. }
  85. function addGANet() {
  86. $.ajax({
  87. url: "/api/gan/network/add",
  88. type: "POST",
  89. dataType: "json",
  90. data: {},
  91. success: function(response) {
  92. if (response.error != undefined){
  93. msgbox(response.error, false, 5000);
  94. }else{
  95. msgbox("Network added successfully");
  96. }
  97. console.log("Network added successfully:", response);
  98. listGANet();
  99. },
  100. error: function(xhr, status, error) {
  101. console.log("Error adding network:", error);
  102. }
  103. });
  104. }
  105. function listGANet(){
  106. $.get("/api/gan/network/list", function(data){
  107. $("#GANetList").empty();
  108. if (data.error != undefined){
  109. console.log(data.error);
  110. msgbox("Unable to load auth token for GANet", false, 5000);
  111. //token error or no zerotier found
  112. $(".gansnetworks").addClass("disabled");
  113. $("#GANetList").append(`<tr>
  114. <td colspan="6"><i class="red times circle icon"></i> Auth token access error or not found</td>
  115. </tr>`);
  116. $(".ganControllerID").text('Access Denied');
  117. }else{
  118. var nodeCount = 0;
  119. data.forEach(function(gan){
  120. $("#GANetList").append(`<tr class="ganetEntry" addr="${gan.nwid}">
  121. <td>${gan.nwid}</td>
  122. <td>${gan.name}</td>
  123. <td class="gandesc" addr="${gan.nwid}"></td>
  124. <td class="ganetSubnet"></td>
  125. <td class="ganetNodes"></td>
  126. <td>
  127. <button onclick="openGANetDetails('${gan.nwid}');" class="ui tiny basic icon button" title="Edit Network"><i class="edit icon"></i></button>
  128. <button onclick="removeGANet('${gan.nwid}');" class="ui tiny basic icon button" title="Remove Network"><i class="red remove icon"></i></button>
  129. </td>
  130. </tr>`);
  131. nodeCount += 0;
  132. });
  133. if (data.length == 0){
  134. $("#GANetList").append(`<tr>
  135. <td colspan="6"><i class="ui green circle check icon"></i> No Global Area Network Found on this host</td>
  136. </tr>`);
  137. }
  138. $("#ganodeCount").text(nodeCount);
  139. $("#ganetCount").text(data.length);
  140. //Load description
  141. $(".gandesc").each(function(){
  142. let addr = $(this).attr("addr");
  143. let domEle = $(this);
  144. $.get("/api/gan/network/name?netid=" + addr, function(data){
  145. $(domEle).text(data[1]);
  146. });
  147. });
  148. $(".ganetEntry").each(function(){
  149. let addr = $(this).attr("addr");
  150. let subnetEle = $(this).find(".ganetSubnet");
  151. let nodeEle = $(this).find(".ganetNodes");
  152. $.get("/api/gan/network/list?netid=" + addr, function(data){
  153. if (data.routes != undefined && data.routes.length > 0){
  154. if (data.ipAssignmentPools != undefined && data.ipAssignmentPools.length > 0){
  155. $(subnetEle).html(`${data.routes[0].target} <br> (${data.ipAssignmentPools[0].ipRangeStart} - ${data.ipAssignmentPools[0].ipRangeEnd})`);
  156. }else{
  157. $(subnetEle).html(`${data.routes[0].target}<br>(Unassigned Range)`);
  158. }
  159. }else{
  160. $(subnetEle).text("Unassigned");
  161. }
  162. //console.log(data);
  163. });
  164. $.get("/api/gan/members/list?netid=" + addr, function(data){
  165. $(nodeEle).text(data.length);
  166. })
  167. });
  168. }
  169. })
  170. }
  171. //Remove the given GANet
  172. function removeGANet(netid){
  173. if (confirm("Confirm remove Network " + netid + " PERMANENTLY ?"))
  174. $.ajax({
  175. url: "/api/gan/network/remove",
  176. type: "POST",
  177. dataType: "json",
  178. data: {
  179. id: netid,
  180. },
  181. success: function(data){
  182. if (data.error != undefined){
  183. msgbox(data.error, false, 5000);
  184. }else{
  185. msgbox("Net " + netid + " removed");
  186. }
  187. listGANet();
  188. }
  189. });
  190. }
  191. function openGANetDetails(netid){
  192. $("#ganetWindow").load("./components/gandetails.html", function(){
  193. setTimeout(function(){
  194. initGanetDetails(netid);
  195. });
  196. });
  197. }
  198. //Bind event to tab switch
  199. tabSwitchEventBind["gan"] = function(){
  200. //On switch over to this page, load info
  201. listGANet();
  202. initGANetID();
  203. }
  204. </script>