@edgible-team/cli 1.0.1

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.
Files changed (102) hide show
  1. package/LICENSE +136 -0
  2. package/README.md +450 -0
  3. package/dist/client/api-client.js +1057 -0
  4. package/dist/client/index.js +21 -0
  5. package/dist/commands/agent.js +1280 -0
  6. package/dist/commands/ai.js +608 -0
  7. package/dist/commands/application.js +885 -0
  8. package/dist/commands/auth.js +570 -0
  9. package/dist/commands/base/BaseCommand.js +93 -0
  10. package/dist/commands/base/CommandHandler.js +7 -0
  11. package/dist/commands/base/command-wrapper.js +58 -0
  12. package/dist/commands/base/middleware.js +77 -0
  13. package/dist/commands/config.js +116 -0
  14. package/dist/commands/connectivity.js +59 -0
  15. package/dist/commands/debug.js +98 -0
  16. package/dist/commands/discover.js +144 -0
  17. package/dist/commands/examples/migrated-command-example.js +180 -0
  18. package/dist/commands/gateway.js +494 -0
  19. package/dist/commands/managedGateway.js +787 -0
  20. package/dist/commands/utils/config-validator.js +76 -0
  21. package/dist/commands/utils/gateway-prompt.js +79 -0
  22. package/dist/commands/utils/input-parser.js +120 -0
  23. package/dist/commands/utils/output-formatter.js +109 -0
  24. package/dist/config/app-config.js +99 -0
  25. package/dist/detection/SystemCapabilityDetector.js +1244 -0
  26. package/dist/detection/ToolDetector.js +305 -0
  27. package/dist/detection/WorkloadDetector.js +314 -0
  28. package/dist/di/bindings.js +99 -0
  29. package/dist/di/container.js +88 -0
  30. package/dist/di/types.js +32 -0
  31. package/dist/index.js +52 -0
  32. package/dist/interfaces/IDaemonManager.js +3 -0
  33. package/dist/repositories/config-repository.js +62 -0
  34. package/dist/repositories/gateway-repository.js +35 -0
  35. package/dist/scripts/postinstall.js +101 -0
  36. package/dist/services/AgentStatusManager.js +299 -0
  37. package/dist/services/ConnectivityTester.js +271 -0
  38. package/dist/services/DependencyInstaller.js +475 -0
  39. package/dist/services/LocalAgentManager.js +2216 -0
  40. package/dist/services/application/ApplicationService.js +299 -0
  41. package/dist/services/auth/AuthService.js +214 -0
  42. package/dist/services/aws.js +644 -0
  43. package/dist/services/daemon/DaemonManagerFactory.js +65 -0
  44. package/dist/services/daemon/DockerDaemonManager.js +395 -0
  45. package/dist/services/daemon/LaunchdDaemonManager.js +257 -0
  46. package/dist/services/daemon/PodmanDaemonManager.js +369 -0
  47. package/dist/services/daemon/SystemdDaemonManager.js +221 -0
  48. package/dist/services/daemon/WindowsServiceDaemonManager.js +210 -0
  49. package/dist/services/daemon/index.js +16 -0
  50. package/dist/services/edgible.js +3060 -0
  51. package/dist/services/gateway/GatewayService.js +334 -0
  52. package/dist/state/config.js +146 -0
  53. package/dist/types/AgentConfig.js +5 -0
  54. package/dist/types/AgentStatus.js +5 -0
  55. package/dist/types/ApiClient.js +5 -0
  56. package/dist/types/ApiRequests.js +5 -0
  57. package/dist/types/ApiResponses.js +5 -0
  58. package/dist/types/Application.js +5 -0
  59. package/dist/types/CaddyJson.js +5 -0
  60. package/dist/types/UnifiedAgentStatus.js +56 -0
  61. package/dist/types/WireGuard.js +5 -0
  62. package/dist/types/Workload.js +5 -0
  63. package/dist/types/agent.js +5 -0
  64. package/dist/types/command-options.js +5 -0
  65. package/dist/types/connectivity.js +5 -0
  66. package/dist/types/errors.js +250 -0
  67. package/dist/types/gateway-types.js +5 -0
  68. package/dist/types/index.js +48 -0
  69. package/dist/types/models/ApplicationData.js +5 -0
  70. package/dist/types/models/CertificateData.js +5 -0
  71. package/dist/types/models/DeviceData.js +5 -0
  72. package/dist/types/models/DevicePoolData.js +5 -0
  73. package/dist/types/models/OrganizationData.js +5 -0
  74. package/dist/types/models/OrganizationInviteData.js +5 -0
  75. package/dist/types/models/ProviderConfiguration.js +5 -0
  76. package/dist/types/models/ResourceData.js +5 -0
  77. package/dist/types/models/ServiceResourceData.js +5 -0
  78. package/dist/types/models/UserData.js +5 -0
  79. package/dist/types/route.js +5 -0
  80. package/dist/types/validation/schemas.js +218 -0
  81. package/dist/types/validation.js +5 -0
  82. package/dist/utils/FileIntegrityManager.js +256 -0
  83. package/dist/utils/PathMigration.js +219 -0
  84. package/dist/utils/PathResolver.js +235 -0
  85. package/dist/utils/PlatformDetector.js +277 -0
  86. package/dist/utils/console-logger.js +130 -0
  87. package/dist/utils/docker-compose-parser.js +179 -0
  88. package/dist/utils/errors.js +130 -0
  89. package/dist/utils/health-checker.js +155 -0
  90. package/dist/utils/json-logger.js +72 -0
  91. package/dist/utils/log-formatter.js +293 -0
  92. package/dist/utils/logger.js +59 -0
  93. package/dist/utils/network-utils.js +217 -0
  94. package/dist/utils/output.js +182 -0
  95. package/dist/utils/passwordValidation.js +91 -0
  96. package/dist/utils/progress.js +167 -0
  97. package/dist/utils/sudo-checker.js +22 -0
  98. package/dist/utils/urls.js +32 -0
  99. package/dist/utils/validation.js +31 -0
  100. package/dist/validation/schemas.js +175 -0
  101. package/dist/validation/validator.js +67 -0
  102. package/package.json +83 -0
