Docker Hosts are now a table & have their own dialog

This commit is contained in:
c0derMo
2022-07-22 15:47:04 +00:00
parent ac449ec1c2
commit 0d098b0958
10 changed files with 385 additions and 31 deletions

View File

@@ -122,10 +122,30 @@ async function sendInfo(socket) {
});
}
async function sendDockerHostList(socket) {
const timeLogger = new TimeLogger();
let result = [];
let list = await R.find("docker_host", " user_id = ? ", [
socket.userID,
]);
for (let bean of list) {
result.push(bean.export());
}
io.to(socket.userID).emit("dockerHostList", result);
timeLogger.print("Send Docker Host List");
return list;
}
module.exports = {
sendNotificationList,
sendImportantHeartbeatList,
sendHeartbeatList,
sendProxyList,
sendInfo,
sendDockerHostList
};

67
server/docker.js Normal file
View File

@@ -0,0 +1,67 @@
const axios = require("axios");
const { R } = require("redbean-node");
const version = require("../package.json").version;
const https = require("https");
class DockerHost {
static async save(dockerHost, dockerHostID, userID) {
let bean;
if (dockerHostID) {
bean = await R.findOne("docker_host", " id = ? AND user_id = ? ", [ dockerHostID, userID ]);
if (!bean) {
throw new Error("docker host not found");
}
} else {
bean = R.dispense("docker_host");
}
bean.user_id = userID;
bean.docker_daemon = dockerHost.docker_daemon;
bean.docker_type = dockerHost.docker_type;
bean.name = dockerHost.name;
await R.store(bean);
return bean;
}
static async delete(dockerHostID, userID) {
let bean = await R.findOne("docker_host", " id = ? AND user_id = ? ", [ dockerHostID, userID ]);
if (!bean) {
throw new Error("docker host not found");
}
await R.trash(bean);
}
static async getAmountContainer(dockerHost) {
const options = {
url: "/containers/json?all=true",
headers: {
"Accept": "*/*",
"User-Agent": "Uptime-Kuma/" + version
},
httpsAgent: new https.Agent({
maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
rejectUnauthorized: false,
}),
};
if (dockerHost.docker_type === "socket") {
options.socketPath = dockerHost.docker_daemon;
} else if (dockerHost.docker_type === "tcp") {
options.baseURL = dockerHost.docker_daemon;
}
let res = await axios.request(options);
return res.data.length;
}
}
module.exports = {
DockerHost,
}

View File

@@ -0,0 +1,19 @@
const { BeanModel } = require("redbean-node/dist/bean-model");
class DockerHost extends BeanModel {
/**
* Returns an object that ready to parse to JSON
* @returns {Object}
*/
toJSON() {
return {
id: this._id,
userId: this._user_id,
daemon: this._dockerDaemon,
type: this._dockerType,
name: this._name,
}
}
}
module.exports = DockerHost;

View File

@@ -89,8 +89,7 @@ class Monitor extends BeanModel {
dns_last_result: this.dns_last_result,
pushToken: this.pushToken,
docker_container: this.docker_container,
docker_daemon: this.docker_daemon,
docker_type: this.docker_type,
docker_host: this.docker_host,
proxyId: this.proxy_id,
notificationIDList,
tags: tags,
@@ -471,6 +470,8 @@ class Monitor extends BeanModel {
} else if (this.type === "docker") {
log.debug(`[${this.name}] Prepare Options for Axios`);
const docker_host = await R.load("docker_host", this.docker_host);
const options = {
url: `/containers/${this.docker_container}/json`,
headers: {
@@ -483,10 +484,10 @@ class Monitor extends BeanModel {
}),
};
if (this.docker_type === "socket") {
options.socketPath = this.docker_daemon;
} else if (this.docker_type === "tcp") {
options.baseURL = this.docker_daemon;
if (docker_host._dockerType === "socket") {
options.socketPath = docker_host._dockerDaemon;
} else if (docker_host._dockerType === "tcp") {
options.baseURL = docker_host._dockerDaemon;
}
log.debug(`[${this.name}] Axios Request`);

View File

@@ -118,13 +118,14 @@ if (config.demoMode) {
}
// Must be after io instantiation
const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sendInfo, sendProxyList } = require("./client");
const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sendInfo, sendProxyList, sendDockerHostList } = require("./client");
const { statusPageSocketHandler } = require("./socket-handlers/status-page-socket-handler");
const databaseSocketHandler = require("./socket-handlers/database-socket-handler");
const TwoFA = require("./2fa");
const StatusPage = require("./model/status_page");
const { cloudflaredSocketHandler, autoStart: cloudflaredAutoStart, stop: cloudflaredStop } = require("./socket-handlers/cloudflared-socket-handler");
const { proxySocketHandler } = require("./socket-handlers/proxy-socket-handler");
const { dockerSocketHandler } = require("./socket-handlers/docker-socket-handler");
app.use(express.json());
@@ -665,8 +666,7 @@ let needSetup = false;
bean.dns_resolve_server = monitor.dns_resolve_server;
bean.pushToken = monitor.pushToken;
bean.docker_container = monitor.docker_container;
bean.docker_daemon = monitor.docker_daemon;
bean.docker_type = monitor.docker_type;
bean.docker_host = monitor.docker_host;
bean.proxyId = Number.isInteger(monitor.proxyId) ? monitor.proxyId : null;
bean.mqttUsername = monitor.mqttUsername;
bean.mqttPassword = monitor.mqttPassword;
@@ -1425,6 +1425,7 @@ let needSetup = false;
cloudflaredSocketHandler(socket);
databaseSocketHandler(socket);
proxySocketHandler(socket);
dockerSocketHandler(socket);
log.debug("server", "added all socket handlers");
@@ -1525,6 +1526,7 @@ async function afterLogin(socket, user) {
let monitorList = await server.sendMonitorList(socket);
sendNotificationList(socket);
sendProxyList(socket);
sendDockerHostList(socket);
await sleep(500);

View File

@@ -0,0 +1,67 @@
const { sendDockerHostList } = require("../client");
const { checkLogin } = require("../util-server");
const { DockerHost } = require("../docker");
module.exports.dockerSocketHandler = (socket) => {
socket.on("addDockerHost", async (dockerHost, dockerHostID, callback) => {
try {
checkLogin(socket);
let dockerHostBean = await DockerHost.save(dockerHost, dockerHostID, socket.userID);
await sendDockerHostList(socket);
callback({
ok: true,
msg: "Saved",
id: dockerHostBean.id,
});
} catch (e) {
callback({
ok: false,
msg: e.message,
})
}
});
socket.on("deleteDockerHost", async (dockerHostID, callback) => {
try {
checkLogin(socket);
await DockerHost.delete(dockerHostID, socket.userID);
await sendDockerHostList(socket);
callback({
ok: true,
msg: "Deleted",
});
} catch (e) {
callback({
ok: false,
msg: e.message,
})
}
});
socket.on("testDockerHost", async (dockerHost, callback) => {
try {
checkLogin(socket);
let amount = await DockerHost.getAmountContainer(dockerHost);
callback({
ok: true,
msg: "Amount of containers: " + amount,
});
} catch (e) {
console.error(e);
callback({
ok: false,
msg: e.message,
})
}
})
}