dsh-server-dashboard 0.1.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 +123 -0
- package/cordis.patch.yml +6 -0
- package/dist/client/thresholds.js +11 -0
- package/dist/client/types.js +2 -0
- package/dist/client.js +4606 -0
- package/dist/host/collector.js +878 -0
- package/dist/host/sshconfig.js +68 -0
- package/dist/index.js +718 -0
- package/package.json +78 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export function parseSshConfig(text) {
|
|
2
|
+
const out = [];
|
|
3
|
+
const lines = text.split(/\r?\n/);
|
|
4
|
+
let current = null;
|
|
5
|
+
let hostEntries = [];
|
|
6
|
+
const flush = () => {
|
|
7
|
+
if (current && hostEntries.length > 0 && current.host) {
|
|
8
|
+
for (const alias of hostEntries) {
|
|
9
|
+
if (alias.includes('*') || alias.includes('?'))
|
|
10
|
+
continue; // skip patterns
|
|
11
|
+
out.push({
|
|
12
|
+
alias,
|
|
13
|
+
host: current.host,
|
|
14
|
+
port: current.port ?? 22,
|
|
15
|
+
username: current.username ?? 'root',
|
|
16
|
+
identityFile: current.identityFile,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
current = null;
|
|
21
|
+
hostEntries = [];
|
|
22
|
+
};
|
|
23
|
+
for (const raw of lines) {
|
|
24
|
+
const line = raw.trim();
|
|
25
|
+
if (!line || line.startsWith('#'))
|
|
26
|
+
continue;
|
|
27
|
+
const idx = line.search(/\s|=/);
|
|
28
|
+
if (idx === -1)
|
|
29
|
+
continue;
|
|
30
|
+
let key = line.slice(0, idx).toLowerCase();
|
|
31
|
+
let value = line.slice(idx + 1).trim().replace(/^=/, '').trim();
|
|
32
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
33
|
+
value = value.slice(1, -1);
|
|
34
|
+
}
|
|
35
|
+
switch (key) {
|
|
36
|
+
case 'host':
|
|
37
|
+
flush();
|
|
38
|
+
hostEntries = value.split(/\s+/).filter(Boolean);
|
|
39
|
+
current = {};
|
|
40
|
+
break;
|
|
41
|
+
case 'match':
|
|
42
|
+
// Match 块依赖连接时上下文(用户/主机/命令),静态解析无法判定成立与否 —
|
|
43
|
+
// flush 置空 current 进入丢弃态,块内参数无处并入,直到下一个 Host/Match
|
|
44
|
+
flush();
|
|
45
|
+
break;
|
|
46
|
+
case 'hostname':
|
|
47
|
+
if (current)
|
|
48
|
+
current.host = value;
|
|
49
|
+
break;
|
|
50
|
+
case 'port':
|
|
51
|
+
if (current)
|
|
52
|
+
current.port = Number(value) || 22;
|
|
53
|
+
break;
|
|
54
|
+
case 'user':
|
|
55
|
+
if (current)
|
|
56
|
+
current.username = value;
|
|
57
|
+
break;
|
|
58
|
+
case 'identityfile':
|
|
59
|
+
if (current)
|
|
60
|
+
current.identityFile = value.replace(/^~/, process.env.USERPROFILE ?? '~');
|
|
61
|
+
break;
|
|
62
|
+
default:
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
flush();
|
|
67
|
+
return out;
|
|
68
|
+
}
|