@@ -0,0 +1,299 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.AgentStatusManager = void 0;
37
+ const fs = __importStar(require("fs/promises"));
38
+ const path = __importStar(require("path"));
39
+ const events_1 = require("events");
40
+ const crypto_1 = require("crypto");
41
+ const UnifiedAgentStatus_1 = require("../types/UnifiedAgentStatus");
42
+ const FileIntegrityManager_1 = require("../utils/FileIntegrityManager");
43
+ const PathResolver_1 = require("../utils/PathResolver");
44
+ const config_1 = require("../state/config");
45
+ class AgentStatusManager extends events_1.EventEmitter {
46
+ constructor() {
47
+ super();
48
+ this.isWatching = false;
49
+ this.lastStatus = null;
50
+ this.watchIntervalMs = 1000; // 1 second
51
+ this.maxRetries = 3;
52
+ this.retryDelay = 500; // 500ms
53
+ // Get user config to determine installation type
54
+ const configManager = new config_1.ConfigManager();
55
+ const userConfig = configManager.getConfig();
56
+ // Resolve agent config paths based on installation type
57
+ const useSystemPath = userConfig.agentInstallationType === 'systemd' ||
58
+ userConfig.agentInstallationType === 'launchd' ||
59
+ userConfig.agentInstallationType === 'windows-service' ||
60
+ userConfig.agentInstallationType === 'docker' ||
61
+ userConfig.agentInstallationType === 'podman';
62
+ this.statusFile = PathResolver_1.PathResolver.getAgentStatusPath(useSystemPath);
63
+ this.configFile = PathResolver_1.PathResolver.getAgentConfigFilePath(useSystemPath);
64
+ }
65
+ async getStatus() {
66
+ const startTime = Date.now();
67
+ try {
68
+ // Check if status file exists
69
+ if (!await this.fileExists(this.statusFile)) {
70
+ return {
71
+ status: null,
72
+ isValid: false,
73
+ error: 'Status file not found - agent may not be running',
74
+ lastChecked: new Date()
75
+ };
76
+ }
77
+ // Use file integrity manager for safe reading
78
+ const result = await FileIntegrityManager_1.FileIntegrityManager.readJsonFileSafely(this.statusFile);
79
+ if (!result.isValid) {
80
+ // Try to cleanup corrupted files
81
+ await FileIntegrityManager_1.FileIntegrityManager.cleanupCorruptedFiles(path.dirname(this.statusFile));
82
+ return {
83
+ status: null,
84
+ isValid: false,
85
+ error: result.error || 'Status file validation failed',
86
+ lastChecked: new Date()
87
+ };
88
+ }
89
+ const statusData = result.data;
90
+ // Convert agent-v2 status to unified status
91
+ const status = (0, UnifiedAgentStatus_1.convertAgentV2Status)(statusData);
92
+ // Check if status is stale (older than 1 minute for more responsive detection)
93
+ const age = Date.now() - status.timestamp;
94
+ if (age > 60000) { // 1 minute instead of 2 minutes
95
+ return {
96
+ status,
97
+ isValid: false,
98
+ error: 'Status is stale - agent may not be responding',
99
+ lastChecked: new Date()
100
+ };
101
+ }
102
+ this.lastStatus = status;
103
+ return {
104
+ status,
105
+ isValid: true,
106
+ lastChecked: new Date()
107
+ };
108
+ }
109
+ catch (error) {
110
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
111
+ return {
112
+ status: this.lastStatus, // Return last known status if available
113
+ isValid: false,
114
+ error: `Failed to read status: ${errorMessage}`,
115
+ lastChecked: new Date()
116
+ };
117
+ }
118
+ }
119
+ async updateConfig(config) {
120
+ try {
121
+ // Ensure directory exists
122
+ const configDir = path.dirname(this.configFile);
123
+ await fs.mkdir(configDir, { recursive: true });
124
+ // Use file integrity manager for safe writing
125
+ const result = await FileIntegrityManager_1.FileIntegrityManager.writeJsonFileSafely(this.configFile, config);
126
+ if (!result.success) {
127
+ throw new Error(result.error || 'Failed to write config file');
128
+ }
129
+ this.emit('configUpdated', config);
130
+ }
131
+ catch (error) {
132
+ console.error('Failed to update agent config:', error);
133
+ throw error;
134
+ }
135
+ }
136
+ startWatching(callback) {
137
+ if (this.isWatching) {
138
+ console.warn('Already watching agent status');
139
+ return;
140
+ }
141
+ this.isWatching = true;
142
+ // Watch for status file changes
143
+ this.watchInterval = setInterval(async () => {
144
+ try {
145
+ const result = await this.getStatus();
146
+ callback(result);
147
+ }
148
+ catch (error) {
149
+ console.error('Error in status watch callback:', error);
150
+ }
151
+ }, this.watchIntervalMs);
152
+ console.log('Started watching agent status');
153
+ }
154
+ stopWatching() {
155
+ if (this.watchInterval) {
156
+ clearInterval(this.watchInterval);
157
+ this.watchInterval = undefined;
158
+ }
159
+ this.isWatching = false;
160
+ console.log('Stopped watching agent status');
161
+ }
162
+ async fileExists(filePath) {
163
+ try {
164
+ await fs.access(filePath);
165
+ return true;
166
+ }
167
+ catch {
168
+ return false;
169
+ }
170
+ }
171
+ async readStatusFileWithRetry() {
172
+ let lastError = null;
173
+ for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
174
+ try {
175
+ const data = await fs.readFile(this.statusFile, 'utf8');
176
+ return JSON.parse(data);
177
+ }
178
+ catch (error) {
179
+ lastError = error instanceof Error ? error : new Error('Unknown error');
180
+ if (attempt < this.maxRetries) {
181
+ // Wait before retry
182
+ await new Promise(resolve => setTimeout(resolve, this.retryDelay * attempt));
183
+ }
184
+ }
185
+ }
186
+ throw lastError || new Error('Failed to read status file');
187
+ }
188
+ async validateStatusFile(statusData) {
189
+ try {
190
+ // Check if metadata exists
191
+ if (!statusData.metadata) {
192
+ console.warn('Status file missing metadata');
193
+ return false;
194
+ }
195
+ const metadata = statusData.metadata;
196
+ // Verify checksum
197
+ const statusWithoutMetadata = { ...statusData };
198
+ delete statusWithoutMetadata.metadata;
199
+ const expectedChecksum = this.calculateChecksum(statusWithoutMetadata);
200
+ if (metadata.checksum !== expectedChecksum) {
201
+ console.warn('Status file checksum mismatch');
202
+ return false;
203
+ }
204
+ // Check if file is too old (more than 1 hour)
205
+ const age = Date.now() - metadata.lastModified;
206
+ if (age > 3600000) { // 1 hour
207
+ console.warn('Status file is too old');
208
+ return false;
209
+ }
210
+ // Check required fields
211
+ const requiredFields = ['running', 'health', 'timestamp', 'pid'];
212
+ for (const field of requiredFields) {
213
+ if (statusWithoutMetadata[field] === undefined) {
214
+ console.warn(`Status file missing required field: ${field}`);
215
+ return false;
216
+ }
217
+ }
218
+ return true;
219
+ }
220
+ catch (error) {
221
+ console.error('Failed to validate status file:', error);
222
+ return false;
223
+ }
224
+ }
225
+ calculateChecksum(status) {
226
+ const statusString = JSON.stringify(status);
227
+ return (0, crypto_1.createHash)('sha256').update(statusString).digest('hex').substring(0, 16);
228
+ }
229
+ // Public method to get status file path
230
+ getStatusFilePath() {
231
+ return this.statusFile;
232
+ }
233
+ // Public method to get config file path
234
+ getConfigFilePath() {
235
+ return this.configFile;
236
+ }
237
+ // Public method to check if agent is running based on file existence and content
238
+ async isAgentRunning() {
239
+ try {
240
+ const result = await this.getStatus();
241
+ return result.isValid && result.status?.running === true;
242
+ }
243
+ catch {
244
+ return false;
245
+ }
246
+ }
247
+ // Public method to get agent PID
248
+ async getAgentPID() {
249
+ try {
250
+ const result = await this.getStatus();
251
+ return result.status?.pid || null;
252
+ }
253
+ catch {
254
+ return null;
255
+ }
256
+ }
257
+ // Public method to get agent uptime
258
+ async getAgentUptime() {
259
+ try {
260
+ const result = await this.getStatus();
261
+ return result.status?.uptime || 0;
262
+ }
263
+ catch {
264
+ return 0;
265
+ }
266
+ }
267
+ // Public method to get agent version
268
+ async getAgentVersion() {
269
+ try {
270
+ const result = await this.getStatus();
271
+ return result.status?.version || null;
272
+ }
273
+ catch {
274
+ return null;
275
+ }
276
+ }
277
+ // Public method to get agent health
278
+ async getAgentHealth() {
279
+ try {
280
+ const result = await this.getStatus();
281
+ return result.status?.health || 'unknown';
282
+ }
283
+ catch {
284
+ return 'unknown';
285
+ }
286
+ }
287
+ // Public method to get current status
288
+ async getCurrentStatus() {
289
+ try {
290
+ const result = await this.getStatus();
291
+ return result.status;
292
+ }
293
+ catch {
294
+ return null;
295
+ }
296
+ }
297
+ }
298
+ exports.AgentStatusManager = AgentStatusManager;
299
+ //# sourceMappingURL=AgentStatusManager.js.map
@@ -0,0 +1,271 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConnectivityTester = void 0;
4
+ const network_utils_1 = require("../utils/network-utils");
5
+ const health_checker_1 = require("../utils/health-checker");
6
+ class ConnectivityTester {
7
+ /**
8
+ * Test TCP/UDP port connectivity
9
+ */
10
+ async testPortConnectivity(host, port, protocol, timeout = 5000) {
11
+ const startTime = Date.now();
12
+ let result;
13
+ if (protocol === 'tcp') {
14
+ result = await network_utils_1.NetworkUtils.testTcpPort(host, port, timeout);
15
+ }
16
+ else {
17
+ result = await network_utils_1.NetworkUtils.testUdpPort(host, port, timeout);
18
+ }
19
+ return {
20
+ success: result.success,
21
+ latency: result.latency,
22
+ error: result.error,
23
+ timestamp: new Date(),
24
+ host,
25
+ port,
26
+ protocol
27
+ };
28
+ }
29
+ /**
30
+ * Test HTTP/HTTPS endpoint health
31
+ */
32
+ async testHttpEndpoint(url, expectedStatus, timeout = 5000) {
33
+ const config = {
34
+ enabled: true,
35
+ interval: 30,
36
+ timeout: timeout / 1000,
37
+ retries: 1,
38
+ expectedStatus
39
+ };
40
+ const options = {
41
+ timeout,
42
+ expectedStatus
43
+ };
44
+ return await health_checker_1.HealthChecker.checkHttpHealth(url, config, options);
45
+ }
46
+ /**
47
+ * Test application-specific endpoints
48
+ */
49
+ async testApplicationEndpoint(application, gatewayIp) {
50
+ const protocol = application.protocol === 'https' ? 'https' : 'http';
51
+ const url = `${protocol}://${gatewayIp}:${application.port}`;
52
+ const httpResult = await this.testHttpEndpoint(url, 200, 10000);
53
+ return {
54
+ ...httpResult,
55
+ applicationId: application.id,
56
+ gatewayIp,
57
+ workloadIp: application.servingIp,
58
+ port: application.port,
59
+ protocol: application.protocol,
60
+ testType: 'http'
61
+ };
62
+ }
63
+ /**
64
+ * Comprehensive connectivity test from gateway to workload
65
+ */
66
+ async testGatewayToWorkloadConnectivity(gateway, workload, port) {
67
+ const startTime = Date.now();
68
+ const tests = [];
69
+ const recommendations = [];
70
+ // Test 1: Basic port connectivity
71
+ const portTest = await this.testPortConnectivity(workload.ipAddress || 'localhost', port, 'tcp', 5000);
72
+ tests.push({
73
+ success: portTest.success,
74
+ applicationId: 'test',
75
+ gatewayIp: gateway.publicIp,
76
+ workloadIp: workload.ipAddress || 'localhost',
77
+ port,
78
+ protocol: 'tcp',
79
+ testType: 'connectivity',
80
+ host: workload.ipAddress || 'localhost',
81
+ latency: portTest.latency,
82
+ error: portTest.error,
83
+ timestamp: portTest.timestamp,
84
+ url: `tcp://${workload.ipAddress || 'localhost'}:${port}`,
85
+ method: 'CONNECT'
86
+ });
87
+ // Test 2: HTTP endpoint test (if applicable)
88
+ if (port === 80 || port === 443 || port === 8080 || port === 3000) {
89
+ const protocol = port === 443 ? 'https' : 'http';
90
+ const url = `${protocol}://${workload.ipAddress || 'localhost'}:${port}`;
91
+ const httpTest = await this.testHttpEndpoint(url, 200, 5000);
92
+ tests.push({
93
+ ...httpTest,
94
+ applicationId: 'test',
95
+ gatewayIp: gateway.publicIp,
96
+ workloadIp: workload.ipAddress || 'localhost',
97
+ port,
98
+ protocol: protocol,
99
+ testType: 'http'
100
+ });
101
+ }
102
+ // Test 3: Gateway to workload connectivity
103
+ if (workload.ipAddress && workload.ipAddress !== 'localhost') {
104
+ const gatewayToWorkloadTest = await this.testPortConnectivity(workload.ipAddress, port, 'tcp', 10000);
105
+ tests.push({
106
+ success: gatewayToWorkloadTest.success,
107
+ applicationId: 'test',
108
+ gatewayIp: gateway.publicIp,
109
+ workloadIp: workload.ipAddress,
110
+ port,
111
+ protocol: 'tcp',
112
+ testType: 'connectivity',
113
+ host: workload.ipAddress,
114
+ latency: gatewayToWorkloadTest.latency,
115
+ error: gatewayToWorkloadTest.error,
116
+ timestamp: gatewayToWorkloadTest.timestamp,
117
+ url: `tcp://${workload.ipAddress}:${port}`,
118
+ method: 'CONNECT'
119
+ });
120
+ }
121
+ // Generate diagnostics
122
+ const diagnostics = await this.generateDiagnostics(tests, gateway, workload);
123
+ // Generate recommendations
124
+ if (!tests.every(t => t.success)) {
125
+ recommendations.push('Check firewall settings on both gateway and workload');
126
+ recommendations.push('Verify the workload service is running and listening on the correct port');
127
+ recommendations.push('Ensure network connectivity between gateway and workload');
128
+ }
129
+ if (tests.some(t => t.latency && t.latency > 1000)) {
130
+ recommendations.push('High latency detected - check network performance');
131
+ }
132
+ const overall = tests.length > 0 && tests.every(t => t.success);
133
+ return {
134
+ overall,
135
+ tests,
136
+ diagnostics,
137
+ recommendations,
138
+ timestamp: new Date(),
139
+ duration: Date.now() - startTime
140
+ };
141
+ }
142
+ /**
143
+ * Network diagnostics and troubleshooting
144
+ */
145
+ async diagnoseConnectivityIssues(application) {
146
+ const networkIssues = [];
147
+ const configurationIssues = [];
148
+ const serviceIssues = [];
149
+ const suggestions = [];
150
+ // Test basic connectivity
151
+ const portTest = await this.testPortConnectivity(application.servingIp, application.port, 'tcp', 5000);
152
+ if (!portTest.success) {
153
+ if (portTest.error?.includes('ECONNREFUSED')) {
154
+ serviceIssues.push({
155
+ type: 'service_down',
156
+ severity: 'critical',
157
+ description: 'Service is not running or not accepting connections',
158
+ affectedServices: [application.name],
159
+ suggestedFix: 'Start the service or check if it\'s listening on the correct port'
160
+ });
161
+ }
162
+ else if (portTest.error?.includes('ETIMEDOUT')) {
163
+ networkIssues.push({
164
+ type: 'timeout',
165
+ severity: 'high',
166
+ description: 'Connection timeout - service may be overloaded or unreachable',
167
+ affectedHosts: [application.servingIp],
168
+ suggestedFix: 'Check network connectivity and service performance'
169
+ });
170
+ }
171
+ else if (portTest.error?.includes('ENOTFOUND')) {
172
+ networkIssues.push({
173
+ type: 'dns',
174
+ severity: 'high',
175
+ description: 'Host not found - DNS resolution failed',
176
+ affectedHosts: [application.servingIp],
177
+ suggestedFix: 'Check DNS configuration and hostname resolution'
178
+ });
179
+ }
180
+ }
181
+ // Test HTTP endpoint if applicable
182
+ if (application.protocol === 'http' || application.protocol === 'https') {
183
+ const url = `${application.protocol}://${application.servingIp}:${application.port}`;
184
+ const httpTest = await this.testHttpEndpoint(url, 200, 5000);
185
+ if (!httpTest.success) {
186
+ if (httpTest.statusCode && httpTest.statusCode >= 500) {
187
+ serviceIssues.push({
188
+ type: 'service_error',
189
+ severity: 'high',
190
+ description: `Service returned error status ${httpTest.statusCode}`,
191
+ affectedServices: [application.name],
192
+ suggestedFix: 'Check service logs and application health'
193
+ });
194
+ }
195
+ else if (httpTest.statusCode && httpTest.statusCode >= 400) {
196
+ configurationIssues.push({
197
+ type: 'service_not_running',
198
+ severity: 'medium',
199
+ description: `Service returned client error ${httpTest.statusCode}`,
200
+ affectedServices: [application.name],
201
+ suggestedFix: 'Check application configuration and request format'
202
+ });
203
+ }
204
+ }
205
+ }
206
+ // Generate suggestions based on issues found
207
+ if (networkIssues.length > 0) {
208
+ suggestions.push('Check network connectivity and firewall rules');
209
+ }
210
+ if (configurationIssues.length > 0) {
211
+ suggestions.push('Review application configuration and service settings');
212
+ }
213
+ if (serviceIssues.length > 0) {
214
+ suggestions.push('Check service status and application logs');
215
+ }
216
+ return {
217
+ networkIssues,
218
+ configurationIssues,
219
+ serviceIssues,
220
+ suggestions
221
+ };
222
+ }
223
+ /**
224
+ * Generate diagnostics from test results
225
+ */
226
+ async generateDiagnostics(tests, gateway, workload) {
227
+ const networkIssues = [];
228
+ const configurationIssues = [];
229
+ const serviceIssues = [];
230
+ const suggestions = [];
231
+ for (const test of tests) {
232
+ if (!test.success) {
233
+ if (test.error?.includes('ECONNREFUSED')) {
234
+ serviceIssues.push({
235
+ type: 'service_down',
236
+ severity: 'critical',
237
+ description: 'Service is not running or not accepting connections',
238
+ affectedServices: [workload.name],
239
+ suggestedFix: 'Start the service or check if it\'s listening on the correct port'
240
+ });
241
+ }
242
+ else if (test.error?.includes('ETIMEDOUT')) {
243
+ networkIssues.push({
244
+ type: 'timeout',
245
+ severity: 'high',
246
+ description: 'Connection timeout - service may be overloaded or unreachable',
247
+ affectedHosts: [test.host],
248
+ suggestedFix: 'Check network connectivity and service performance'
249
+ });
250
+ }
251
+ else if (test.error?.includes('ENOTFOUND')) {
252
+ networkIssues.push({
253
+ type: 'dns',
254
+ severity: 'high',
255
+ description: 'Host not found - DNS resolution failed',
256
+ affectedHosts: [test.host],
257
+ suggestedFix: 'Check DNS configuration and hostname resolution'
258
+ });
259
+ }
260
+ }
261
+ }
262
+ return {
263
+ networkIssues,
264
+ configurationIssues,
265
+ serviceIssues,
266
+ suggestions
267
+ };
268
+ }
269
+ }
270
+ exports.ConnectivityTester = ConnectivityTester;
271
+ //# sourceMappingURL=ConnectivityTester.js.map