2023-12-20 15:29:24 +00:00
|
|
|
import { DockgeSocket } from "./util-server";
|
|
|
|
import { io, Socket as SocketClient } from "socket.io-client";
|
|
|
|
import { log } from "./log";
|
|
|
|
import { Agent } from "./models/agent";
|
|
|
|
import { LooseObject } from "../common/util-common";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dockge Instance Manager
|
|
|
|
*/
|
|
|
|
export class AgentManager {
|
|
|
|
|
|
|
|
protected socket : DockgeSocket;
|
|
|
|
protected instanceSocketList : Record<string, SocketClient> = {};
|
|
|
|
|
|
|
|
constructor(socket: DockgeSocket) {
|
|
|
|
this.socket = socket;
|
|
|
|
}
|
|
|
|
|
|
|
|
connect(url : string, username : string, password : string) {
|
|
|
|
let obj = new URL(url);
|
|
|
|
let endpoint = obj.host;
|
|
|
|
|
|
|
|
this.socket.emit("agentStatus", {
|
|
|
|
endpoint: endpoint,
|
|
|
|
status: "connecting",
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!endpoint) {
|
|
|
|
log.error("agent-manager", "Invalid endpoint: " + endpoint + " URL: " + url);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.instanceSocketList[endpoint]) {
|
|
|
|
log.debug("agent-manager", "Already connected to the socket server: " + endpoint);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
log.info("agent-manager", "Connecting to the socket server: " + endpoint);
|
|
|
|
let client = io(url, {
|
|
|
|
extraHeaders: {
|
|
|
|
endpoint,
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
client.on("connect", () => {
|
|
|
|
log.info("agent-manager", "Connected to the socket server: " + endpoint);
|
|
|
|
|
|
|
|
client.emit("login", {
|
|
|
|
username: username,
|
|
|
|
password: password,
|
|
|
|
}, (res) => {
|
|
|
|
if (res.ok) {
|
|
|
|
log.info("agent-manager", "Logged in to the socket server: " + endpoint);
|
|
|
|
this.socket.emit("agentStatus", {
|
|
|
|
endpoint: endpoint,
|
|
|
|
status: "online",
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
log.error("agent-manager", "Failed to login to the socket server: " + endpoint);
|
|
|
|
this.socket.emit("agentStatus", {
|
|
|
|
endpoint: endpoint,
|
|
|
|
status: "offline",
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
client.on("error", (err) => {
|
|
|
|
log.error("agent-manager", "Error from the socket server: " + endpoint);
|
|
|
|
log.error("agent-manager", err);
|
|
|
|
this.socket.emit("agentStatus", {
|
|
|
|
endpoint: endpoint,
|
|
|
|
status: "offline",
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
client.on("disconnect", () => {
|
|
|
|
log.info("agent-manager", "Disconnected from the socket server: " + endpoint);
|
|
|
|
this.socket.emit("agentStatus", {
|
|
|
|
endpoint: endpoint,
|
|
|
|
status: "offline",
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
client.on("agent", (...args : unknown[]) => {
|
|
|
|
log.debug("agent-manager", "Forward event");
|
|
|
|
this.socket.emit("agent", ...args);
|
|
|
|
});
|
|
|
|
|
|
|
|
this.instanceSocketList[endpoint] = client;
|
|
|
|
}
|
|
|
|
|
|
|
|
disconnect(endpoint : string) {
|
|
|
|
let client = this.instanceSocketList[endpoint];
|
|
|
|
client?.disconnect();
|
|
|
|
}
|
|
|
|
|
|
|
|
async connectAll() {
|
|
|
|
if (this.socket.endpoint) {
|
|
|
|
log.info("agent-manager", "This connection is connected as an agent, skip connectAll()");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let list : Record<string, Agent> = await Agent.getAgentList();
|
|
|
|
|
|
|
|
if (Object.keys(list).length !== 0) {
|
|
|
|
log.info("agent-manager", "Connecting to all instance socket server(s)...");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let endpoint in list) {
|
|
|
|
let agent = list[endpoint];
|
|
|
|
this.connect(agent.url, agent.username, agent.password);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
disconnectAll() {
|
|
|
|
for (let endpoint in this.instanceSocketList) {
|
|
|
|
this.disconnect(endpoint);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
emitToEndpoint(endpoint: string, eventName: string, ...args : unknown[]) {
|
|
|
|
log.debug("agent-manager", "Emitting event to endpoint: " + endpoint);
|
|
|
|
let client = this.instanceSocketList[endpoint];
|
|
|
|
if (!client) {
|
|
|
|
log.error("agent-manager", "Socket client not found for endpoint: " + endpoint);
|
|
|
|
throw new Error("Socket client not found for endpoint: " + endpoint);
|
|
|
|
}
|
|
|
|
client?.emit("agent", endpoint, eventName, ...args);
|
|
|
|
}
|
|
|
|
|
|
|
|
emitToAllEndpoints(eventName: string, ...args : unknown[]) {
|
|
|
|
log.debug("agent-manager", "Emitting event to all endpoints");
|
|
|
|
for (let endpoint in this.instanceSocketList) {
|
|
|
|
this.emitToEndpoint(endpoint, eventName, ...args);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async sendAgentList() {
|
|
|
|
let list = await Agent.getAgentList();
|
|
|
|
let result : Record<string, LooseObject> = {};
|
2023-12-21 12:47:47 +00:00
|
|
|
|
|
|
|
// Myself
|
|
|
|
result[""] = {
|
|
|
|
url: "",
|
|
|
|
username: "",
|
|
|
|
endpoint: "",
|
|
|
|
};
|
|
|
|
|
2023-12-20 15:29:24 +00:00
|
|
|
for (let endpoint in list) {
|
|
|
|
let agent = list[endpoint];
|
|
|
|
result[endpoint] = agent.toJSON();
|
|
|
|
}
|
2023-12-21 12:47:47 +00:00
|
|
|
|
2023-12-20 15:29:24 +00:00
|
|
|
this.socket.emit("agentList", {
|
|
|
|
ok: true,
|
|
|
|
agentList: result,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|