@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.
- package/LICENSE +136 -0
- package/README.md +450 -0
- package/dist/client/api-client.js +1057 -0
- package/dist/client/index.js +21 -0
- package/dist/commands/agent.js +1280 -0
- package/dist/commands/ai.js +608 -0
- package/dist/commands/application.js +885 -0
- package/dist/commands/auth.js +570 -0
- package/dist/commands/base/BaseCommand.js +93 -0
- package/dist/commands/base/CommandHandler.js +7 -0
- package/dist/commands/base/command-wrapper.js +58 -0
- package/dist/commands/base/middleware.js +77 -0
- package/dist/commands/config.js +116 -0
- package/dist/commands/connectivity.js +59 -0
- package/dist/commands/debug.js +98 -0
- package/dist/commands/discover.js +144 -0
- package/dist/commands/examples/migrated-command-example.js +180 -0
- package/dist/commands/gateway.js +494 -0
- package/dist/commands/managedGateway.js +787 -0
- package/dist/commands/utils/config-validator.js +76 -0
- package/dist/commands/utils/gateway-prompt.js +79 -0
- package/dist/commands/utils/input-parser.js +120 -0
- package/dist/commands/utils/output-formatter.js +109 -0
- package/dist/config/app-config.js +99 -0
- package/dist/detection/SystemCapabilityDetector.js +1244 -0
- package/dist/detection/ToolDetector.js +305 -0
- package/dist/detection/WorkloadDetector.js +314 -0
- package/dist/di/bindings.js +99 -0
- package/dist/di/container.js +88 -0
- package/dist/di/types.js +32 -0
- package/dist/index.js +52 -0
- package/dist/interfaces/IDaemonManager.js +3 -0
- package/dist/repositories/config-repository.js +62 -0
- package/dist/repositories/gateway-repository.js +35 -0
- package/dist/scripts/postinstall.js +101 -0
- package/dist/services/AgentStatusManager.js +299 -0
- package/dist/services/ConnectivityTester.js +271 -0
- package/dist/services/DependencyInstaller.js +475 -0
- package/dist/services/LocalAgentManager.js +2216 -0
- package/dist/services/application/ApplicationService.js +299 -0
- package/dist/services/auth/AuthService.js +214 -0
- package/dist/services/aws.js +644 -0
- package/dist/services/daemon/DaemonManagerFactory.js +65 -0
- package/dist/services/daemon/DockerDaemonManager.js +395 -0
- package/dist/services/daemon/LaunchdDaemonManager.js +257 -0
- package/dist/services/daemon/PodmanDaemonManager.js +369 -0
- package/dist/services/daemon/SystemdDaemonManager.js +221 -0
- package/dist/services/daemon/WindowsServiceDaemonManager.js +210 -0
- package/dist/services/daemon/index.js +16 -0
- package/dist/services/edgible.js +3060 -0
- package/dist/services/gateway/GatewayService.js +334 -0
- package/dist/state/config.js +146 -0
- package/dist/types/AgentConfig.js +5 -0
- package/dist/types/AgentStatus.js +5 -0
- package/dist/types/ApiClient.js +5 -0
- package/dist/types/ApiRequests.js +5 -0
- package/dist/types/ApiResponses.js +5 -0
- package/dist/types/Application.js +5 -0
- package/dist/types/CaddyJson.js +5 -0
- package/dist/types/UnifiedAgentStatus.js +56 -0
- package/dist/types/WireGuard.js +5 -0
- package/dist/types/Workload.js +5 -0
- package/dist/types/agent.js +5 -0
- package/dist/types/command-options.js +5 -0
- package/dist/types/connectivity.js +5 -0
- package/dist/types/errors.js +250 -0
- package/dist/types/gateway-types.js +5 -0
- package/dist/types/index.js +48 -0
- package/dist/types/models/ApplicationData.js +5 -0
- package/dist/types/models/CertificateData.js +5 -0
- package/dist/types/models/DeviceData.js +5 -0
- package/dist/types/models/DevicePoolData.js +5 -0
- package/dist/types/models/OrganizationData.js +5 -0
- package/dist/types/models/OrganizationInviteData.js +5 -0
- package/dist/types/models/ProviderConfiguration.js +5 -0
- package/dist/types/models/ResourceData.js +5 -0
- package/dist/types/models/ServiceResourceData.js +5 -0
- package/dist/types/models/UserData.js +5 -0
- package/dist/types/route.js +5 -0
- package/dist/types/validation/schemas.js +218 -0
- package/dist/types/validation.js +5 -0
- package/dist/utils/FileIntegrityManager.js +256 -0
- package/dist/utils/PathMigration.js +219 -0
- package/dist/utils/PathResolver.js +235 -0
- package/dist/utils/PlatformDetector.js +277 -0
- package/dist/utils/console-logger.js +130 -0
- package/dist/utils/docker-compose-parser.js +179 -0
- package/dist/utils/errors.js +130 -0
- package/dist/utils/health-checker.js +155 -0
- package/dist/utils/json-logger.js +72 -0
- package/dist/utils/log-formatter.js +293 -0
- package/dist/utils/logger.js +59 -0
- package/dist/utils/network-utils.js +217 -0
- package/dist/utils/output.js +182 -0
- package/dist/utils/passwordValidation.js +91 -0
- package/dist/utils/progress.js +167 -0
- package/dist/utils/sudo-checker.js +22 -0
- package/dist/utils/urls.js +32 -0
- package/dist/utils/validation.js +31 -0
- package/dist/validation/schemas.js +175 -0
- package/dist/validation/validator.js +67 -0
- package/package.json +83 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ToolDetector = void 0;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
class ToolDetector {
|
|
10
|
+
static async detectTools() {
|
|
11
|
+
const detectedTools = [];
|
|
12
|
+
for (const tool of this.tools) {
|
|
13
|
+
try {
|
|
14
|
+
const version = this.getToolVersion(tool.command);
|
|
15
|
+
if (version !== null) {
|
|
16
|
+
detectedTools.push({
|
|
17
|
+
...tool,
|
|
18
|
+
available: true,
|
|
19
|
+
version: version
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
detectedTools.push({
|
|
24
|
+
...tool,
|
|
25
|
+
available: false
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
// Tool not available
|
|
31
|
+
detectedTools.push({
|
|
32
|
+
...tool,
|
|
33
|
+
available: false
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return detectedTools;
|
|
38
|
+
}
|
|
39
|
+
static getToolVersion(command) {
|
|
40
|
+
try {
|
|
41
|
+
// Special handling for different tools
|
|
42
|
+
if (command === 'docker') {
|
|
43
|
+
const output = (0, child_process_1.execSync)('docker --version', { encoding: 'utf8', timeout: 5000 });
|
|
44
|
+
return output.trim().replace('Docker version ', '');
|
|
45
|
+
}
|
|
46
|
+
if (command === 'kubectl') {
|
|
47
|
+
const output = (0, child_process_1.execSync)('kubectl version --client', { encoding: 'utf8', timeout: 5000 });
|
|
48
|
+
const lines = output.split('\n');
|
|
49
|
+
const versionLine = lines.find(line => line.includes('Client Version:'));
|
|
50
|
+
return versionLine ? versionLine.trim().replace('Client Version: ', '') : 'Unknown';
|
|
51
|
+
}
|
|
52
|
+
if (command === 'aws') {
|
|
53
|
+
const output = (0, child_process_1.execSync)('aws --version', { encoding: 'utf8', timeout: 5000 });
|
|
54
|
+
return output.trim().replace('aws-cli/', '');
|
|
55
|
+
}
|
|
56
|
+
if (command === 'az') {
|
|
57
|
+
const output = (0, child_process_1.execSync)('az --version', { encoding: 'utf8', timeout: 5000 });
|
|
58
|
+
const lines = output.split('\n');
|
|
59
|
+
const versionLine = lines.find(line => line.includes('azure-cli'));
|
|
60
|
+
return versionLine ? versionLine.trim().replace('azure-cli ', '') : 'Unknown';
|
|
61
|
+
}
|
|
62
|
+
if (command === 'gcloud') {
|
|
63
|
+
const output = (0, child_process_1.execSync)('gcloud --version', { encoding: 'utf8', timeout: 5000 });
|
|
64
|
+
const lines = output.split('\n');
|
|
65
|
+
const versionLine = lines.find(line => line.includes('Google Cloud SDK'));
|
|
66
|
+
return versionLine ? versionLine.trim().replace('Google Cloud SDK ', '') : 'Unknown';
|
|
67
|
+
}
|
|
68
|
+
if (command === 'terraform') {
|
|
69
|
+
const output = (0, child_process_1.execSync)('terraform --version', { encoding: 'utf8', timeout: 5000 });
|
|
70
|
+
const lines = output.split('\n');
|
|
71
|
+
const versionLine = lines.find(line => line.includes('Terraform v'));
|
|
72
|
+
return versionLine ? versionLine.trim().replace('Terraform v', '') : 'Unknown';
|
|
73
|
+
}
|
|
74
|
+
if (command === 'powershell') {
|
|
75
|
+
// Check if we're on Windows and PowerShell is available
|
|
76
|
+
if (process.platform === 'win32') {
|
|
77
|
+
const output = (0, child_process_1.execSync)('powershell -Command "$PSVersionTable.PSVersion"', { encoding: 'utf8', timeout: 5000 });
|
|
78
|
+
return output.trim();
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
// Generic version detection
|
|
83
|
+
const output = (0, child_process_1.execSync)(`${command} --version`, { encoding: 'utf8', timeout: 5000 });
|
|
84
|
+
const lines = output.split('\n');
|
|
85
|
+
const versionLine = lines[0];
|
|
86
|
+
return versionLine ? versionLine.trim() : 'Unknown';
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
static displayDetectedTools(tools) {
|
|
93
|
+
const availableTools = tools.filter(tool => tool.available);
|
|
94
|
+
const unavailableTools = tools.filter(tool => !tool.available);
|
|
95
|
+
if (availableTools.length === 0) {
|
|
96
|
+
console.log(chalk_1.default.yellow('ā No container/VM/workload management tools detected'));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
console.log(chalk_1.default.blue.bold('\nš§ Detected Infrastructure Tools:\n'));
|
|
100
|
+
// Group tools by category
|
|
101
|
+
const categories = {
|
|
102
|
+
container: availableTools.filter(tool => tool.category === 'container'),
|
|
103
|
+
vm: availableTools.filter(tool => tool.category === 'vm'),
|
|
104
|
+
orchestration: availableTools.filter(tool => tool.category === 'orchestration'),
|
|
105
|
+
cloud: availableTools.filter(tool => tool.category === 'cloud'),
|
|
106
|
+
other: availableTools.filter(tool => tool.category === 'other')
|
|
107
|
+
};
|
|
108
|
+
Object.entries(categories).forEach(([category, categoryTools]) => {
|
|
109
|
+
if (categoryTools.length > 0) {
|
|
110
|
+
console.log(chalk_1.default.cyan.bold(`š¦ ${category.charAt(0).toUpperCase() + category.slice(1)}:`));
|
|
111
|
+
categoryTools.forEach(tool => {
|
|
112
|
+
const versionText = tool.version ? ` (${tool.version})` : '';
|
|
113
|
+
console.log(chalk_1.default.green(` ā ${tool.name}${versionText}`));
|
|
114
|
+
console.log(chalk_1.default.gray(` ${tool.description}`));
|
|
115
|
+
});
|
|
116
|
+
console.log('');
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
if (unavailableTools.length > 0) {
|
|
120
|
+
console.log(chalk_1.default.gray(`š” ${unavailableTools.length} additional tools not detected (${unavailableTools.map(t => t.name).join(', ')})`));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
static getToolSummary(tools) {
|
|
124
|
+
const availableTools = tools.filter(tool => tool.available);
|
|
125
|
+
const categories = new Set(availableTools.map(tool => tool.category));
|
|
126
|
+
return `${availableTools.length} tools detected across ${categories.size} categories`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
exports.ToolDetector = ToolDetector;
|
|
130
|
+
ToolDetector.tools = [
|
|
131
|
+
// Container runtimes
|
|
132
|
+
{
|
|
133
|
+
name: 'Docker',
|
|
134
|
+
command: 'docker',
|
|
135
|
+
category: 'container',
|
|
136
|
+
description: 'Container runtime and platform',
|
|
137
|
+
available: false
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: 'Podman',
|
|
141
|
+
command: 'podman',
|
|
142
|
+
category: 'container',
|
|
143
|
+
description: 'Daemonless container engine',
|
|
144
|
+
available: false
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: 'Containerd',
|
|
148
|
+
command: 'ctr',
|
|
149
|
+
category: 'container',
|
|
150
|
+
description: 'Container runtime',
|
|
151
|
+
available: false
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: 'LXC',
|
|
155
|
+
command: 'lxc',
|
|
156
|
+
category: 'container',
|
|
157
|
+
description: 'Linux containers',
|
|
158
|
+
available: false
|
|
159
|
+
},
|
|
160
|
+
// VM Management
|
|
161
|
+
{
|
|
162
|
+
name: 'VirtualBox',
|
|
163
|
+
command: 'vboxmanage',
|
|
164
|
+
category: 'vm',
|
|
165
|
+
description: 'Virtual machine management',
|
|
166
|
+
available: false
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: 'VMware',
|
|
170
|
+
command: 'vmrun',
|
|
171
|
+
category: 'vm',
|
|
172
|
+
description: 'VMware virtualization',
|
|
173
|
+
available: false
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: 'QEMU',
|
|
177
|
+
command: 'qemu-system-x86_64',
|
|
178
|
+
category: 'vm',
|
|
179
|
+
description: 'Machine emulator and virtualizer',
|
|
180
|
+
available: false
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: 'KVM',
|
|
184
|
+
command: 'kvm',
|
|
185
|
+
category: 'vm',
|
|
186
|
+
description: 'Kernel-based Virtual Machine',
|
|
187
|
+
available: false
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: 'Hyper-V',
|
|
191
|
+
command: 'powershell',
|
|
192
|
+
category: 'vm',
|
|
193
|
+
description: 'Windows virtualization platform',
|
|
194
|
+
available: false
|
|
195
|
+
},
|
|
196
|
+
// Orchestration
|
|
197
|
+
{
|
|
198
|
+
name: 'Kubernetes',
|
|
199
|
+
command: 'kubectl',
|
|
200
|
+
category: 'orchestration',
|
|
201
|
+
description: 'Container orchestration platform',
|
|
202
|
+
available: false
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'Docker Compose',
|
|
206
|
+
command: 'docker-compose',
|
|
207
|
+
category: 'orchestration',
|
|
208
|
+
description: 'Multi-container Docker applications',
|
|
209
|
+
available: false
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: 'Docker Swarm',
|
|
213
|
+
command: 'docker',
|
|
214
|
+
category: 'orchestration',
|
|
215
|
+
description: 'Docker native clustering',
|
|
216
|
+
available: false
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: 'Nomad',
|
|
220
|
+
command: 'nomad',
|
|
221
|
+
category: 'orchestration',
|
|
222
|
+
description: 'Workload orchestrator',
|
|
223
|
+
available: false
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
name: 'Mesos',
|
|
227
|
+
command: 'mesos-master',
|
|
228
|
+
category: 'orchestration',
|
|
229
|
+
description: 'Distributed systems kernel',
|
|
230
|
+
available: false
|
|
231
|
+
},
|
|
232
|
+
// Cloud CLI Tools
|
|
233
|
+
{
|
|
234
|
+
name: 'AWS CLI',
|
|
235
|
+
command: 'aws',
|
|
236
|
+
category: 'cloud',
|
|
237
|
+
description: 'Amazon Web Services CLI',
|
|
238
|
+
available: false
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: 'Azure CLI',
|
|
242
|
+
command: 'az',
|
|
243
|
+
category: 'cloud',
|
|
244
|
+
description: 'Microsoft Azure CLI',
|
|
245
|
+
available: false
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: 'Google Cloud CLI',
|
|
249
|
+
command: 'gcloud',
|
|
250
|
+
category: 'cloud',
|
|
251
|
+
description: 'Google Cloud Platform CLI',
|
|
252
|
+
available: false
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
name: 'DigitalOcean CLI',
|
|
256
|
+
command: 'doctl',
|
|
257
|
+
category: 'cloud',
|
|
258
|
+
description: 'DigitalOcean CLI',
|
|
259
|
+
available: false
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: 'Terraform',
|
|
263
|
+
command: 'terraform',
|
|
264
|
+
category: 'cloud',
|
|
265
|
+
description: 'Infrastructure as Code',
|
|
266
|
+
available: false
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
name: 'Ansible',
|
|
270
|
+
command: 'ansible',
|
|
271
|
+
category: 'cloud',
|
|
272
|
+
description: 'Configuration management',
|
|
273
|
+
available: false
|
|
274
|
+
},
|
|
275
|
+
// Other Infrastructure Tools
|
|
276
|
+
{
|
|
277
|
+
name: 'Vagrant',
|
|
278
|
+
command: 'vagrant',
|
|
279
|
+
category: 'other',
|
|
280
|
+
description: 'Development environment management',
|
|
281
|
+
available: false
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
name: 'Packer',
|
|
285
|
+
command: 'packer',
|
|
286
|
+
category: 'other',
|
|
287
|
+
description: 'Machine image creation',
|
|
288
|
+
available: false
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
name: 'Helm',
|
|
292
|
+
command: 'helm',
|
|
293
|
+
category: 'other',
|
|
294
|
+
description: 'Kubernetes package manager',
|
|
295
|
+
available: false
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: 'Istio',
|
|
299
|
+
command: 'istioctl',
|
|
300
|
+
category: 'other',
|
|
301
|
+
description: 'Service mesh platform',
|
|
302
|
+
available: false
|
|
303
|
+
}
|
|
304
|
+
];
|
|
305
|
+
//# sourceMappingURL=ToolDetector.js.map
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WorkloadDetector = void 0;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
class WorkloadDetector {
|
|
10
|
+
/**
|
|
11
|
+
* Detect all running workloads from various sources
|
|
12
|
+
*/
|
|
13
|
+
static async detectWorkloads() {
|
|
14
|
+
const workloads = [];
|
|
15
|
+
try {
|
|
16
|
+
// Detect Docker workloads
|
|
17
|
+
const dockerWorkloads = await this.detectDockerWorkloads();
|
|
18
|
+
workloads.push(...dockerWorkloads);
|
|
19
|
+
// Detect Kubernetes workloads
|
|
20
|
+
const k8sWorkloads = await this.detectKubernetesWorkloads();
|
|
21
|
+
workloads.push(...k8sWorkloads);
|
|
22
|
+
// Detect VM workloads
|
|
23
|
+
const vmWorkloads = await this.detectVMWorkloads();
|
|
24
|
+
workloads.push(...vmWorkloads);
|
|
25
|
+
// Detect process-based workloads
|
|
26
|
+
const processWorkloads = await this.detectProcessWorkloads();
|
|
27
|
+
workloads.push(...processWorkloads);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error(chalk_1.default.red('Error detecting workloads:'), error);
|
|
31
|
+
}
|
|
32
|
+
return workloads;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Detect Docker containers
|
|
36
|
+
*/
|
|
37
|
+
static async detectDockerWorkloads() {
|
|
38
|
+
const workloads = [];
|
|
39
|
+
try {
|
|
40
|
+
// Check if Docker is available
|
|
41
|
+
(0, child_process_1.execSync)('docker --version', { encoding: 'utf8', timeout: 5000 });
|
|
42
|
+
// Get running containers
|
|
43
|
+
const output = (0, child_process_1.execSync)('docker ps --format "{{.ID}}|{{.Names}}|{{.Image}}|{{.Status}}|{{.Ports}}"', {
|
|
44
|
+
encoding: 'utf8',
|
|
45
|
+
timeout: 10000
|
|
46
|
+
});
|
|
47
|
+
const lines = output.trim().split('\n').filter(line => line.trim());
|
|
48
|
+
for (const line of lines) {
|
|
49
|
+
const [id, name, image, status, ports] = line.split('|');
|
|
50
|
+
// Parse port mappings
|
|
51
|
+
const portMappings = [];
|
|
52
|
+
if (ports && ports !== '') {
|
|
53
|
+
const portStrings = ports.split(',');
|
|
54
|
+
for (const portString of portStrings) {
|
|
55
|
+
const match = portString.match(/(\d+\.\d+\.\d+\.\d+:)?(\d+)->(\d+)\/(tcp|udp)/);
|
|
56
|
+
if (match) {
|
|
57
|
+
portMappings.push({
|
|
58
|
+
hostIp: match[1] ? match[1].slice(0, -1) : undefined,
|
|
59
|
+
hostPort: parseInt(match[2]),
|
|
60
|
+
containerPort: parseInt(match[3]),
|
|
61
|
+
protocol: match[4]
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Get container IP
|
|
67
|
+
let containerIp;
|
|
68
|
+
try {
|
|
69
|
+
const inspectOutput = (0, child_process_1.execSync)(`docker inspect ${id} --format "{{.NetworkSettings.IPAddress}}"`, {
|
|
70
|
+
encoding: 'utf8',
|
|
71
|
+
timeout: 5000
|
|
72
|
+
});
|
|
73
|
+
containerIp = inspectOutput.trim() || undefined;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
// Ignore errors getting IP
|
|
77
|
+
}
|
|
78
|
+
workloads.push({
|
|
79
|
+
id: id.substring(0, 12), // Short ID
|
|
80
|
+
name: name,
|
|
81
|
+
type: 'docker',
|
|
82
|
+
status: status.includes('Up') ? 'running' : 'stopped',
|
|
83
|
+
image: image,
|
|
84
|
+
ports: portMappings,
|
|
85
|
+
ipAddress: containerIp,
|
|
86
|
+
labels: {},
|
|
87
|
+
description: `Docker container running ${image}`
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
// Docker not available or error
|
|
93
|
+
}
|
|
94
|
+
return workloads;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Detect Kubernetes workloads
|
|
98
|
+
*/
|
|
99
|
+
static async detectKubernetesWorkloads() {
|
|
100
|
+
const workloads = [];
|
|
101
|
+
try {
|
|
102
|
+
// Check if kubectl is available
|
|
103
|
+
(0, child_process_1.execSync)('kubectl version --client', { encoding: 'utf8', timeout: 5000 });
|
|
104
|
+
// Get pods
|
|
105
|
+
const output = (0, child_process_1.execSync)('kubectl get pods --all-namespaces -o json', {
|
|
106
|
+
encoding: 'utf8',
|
|
107
|
+
timeout: 15000
|
|
108
|
+
});
|
|
109
|
+
const data = JSON.parse(output);
|
|
110
|
+
for (const item of data.items || []) {
|
|
111
|
+
const pod = item;
|
|
112
|
+
const status = pod.status?.phase?.toLowerCase() || 'unknown';
|
|
113
|
+
// Get pod IP
|
|
114
|
+
const podIp = pod.status?.podIP;
|
|
115
|
+
// Parse container ports
|
|
116
|
+
const portMappings = [];
|
|
117
|
+
if (pod.spec?.containers) {
|
|
118
|
+
for (const container of pod.spec.containers) {
|
|
119
|
+
if (container.ports) {
|
|
120
|
+
for (const port of container.ports) {
|
|
121
|
+
portMappings.push({
|
|
122
|
+
containerPort: port.containerPort,
|
|
123
|
+
protocol: (port.protocol || 'tcp').toLowerCase(),
|
|
124
|
+
hostPort: port.hostPort
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
workloads.push({
|
|
131
|
+
id: pod.metadata.uid.substring(0, 12),
|
|
132
|
+
name: pod.metadata.name,
|
|
133
|
+
type: 'kubernetes',
|
|
134
|
+
status: status === 'running' ? 'running' : 'stopped',
|
|
135
|
+
image: pod.spec?.containers?.[0]?.image,
|
|
136
|
+
ports: portMappings,
|
|
137
|
+
ipAddress: podIp,
|
|
138
|
+
namespace: pod.metadata.namespace,
|
|
139
|
+
labels: pod.metadata.labels || {},
|
|
140
|
+
createdAt: pod.metadata.creationTimestamp,
|
|
141
|
+
description: `Kubernetes pod in namespace ${pod.metadata.namespace}`
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
// kubectl not available or error
|
|
147
|
+
}
|
|
148
|
+
return workloads;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Detect VM workloads
|
|
152
|
+
*/
|
|
153
|
+
static async detectVMWorkloads() {
|
|
154
|
+
const workloads = [];
|
|
155
|
+
try {
|
|
156
|
+
// Check for VirtualBox VMs
|
|
157
|
+
try {
|
|
158
|
+
const output = (0, child_process_1.execSync)('vboxmanage list runningvms', { encoding: 'utf8', timeout: 10000 });
|
|
159
|
+
const lines = output.trim().split('\n').filter(line => line.trim());
|
|
160
|
+
for (const line of lines) {
|
|
161
|
+
const match = line.match(/^"([^"]+)"\s+\(([^)]+)\)$/);
|
|
162
|
+
if (match) {
|
|
163
|
+
const [, name, uuid] = match;
|
|
164
|
+
workloads.push({
|
|
165
|
+
id: uuid.substring(0, 12),
|
|
166
|
+
name: name,
|
|
167
|
+
type: 'vm',
|
|
168
|
+
status: 'running',
|
|
169
|
+
description: 'VirtualBox virtual machine'
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
// VirtualBox not available
|
|
176
|
+
}
|
|
177
|
+
// Check for VMware VMs
|
|
178
|
+
try {
|
|
179
|
+
const output = (0, child_process_1.execSync)('vmrun list', { encoding: 'utf8', timeout: 10000 });
|
|
180
|
+
const lines = output.trim().split('\n').filter(line => line.trim() && !line.includes('Total running VMs'));
|
|
181
|
+
for (const line of lines) {
|
|
182
|
+
const vmPath = line.trim();
|
|
183
|
+
const vmName = vmPath.split('/').pop()?.replace('.vmx', '') || 'Unknown';
|
|
184
|
+
workloads.push({
|
|
185
|
+
id: vmPath.substring(0, 12),
|
|
186
|
+
name: vmName,
|
|
187
|
+
type: 'vm',
|
|
188
|
+
status: 'running',
|
|
189
|
+
description: 'VMware virtual machine'
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
// VMware not available
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
// VM tools not available
|
|
199
|
+
}
|
|
200
|
+
return workloads;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Detect process-based workloads (web servers, databases, etc.)
|
|
204
|
+
*/
|
|
205
|
+
static async detectProcessWorkloads() {
|
|
206
|
+
const workloads = [];
|
|
207
|
+
try {
|
|
208
|
+
// Common web server and database processes
|
|
209
|
+
const commonProcesses = [
|
|
210
|
+
{ name: 'nginx', port: 80, description: 'Nginx web server' },
|
|
211
|
+
{ name: 'apache2', port: 80, description: 'Apache web server' },
|
|
212
|
+
{ name: 'httpd', port: 80, description: 'Apache HTTP server' },
|
|
213
|
+
{ name: 'node', port: 3000, description: 'Node.js application' },
|
|
214
|
+
{ name: 'python', port: 8000, description: 'Python web application' },
|
|
215
|
+
{ name: 'mysqld', port: 3306, description: 'MySQL database' },
|
|
216
|
+
{ name: 'postgres', port: 5432, description: 'PostgreSQL database' },
|
|
217
|
+
{ name: 'redis-server', port: 6379, description: 'Redis server' },
|
|
218
|
+
{ name: 'mongod', port: 27017, description: 'MongoDB database' }
|
|
219
|
+
];
|
|
220
|
+
for (const process of commonProcesses) {
|
|
221
|
+
try {
|
|
222
|
+
const output = (0, child_process_1.execSync)(`pgrep -f ${process.name}`, { encoding: 'utf8', timeout: 5000 });
|
|
223
|
+
if (output.trim()) {
|
|
224
|
+
const pid = output.trim().split('\n')[0];
|
|
225
|
+
// Try to get the port the process is listening on
|
|
226
|
+
let port;
|
|
227
|
+
try {
|
|
228
|
+
const netstatOutput = (0, child_process_1.execSync)(`netstat -tlnp 2>/dev/null | grep ${pid}`, { encoding: 'utf8', timeout: 5000 });
|
|
229
|
+
const portMatch = netstatOutput.match(/:(\d+)/);
|
|
230
|
+
if (portMatch) {
|
|
231
|
+
port = parseInt(portMatch[1]);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
// Use default port
|
|
236
|
+
port = process.port;
|
|
237
|
+
}
|
|
238
|
+
workloads.push({
|
|
239
|
+
id: pid,
|
|
240
|
+
name: `${process.name}-${pid}`,
|
|
241
|
+
type: 'process',
|
|
242
|
+
status: 'running',
|
|
243
|
+
ports: port ? [{ containerPort: port, protocol: 'tcp' }] : undefined,
|
|
244
|
+
description: process.description
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
// Process not running
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
// Error detecting processes
|
|
255
|
+
}
|
|
256
|
+
return workloads;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Display detected workloads
|
|
260
|
+
*/
|
|
261
|
+
static displayWorkloads(workloads) {
|
|
262
|
+
if (workloads.length === 0) {
|
|
263
|
+
console.log(chalk_1.default.yellow('ā No running workloads detected'));
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
console.log(chalk_1.default.blue.bold('\nš Detected Running Workloads:\n'));
|
|
267
|
+
// Group workloads by type
|
|
268
|
+
const types = {
|
|
269
|
+
docker: workloads.filter(w => w.type === 'docker'),
|
|
270
|
+
kubernetes: workloads.filter(w => w.type === 'kubernetes'),
|
|
271
|
+
vm: workloads.filter(w => w.type === 'vm'),
|
|
272
|
+
process: workloads.filter(w => w.type === 'process')
|
|
273
|
+
};
|
|
274
|
+
Object.entries(types).forEach(([type, typeWorkloads]) => {
|
|
275
|
+
if (typeWorkloads.length > 0) {
|
|
276
|
+
console.log(chalk_1.default.cyan.bold(`š¦ ${type.charAt(0).toUpperCase() + type.slice(1)}:`));
|
|
277
|
+
typeWorkloads.forEach(workload => {
|
|
278
|
+
const statusColor = workload.status === 'running' ? chalk_1.default.green : chalk_1.default.red;
|
|
279
|
+
const statusIcon = workload.status === 'running' ? 'ā' : 'ā';
|
|
280
|
+
console.log(chalk_1.default.white(` ${statusIcon} ${workload.name}`));
|
|
281
|
+
console.log(chalk_1.default.gray(` ID: ${workload.id}`));
|
|
282
|
+
console.log(chalk_1.default.gray(` Status: ${statusColor(workload.status)}`));
|
|
283
|
+
if (workload.image) {
|
|
284
|
+
console.log(chalk_1.default.gray(` Image: ${workload.image}`));
|
|
285
|
+
}
|
|
286
|
+
if (workload.ipAddress) {
|
|
287
|
+
console.log(chalk_1.default.gray(` IP: ${workload.ipAddress}`));
|
|
288
|
+
}
|
|
289
|
+
if (workload.ports && workload.ports.length > 0) {
|
|
290
|
+
const portInfo = workload.ports.map(p => p.hostPort ? `${p.hostPort}:${p.containerPort}` : `${p.containerPort}`).join(', ');
|
|
291
|
+
console.log(chalk_1.default.gray(` Ports: ${portInfo}`));
|
|
292
|
+
}
|
|
293
|
+
if (workload.namespace) {
|
|
294
|
+
console.log(chalk_1.default.gray(` Namespace: ${workload.namespace}`));
|
|
295
|
+
}
|
|
296
|
+
if (workload.description) {
|
|
297
|
+
console.log(chalk_1.default.gray(` ${workload.description}`));
|
|
298
|
+
}
|
|
299
|
+
console.log('');
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Get workload summary
|
|
306
|
+
*/
|
|
307
|
+
static getWorkloadSummary(workloads) {
|
|
308
|
+
const runningWorkloads = workloads.filter(w => w.status === 'running');
|
|
309
|
+
const types = new Set(workloads.map(w => w.type));
|
|
310
|
+
return `${runningWorkloads.length} running workloads across ${types.size} types`;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
exports.WorkloadDetector = WorkloadDetector;
|
|
314
|
+
//# sourceMappingURL=WorkloadDetector.js.map
|