@aristanetworks/eos-mcp-server 0.6.1-beta → 0.8.1-beta
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/CHANGELOG.md +26 -0
- package/README.md +171 -44
- package/dist/config/diagnostics.d.ts +65 -0
- package/dist/config/diagnostics.js +38 -0
- package/dist/config/diagnostics.js.map +1 -0
- package/dist/config/loadConfig.js +1 -0
- package/dist/config/loadConfig.js.map +1 -1
- package/dist/config/schema.d.ts +182 -8
- package/dist/config/schema.js +3 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/diagnostics/concurrency.d.ts +29 -0
- package/dist/diagnostics/concurrency.js +115 -0
- package/dist/diagnostics/concurrency.js.map +1 -0
- package/dist/diagnostics/eapiRunner.d.ts +10 -0
- package/dist/diagnostics/eapiRunner.js +52 -0
- package/dist/diagnostics/eapiRunner.js.map +1 -0
- package/dist/diagnostics/executionError.d.ts +7 -0
- package/dist/diagnostics/executionError.js +10 -0
- package/dist/diagnostics/executionError.js.map +1 -0
- package/dist/diagnostics/executor.d.ts +31 -0
- package/dist/diagnostics/executor.js +114 -0
- package/dist/diagnostics/executor.js.map +1 -0
- package/dist/diagnostics/ping.d.ts +7 -0
- package/dist/diagnostics/ping.js +131 -0
- package/dist/diagnostics/ping.js.map +1 -0
- package/dist/diagnostics/types.d.ts +81 -0
- package/dist/diagnostics/types.js +2 -0
- package/dist/diagnostics/types.js.map +1 -0
- package/dist/eapi/client.d.ts +3 -1
- package/dist/eapi/client.js +18 -6
- package/dist/eapi/client.js.map +1 -1
- package/dist/eapi/types.d.ts +9 -0
- package/dist/eapi/types.js.map +1 -1
- package/dist/inventory/buildModel.js +1 -0
- package/dist/inventory/buildModel.js.map +1 -1
- package/dist/inventory/listInventoryView.d.ts +1 -0
- package/dist/inventory/listInventoryView.js +1 -0
- package/dist/inventory/listInventoryView.js.map +1 -1
- package/dist/inventory/policy.d.ts +1 -0
- package/dist/inventory/policy.js +3 -1
- package/dist/inventory/policy.js.map +1 -1
- package/dist/inventory/types.d.ts +1 -0
- package/dist/inventory/varValidation.js +1 -0
- package/dist/inventory/varValidation.js.map +1 -1
- package/dist/mcp/createServer.js +39 -4
- package/dist/mcp/createServer.js.map +1 -1
- package/dist/mcp/tools/getServerInfo.d.ts +2 -1
- package/dist/mcp/tools/getServerInfo.js +2 -2
- package/dist/mcp/tools/getServerInfo.js.map +1 -1
- package/dist/mcp/tools/ping.d.ts +31 -0
- package/dist/mcp/tools/ping.js +27 -0
- package/dist/mcp/tools/ping.js.map +1 -0
- package/dist/operations/readExecution.d.ts +3 -1
- package/dist/operations/readExecution.js +24 -16
- package/dist/operations/readExecution.js.map +1 -1
- package/dist/serverInfo/buildServerInfo.d.ts +2 -1
- package/dist/serverInfo/buildServerInfo.js +17 -2
- package/dist/serverInfo/buildServerInfo.js.map +1 -1
- package/dist/serverInfo/types.d.ts +16 -0
- package/docs/CHECKPOINT.md +8 -1
- package/docs/CODE_WALKTHROUGH.md +25 -6
- package/docs/DESIGN.md +17 -4
- package/docs/DIAGNOSTICS.md +167 -0
- package/docs/IMPLEMENTATION_PLAN.md +4 -3
- package/docs/QUICKSTART.md +13 -13
- package/docs/adr/0001-non-configuring-diagnostics.md +5 -0
- package/docs/adr/0002-fail-closed-diagnostic-reservations.md +9 -0
- package/docs/adr/0003-durable-diagnostic-ledger.md +11 -0
- package/docs/adr/0004-offline-operator-attested-release.md +7 -0
- package/docs/adr/0005-multi-destination-ping.md +9 -0
- package/docs/adr/0006-in-memory-timed-diagnostic-capacity.md +21 -0
- package/docs/research/eos-diagnostic-lifecycle.md +86 -0
- package/package.json +1 -1
- package/dist/inventory/writePolicy.d.ts +0 -2
- package/dist/inventory/writePolicy.js +0 -36
- package/dist/inventory/writePolicy.js.map +0 -1
package/dist/config/schema.d.ts
CHANGED
|
@@ -1,6 +1,67 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare const serverConfigFileSchema: z.ZodObject<{
|
|
3
3
|
version: z.ZodOptional<z.ZodLiteral<1>>;
|
|
4
|
+
diagnostics: z.ZodOptional<z.ZodEffects<z.ZodObject<{
|
|
5
|
+
stateFile: z.ZodOptional<z.ZodNever>;
|
|
6
|
+
defaultPingCount: z.ZodDefault<z.ZodNumber>;
|
|
7
|
+
maxPingCount: z.ZodDefault<z.ZodNumber>;
|
|
8
|
+
maxProbesPerRequest: z.ZodDefault<z.ZodNumber>;
|
|
9
|
+
maxDestinationsPerRequest: z.ZodDefault<z.ZodNumber>;
|
|
10
|
+
deviceConcurrency: z.ZodDefault<z.ZodNumber>;
|
|
11
|
+
pingReplyTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
12
|
+
commandTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
13
|
+
httpTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
14
|
+
overallOperationTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
15
|
+
nativeRequestTimeout: z.ZodDefault<z.ZodBoolean>;
|
|
16
|
+
}, "strict", z.ZodTypeAny, {
|
|
17
|
+
defaultPingCount: number;
|
|
18
|
+
maxPingCount: number;
|
|
19
|
+
maxProbesPerRequest: number;
|
|
20
|
+
maxDestinationsPerRequest: number;
|
|
21
|
+
deviceConcurrency: number;
|
|
22
|
+
pingReplyTimeoutMs: number;
|
|
23
|
+
commandTimeoutMs: number;
|
|
24
|
+
httpTimeoutMs: number;
|
|
25
|
+
overallOperationTimeoutMs: number;
|
|
26
|
+
nativeRequestTimeout: boolean;
|
|
27
|
+
stateFile?: undefined;
|
|
28
|
+
}, {
|
|
29
|
+
stateFile?: undefined;
|
|
30
|
+
defaultPingCount?: number | undefined;
|
|
31
|
+
maxPingCount?: number | undefined;
|
|
32
|
+
maxProbesPerRequest?: number | undefined;
|
|
33
|
+
maxDestinationsPerRequest?: number | undefined;
|
|
34
|
+
deviceConcurrency?: number | undefined;
|
|
35
|
+
pingReplyTimeoutMs?: number | undefined;
|
|
36
|
+
commandTimeoutMs?: number | undefined;
|
|
37
|
+
httpTimeoutMs?: number | undefined;
|
|
38
|
+
overallOperationTimeoutMs?: number | undefined;
|
|
39
|
+
nativeRequestTimeout?: boolean | undefined;
|
|
40
|
+
}>, {
|
|
41
|
+
defaultPingCount: number;
|
|
42
|
+
maxPingCount: number;
|
|
43
|
+
maxProbesPerRequest: number;
|
|
44
|
+
maxDestinationsPerRequest: number;
|
|
45
|
+
deviceConcurrency: number;
|
|
46
|
+
pingReplyTimeoutMs: number;
|
|
47
|
+
commandTimeoutMs: number;
|
|
48
|
+
httpTimeoutMs: number;
|
|
49
|
+
overallOperationTimeoutMs: number;
|
|
50
|
+
nativeRequestTimeout: boolean;
|
|
51
|
+
stateFile?: undefined;
|
|
52
|
+
}, {
|
|
53
|
+
stateFile?: undefined;
|
|
54
|
+
defaultPingCount?: number | undefined;
|
|
55
|
+
maxPingCount?: number | undefined;
|
|
56
|
+
maxProbesPerRequest?: number | undefined;
|
|
57
|
+
maxDestinationsPerRequest?: number | undefined;
|
|
58
|
+
deviceConcurrency?: number | undefined;
|
|
59
|
+
pingReplyTimeoutMs?: number | undefined;
|
|
60
|
+
commandTimeoutMs?: number | undefined;
|
|
61
|
+
httpTimeoutMs?: number | undefined;
|
|
62
|
+
overallOperationTimeoutMs?: number | undefined;
|
|
63
|
+
nativeRequestTimeout?: boolean | undefined;
|
|
64
|
+
}>>;
|
|
4
65
|
inventory: z.ZodOptional<z.ZodString>;
|
|
5
66
|
actor: z.ZodOptional<z.ZodString>;
|
|
6
67
|
logFile: z.ZodOptional<z.ZodString>;
|
|
@@ -31,14 +92,27 @@ export declare const serverConfigFileSchema: z.ZodObject<{
|
|
|
31
92
|
mcpPasswordEnv?: string | undefined;
|
|
32
93
|
}>>;
|
|
33
94
|
}, "strict", z.ZodTypeAny, {
|
|
95
|
+
deviceConcurrency?: number | undefined;
|
|
96
|
+
overallOperationTimeoutMs?: number | undefined;
|
|
34
97
|
version?: 1 | undefined;
|
|
98
|
+
diagnostics?: {
|
|
99
|
+
defaultPingCount: number;
|
|
100
|
+
maxPingCount: number;
|
|
101
|
+
maxProbesPerRequest: number;
|
|
102
|
+
maxDestinationsPerRequest: number;
|
|
103
|
+
deviceConcurrency: number;
|
|
104
|
+
pingReplyTimeoutMs: number;
|
|
105
|
+
commandTimeoutMs: number;
|
|
106
|
+
httpTimeoutMs: number;
|
|
107
|
+
overallOperationTimeoutMs: number;
|
|
108
|
+
nativeRequestTimeout: boolean;
|
|
109
|
+
stateFile?: undefined;
|
|
110
|
+
} | undefined;
|
|
35
111
|
inventory?: string | undefined;
|
|
36
112
|
actor?: string | undefined;
|
|
37
113
|
logFile?: string | undefined;
|
|
38
114
|
caFile?: string | undefined;
|
|
39
115
|
readTimeoutMs?: number | undefined;
|
|
40
|
-
overallOperationTimeoutMs?: number | undefined;
|
|
41
|
-
deviceConcurrency?: number | undefined;
|
|
42
116
|
maxReadTargets?: number | undefined;
|
|
43
117
|
maxShowCommandsPerRequest?: number | undefined;
|
|
44
118
|
maxLoggingMessagesPerRequest?: number | undefined;
|
|
@@ -52,14 +126,27 @@ export declare const serverConfigFileSchema: z.ZodObject<{
|
|
|
52
126
|
mcpPasswordEnv?: string | undefined;
|
|
53
127
|
} | undefined;
|
|
54
128
|
}, {
|
|
129
|
+
deviceConcurrency?: number | undefined;
|
|
130
|
+
overallOperationTimeoutMs?: number | undefined;
|
|
55
131
|
version?: 1 | undefined;
|
|
132
|
+
diagnostics?: {
|
|
133
|
+
stateFile?: undefined;
|
|
134
|
+
defaultPingCount?: number | undefined;
|
|
135
|
+
maxPingCount?: number | undefined;
|
|
136
|
+
maxProbesPerRequest?: number | undefined;
|
|
137
|
+
maxDestinationsPerRequest?: number | undefined;
|
|
138
|
+
deviceConcurrency?: number | undefined;
|
|
139
|
+
pingReplyTimeoutMs?: number | undefined;
|
|
140
|
+
commandTimeoutMs?: number | undefined;
|
|
141
|
+
httpTimeoutMs?: number | undefined;
|
|
142
|
+
overallOperationTimeoutMs?: number | undefined;
|
|
143
|
+
nativeRequestTimeout?: boolean | undefined;
|
|
144
|
+
} | undefined;
|
|
56
145
|
inventory?: string | undefined;
|
|
57
146
|
actor?: string | undefined;
|
|
58
147
|
logFile?: string | undefined;
|
|
59
148
|
caFile?: string | undefined;
|
|
60
149
|
readTimeoutMs?: number | undefined;
|
|
61
|
-
overallOperationTimeoutMs?: number | undefined;
|
|
62
|
-
deviceConcurrency?: number | undefined;
|
|
63
150
|
maxReadTargets?: number | undefined;
|
|
64
151
|
maxShowCommandsPerRequest?: number | undefined;
|
|
65
152
|
maxLoggingMessagesPerRequest?: number | undefined;
|
|
@@ -75,6 +162,67 @@ export declare const serverConfigFileSchema: z.ZodObject<{
|
|
|
75
162
|
}>;
|
|
76
163
|
export declare const resolvedServerConfigSchema: z.ZodObject<{
|
|
77
164
|
configPath: z.ZodOptional<z.ZodString>;
|
|
165
|
+
diagnostics: z.ZodDefault<z.ZodEffects<z.ZodObject<{
|
|
166
|
+
stateFile: z.ZodOptional<z.ZodNever>;
|
|
167
|
+
defaultPingCount: z.ZodDefault<z.ZodNumber>;
|
|
168
|
+
maxPingCount: z.ZodDefault<z.ZodNumber>;
|
|
169
|
+
maxProbesPerRequest: z.ZodDefault<z.ZodNumber>;
|
|
170
|
+
maxDestinationsPerRequest: z.ZodDefault<z.ZodNumber>;
|
|
171
|
+
deviceConcurrency: z.ZodDefault<z.ZodNumber>;
|
|
172
|
+
pingReplyTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
173
|
+
commandTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
174
|
+
httpTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
175
|
+
overallOperationTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
176
|
+
nativeRequestTimeout: z.ZodDefault<z.ZodBoolean>;
|
|
177
|
+
}, "strict", z.ZodTypeAny, {
|
|
178
|
+
defaultPingCount: number;
|
|
179
|
+
maxPingCount: number;
|
|
180
|
+
maxProbesPerRequest: number;
|
|
181
|
+
maxDestinationsPerRequest: number;
|
|
182
|
+
deviceConcurrency: number;
|
|
183
|
+
pingReplyTimeoutMs: number;
|
|
184
|
+
commandTimeoutMs: number;
|
|
185
|
+
httpTimeoutMs: number;
|
|
186
|
+
overallOperationTimeoutMs: number;
|
|
187
|
+
nativeRequestTimeout: boolean;
|
|
188
|
+
stateFile?: undefined;
|
|
189
|
+
}, {
|
|
190
|
+
stateFile?: undefined;
|
|
191
|
+
defaultPingCount?: number | undefined;
|
|
192
|
+
maxPingCount?: number | undefined;
|
|
193
|
+
maxProbesPerRequest?: number | undefined;
|
|
194
|
+
maxDestinationsPerRequest?: number | undefined;
|
|
195
|
+
deviceConcurrency?: number | undefined;
|
|
196
|
+
pingReplyTimeoutMs?: number | undefined;
|
|
197
|
+
commandTimeoutMs?: number | undefined;
|
|
198
|
+
httpTimeoutMs?: number | undefined;
|
|
199
|
+
overallOperationTimeoutMs?: number | undefined;
|
|
200
|
+
nativeRequestTimeout?: boolean | undefined;
|
|
201
|
+
}>, {
|
|
202
|
+
defaultPingCount: number;
|
|
203
|
+
maxPingCount: number;
|
|
204
|
+
maxProbesPerRequest: number;
|
|
205
|
+
maxDestinationsPerRequest: number;
|
|
206
|
+
deviceConcurrency: number;
|
|
207
|
+
pingReplyTimeoutMs: number;
|
|
208
|
+
commandTimeoutMs: number;
|
|
209
|
+
httpTimeoutMs: number;
|
|
210
|
+
overallOperationTimeoutMs: number;
|
|
211
|
+
nativeRequestTimeout: boolean;
|
|
212
|
+
stateFile?: undefined;
|
|
213
|
+
}, {
|
|
214
|
+
stateFile?: undefined;
|
|
215
|
+
defaultPingCount?: number | undefined;
|
|
216
|
+
maxPingCount?: number | undefined;
|
|
217
|
+
maxProbesPerRequest?: number | undefined;
|
|
218
|
+
maxDestinationsPerRequest?: number | undefined;
|
|
219
|
+
deviceConcurrency?: number | undefined;
|
|
220
|
+
pingReplyTimeoutMs?: number | undefined;
|
|
221
|
+
commandTimeoutMs?: number | undefined;
|
|
222
|
+
httpTimeoutMs?: number | undefined;
|
|
223
|
+
overallOperationTimeoutMs?: number | undefined;
|
|
224
|
+
nativeRequestTimeout?: boolean | undefined;
|
|
225
|
+
}>>;
|
|
78
226
|
inventoryPath: z.ZodOptional<z.ZodString>;
|
|
79
227
|
actor: z.ZodOptional<z.ZodString>;
|
|
80
228
|
logFile: z.ZodOptional<z.ZodString>;
|
|
@@ -105,8 +253,21 @@ export declare const resolvedServerConfigSchema: z.ZodObject<{
|
|
|
105
253
|
mcpPasswordEnv?: string | undefined;
|
|
106
254
|
}>>;
|
|
107
255
|
}, "strip", z.ZodTypeAny, {
|
|
108
|
-
readTimeoutMs: number;
|
|
109
256
|
deviceConcurrency: number;
|
|
257
|
+
diagnostics: {
|
|
258
|
+
defaultPingCount: number;
|
|
259
|
+
maxPingCount: number;
|
|
260
|
+
maxProbesPerRequest: number;
|
|
261
|
+
maxDestinationsPerRequest: number;
|
|
262
|
+
deviceConcurrency: number;
|
|
263
|
+
pingReplyTimeoutMs: number;
|
|
264
|
+
commandTimeoutMs: number;
|
|
265
|
+
httpTimeoutMs: number;
|
|
266
|
+
overallOperationTimeoutMs: number;
|
|
267
|
+
nativeRequestTimeout: boolean;
|
|
268
|
+
stateFile?: undefined;
|
|
269
|
+
};
|
|
270
|
+
readTimeoutMs: number;
|
|
110
271
|
maxReadTargets: number;
|
|
111
272
|
maxShowCommandsPerRequest: number;
|
|
112
273
|
maxLoggingMessagesPerRequest: number;
|
|
@@ -119,19 +280,32 @@ export declare const resolvedServerConfigSchema: z.ZodObject<{
|
|
|
119
280
|
mcpValidateCerts?: boolean | undefined;
|
|
120
281
|
mcpPasswordEnv?: string | undefined;
|
|
121
282
|
};
|
|
283
|
+
overallOperationTimeoutMs?: number | undefined;
|
|
122
284
|
actor?: string | undefined;
|
|
123
285
|
logFile?: string | undefined;
|
|
124
286
|
caFile?: string | undefined;
|
|
125
|
-
overallOperationTimeoutMs?: number | undefined;
|
|
126
287
|
configPath?: string | undefined;
|
|
127
288
|
inventoryPath?: string | undefined;
|
|
128
289
|
}, {
|
|
290
|
+
deviceConcurrency?: number | undefined;
|
|
291
|
+
overallOperationTimeoutMs?: number | undefined;
|
|
292
|
+
diagnostics?: {
|
|
293
|
+
stateFile?: undefined;
|
|
294
|
+
defaultPingCount?: number | undefined;
|
|
295
|
+
maxPingCount?: number | undefined;
|
|
296
|
+
maxProbesPerRequest?: number | undefined;
|
|
297
|
+
maxDestinationsPerRequest?: number | undefined;
|
|
298
|
+
deviceConcurrency?: number | undefined;
|
|
299
|
+
pingReplyTimeoutMs?: number | undefined;
|
|
300
|
+
commandTimeoutMs?: number | undefined;
|
|
301
|
+
httpTimeoutMs?: number | undefined;
|
|
302
|
+
overallOperationTimeoutMs?: number | undefined;
|
|
303
|
+
nativeRequestTimeout?: boolean | undefined;
|
|
304
|
+
} | undefined;
|
|
129
305
|
actor?: string | undefined;
|
|
130
306
|
logFile?: string | undefined;
|
|
131
307
|
caFile?: string | undefined;
|
|
132
308
|
readTimeoutMs?: number | undefined;
|
|
133
|
-
overallOperationTimeoutMs?: number | undefined;
|
|
134
|
-
deviceConcurrency?: number | undefined;
|
|
135
309
|
maxReadTargets?: number | undefined;
|
|
136
310
|
maxShowCommandsPerRequest?: number | undefined;
|
|
137
311
|
maxLoggingMessagesPerRequest?: number | undefined;
|
package/dist/config/schema.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { diagnosticsConfigSchema } from "./diagnostics.js";
|
|
2
3
|
const eapiVersionSchema = z.union([z.literal(1), z.literal("latest")]);
|
|
3
4
|
export const serverConfigFileSchema = z
|
|
4
5
|
.object({
|
|
5
6
|
version: z.literal(1).optional(),
|
|
7
|
+
diagnostics: diagnosticsConfigSchema.optional(),
|
|
6
8
|
inventory: z.string().min(1).optional(),
|
|
7
9
|
actor: z.string().min(1).optional(),
|
|
8
10
|
logFile: z.string().min(1).optional(),
|
|
@@ -29,6 +31,7 @@ export const serverConfigFileSchema = z
|
|
|
29
31
|
export const resolvedServerConfigSchema = z
|
|
30
32
|
.object({
|
|
31
33
|
configPath: z.string().min(1).optional(),
|
|
34
|
+
diagnostics: diagnosticsConfigSchema.default({}),
|
|
32
35
|
inventoryPath: z.string().min(1).optional(),
|
|
33
36
|
actor: z.string().min(1).optional(),
|
|
34
37
|
logFile: z.string().min(1).optional(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { DiagnosticCapacitySnapshot, DiagnosticRequest } from "./types.js";
|
|
2
|
+
interface DiagnosticReservationIntent {
|
|
3
|
+
inventoryHostname: string;
|
|
4
|
+
diagnostic: DiagnosticRequest["kind"];
|
|
5
|
+
}
|
|
6
|
+
export interface DiagnosticReservation {
|
|
7
|
+
readonly requestId: string;
|
|
8
|
+
complete(): void;
|
|
9
|
+
markUncertain(reasonCode: string): void;
|
|
10
|
+
}
|
|
11
|
+
/** One instance per server process. A slot with unknown remote completion stays held for the
|
|
12
|
+
* execution budget, then frees itself; a late confirmed response frees it sooner (ADR 0006).
|
|
13
|
+
*/
|
|
14
|
+
export declare class DiagnosticConcurrency {
|
|
15
|
+
private readonly limit;
|
|
16
|
+
private readonly uncertainHoldMs;
|
|
17
|
+
/** Held slots; an uncertain slot carries the timer that frees it. */
|
|
18
|
+
private readonly reservations;
|
|
19
|
+
private readonly waiting;
|
|
20
|
+
private closed;
|
|
21
|
+
constructor(limit: number, uncertainHoldMs: number);
|
|
22
|
+
close(): void;
|
|
23
|
+
snapshot(): DiagnosticCapacitySnapshot;
|
|
24
|
+
acquire(signal: AbortSignal, intent: DiagnosticReservationIntent): Promise<DiagnosticReservation>;
|
|
25
|
+
private reserve;
|
|
26
|
+
private free;
|
|
27
|
+
private markUncertain;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { AppError } from "../core/errors.js";
|
|
3
|
+
/** One instance per server process. A slot with unknown remote completion stays held for the
|
|
4
|
+
* execution budget, then frees itself; a late confirmed response frees it sooner (ADR 0006).
|
|
5
|
+
*/
|
|
6
|
+
export class DiagnosticConcurrency {
|
|
7
|
+
limit;
|
|
8
|
+
uncertainHoldMs;
|
|
9
|
+
/** Held slots; an uncertain slot carries the timer that frees it. */
|
|
10
|
+
reservations = new Map();
|
|
11
|
+
waiting = [];
|
|
12
|
+
closed = false;
|
|
13
|
+
constructor(limit, uncertainHoldMs) {
|
|
14
|
+
this.limit = limit;
|
|
15
|
+
this.uncertainHoldMs = uncertainHoldMs;
|
|
16
|
+
}
|
|
17
|
+
close() {
|
|
18
|
+
if (this.closed)
|
|
19
|
+
return;
|
|
20
|
+
this.closed = true;
|
|
21
|
+
for (const timer of this.reservations.values())
|
|
22
|
+
clearTimeout(timer);
|
|
23
|
+
const error = closedError();
|
|
24
|
+
for (const waiter of this.waiting.splice(0))
|
|
25
|
+
waiter.reject(error);
|
|
26
|
+
}
|
|
27
|
+
snapshot() {
|
|
28
|
+
const reservations = Array.from(this.reservations.keys(), (reservation) => ({ ...reservation }));
|
|
29
|
+
const uncertain = reservations.filter((reservation) => reservation.state === "uncertain").length;
|
|
30
|
+
return {
|
|
31
|
+
limit: this.limit,
|
|
32
|
+
available_count: this.closed ? 0 : Math.max(0, this.limit - reservations.length),
|
|
33
|
+
active_count: reservations.length - uncertain,
|
|
34
|
+
uncertain_count: uncertain,
|
|
35
|
+
queued_count: this.waiting.length,
|
|
36
|
+
reservations
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
acquire(signal, intent) {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
if (signal.aborted) {
|
|
42
|
+
reject(abortedError());
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (this.closed) {
|
|
46
|
+
reject(closedError());
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const cancelled = () => {
|
|
50
|
+
const index = this.waiting.indexOf(waiter);
|
|
51
|
+
if (index >= 0)
|
|
52
|
+
this.waiting.splice(index, 1);
|
|
53
|
+
waiter.reject(abortedError());
|
|
54
|
+
};
|
|
55
|
+
const waiter = {
|
|
56
|
+
reject: (error) => {
|
|
57
|
+
signal.removeEventListener("abort", cancelled);
|
|
58
|
+
reject(error);
|
|
59
|
+
},
|
|
60
|
+
grant: () => {
|
|
61
|
+
signal.removeEventListener("abort", cancelled);
|
|
62
|
+
resolve(this.reserve(intent));
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
if (this.reservations.size < this.limit) {
|
|
66
|
+
waiter.grant();
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
this.waiting.push(waiter);
|
|
70
|
+
signal.addEventListener("abort", cancelled, { once: true });
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
reserve(intent) {
|
|
75
|
+
const requestId = randomUUID();
|
|
76
|
+
const state = {
|
|
77
|
+
reservation_id: requestId,
|
|
78
|
+
inventory_hostname: intent.inventoryHostname,
|
|
79
|
+
diagnostic: intent.diagnostic,
|
|
80
|
+
state: "active",
|
|
81
|
+
reserved_at: new Date().toISOString()
|
|
82
|
+
};
|
|
83
|
+
this.reservations.set(state, undefined);
|
|
84
|
+
return {
|
|
85
|
+
requestId,
|
|
86
|
+
complete: () => this.free(state),
|
|
87
|
+
markUncertain: (reasonCode) => this.markUncertain(state, reasonCode)
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
free(state) {
|
|
91
|
+
if (!this.reservations.has(state))
|
|
92
|
+
return;
|
|
93
|
+
clearTimeout(this.reservations.get(state));
|
|
94
|
+
this.reservations.delete(state);
|
|
95
|
+
this.waiting.shift()?.grant();
|
|
96
|
+
}
|
|
97
|
+
markUncertain(state, reasonCode) {
|
|
98
|
+
if (this.closed || !this.reservations.has(state) || state.state === "uncertain")
|
|
99
|
+
return;
|
|
100
|
+
const now = Date.now();
|
|
101
|
+
state.state = "uncertain";
|
|
102
|
+
state.uncertain_since = new Date(now).toISOString();
|
|
103
|
+
state.releases_at = new Date(now + this.uncertainHoldMs).toISOString();
|
|
104
|
+
state.reason_code = reasonCode;
|
|
105
|
+
// Unref so a held slot never keeps a stopping server alive.
|
|
106
|
+
this.reservations.set(state, setTimeout(() => this.free(state), this.uncertainHoldMs).unref());
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function closedError() {
|
|
110
|
+
return new AppError("diagnostic_server_stopping", "Diagnostic execution is shutting down");
|
|
111
|
+
}
|
|
112
|
+
function abortedError() {
|
|
113
|
+
return new AppError("operation_aborted", "Diagnostic was cancelled while waiting for capacity");
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=concurrency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../src/diagnostics/concurrency.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ResolvedServerConfig } from "../config/schema.js";
|
|
2
|
+
import type { EosTextCommandRunner } from "../eapi/types.js";
|
|
3
|
+
import type { InventoryHostModel } from "../inventory/types.js";
|
|
4
|
+
import type { DiagnosticDeviceRunner, DiagnosticExecutionContext, DiagnosticObservation, PreparedDiagnostic } from "./types.js";
|
|
5
|
+
export declare class EapiDiagnosticRunner implements DiagnosticDeviceRunner {
|
|
6
|
+
private readonly config;
|
|
7
|
+
private readonly runner;
|
|
8
|
+
constructor(config: ResolvedServerConfig, runner: EosTextCommandRunner);
|
|
9
|
+
execute(host: InventoryHostModel, request: PreparedDiagnostic, context: DiagnosticExecutionContext): Promise<DiagnosticObservation>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { resolveEapiConnection } from "../connection/resolveConnection.js";
|
|
2
|
+
import { AppError, toErrorCode, toErrorMessage } from "../core/errors.js";
|
|
3
|
+
import { isObject } from "../utils/value.js";
|
|
4
|
+
import { DiagnosticExecutionError } from "./executionError.js";
|
|
5
|
+
import { buildPingCommand } from "./ping.js";
|
|
6
|
+
export class EapiDiagnosticRunner {
|
|
7
|
+
config;
|
|
8
|
+
runner;
|
|
9
|
+
constructor(config, runner) {
|
|
10
|
+
this.config = config;
|
|
11
|
+
this.runner = runner;
|
|
12
|
+
}
|
|
13
|
+
async execute(host, request, context) {
|
|
14
|
+
let connection;
|
|
15
|
+
try {
|
|
16
|
+
connection = { ...resolveEapiConnection(this.config, host), timeoutMs: this.config.diagnostics.httpTimeoutMs };
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
throw new DiagnosticExecutionError(toErrorCode(error, "diagnostic_execution_failed"), toErrorMessage(error), "not_dispatched");
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const results = await this.runner.runTextCommands(connection, [buildPingCommand(request)], {
|
|
23
|
+
enable: true,
|
|
24
|
+
signal: context.signal,
|
|
25
|
+
requestId: context.requestId,
|
|
26
|
+
// Lets EOS stop the command itself at the same budget the server holds an uncertain slot for.
|
|
27
|
+
...(this.config.diagnostics.nativeRequestTimeout ? { requestTimeoutSeconds: this.config.diagnostics.commandTimeoutMs / 1000 } : {})
|
|
28
|
+
});
|
|
29
|
+
const output = results[0]?.output;
|
|
30
|
+
if (results.length !== 1 || typeof output !== "string") {
|
|
31
|
+
throw new DiagnosticExecutionError("diagnostic_output_unrecognized", "Expected one text result from EOS", "unknown");
|
|
32
|
+
}
|
|
33
|
+
return { kind: request.kind, output };
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
// After dispatch, an error is never proof that remote work has stopped.
|
|
37
|
+
const code = toErrorCode(error, "diagnostic_execution_failed");
|
|
38
|
+
if (!["eapi_json_rpc_error", "json_output_unavailable", "eapi_http_error", "eapi_response_invalid_json"].includes(code))
|
|
39
|
+
throw error;
|
|
40
|
+
const data = error instanceof AppError ? error.details?.data : undefined;
|
|
41
|
+
const text = Array.isArray(data)
|
|
42
|
+
? data.filter(isObject).map((entry) => entry.output).filter((entry) => typeof entry === "string").join("")
|
|
43
|
+
: undefined;
|
|
44
|
+
// Preserve EOS error evidence internally; only the executor's explicit
|
|
45
|
+
// includeRaw path may expose it. RPC error messages contain raw data.
|
|
46
|
+
throw new DiagnosticExecutionError(code, `EOS diagnostic request failed (${code})`, "unknown", {
|
|
47
|
+
raw_output: text || toErrorMessage(error)
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=eapiRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eapiRunner.js","sourceRoot":"","sources":["../../src/diagnostics/eapiRunner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AppError } from "../core/errors.js";
|
|
2
|
+
export type DiagnosticExecutionState = "not_dispatched" | "completed" | "unknown";
|
|
3
|
+
/** Explicit adapter classification; ordinary errors leave execution state unknown. */
|
|
4
|
+
export declare class DiagnosticExecutionError extends AppError {
|
|
5
|
+
readonly executionState: DiagnosticExecutionState;
|
|
6
|
+
constructor(code: string, message: string, executionState: DiagnosticExecutionState, details?: Record<string, unknown>);
|
|
7
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AppError } from "../core/errors.js";
|
|
2
|
+
/** Explicit adapter classification; ordinary errors leave execution state unknown. */
|
|
3
|
+
export class DiagnosticExecutionError extends AppError {
|
|
4
|
+
executionState;
|
|
5
|
+
constructor(code, message, executionState, details) {
|
|
6
|
+
super(code, message, details);
|
|
7
|
+
this.executionState = executionState;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=executionError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executionError.js","sourceRoot":"","sources":["../../src/diagnostics/executionError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C,sFAAsF;AACtF,MAAM,OAAO,wBAAyB,SAAQ,QAAQ;IAIzC;IAHX,YACE,IAAY,EACZ,OAAe,EACN,cAAwC,EACjD,OAAiC;QAEjC,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAHrB,mBAAc,GAAd,cAAc,CAA0B;IAInD,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ResolvedServerConfig } from "../config/schema.js";
|
|
2
|
+
import type { InventoryModel } from "../inventory/types.js";
|
|
3
|
+
import { type ReadDeviceResultBase, type ReadOperationResultEnvelope } from "../operations/readExecution.js";
|
|
4
|
+
import type { DiagnosticCapacitySnapshot, DiagnosticDeviceRunner, DiagnosticFinding, DiagnosticRequest, ResolvedDiagnosticRequest } from "./types.js";
|
|
5
|
+
export interface DiagnosticDeviceResult extends ReadDeviceResultBase {
|
|
6
|
+
destination: string;
|
|
7
|
+
finding?: DiagnosticFinding;
|
|
8
|
+
raw_output?: string;
|
|
9
|
+
}
|
|
10
|
+
export type DiagnosticResult = ReadOperationResultEnvelope<DiagnosticDeviceResult> & {
|
|
11
|
+
request: ResolvedDiagnosticRequest;
|
|
12
|
+
};
|
|
13
|
+
/** Owns policy, budgets, fan-out, global admission, cancellation, and result normalization. */
|
|
14
|
+
export declare class DiagnosticExecutor {
|
|
15
|
+
private readonly model;
|
|
16
|
+
private readonly config;
|
|
17
|
+
private readonly runner;
|
|
18
|
+
private readonly concurrency;
|
|
19
|
+
private readonly shutdown;
|
|
20
|
+
constructor(model: InventoryModel, config: ResolvedServerConfig, runner: DiagnosticDeviceRunner);
|
|
21
|
+
close(): void;
|
|
22
|
+
getCapacity(): DiagnosticCapacitySnapshot;
|
|
23
|
+
execute(options: {
|
|
24
|
+
target: string;
|
|
25
|
+
request: DiagnosticRequest;
|
|
26
|
+
includeRaw?: boolean;
|
|
27
|
+
signal?: AbortSignal;
|
|
28
|
+
}): Promise<DiagnosticResult>;
|
|
29
|
+
private runExecution;
|
|
30
|
+
private executeOnDevice;
|
|
31
|
+
}
|