1
0

dockerContainersList.html 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <!-- Notes: This should be open in its original path-->
  5. <meta charset="utf-8" />
  6. <link rel="stylesheet" href="../script/semantic/semantic.min.css" />
  7. <script src="../script/jquery-3.6.0.min.js"></script>
  8. <script src="../script/semantic/semantic.min.js"></script>
  9. </head>
  10. <body>
  11. <br />
  12. <div class="ui container">
  13. <div class="field">
  14. <div class="ui checkbox">
  15. <input type="checkbox" id="showUnexposed" class="hidden" />
  16. <label for="showUnexposed"
  17. >Show Containers with Unexposed Ports
  18. <br />
  19. <small
  20. >Please make sure Zoraxy and the target container share a
  21. network</small
  22. >
  23. </label>
  24. </div>
  25. </div>
  26. <div class="ui header">
  27. <div class="content">
  28. List of Docker Containers
  29. <div class="sub header">
  30. Below is a list of all detected Docker containers currently running
  31. on the system.
  32. </div>
  33. </div>
  34. </div>
  35. <div id="containersList" class="ui middle aligned divided list active">
  36. <div class="ui loader active"></div>
  37. </div>
  38. <div class="ui horizontal divider"></div>
  39. <div id="containersAddedListHeader" class="ui header" hidden>
  40. Already added containers:
  41. </div>
  42. <div
  43. id="containersAddedList"
  44. class="ui middle aligned divided list"
  45. ></div>
  46. </div>
  47. <script>
  48. let lines = {};
  49. let linesAdded = {};
  50. document
  51. .getElementById("showUnexposed")
  52. .addEventListener("change", () => {
  53. console.log("showUnexposed", $("#showUnexposed").is(":checked"));
  54. $("#containersList").html('<div class="ui loader active"></div>');
  55. $("#containersAddedList").empty();
  56. $("#containersAddedListHeader").attr("hidden", true);
  57. lines = {};
  58. linesAdded = {};
  59. getDockerContainers();
  60. });
  61. function getDockerContainers() {
  62. const hostRequest = $.get("/api/proxy/list?type=host");
  63. const dockerRequest = $.get("/api/docker/containers");
  64. Promise.all([hostRequest, dockerRequest])
  65. .then(([hostData, dockerData]) => {
  66. if (!dockerData.error && !hostData.error) {
  67. const { containers, network } = dockerData;
  68. const existingTargets = new Set(
  69. hostData.flatMap(({ ActiveOrigins }) =>
  70. ActiveOrigins.map(({ OriginIpOrDomain }) => OriginIpOrDomain)
  71. )
  72. );
  73. for (const container of containers) {
  74. const Ports = container.Ports;
  75. const name = container.Names[0].replace(/^\//, "");
  76. for (const portObject of Ports) {
  77. let port = portObject.PublicPort;
  78. if (!port) {
  79. if (!$("#showUnexposed").is(":checked")) {
  80. continue;
  81. }
  82. port = portObject.PrivatePort;
  83. }
  84. const key = `${name}-${port}`;
  85. // if port is not exposed, use container's name and let docker handle the routing
  86. // BUT this will only work if the container is on the same network as Zoraxy
  87. const targetAddress = portObject.IP || name;
  88. if (
  89. existingTargets.has(`${targetAddress}:${port}`) &&
  90. !linesAdded[key]
  91. ) {
  92. linesAdded[key] = {
  93. name,
  94. ip: targetAddress,
  95. port,
  96. };
  97. } else if (!lines[key]) {
  98. lines[key] = {
  99. name,
  100. ip: targetAddress,
  101. port,
  102. };
  103. }
  104. }
  105. }
  106. for (const [key, line] of Object.entries(lines)) {
  107. $("#containersList").append(
  108. `<div class="item">
  109. <div class="right floated content">
  110. <div class="ui button" onclick="addContainerItem('${key}');">Add</div>
  111. </div>
  112. <div class="content">
  113. <div class="header">${line.name}</div>
  114. <div class="description">
  115. ${line.ip}:${line.port}
  116. </div>
  117. </div>`
  118. );
  119. }
  120. for (const [key, line] of Object.entries(linesAdded)) {
  121. $("#containersAddedList").append(
  122. `<div class="item">
  123. <div class="content">
  124. <div class="header">${line.name}</div>
  125. <div class="description">
  126. ${line.ip}:${line.port}
  127. </div>
  128. </div>`
  129. );
  130. }
  131. Object.entries(linesAdded).length &&
  132. $("#containersAddedListHeader").removeAttr("hidden");
  133. $("#containersList .loader").removeClass("active");
  134. } else {
  135. parent.msgbox(
  136. `Error loading data: ${dockerData.error || hostData.error}`,
  137. false
  138. );
  139. $("#containersList").html(
  140. `<div class="ui basic segment"><i class="ui red times icon"></i> ${
  141. dockerData.error || hostData.error
  142. }</div>`
  143. );
  144. }
  145. })
  146. .catch((error) => {
  147. console.log(error.responseText);
  148. parent.msgbox("Error loading data: " + error.message, false);
  149. });
  150. }
  151. getDockerContainers();
  152. function addContainerItem(item) {
  153. if (lines[item]) {
  154. parent.addContainerItem(lines[item]);
  155. }
  156. }
  157. </script>
  158. </body>
  159. </html>