gan.html 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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" id="connectedNodes" count="0">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. <!--
  35. <div class="ui icon input" style="margin-bottom: 1em;">
  36. <input type="text" placeholder="Search a Network">
  37. <i class="circular search link icon"></i>
  38. </div>-->
  39. <div style="width: 100%; overflow-x: auto;">
  40. <table class="ui celled basic unstackable striped table">
  41. <thead>
  42. <tr>
  43. <th>Network ID</th>
  44. <th>Name</th>
  45. <th>Description</th>
  46. <th>Subnet (Assign Range)</th>
  47. <th>Nodes</th>
  48. <th>Actions</th>
  49. </tr>
  50. </thead>
  51. <tbody id="GANetList">
  52. <tr>
  53. <td colspan="6"><i class="ui green circle check icon"></i> No Global Area Network Found on this host</td>
  54. </tr>
  55. </tbody>
  56. </table>
  57. </div>
  58. </div>
  59. </div>
  60. </div>
  61. <script>
  62. /*
  63. Network Management Functions
  64. */
  65. function handleAddNetwork(){
  66. let networkName = $("#networkName").val().trim();
  67. if (networkName == ""){
  68. msgbox("Network name cannot be empty", false, 5000);
  69. return;
  70. }
  71. //Add network with default settings
  72. addGANet(networkName, "192.168.196.0/24");
  73. $("#networkName").val("");
  74. }
  75. function initGANetID(){
  76. $.get("/api/gan/network/info", function(data){
  77. if (data.error !== undefined){
  78. msgbox(data.error, false, 5000)
  79. }else{
  80. if (data != ""){
  81. $(".ganControllerID").text(data);
  82. }
  83. }
  84. })
  85. }
  86. function addGANet() {
  87. $.cjax({
  88. url: "/api/gan/network/add",
  89. type: "POST",
  90. dataType: "json",
  91. data: {},
  92. success: function(response) {
  93. if (response.error != undefined){
  94. msgbox(response.error, false, 5000);
  95. }else{
  96. msgbox("Network added successfully");
  97. }
  98. console.log("Network added successfully:", response);
  99. listGANet();
  100. },
  101. error: function(xhr, status, error) {
  102. console.log("Error adding network:", error);
  103. }
  104. });
  105. }
  106. function listGANet(){
  107. $("#connectedNodes").attr("count", "0");
  108. $.get("/api/gan/network/list", function(data){
  109. $("#GANetList").empty();
  110. if (data.error != undefined){
  111. console.log(data.error);
  112. msgbox("Unable to load auth token for GANet", false, 5000);
  113. //token error or no zerotier found
  114. $(".gansnetworks").addClass("disabled");
  115. $("#GANetList").append(`<tr>
  116. <td colspan="6"><i class="red times circle icon"></i> Auth token access error or not found</td>
  117. </tr>`);
  118. $(".ganControllerID").text('Access Denied');
  119. }else{
  120. var nodeCount = 0;
  121. data.forEach(function(gan){
  122. $("#GANetList").append(`<tr class="ganetEntry" addr="${gan.nwid}">
  123. <td><a href="#" onclick="event.preventDefault(); openGANetDetails('${gan.nwid}');">${gan.nwid}</a></td>
  124. <td>${gan.name}</td>
  125. <td class="gandesc" addr="${gan.nwid}"></td>
  126. <td class="ganetSubnet"></td>
  127. <td class="ganetNodes"></td>
  128. <td>
  129. <button onclick="openGANetDetails('${gan.nwid}');" class="ui tiny basic icon button" title="Edit Network"><i class="edit icon"></i></button>
  130. <button onclick="removeGANet('${gan.nwid}');" class="ui tiny basic icon button" title="Remove Network"><i class="red remove icon"></i></button>
  131. </td>
  132. </tr>`);
  133. nodeCount += 0;
  134. });
  135. if (data.length == 0){
  136. $("#GANetList").append(`<tr>
  137. <td colspan="6"><i class="ui green circle check icon"></i> No Global Area Network Found on this host</td>
  138. </tr>`);
  139. }
  140. $("#ganodeCount").text(nodeCount);
  141. $("#ganetCount").text(data.length);
  142. //Load description
  143. $(".gandesc").each(function(){
  144. let addr = $(this).attr("addr");
  145. let domEle = $(this);
  146. $.get("/api/gan/network/name?netid=" + addr, function(data){
  147. $(domEle).text(data[1]);
  148. });
  149. });
  150. $(".ganetEntry").each(function(){
  151. let addr = $(this).attr("addr");
  152. let subnetEle = $(this).find(".ganetSubnet");
  153. let nodeEle = $(this).find(".ganetNodes");
  154. $.get("/api/gan/network/list?netid=" + addr, function(data){
  155. if (data.routes != undefined && data.routes.length > 0){
  156. if (data.ipAssignmentPools != undefined && data.ipAssignmentPools.length > 0){
  157. $(subnetEle).html(`${data.routes[0].target} <br> (${data.ipAssignmentPools[0].ipRangeStart} - ${data.ipAssignmentPools[0].ipRangeEnd})`);
  158. }else{
  159. $(subnetEle).html(`${data.routes[0].target}<br>(Unassigned Range)`);
  160. }
  161. }else{
  162. $(subnetEle).text("Unassigned");
  163. }
  164. //console.log(data);
  165. });
  166. $.get("/api/gan/members/list?netid=" + addr, function(data){
  167. $(nodeEle).text(data.length);
  168. let currentNodesCount = parseInt($("#connectedNodes").attr("count"));
  169. currentNodesCount += data.length;
  170. $("#connectedNodes").attr("count", currentNodesCount);
  171. $("#ganodeCount").text($("#connectedNodes").attr("count"));
  172. })
  173. });
  174. }
  175. })
  176. }
  177. //Remove the given GANet
  178. function removeGANet(netid){
  179. if (confirm("Confirm remove Network " + netid + " PERMANENTLY ?"))
  180. $.cjax({
  181. url: "/api/gan/network/remove",
  182. type: "POST",
  183. dataType: "json",
  184. data: {
  185. id: netid,
  186. },
  187. success: function(data){
  188. if (data.error != undefined){
  189. msgbox(data.error, false, 5000);
  190. }else{
  191. msgbox("Net " + netid + " removed");
  192. }
  193. listGANet();
  194. }
  195. });
  196. }
  197. function openGANetDetails(netid){
  198. $("#ganetWindow").load("./components/gandetails.html", function(){
  199. setTimeout(function(){
  200. initGanetDetails(netid);
  201. });
  202. });
  203. }
  204. //Bind event to tab switch
  205. tabSwitchEventBind["gan"] = function(){
  206. //On switch over to this page, load info
  207. listGANet();
  208. initGANetID();
  209. }
  210. </script>