@sonde/packs 0.1.2 → 0.1.3

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 (105) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +39 -35
  3. package/CHANGELOG.md +9 -0
  4. package/dist/docker/manifest (# Edit conflict 2026-02-19 LIl7ilN #).js +54 -0
  5. package/dist/index.d.ts +9 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +9 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/integrations/a10.d.ts +3 -0
  10. package/dist/integrations/a10.d.ts.map +1 -0
  11. package/dist/integrations/a10.js +218 -0
  12. package/dist/integrations/a10.js.map +1 -0
  13. package/dist/integrations/checkpoint.d.ts +3 -0
  14. package/dist/integrations/checkpoint.d.ts.map +1 -0
  15. package/dist/integrations/checkpoint.js +249 -0
  16. package/dist/integrations/checkpoint.js.map +1 -0
  17. package/dist/integrations/datadog.d.ts +3 -0
  18. package/dist/integrations/datadog.d.ts.map +1 -0
  19. package/dist/integrations/datadog.js +195 -0
  20. package/dist/integrations/datadog.js.map +1 -0
  21. package/dist/integrations/jira.d.ts +3 -0
  22. package/dist/integrations/jira.d.ts.map +1 -0
  23. package/dist/integrations/jira.js +199 -0
  24. package/dist/integrations/jira.js.map +1 -0
  25. package/dist/integrations/loki.d.ts +3 -0
  26. package/dist/integrations/loki.d.ts.map +1 -0
  27. package/dist/integrations/loki.js +178 -0
  28. package/dist/integrations/loki.js.map +1 -0
  29. package/dist/integrations/meraki.d.ts +3 -0
  30. package/dist/integrations/meraki.d.ts.map +1 -0
  31. package/dist/integrations/meraki.js +238 -0
  32. package/dist/integrations/meraki.js.map +1 -0
  33. package/dist/integrations/pagerduty.d.ts +3 -0
  34. package/dist/integrations/pagerduty.d.ts.map +1 -0
  35. package/dist/integrations/pagerduty.js +229 -0
  36. package/dist/integrations/pagerduty.js.map +1 -0
  37. package/dist/integrations/thousandeyes.d.ts +3 -0
  38. package/dist/integrations/thousandeyes.d.ts.map +1 -0
  39. package/dist/integrations/thousandeyes.js +263 -0
  40. package/dist/integrations/thousandeyes.js.map +1 -0
  41. package/dist/integrations/vcenter.d.ts +3 -0
  42. package/dist/integrations/vcenter.d.ts.map +1 -0
  43. package/dist/integrations/vcenter.js +190 -0
  44. package/dist/integrations/vcenter.js.map +1 -0
  45. package/dist/proxmox/probes/ceph-status.test.d.ts (# Edit conflict 2026-02-19 N25hAvJ #).map +1 -0
  46. package/dist/system/index.d.ts.map +1 -1
  47. package/dist/system/index.js +8 -0
  48. package/dist/system/index.js.map +1 -1
  49. package/dist/system/manifest.d.ts.map +1 -1
  50. package/dist/system/manifest.js +82 -3
  51. package/dist/system/manifest.js.map +1 -1
  52. package/dist/system/probes/logs-dmesg.d.ts +13 -0
  53. package/dist/system/probes/logs-dmesg.d.ts.map +1 -0
  54. package/dist/system/probes/logs-dmesg.js +22 -0
  55. package/dist/system/probes/logs-dmesg.js.map +1 -0
  56. package/dist/system/probes/logs-dmesg.test.d.ts +2 -0
  57. package/dist/system/probes/logs-dmesg.test.d.ts.map +1 -0
  58. package/dist/system/probes/logs-dmesg.test.js +55 -0
  59. package/dist/system/probes/logs-dmesg.test.js.map +1 -0
  60. package/dist/system/probes/logs-journal.d.ts +21 -0
  61. package/dist/system/probes/logs-journal.d.ts.map +1 -0
  62. package/dist/system/probes/logs-journal.js +70 -0
  63. package/dist/system/probes/logs-journal.js.map +1 -0
  64. package/dist/system/probes/logs-journal.test.d.ts +2 -0
  65. package/dist/system/probes/logs-journal.test.d.ts.map +1 -0
  66. package/dist/system/probes/logs-journal.test.js +113 -0
  67. package/dist/system/probes/logs-journal.test.js.map +1 -0
  68. package/dist/system/probes/logs-tail.d.ts +14 -0
  69. package/dist/system/probes/logs-tail.d.ts.map +1 -0
  70. package/dist/system/probes/logs-tail.js +40 -0
  71. package/dist/system/probes/logs-tail.js.map +1 -0
  72. package/dist/system/probes/logs-tail.test.d.ts +2 -0
  73. package/dist/system/probes/logs-tail.test.d.ts.map +1 -0
  74. package/dist/system/probes/logs-tail.test.js +82 -0
  75. package/dist/system/probes/logs-tail.test.js.map +1 -0
  76. package/dist/system/probes/traceroute.d.ts +17 -0
  77. package/dist/system/probes/traceroute.d.ts.map +1 -0
  78. package/dist/system/probes/traceroute.js +72 -0
  79. package/dist/system/probes/traceroute.js.map +1 -0
  80. package/dist/system/probes/traceroute.test.d.ts +2 -0
  81. package/dist/system/probes/traceroute.test.d.ts.map +1 -0
  82. package/dist/system/probes/traceroute.test.js +98 -0
  83. package/dist/system/probes/traceroute.test.js.map +1 -0
  84. package/package.json +1 -1
  85. package/src/index.ts +9 -0
  86. package/src/integrations/a10.ts +370 -0
  87. package/src/integrations/checkpoint.ts +381 -0
  88. package/src/integrations/datadog.ts +281 -0
  89. package/src/integrations/jira.ts +272 -0
  90. package/src/integrations/loki.ts +228 -0
  91. package/src/integrations/meraki.ts +344 -0
  92. package/src/integrations/pagerduty.ts +319 -0
  93. package/src/integrations/thousandeyes.ts +353 -0
  94. package/src/integrations/vcenter.ts +261 -0
  95. package/src/system/index.ts +8 -0
  96. package/src/system/manifest.ts +93 -3
  97. package/src/system/probes/logs-dmesg.test.ts +83 -0
  98. package/src/system/probes/logs-dmesg.ts +38 -0
  99. package/src/system/probes/logs-journal.test.ts +142 -0
  100. package/src/system/probes/logs-journal.ts +103 -0
  101. package/src/system/probes/logs-tail.test.ts +140 -0
  102. package/src/system/probes/logs-tail.ts +70 -0
  103. package/src/system/probes/traceroute.test.ts +149 -0
  104. package/src/system/probes/traceroute.ts +99 -0
  105. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,370 @@
1
+ import type {
2
+ FetchFn,
3
+ IntegrationConfig,
4
+ IntegrationCredentials,
5
+ IntegrationPack,
6
+ IntegrationProbeHandler,
7
+ } from '@sonde/shared';
8
+
9
+ // --- Session-based auth ---
10
+
11
+ /** Auth signature cache: signature + expiry timestamp */
12
+ let cachedSession: { signature: string; expiresAt: number } | null = null;
13
+
14
+ /** Acquire an A10 auth signature via POST /axapi/v3/auth */
15
+ async function getSignature(
16
+ config: IntegrationConfig,
17
+ credentials: IntegrationCredentials,
18
+ fetchFn: FetchFn,
19
+ ): Promise<string> {
20
+ const now = Date.now();
21
+ if (cachedSession && cachedSession.expiresAt > now) {
22
+ return cachedSession.signature;
23
+ }
24
+
25
+ const { username, password } = credentials.credentials;
26
+ if (!username || !password) {
27
+ throw new Error('A10 Networks requires username and password credentials');
28
+ }
29
+
30
+ const url = `${config.endpoint.replace(/\/$/, '')}/axapi/v3/auth`;
31
+ const res = await fetchFn(url, {
32
+ method: 'POST',
33
+ headers: {
34
+ 'Content-Type': 'application/json',
35
+ ...config.headers,
36
+ },
37
+ body: JSON.stringify({ credentials: { username, password } }),
38
+ });
39
+
40
+ if (!res.ok) {
41
+ throw new Error(`A10 auth failed: ${res.status} ${res.statusText}`);
42
+ }
43
+
44
+ const data = (await res.json()) as {
45
+ authresponse?: { signature?: string };
46
+ };
47
+ const signature = data.authresponse?.signature;
48
+ if (!signature) {
49
+ throw new Error('A10 auth response missing signature');
50
+ }
51
+
52
+ cachedSession = { signature, expiresAt: now + 5 * 60 * 1000 };
53
+ return signature;
54
+ }
55
+
56
+ // --- REST helper ---
57
+
58
+ async function a10Get<T>(
59
+ apiPath: string,
60
+ config: IntegrationConfig,
61
+ credentials: IntegrationCredentials,
62
+ fetchFn: FetchFn,
63
+ params?: Record<string, string>,
64
+ ): Promise<T> {
65
+ const signature = await getSignature(config, credentials, fetchFn);
66
+ const base = `${config.endpoint.replace(/\/$/, '')}/axapi/v3/${apiPath}`;
67
+ const url = new URL(base);
68
+ if (params) {
69
+ for (const [key, value] of Object.entries(params)) {
70
+ url.searchParams.set(key, value);
71
+ }
72
+ }
73
+
74
+ const headers: Record<string, string> = {
75
+ Accept: 'application/json',
76
+ Authorization: `A10 ${signature}`,
77
+ ...config.headers,
78
+ };
79
+
80
+ const res = await fetchFn(url.toString(), { headers });
81
+ if (!res.ok) {
82
+ throw new Error(`A10 API returned ${res.status}: ${res.statusText}`);
83
+ }
84
+ return (await res.json()) as T;
85
+ }
86
+
87
+ // --- Probe handlers ---
88
+
89
+ const systemInfo: IntegrationProbeHandler = async (
90
+ _params,
91
+ config,
92
+ credentials,
93
+ fetchFn,
94
+ ) => {
95
+ const data = await a10Get<{
96
+ version?: {
97
+ oper?: {
98
+ 'sw-version'?: string;
99
+ 'serial-number'?: string;
100
+ 'platform-name'?: string;
101
+ 'up-time'?: string;
102
+ };
103
+ };
104
+ }>('version/oper', config, credentials, fetchFn);
105
+
106
+ const oper = data.version?.oper ?? {};
107
+ return {
108
+ version: oper['sw-version'] ?? null,
109
+ serialNumber: oper['serial-number'] ?? null,
110
+ platform: oper['platform-name'] ?? null,
111
+ uptime: oper['up-time'] ?? null,
112
+ };
113
+ };
114
+
115
+ const virtualServersList: IntegrationProbeHandler = async (
116
+ _params,
117
+ config,
118
+ credentials,
119
+ fetchFn,
120
+ ) => {
121
+ const data = await a10Get<{
122
+ 'virtual-server-list'?: Array<{
123
+ name?: string;
124
+ 'ip-address'?: string;
125
+ status?: string;
126
+ 'port-list'?: Array<{
127
+ 'port-number'?: number;
128
+ protocol?: string;
129
+ status?: string;
130
+ }>;
131
+ }>;
132
+ }>('slb/virtual-server', config, credentials, fetchFn);
133
+
134
+ const servers = (data['virtual-server-list'] ?? []).map((vs) => ({
135
+ name: vs.name ?? null,
136
+ ipAddress: vs['ip-address'] ?? null,
137
+ status: vs.status ?? null,
138
+ ports: (vs['port-list'] ?? []).map((p) => ({
139
+ portNumber: p['port-number'] ?? null,
140
+ protocol: p.protocol ?? null,
141
+ status: p.status ?? null,
142
+ })),
143
+ }));
144
+
145
+ return { virtualServers: servers, count: servers.length };
146
+ };
147
+
148
+ const virtualServerStats: IntegrationProbeHandler = async (
149
+ params,
150
+ config,
151
+ credentials,
152
+ fetchFn,
153
+ ) => {
154
+ const name = params?.name as string;
155
+ if (!name) throw new Error('name parameter is required (virtual server name)');
156
+
157
+ const data = await a10Get<{
158
+ 'virtual-server'?: {
159
+ stats?: {
160
+ 'curr-conn'?: number;
161
+ 'total-conn'?: number;
162
+ 'bytes-in'?: number;
163
+ 'bytes-out'?: number;
164
+ };
165
+ };
166
+ }>(
167
+ `slb/virtual-server/${encodeURIComponent(name)}/stats`,
168
+ config,
169
+ credentials,
170
+ fetchFn,
171
+ );
172
+
173
+ const stats = data['virtual-server']?.stats ?? {};
174
+ return {
175
+ name,
176
+ currConn: stats['curr-conn'] ?? 0,
177
+ totalConn: stats['total-conn'] ?? 0,
178
+ bytesIn: stats['bytes-in'] ?? 0,
179
+ bytesOut: stats['bytes-out'] ?? 0,
180
+ };
181
+ };
182
+
183
+ const serviceGroupsList: IntegrationProbeHandler = async (
184
+ _params,
185
+ config,
186
+ credentials,
187
+ fetchFn,
188
+ ) => {
189
+ const data = await a10Get<{
190
+ 'service-group-list'?: Array<{
191
+ name?: string;
192
+ protocol?: string;
193
+ 'lb-method'?: string;
194
+ 'member-list'?: Array<{
195
+ name?: string;
196
+ port?: number;
197
+ 'member-state'?: string;
198
+ }>;
199
+ }>;
200
+ }>('slb/service-group', config, credentials, fetchFn);
201
+
202
+ const groups = (data['service-group-list'] ?? []).map((sg) => ({
203
+ name: sg.name ?? null,
204
+ protocol: sg.protocol ?? null,
205
+ lbMethod: sg['lb-method'] ?? null,
206
+ members: (sg['member-list'] ?? []).map((m) => ({
207
+ name: m.name ?? null,
208
+ port: m.port ?? null,
209
+ state: m['member-state'] ?? null,
210
+ })),
211
+ }));
212
+
213
+ return { serviceGroups: groups, count: groups.length };
214
+ };
215
+
216
+ const serversList: IntegrationProbeHandler = async (
217
+ _params,
218
+ config,
219
+ credentials,
220
+ fetchFn,
221
+ ) => {
222
+ const data = await a10Get<{
223
+ 'server-list'?: Array<{
224
+ name?: string;
225
+ host?: string;
226
+ status?: string;
227
+ 'port-list'?: Array<{
228
+ 'port-number'?: number;
229
+ protocol?: string;
230
+ 'health-check'?: string;
231
+ status?: string;
232
+ }>;
233
+ }>;
234
+ }>('slb/server', config, credentials, fetchFn);
235
+
236
+ const servers = (data['server-list'] ?? []).map((s) => ({
237
+ name: s.name ?? null,
238
+ host: s.host ?? null,
239
+ status: s.status ?? null,
240
+ ports: (s['port-list'] ?? []).map((p) => ({
241
+ portNumber: p['port-number'] ?? null,
242
+ protocol: p.protocol ?? null,
243
+ healthCheck: p['health-check'] ?? null,
244
+ status: p.status ?? null,
245
+ })),
246
+ }));
247
+
248
+ return { servers, count: servers.length };
249
+ };
250
+
251
+ const interfacesStats: IntegrationProbeHandler = async (
252
+ _params,
253
+ config,
254
+ credentials,
255
+ fetchFn,
256
+ ) => {
257
+ const data = await a10Get<{
258
+ ethernet?: {
259
+ oper?: {
260
+ 'interface-list'?: Array<{
261
+ 'port-num'?: number;
262
+ status?: string;
263
+ speed?: string;
264
+ 'rx-pkts'?: number;
265
+ 'tx-pkts'?: number;
266
+ 'rx-errors'?: number;
267
+ 'tx-errors'?: number;
268
+ }>;
269
+ };
270
+ };
271
+ }>('interface/ethernet/oper', config, credentials, fetchFn);
272
+
273
+ const interfaces = (data.ethernet?.oper?.['interface-list'] ?? []).map((iface) => ({
274
+ portNum: iface['port-num'] ?? null,
275
+ status: iface.status ?? null,
276
+ speed: iface.speed ?? null,
277
+ rxPackets: iface['rx-pkts'] ?? 0,
278
+ txPackets: iface['tx-pkts'] ?? 0,
279
+ rxErrors: iface['rx-errors'] ?? 0,
280
+ txErrors: iface['tx-errors'] ?? 0,
281
+ }));
282
+
283
+ return { interfaces, count: interfaces.length };
284
+ };
285
+
286
+ // --- Pack definition ---
287
+
288
+ export const a10Pack: IntegrationPack = {
289
+ manifest: {
290
+ name: 'a10',
291
+ type: 'integration',
292
+ version: '0.1.0',
293
+ description:
294
+ 'A10 Networks — virtual servers, service groups, real server health, and interface stats',
295
+ requires: { groups: [], files: [], commands: [] },
296
+ probes: [
297
+ {
298
+ name: 'system.info',
299
+ description: 'System version, serial number, platform, and uptime',
300
+ capability: 'observe',
301
+ params: {},
302
+ timeout: 15000,
303
+ },
304
+ {
305
+ name: 'virtual-servers.list',
306
+ description: 'List virtual servers (VIPs) with port and status info',
307
+ capability: 'observe',
308
+ params: {},
309
+ timeout: 15000,
310
+ },
311
+ {
312
+ name: 'virtual-server.stats',
313
+ description: 'Connection and throughput stats for a virtual server',
314
+ capability: 'observe',
315
+ params: {
316
+ name: {
317
+ type: 'string',
318
+ description: 'Virtual server name',
319
+ required: true,
320
+ },
321
+ },
322
+ timeout: 15000,
323
+ },
324
+ {
325
+ name: 'service-groups.list',
326
+ description: 'List service groups with members and health status',
327
+ capability: 'observe',
328
+ params: {},
329
+ timeout: 15000,
330
+ },
331
+ {
332
+ name: 'servers.list',
333
+ description: 'List real servers with port health checks',
334
+ capability: 'observe',
335
+ params: {},
336
+ timeout: 15000,
337
+ },
338
+ {
339
+ name: 'interfaces.stats',
340
+ description: 'Ethernet interface stats: packets, errors, speed, and status',
341
+ capability: 'observe',
342
+ params: {},
343
+ timeout: 15000,
344
+ },
345
+ ],
346
+ runbook: {
347
+ category: 'load-balancer',
348
+ probes: ['system.info', 'virtual-servers.list'],
349
+ parallel: true,
350
+ },
351
+ },
352
+
353
+ handlers: {
354
+ 'system.info': systemInfo,
355
+ 'virtual-servers.list': virtualServersList,
356
+ 'virtual-server.stats': virtualServerStats,
357
+ 'service-groups.list': serviceGroupsList,
358
+ 'servers.list': serversList,
359
+ 'interfaces.stats': interfacesStats,
360
+ },
361
+
362
+ testConnection: async (config, credentials, fetchFn) => {
363
+ try {
364
+ await getSignature(config, credentials, fetchFn);
365
+ return true;
366
+ } catch {
367
+ return false;
368
+ }
369
+ },
370
+ };