Skip to content

Commit df88084

Browse files
authored
Merge pull request #391 from eyerrock/list-containers-with-unexposed-ports
list containers with unexposed ports
2 parents 74017ba + 4774299 commit df88084

File tree

1 file changed

+84
-51
lines changed

1 file changed

+84
-51
lines changed

src/web/snippet/dockerContainersList.html

+84-51
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,27 @@
22
<html>
33
<head>
44
<!-- Notes: This should be open in its original path-->
5-
<meta charset="utf-8">
5+
<meta charset="utf-8" />
66
<link rel="stylesheet" href="../script/semantic/semantic.min.css" />
77
<script src="../script/jquery-3.6.0.min.js"></script>
88
<script src="../script/semantic/semantic.min.js"></script>
99
</head>
1010
<body>
1111
<br />
1212
<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>
1326
<div class="ui header">
1427
<div class="content">
1528
List of Docker Containers
@@ -33,56 +46,70 @@
3346
</div>
3447

3548
<script>
36-
const lines = {};
37-
const linesAded = {};
49+
let lines = {};
50+
let linesAdded = {};
51+
52+
document
53+
.getElementById("showUnexposed")
54+
.addEventListener("change", () => {
55+
console.log("showUnexposed", $("#showUnexposed").is(":checked"));
56+
$("#containersList").html('<div class="ui loader active"></div>');
57+
58+
$("#containersAddedList").empty();
59+
$("#containersAddedListHeader").attr("hidden", true);
60+
61+
lines = {};
62+
linesAdded = {};
63+
64+
getDockerContainers();
65+
});
3866

3967
function getDockerContainers() {
4068
const hostRequest = $.get("/api/proxy/list?type=host");
4169
const dockerRequest = $.get("/api/docker/containers");
4270

43-
// Wait for both requests to complete
4471
Promise.all([hostRequest, dockerRequest])
4572
.then(([hostData, dockerData]) => {
46-
if (
47-
dockerData.error === undefined &&
48-
hostData.error === undefined
49-
) {
73+
if (!dockerData.error && !hostData.error) {
5074
const { containers, network } = dockerData;
51-
const bridge = network.find(({ Name }) => Name === "bridge");
52-
const {
53-
IPAM: {
54-
Config: [{ Gateway: gateway }],
55-
},
56-
} = bridge;
57-
const existedDomains = hostData.reduce((acc, { ActiveOrigins }) => {
58-
return acc.concat(ActiveOrigins.map(({ OriginIpOrDomain }) => OriginIpOrDomain));
59-
}, []);
75+
76+
const existingTargets = new Set(
77+
hostData.flatMap(({ ActiveOrigins }) =>
78+
ActiveOrigins.map(({ OriginIpOrDomain }) => OriginIpOrDomain)
79+
)
80+
);
6081

6182
for (const container of containers) {
62-
const {
63-
Ports,
64-
Names: [name],
65-
} = container;
66-
67-
for (const portObject of Ports.filter(
68-
({ IP: ip }) => ip === "::" || ip === '0.0.0.0'
69-
)) {
70-
const { IP: ip, PublicPort: port } = portObject;
83+
const Ports = container.Ports;
84+
const name = container.Names[0].replace(/^\//, "");
85+
86+
for (const portObject of Ports) {
87+
let port = portObject.PublicPort;
88+
if (!port) {
89+
if (!$("#showUnexposed").is(":checked")) {
90+
continue;
91+
}
92+
port = portObject.PrivatePort;
93+
}
7194
const key = `${name}-${port}`;
7295

96+
// if port is not exposed, use container's name and let docker handle the routing
97+
// BUT this will only work if the container is on the same network as Zoraxy
98+
const targetAddress = portObject.IP || name;
99+
73100
if (
74-
existedDomains.some((item) => item === `${gateway}:${port}`) &&
75-
!linesAded[key]
101+
existingTargets.has(`${targetAddress}:${port}`) &&
102+
!linesAdded[key]
76103
) {
77-
linesAded[key] = {
78-
name: name.replace(/^\//, ""),
79-
ip: gateway,
104+
linesAdded[key] = {
105+
name,
106+
ip: targetAddress,
80107
port,
81108
};
82109
} else if (!lines[key]) {
83110
lines[key] = {
84-
name: name.replace(/^\//, ""),
85-
ip: gateway,
111+
name,
112+
ip: targetAddress,
86113
port,
87114
};
88115
}
@@ -92,37 +119,43 @@
92119
for (const [key, line] of Object.entries(lines)) {
93120
$("#containersList").append(
94121
`<div class="item">
95-
<div class="right floated content">
96-
<div class="ui button" onclick="addContainerItem('${key}');">Add</div>
97-
</div>
98-
<div class="content">
99-
<div class="header">${line.name}</div>
100-
<div class="description">
101-
${line.ip}:${line.port}
102-
</div>
103-
</div>`
122+
<div class="right floated content">
123+
<div class="ui button" onclick="addContainerItem('${key}');">Add</div>
124+
</div>
125+
<div class="content">
126+
<div class="header">${line.name}</div>
127+
<div class="description">
128+
${line.ip}:${line.port}
129+
</div>
130+
</div>`
104131
);
105132
}
106-
for (const [key, line] of Object.entries(linesAded)) {
133+
134+
for (const [key, line] of Object.entries(linesAdded)) {
107135
$("#containersAddedList").append(
108136
`<div class="item">
109-
<div class="content">
110-
<div class="header">${line.name}</div>
111-
<div class="description">
112-
${line.ip}:${line.port}
113-
</div>
114-
</div>`
137+
<div class="content">
138+
<div class="header">${line.name}</div>
139+
<div class="description">
140+
${line.ip}:${line.port}
141+
</div>
142+
</div>`
115143
);
116144
}
117-
Object.entries(linesAded).length &&
145+
146+
Object.entries(linesAdded).length &&
118147
$("#containersAddedListHeader").removeAttr("hidden");
119148
$("#containersList .loader").removeClass("active");
120149
} else {
121150
parent.msgbox(
122151
`Error loading data: ${dockerData.error || hostData.error}`,
123152
false
124153
);
125-
$("#containersList").html(`<div class="ui basic segment"><i class="ui red times icon"></i> ${dockerData.error || hostData.error}</div>`);
154+
$("#containersList").html(
155+
`<div class="ui basic segment"><i class="ui red times icon"></i> ${
156+
dockerData.error || hostData.error
157+
}</div>`
158+
);
126159
}
127160
})
128161
.catch((error) => {

0 commit comments

Comments
 (0)