telegram-ssh-bot 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +103 -22
- package/deploy/.env.example +86 -0
- package/dist/config/index.d.ts +68 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +315 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +6 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +50 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/Bot.d.ts +91 -0
- package/dist/core/Bot.d.ts.map +1 -0
- package/dist/core/Bot.js +263 -0
- package/dist/core/Bot.js.map +1 -0
- package/dist/core/ConnectionPool.d.ts +125 -0
- package/dist/core/ConnectionPool.d.ts.map +1 -0
- package/dist/core/ConnectionPool.js +397 -0
- package/dist/core/ConnectionPool.js.map +1 -0
- package/dist/core/SSHClient.d.ts +112 -0
- package/dist/core/SSHClient.d.ts.map +1 -0
- package/dist/core/SSHClient.js +367 -0
- package/dist/core/SSHClient.js.map +1 -0
- package/dist/core/ServerManager.d.ts +80 -0
- package/dist/core/ServerManager.d.ts.map +1 -0
- package/dist/core/ServerManager.js +207 -0
- package/dist/core/ServerManager.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +1 -0
- package/dist/errors/AuthError.d.ts +30 -0
- package/dist/errors/AuthError.d.ts.map +1 -0
- package/dist/errors/AuthError.js +35 -0
- package/dist/errors/AuthError.js.map +1 -0
- package/dist/errors/BaseError.d.ts +17 -0
- package/dist/errors/BaseError.d.ts.map +1 -0
- package/dist/errors/BaseError.js +34 -0
- package/dist/errors/BaseError.js.map +1 -0
- package/dist/errors/ConfigurationError.d.ts +24 -0
- package/dist/errors/ConfigurationError.d.ts.map +1 -0
- package/dist/errors/ConfigurationError.js +24 -0
- package/dist/errors/ConfigurationError.js.map +1 -0
- package/dist/errors/PoolError.d.ts +21 -0
- package/dist/errors/PoolError.d.ts.map +1 -0
- package/dist/errors/PoolError.js +30 -0
- package/dist/errors/PoolError.js.map +1 -0
- package/dist/errors/SSHError.d.ts +24 -0
- package/dist/errors/SSHError.d.ts.map +1 -0
- package/dist/errors/SSHError.js +38 -0
- package/dist/errors/SSHError.js.map +1 -0
- package/dist/errors/StorageError.d.ts +24 -0
- package/dist/errors/StorageError.d.ts.map +1 -0
- package/dist/errors/StorageError.js +35 -0
- package/dist/errors/StorageError.js.map +1 -0
- package/dist/errors/ValidationError.d.ts +29 -0
- package/dist/errors/ValidationError.d.ts.map +1 -0
- package/dist/errors/ValidationError.js +35 -0
- package/dist/errors/ValidationError.js.map +1 -0
- package/dist/errors/index.d.ts +11 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +18 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/handlers/BaseHandler.d.ts +50 -0
- package/dist/handlers/BaseHandler.d.ts.map +1 -0
- package/dist/handlers/BaseHandler.js +87 -0
- package/dist/handlers/BaseHandler.js.map +1 -0
- package/dist/handlers/CommandHandler.d.ts +23 -0
- package/dist/handlers/CommandHandler.d.ts.map +1 -0
- package/dist/handlers/CommandHandler.js +99 -0
- package/dist/handlers/CommandHandler.js.map +1 -0
- package/dist/handlers/HealthHandler.d.ts +25 -0
- package/dist/handlers/HealthHandler.d.ts.map +1 -0
- package/dist/handlers/HealthHandler.js +51 -0
- package/dist/handlers/HealthHandler.js.map +1 -0
- package/dist/handlers/HelpHandler.d.ts +32 -0
- package/dist/handlers/HelpHandler.d.ts.map +1 -0
- package/dist/handlers/HelpHandler.js +76 -0
- package/dist/handlers/HelpHandler.js.map +1 -0
- package/dist/handlers/ServerHandler.d.ts +72 -0
- package/dist/handlers/ServerHandler.d.ts.map +1 -0
- package/dist/handlers/ServerHandler.js +272 -0
- package/dist/handlers/ServerHandler.js.map +1 -0
- package/dist/handlers/index.d.ts +9 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +9 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +348 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/AuthMiddleware.d.ts +28 -0
- package/dist/middleware/AuthMiddleware.d.ts.map +1 -0
- package/dist/middleware/AuthMiddleware.js +49 -0
- package/dist/middleware/AuthMiddleware.js.map +1 -0
- package/dist/middleware/RateLimitMiddleware.d.ts +23 -0
- package/dist/middleware/RateLimitMiddleware.d.ts.map +1 -0
- package/dist/middleware/RateLimitMiddleware.js +34 -0
- package/dist/middleware/RateLimitMiddleware.js.map +1 -0
- package/dist/middleware/index.d.ts +6 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +6 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/services/BackupService.d.ts +119 -0
- package/dist/services/BackupService.d.ts.map +1 -0
- package/dist/services/BackupService.js +313 -0
- package/dist/services/BackupService.js.map +1 -0
- package/dist/services/CryptoService.d.ts +37 -0
- package/dist/services/CryptoService.d.ts.map +1 -0
- package/dist/services/CryptoService.js +108 -0
- package/dist/services/CryptoService.js.map +1 -0
- package/dist/services/HealthService.d.ts +126 -0
- package/dist/services/HealthService.d.ts.map +1 -0
- package/dist/services/HealthService.js +213 -0
- package/dist/services/HealthService.js.map +1 -0
- package/dist/services/LoggingService.d.ts +115 -0
- package/dist/services/LoggingService.d.ts.map +1 -0
- package/dist/services/LoggingService.js +334 -0
- package/dist/services/LoggingService.js.map +1 -0
- package/dist/services/MonitoringService.d.ts +119 -0
- package/dist/services/MonitoringService.d.ts.map +1 -0
- package/dist/services/MonitoringService.js +267 -0
- package/dist/services/MonitoringService.js.map +1 -0
- package/dist/services/NotificationService.d.ts +132 -0
- package/dist/services/NotificationService.d.ts.map +1 -0
- package/dist/services/NotificationService.js +297 -0
- package/dist/services/NotificationService.js.map +1 -0
- package/dist/services/RateLimiter.d.ts +51 -0
- package/dist/services/RateLimiter.d.ts.map +1 -0
- package/dist/services/RateLimiter.js +141 -0
- package/dist/services/RateLimiter.js.map +1 -0
- package/dist/services/ValidationService.d.ts +49 -0
- package/dist/services/ValidationService.d.ts.map +1 -0
- package/dist/services/ValidationService.js +158 -0
- package/dist/services/ValidationService.js.map +1 -0
- package/dist/services/index.d.ts +12 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +12 -0
- package/dist/services/index.js.map +1 -0
- package/dist/types/Bot.d.ts +63 -0
- package/dist/types/Bot.d.ts.map +1 -0
- package/dist/types/Bot.js +5 -0
- package/dist/types/Bot.js.map +1 -0
- package/dist/types/Config.d.ts +57 -0
- package/dist/types/Config.d.ts.map +1 -0
- package/dist/types/Config.js +5 -0
- package/dist/types/Config.js.map +1 -0
- package/dist/types/Errors.d.ts +37 -0
- package/dist/types/Errors.d.ts.map +1 -0
- package/dist/types/Errors.js +34 -0
- package/dist/types/Errors.js.map +1 -0
- package/dist/types/SSH.d.ts +56 -0
- package/dist/types/SSH.d.ts.map +1 -0
- package/dist/types/SSH.js +6 -0
- package/dist/types/SSH.js.map +1 -0
- package/dist/types/Server.d.ts +39 -0
- package/dist/types/Server.d.ts.map +1 -0
- package/dist/types/Server.js +5 -0
- package/dist/types/Server.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/commandUtils.d.ts +25 -0
- package/dist/utils/commandUtils.d.ts.map +1 -0
- package/dist/utils/commandUtils.js +94 -0
- package/dist/utils/commandUtils.js.map +1 -0
- package/dist/utils/fileUtils.d.ts +40 -0
- package/dist/utils/fileUtils.d.ts.map +1 -0
- package/dist/utils/fileUtils.js +114 -0
- package/dist/utils/fileUtils.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/pathUtils.d.ts +40 -0
- package/dist/utils/pathUtils.d.ts.map +1 -0
- package/dist/utils/pathUtils.js +140 -0
- package/dist/utils/pathUtils.js.map +1 -0
- package/package.json +31 -5
- package/scripts/build.sh +20 -0
- package/scripts/postinstall.js +87 -0
- package/scripts/release.sh +22 -0
- package/scripts/setup-env.js +237 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection Pool
|
|
3
|
+
* Manages multiple SSH connections with pooling, timeout, and health monitoring
|
|
4
|
+
*/
|
|
5
|
+
import { EventEmitter } from "events";
|
|
6
|
+
import { ConnectionFailedError, ConnectionTimeoutError, PoolExhaustedError, } from "../errors/index.js";
|
|
7
|
+
import { SSHClient } from "./SSHClient.js";
|
|
8
|
+
/**
|
|
9
|
+
* Connection pool for managing multiple SSH connections
|
|
10
|
+
*/
|
|
11
|
+
export class ConnectionPool extends EventEmitter {
|
|
12
|
+
connections = new Map();
|
|
13
|
+
waitingQueue = [];
|
|
14
|
+
options;
|
|
15
|
+
logger;
|
|
16
|
+
healthCheckTimer = null;
|
|
17
|
+
idleCheckTimer = null;
|
|
18
|
+
totalRequestsServed = 0;
|
|
19
|
+
isDraining = false;
|
|
20
|
+
constructor(options, logger) {
|
|
21
|
+
super();
|
|
22
|
+
this.options = {
|
|
23
|
+
maxConnections: options.maxConnections ?? 10,
|
|
24
|
+
connectionTimeout: options.connectionTimeout ?? 30000,
|
|
25
|
+
commandTimeout: options.commandTimeout ?? 60000,
|
|
26
|
+
idleTimeout: options.idleTimeout ?? 300000, // 5 minutes
|
|
27
|
+
healthCheckInterval: options.healthCheckInterval ?? 60000, // 1 minute
|
|
28
|
+
maxHealthCheckFailures: options.maxHealthCheckFailures ?? 3,
|
|
29
|
+
};
|
|
30
|
+
this.logger = logger;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Initialize the connection pool
|
|
34
|
+
*/
|
|
35
|
+
async initialize() {
|
|
36
|
+
this.startHealthCheck();
|
|
37
|
+
this.startIdleCheck();
|
|
38
|
+
this.logger.info("Connection pool initialized", {
|
|
39
|
+
maxConnections: this.options.maxConnections,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Acquire a connection from the pool
|
|
44
|
+
*/
|
|
45
|
+
async acquire(serverId, config) {
|
|
46
|
+
if (this.isDraining) {
|
|
47
|
+
throw new Error("Connection pool is draining");
|
|
48
|
+
}
|
|
49
|
+
// Check for existing idle connection
|
|
50
|
+
const existingConn = this.findIdleConnection(serverId);
|
|
51
|
+
if (existingConn) {
|
|
52
|
+
existingConn.inUse = true;
|
|
53
|
+
existingConn.lastUsedAt = new Date();
|
|
54
|
+
this.totalRequestsServed++;
|
|
55
|
+
this.logger.debug("Reusing existing connection", {
|
|
56
|
+
serverId,
|
|
57
|
+
connectionId: existingConn.id,
|
|
58
|
+
});
|
|
59
|
+
return existingConn;
|
|
60
|
+
}
|
|
61
|
+
// Check if we can create a new connection
|
|
62
|
+
if (this.connections.size < this.options.maxConnections) {
|
|
63
|
+
return this.createConnection(serverId, config);
|
|
64
|
+
}
|
|
65
|
+
// Wait for a connection to become available
|
|
66
|
+
return this.waitForConnection(serverId, config);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Release a connection back to the pool
|
|
70
|
+
*/
|
|
71
|
+
release(connection) {
|
|
72
|
+
const pooled = this.connections.get(connection.id);
|
|
73
|
+
if (!pooled) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
pooled.inUse = false;
|
|
77
|
+
pooled.lastUsedAt = new Date();
|
|
78
|
+
// Process waiting queue
|
|
79
|
+
this.processWaitingQueue();
|
|
80
|
+
this.logger.debug("Connection released", {
|
|
81
|
+
connectionId: connection.id,
|
|
82
|
+
serverId: connection.serverId,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Remove a connection from the pool
|
|
87
|
+
*/
|
|
88
|
+
async remove(connectionId) {
|
|
89
|
+
const connection = this.connections.get(connectionId);
|
|
90
|
+
if (!connection) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
await connection.client.disconnect();
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
this.logger.warn("Error disconnecting during removal", {
|
|
98
|
+
connectionId,
|
|
99
|
+
error: error instanceof Error ? error.message : String(error),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
this.connections.delete(connectionId);
|
|
103
|
+
this.emit("connectionRemoved", connectionId);
|
|
104
|
+
this.logger.info("Connection removed from pool", { connectionId });
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Drain all connections and shutdown pool
|
|
108
|
+
*/
|
|
109
|
+
async drain() {
|
|
110
|
+
this.isDraining = true;
|
|
111
|
+
// Stop timers
|
|
112
|
+
if (this.healthCheckTimer) {
|
|
113
|
+
clearInterval(this.healthCheckTimer);
|
|
114
|
+
this.healthCheckTimer = null;
|
|
115
|
+
}
|
|
116
|
+
if (this.idleCheckTimer) {
|
|
117
|
+
clearInterval(this.idleCheckTimer);
|
|
118
|
+
this.idleCheckTimer = null;
|
|
119
|
+
}
|
|
120
|
+
// Reject all waiting requests
|
|
121
|
+
for (const request of this.waitingQueue) {
|
|
122
|
+
clearTimeout(request.timeoutId);
|
|
123
|
+
request.reject(new Error("Connection pool is draining"));
|
|
124
|
+
}
|
|
125
|
+
this.waitingQueue.length = 0;
|
|
126
|
+
// Close all connections
|
|
127
|
+
const closePromises = Array.from(this.connections.values()).map(async (conn) => {
|
|
128
|
+
try {
|
|
129
|
+
await conn.client.disconnect();
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
this.logger.warn("Error disconnecting during drain", {
|
|
133
|
+
connectionId: conn.id,
|
|
134
|
+
error: error instanceof Error ? error.message : String(error),
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
await Promise.allSettled(closePromises);
|
|
139
|
+
this.connections.clear();
|
|
140
|
+
this.logger.info("Connection pool drained");
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get pool statistics
|
|
144
|
+
*/
|
|
145
|
+
getStats() {
|
|
146
|
+
let activeConnections = 0;
|
|
147
|
+
let idleConnections = 0;
|
|
148
|
+
for (const conn of this.connections.values()) {
|
|
149
|
+
if (conn.inUse) {
|
|
150
|
+
activeConnections++;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
idleConnections++;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
totalConnections: this.connections.size,
|
|
158
|
+
activeConnections,
|
|
159
|
+
idleConnections,
|
|
160
|
+
waitingRequests: this.waitingQueue.length,
|
|
161
|
+
totalRequestsServed: this.totalRequestsServed,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get active connection count
|
|
166
|
+
*/
|
|
167
|
+
getActiveCount() {
|
|
168
|
+
let count = 0;
|
|
169
|
+
for (const conn of this.connections.values()) {
|
|
170
|
+
if (conn.inUse) {
|
|
171
|
+
count++;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return count;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Execute a command on a pooled connection
|
|
178
|
+
*/
|
|
179
|
+
async executeCommand(serverId, config, command) {
|
|
180
|
+
const connection = await this.acquire(serverId, config);
|
|
181
|
+
try {
|
|
182
|
+
const result = await connection.client.execute(command);
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
this.release(connection);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Find an idle connection for the given server
|
|
191
|
+
*/
|
|
192
|
+
findIdleConnection(serverId) {
|
|
193
|
+
for (const conn of this.connections.values()) {
|
|
194
|
+
if (conn.serverId === serverId && !conn.inUse) {
|
|
195
|
+
return conn;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Create a new connection
|
|
202
|
+
*/
|
|
203
|
+
async createConnection(serverId, config) {
|
|
204
|
+
const connectionId = this.generateConnectionId();
|
|
205
|
+
const client = new SSHClient({
|
|
206
|
+
connectionTimeout: this.options.connectionTimeout,
|
|
207
|
+
commandTimeout: this.options.commandTimeout,
|
|
208
|
+
});
|
|
209
|
+
try {
|
|
210
|
+
await client.connect(config);
|
|
211
|
+
client.setServerId(serverId);
|
|
212
|
+
const pooled = {
|
|
213
|
+
id: connectionId,
|
|
214
|
+
serverId,
|
|
215
|
+
client,
|
|
216
|
+
createdAt: new Date(),
|
|
217
|
+
lastUsedAt: new Date(),
|
|
218
|
+
inUse: true,
|
|
219
|
+
healthCheckFailures: 0,
|
|
220
|
+
};
|
|
221
|
+
this.connections.set(connectionId, pooled);
|
|
222
|
+
this.totalRequestsServed++;
|
|
223
|
+
this.logger.info("New connection created", {
|
|
224
|
+
connectionId,
|
|
225
|
+
serverId,
|
|
226
|
+
totalConnections: this.connections.size,
|
|
227
|
+
});
|
|
228
|
+
this.emit("connectionCreated", connectionId, serverId);
|
|
229
|
+
return pooled;
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
if (error instanceof ConnectionTimeoutError) {
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
throw new ConnectionFailedError(config.host, error instanceof Error ? error : new Error(String(error)));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Wait for a connection to become available
|
|
240
|
+
*/
|
|
241
|
+
waitForConnection(serverId, config) {
|
|
242
|
+
return new Promise((resolve, reject) => {
|
|
243
|
+
let request;
|
|
244
|
+
let handled = false;
|
|
245
|
+
const timeoutId = setTimeout(() => {
|
|
246
|
+
// Ensure we only handle the timeout once
|
|
247
|
+
if (handled) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
handled = true;
|
|
251
|
+
// Find and remove the request from the queue
|
|
252
|
+
const index = this.waitingQueue.findIndex((r) => r.serverId === serverId && r.createdAt === request.createdAt);
|
|
253
|
+
if (index !== -1) {
|
|
254
|
+
this.waitingQueue.splice(index, 1);
|
|
255
|
+
}
|
|
256
|
+
this.logger.debug("Connection request timed out", {
|
|
257
|
+
serverId,
|
|
258
|
+
queueLength: this.waitingQueue.length,
|
|
259
|
+
});
|
|
260
|
+
reject(new PoolExhaustedError(this.options.maxConnections, this.options.connectionTimeout));
|
|
261
|
+
}, this.options.connectionTimeout);
|
|
262
|
+
// Create the request object
|
|
263
|
+
request = {
|
|
264
|
+
serverId,
|
|
265
|
+
config,
|
|
266
|
+
resolve: (conn) => {
|
|
267
|
+
if (handled)
|
|
268
|
+
return;
|
|
269
|
+
handled = true;
|
|
270
|
+
clearTimeout(timeoutId);
|
|
271
|
+
resolve(conn);
|
|
272
|
+
},
|
|
273
|
+
reject: (error) => {
|
|
274
|
+
if (handled)
|
|
275
|
+
return;
|
|
276
|
+
handled = true;
|
|
277
|
+
clearTimeout(timeoutId);
|
|
278
|
+
reject(error);
|
|
279
|
+
},
|
|
280
|
+
timeoutId,
|
|
281
|
+
createdAt: new Date(),
|
|
282
|
+
};
|
|
283
|
+
this.waitingQueue.push(request);
|
|
284
|
+
this.logger.debug("Connection request queued", {
|
|
285
|
+
serverId,
|
|
286
|
+
queueLength: this.waitingQueue.length,
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Process waiting queue when connections become available
|
|
292
|
+
*/
|
|
293
|
+
processWaitingQueue() {
|
|
294
|
+
if (this.waitingQueue.length === 0) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
// Find a request that can be served
|
|
298
|
+
for (let i = 0; i < this.waitingQueue.length; i++) {
|
|
299
|
+
const request = this.waitingQueue[i];
|
|
300
|
+
if (!request)
|
|
301
|
+
continue;
|
|
302
|
+
// Check for idle connection
|
|
303
|
+
const idleConn = this.findIdleConnection(request.serverId);
|
|
304
|
+
if (idleConn) {
|
|
305
|
+
this.waitingQueue.splice(i, 1);
|
|
306
|
+
clearTimeout(request.timeoutId);
|
|
307
|
+
idleConn.inUse = true;
|
|
308
|
+
idleConn.lastUsedAt = new Date();
|
|
309
|
+
this.totalRequestsServed++;
|
|
310
|
+
request.resolve(idleConn);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
// Create new connection if possible
|
|
314
|
+
if (this.connections.size < this.options.maxConnections) {
|
|
315
|
+
this.waitingQueue.splice(i, 1);
|
|
316
|
+
clearTimeout(request.timeoutId);
|
|
317
|
+
this.createConnection(request.serverId, request.config)
|
|
318
|
+
.then(request.resolve)
|
|
319
|
+
.catch(request.reject);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Start health check timer
|
|
326
|
+
*/
|
|
327
|
+
startHealthCheck() {
|
|
328
|
+
this.healthCheckTimer = setInterval(() => {
|
|
329
|
+
this.performHealthCheck();
|
|
330
|
+
}, this.options.healthCheckInterval);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Perform health check on all connections
|
|
334
|
+
*/
|
|
335
|
+
async performHealthCheck() {
|
|
336
|
+
for (const conn of this.connections.values()) {
|
|
337
|
+
if (conn.inUse) {
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
try {
|
|
341
|
+
// Simple health check - execute echo command
|
|
342
|
+
await conn.client.execute("echo 'health_check'");
|
|
343
|
+
conn.healthCheckFailures = 0;
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
conn.healthCheckFailures++;
|
|
347
|
+
this.logger.warn("Connection health check failed", {
|
|
348
|
+
connectionId: conn.id,
|
|
349
|
+
serverId: conn.serverId,
|
|
350
|
+
failures: conn.healthCheckFailures,
|
|
351
|
+
});
|
|
352
|
+
if (conn.healthCheckFailures >= this.options.maxHealthCheckFailures) {
|
|
353
|
+
this.logger.error("Connection removed due to health check failures", undefined, {
|
|
354
|
+
connectionId: conn.id,
|
|
355
|
+
serverId: conn.serverId,
|
|
356
|
+
});
|
|
357
|
+
await this.remove(conn.id);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Start idle connection check timer
|
|
364
|
+
*/
|
|
365
|
+
startIdleCheck() {
|
|
366
|
+
this.idleCheckTimer = setInterval(() => {
|
|
367
|
+
this.removeIdleConnections();
|
|
368
|
+
}, 60000); // Check every minute
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Remove idle connections that have exceeded idle timeout
|
|
372
|
+
*/
|
|
373
|
+
async removeIdleConnections() {
|
|
374
|
+
const now = Date.now();
|
|
375
|
+
for (const conn of this.connections.values()) {
|
|
376
|
+
if (conn.inUse) {
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
const idleTime = now - conn.lastUsedAt.getTime();
|
|
380
|
+
if (idleTime > this.options.idleTimeout) {
|
|
381
|
+
this.logger.info("Removing idle connection", {
|
|
382
|
+
connectionId: conn.id,
|
|
383
|
+
serverId: conn.serverId,
|
|
384
|
+
idleTime: Math.floor(idleTime / 1000),
|
|
385
|
+
});
|
|
386
|
+
await this.remove(conn.id);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Generate unique connection ID
|
|
392
|
+
*/
|
|
393
|
+
generateConnectionId() {
|
|
394
|
+
return `conn_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
//# sourceMappingURL=ConnectionPool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConnectionPool.js","sourceRoot":"","sources":["../../src/core/ConnectionPool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH Client
|
|
3
|
+
* Provides SSH connection management and command execution with timeout and cancellation support
|
|
4
|
+
*/
|
|
5
|
+
import type { CommandResult, ISSHClient, SSHConnectionConfig, SSHConnectionState } from "../types/index.js";
|
|
6
|
+
/**
|
|
7
|
+
* Cancellation token for aborting operations
|
|
8
|
+
*/
|
|
9
|
+
export declare class CancellationToken {
|
|
10
|
+
private cancelled;
|
|
11
|
+
private readonly listeners;
|
|
12
|
+
/**
|
|
13
|
+
* Check if cancellation has been requested
|
|
14
|
+
*/
|
|
15
|
+
get isCancelled(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Request cancellation
|
|
18
|
+
*/
|
|
19
|
+
cancel(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Register a callback for cancellation
|
|
22
|
+
*/
|
|
23
|
+
onCancel(callback: () => void): void;
|
|
24
|
+
/**
|
|
25
|
+
* Throw if cancelled
|
|
26
|
+
*/
|
|
27
|
+
throwIfCancelled(): void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Cancellation token source for creating tokens
|
|
31
|
+
*/
|
|
32
|
+
export declare class CancellationTokenSource {
|
|
33
|
+
readonly token: CancellationToken;
|
|
34
|
+
constructor();
|
|
35
|
+
/**
|
|
36
|
+
* Cancel the operation
|
|
37
|
+
*/
|
|
38
|
+
cancel(): void;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Execute options for command execution
|
|
42
|
+
*/
|
|
43
|
+
export interface ExecuteOptions {
|
|
44
|
+
timeout?: number;
|
|
45
|
+
cancellationToken?: CancellationToken;
|
|
46
|
+
maxBufferSize?: number;
|
|
47
|
+
chunkCallback?: (chunk: string, isStderr: boolean) => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Stream chunk for large outputs
|
|
51
|
+
*/
|
|
52
|
+
export interface StreamChunk {
|
|
53
|
+
data: string;
|
|
54
|
+
isStderr: boolean;
|
|
55
|
+
timestamp: Date;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* SSH Client implementation with enhanced timeout and cancellation support
|
|
59
|
+
*/
|
|
60
|
+
export declare class SSHClient implements ISSHClient {
|
|
61
|
+
private client;
|
|
62
|
+
private serverId;
|
|
63
|
+
private state;
|
|
64
|
+
private readonly connectionTimeout;
|
|
65
|
+
private readonly commandTimeout;
|
|
66
|
+
private activeExecutions;
|
|
67
|
+
constructor(options?: {
|
|
68
|
+
connectionTimeout?: number;
|
|
69
|
+
commandTimeout?: number;
|
|
70
|
+
});
|
|
71
|
+
/**
|
|
72
|
+
* Connect to SSH server
|
|
73
|
+
*/
|
|
74
|
+
connect(config: SSHConnectionConfig): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Disconnect from SSH server
|
|
77
|
+
*/
|
|
78
|
+
disconnect(): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Check if connected to SSH server
|
|
81
|
+
*/
|
|
82
|
+
isConnected(): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Execute a command on the SSH server
|
|
85
|
+
*/
|
|
86
|
+
execute(command: string, options?: ExecuteOptions): Promise<CommandResult>;
|
|
87
|
+
/**
|
|
88
|
+
* Execute a command with streaming output
|
|
89
|
+
*/
|
|
90
|
+
executeStreaming(command: string, onChunk: (chunk: StreamChunk) => void, options?: ExecuteOptions): Promise<CommandResult>;
|
|
91
|
+
/**
|
|
92
|
+
* Cancel all active executions
|
|
93
|
+
*/
|
|
94
|
+
private cancelAllExecutions;
|
|
95
|
+
/**
|
|
96
|
+
* Get the server ID if connected
|
|
97
|
+
*/
|
|
98
|
+
getServerId(): string | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Set the server ID
|
|
101
|
+
*/
|
|
102
|
+
setServerId(id: string): void;
|
|
103
|
+
/**
|
|
104
|
+
* Get current connection state
|
|
105
|
+
*/
|
|
106
|
+
getState(): SSHConnectionState;
|
|
107
|
+
/**
|
|
108
|
+
* Get active execution count
|
|
109
|
+
*/
|
|
110
|
+
getActiveExecutionCount(): number;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=SSHClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SSHClient.d.ts","sourceRoot":"","sources":["../../src/core/SSHClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IAEnD;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACH,MAAM,IAAI,IAAI;IAed;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAQpC;;OAEG;IACH,gBAAgB,IAAI,IAAI;CAKzB;AAED;;GAEG;AACH,qBAAa,uBAAuB;IAClC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;;IAMlC;;OAEG;IACH,MAAM,IAAI,IAAI;CAGf;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,SAAU,YAAW,UAAU;IAC1C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,KAAK,CAAkD;IAC/D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,gBAAgB,CAGV;gBAEF,OAAO,CAAC,EAAE;QACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB;IAKD;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA8EzD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBjC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACG,OAAO,CACX,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,aAAa,CAAC;IAqLzB;;OAEG;IACG,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,EACrC,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,aAAa,CAAC;IAazB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACH,WAAW,IAAI,MAAM,GAAG,SAAS;IAIjC;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI7B;;OAEG;IACH,QAAQ,IAAI,kBAAkB;IAI9B;;OAEG;IACH,uBAAuB,IAAI,MAAM;CAGlC"}
|