@sonde/packs 0.1.1 → 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.
- package/.turbo/turbo-build.log +4 -6
- package/.turbo/turbo-test.log +57 -814
- package/CHANGELOG.md +18 -0
- package/dist/docker/manifest (# Edit conflict 2026-02-19 LIl7ilN #).js +54 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/integrations/a10.d.ts +3 -0
- package/dist/integrations/a10.d.ts.map +1 -0
- package/dist/integrations/a10.js +218 -0
- package/dist/integrations/a10.js.map +1 -0
- package/dist/integrations/checkpoint.d.ts +3 -0
- package/dist/integrations/checkpoint.d.ts.map +1 -0
- package/dist/integrations/checkpoint.js +249 -0
- package/dist/integrations/checkpoint.js.map +1 -0
- package/dist/integrations/citrix.d.ts.map +1 -1
- package/dist/integrations/citrix.js +14 -19
- package/dist/integrations/citrix.js.map +1 -1
- package/dist/integrations/citrix.test.js +3 -3
- package/dist/integrations/citrix.test.js.map +1 -1
- package/dist/integrations/datadog.d.ts +3 -0
- package/dist/integrations/datadog.d.ts.map +1 -0
- package/dist/integrations/datadog.js +195 -0
- package/dist/integrations/datadog.js.map +1 -0
- package/dist/integrations/graph.d.ts.map +1 -1
- package/dist/integrations/graph.js +10 -15
- package/dist/integrations/graph.js.map +1 -1
- package/dist/integrations/graph.test.js +3 -3
- package/dist/integrations/graph.test.js.map +1 -1
- package/dist/integrations/httpbin.d.ts.map +1 -1
- package/dist/integrations/httpbin.js +2 -7
- package/dist/integrations/httpbin.js.map +1 -1
- package/dist/integrations/jira.d.ts +3 -0
- package/dist/integrations/jira.d.ts.map +1 -0
- package/dist/integrations/jira.js +199 -0
- package/dist/integrations/jira.js.map +1 -0
- package/dist/integrations/loki.d.ts +3 -0
- package/dist/integrations/loki.d.ts.map +1 -0
- package/dist/integrations/loki.js +178 -0
- package/dist/integrations/loki.js.map +1 -0
- package/dist/integrations/meraki.d.ts +3 -0
- package/dist/integrations/meraki.d.ts.map +1 -0
- package/dist/integrations/meraki.js +238 -0
- package/dist/integrations/meraki.js.map +1 -0
- package/dist/integrations/nutanix.d.ts.map +1 -1
- package/dist/integrations/nutanix.js +12 -17
- package/dist/integrations/nutanix.js.map +1 -1
- package/dist/integrations/nutanix.test.js +3 -3
- package/dist/integrations/nutanix.test.js.map +1 -1
- package/dist/integrations/pagerduty.d.ts +3 -0
- package/dist/integrations/pagerduty.d.ts.map +1 -0
- package/dist/integrations/pagerduty.js +229 -0
- package/dist/integrations/pagerduty.js.map +1 -0
- package/dist/integrations/proxmox.d.ts.map +1 -1
- package/dist/integrations/proxmox.js +8 -13
- package/dist/integrations/proxmox.js.map +1 -1
- package/dist/integrations/proxmox.test.js +3 -3
- package/dist/integrations/proxmox.test.js.map +1 -1
- package/dist/integrations/servicenow.d.ts.map +1 -1
- package/dist/integrations/servicenow.js +10 -16
- package/dist/integrations/servicenow.js.map +1 -1
- package/dist/integrations/servicenow.test.js +3 -3
- package/dist/integrations/servicenow.test.js.map +1 -1
- package/dist/integrations/splunk.d.ts.map +1 -1
- package/dist/integrations/splunk.js +8 -13
- package/dist/integrations/splunk.js.map +1 -1
- package/dist/integrations/splunk.test.js +3 -3
- package/dist/integrations/splunk.test.js.map +1 -1
- package/dist/integrations/thousandeyes.d.ts +3 -0
- package/dist/integrations/thousandeyes.d.ts.map +1 -0
- package/dist/integrations/thousandeyes.js +263 -0
- package/dist/integrations/thousandeyes.js.map +1 -0
- package/dist/integrations/vcenter.d.ts +3 -0
- package/dist/integrations/vcenter.d.ts.map +1 -0
- package/dist/integrations/vcenter.js +190 -0
- package/dist/integrations/vcenter.js.map +1 -0
- package/dist/proxmox/probes/ceph-status.test.d.ts (# Edit conflict 2026-02-19 N25hAvJ #).map +1 -0
- package/dist/system/index.d.ts.map +1 -1
- package/dist/system/index.js +10 -0
- package/dist/system/index.js.map +1 -1
- package/dist/system/manifest.d.ts.map +1 -1
- package/dist/system/manifest.js +100 -3
- package/dist/system/manifest.js.map +1 -1
- package/dist/system/probes/logs-dmesg.d.ts +13 -0
- package/dist/system/probes/logs-dmesg.d.ts.map +1 -0
- package/dist/system/probes/logs-dmesg.js +22 -0
- package/dist/system/probes/logs-dmesg.js.map +1 -0
- package/dist/system/probes/logs-dmesg.test.d.ts +2 -0
- package/dist/system/probes/logs-dmesg.test.d.ts.map +1 -0
- package/dist/system/probes/logs-dmesg.test.js +55 -0
- package/dist/system/probes/logs-dmesg.test.js.map +1 -0
- package/dist/system/probes/logs-journal.d.ts +21 -0
- package/dist/system/probes/logs-journal.d.ts.map +1 -0
- package/dist/system/probes/logs-journal.js +70 -0
- package/dist/system/probes/logs-journal.js.map +1 -0
- package/dist/system/probes/logs-journal.test.d.ts +2 -0
- package/dist/system/probes/logs-journal.test.d.ts.map +1 -0
- package/dist/system/probes/logs-journal.test.js +113 -0
- package/dist/system/probes/logs-journal.test.js.map +1 -0
- package/dist/system/probes/logs-tail.d.ts +14 -0
- package/dist/system/probes/logs-tail.d.ts.map +1 -0
- package/dist/system/probes/logs-tail.js +40 -0
- package/dist/system/probes/logs-tail.js.map +1 -0
- package/dist/system/probes/logs-tail.test.d.ts +2 -0
- package/dist/system/probes/logs-tail.test.d.ts.map +1 -0
- package/dist/system/probes/logs-tail.test.js +82 -0
- package/dist/system/probes/logs-tail.test.js.map +1 -0
- package/dist/system/probes/ping.d.ts +20 -0
- package/dist/system/probes/ping.d.ts.map +1 -0
- package/dist/system/probes/ping.js +54 -0
- package/dist/system/probes/ping.js.map +1 -0
- package/dist/system/probes/ping.test.d.ts +2 -0
- package/dist/system/probes/ping.test.d.ts.map +1 -0
- package/dist/system/probes/ping.test.js +127 -0
- package/dist/system/probes/ping.test.js.map +1 -0
- package/dist/system/probes/traceroute.d.ts +17 -0
- package/dist/system/probes/traceroute.d.ts.map +1 -0
- package/dist/system/probes/traceroute.js +72 -0
- package/dist/system/probes/traceroute.js.map +1 -0
- package/dist/system/probes/traceroute.test.d.ts +2 -0
- package/dist/system/probes/traceroute.test.d.ts.map +1 -0
- package/dist/system/probes/traceroute.test.js +98 -0
- package/dist/system/probes/traceroute.test.js.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +9 -0
- package/src/integrations/a10.ts +370 -0
- package/src/integrations/checkpoint.ts +381 -0
- package/src/integrations/citrix.test.ts +3 -3
- package/src/integrations/citrix.ts +17 -21
- package/src/integrations/datadog.ts +281 -0
- package/src/integrations/graph.test.ts +3 -3
- package/src/integrations/graph.ts +10 -14
- package/src/integrations/httpbin.ts +2 -6
- package/src/integrations/jira.ts +272 -0
- package/src/integrations/loki.ts +228 -0
- package/src/integrations/meraki.ts +344 -0
- package/src/integrations/nutanix.test.ts +3 -3
- package/src/integrations/nutanix.ts +13 -17
- package/src/integrations/pagerduty.ts +319 -0
- package/src/integrations/proxmox.test.ts +3 -3
- package/src/integrations/proxmox.ts +8 -12
- package/src/integrations/servicenow.test.ts +3 -3
- package/src/integrations/servicenow.ts +10 -15
- package/src/integrations/splunk.test.ts +3 -3
- package/src/integrations/splunk.ts +9 -13
- package/src/integrations/thousandeyes.ts +353 -0
- package/src/integrations/vcenter.ts +261 -0
- package/src/system/index.ts +10 -0
- package/src/system/manifest.ts +113 -3
- package/src/system/probes/logs-dmesg.test.ts +83 -0
- package/src/system/probes/logs-dmesg.ts +38 -0
- package/src/system/probes/logs-journal.test.ts +142 -0
- package/src/system/probes/logs-journal.ts +103 -0
- package/src/system/probes/logs-tail.test.ts +140 -0
- package/src/system/probes/logs-tail.ts +70 -0
- package/src/system/probes/ping.test.ts +163 -0
- package/src/system/probes/ping.ts +89 -0
- package/src/system/probes/traceroute.test.ts +149 -0
- package/src/system/probes/traceroute.ts +99 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -96,10 +96,10 @@ describe('proxmox pack', () => {
|
|
|
96
96
|
expect(result).toBe(false);
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
it('
|
|
99
|
+
it('throws on network error', async () => {
|
|
100
100
|
const fetchFn = vi.fn().mockRejectedValue(new Error('ECONNREFUSED'));
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
await expect(proxmoxPack.testConnection(pveConfig, pveCreds, fetchFn))
|
|
102
|
+
.rejects.toThrow('ECONNREFUSED');
|
|
103
103
|
});
|
|
104
104
|
});
|
|
105
105
|
|
|
@@ -972,18 +972,14 @@ export const proxmoxPack: IntegrationPack = {
|
|
|
972
972
|
},
|
|
973
973
|
|
|
974
974
|
testConnection: async (config, credentials, fetchFn) => {
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
};
|
|
975
|
+
const url = proxmoxUrl(config.endpoint, '/version');
|
|
976
|
+
const headers: Record<string, string> = {
|
|
977
|
+
Accept: 'application/json',
|
|
978
|
+
...buildAuthHeaders(credentials),
|
|
979
|
+
...config.headers,
|
|
980
|
+
};
|
|
982
981
|
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
} catch {
|
|
986
|
-
return false;
|
|
987
|
-
}
|
|
982
|
+
const res = await fetchFn(url, { headers });
|
|
983
|
+
return res.ok;
|
|
988
984
|
},
|
|
989
985
|
};
|
|
@@ -99,10 +99,10 @@ describe('servicenow pack', () => {
|
|
|
99
99
|
expect(result).toBe(false);
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
-
it('
|
|
102
|
+
it('throws on network error', async () => {
|
|
103
103
|
const fetchFn = vi.fn().mockRejectedValue(new Error('ECONNREFUSED'));
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
await expect(servicenowPack.testConnection(config, basicCreds, fetchFn))
|
|
105
|
+
.rejects.toThrow('ECONNREFUSED');
|
|
106
106
|
});
|
|
107
107
|
});
|
|
108
108
|
|
|
@@ -266,20 +266,15 @@ export const servicenowPack: IntegrationPack = {
|
|
|
266
266
|
},
|
|
267
267
|
|
|
268
268
|
testConnection: async (config, credentials, fetchFn) => {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
const res = await fetchFn(parsed.toString(), { headers });
|
|
280
|
-
return res.ok;
|
|
281
|
-
} catch {
|
|
282
|
-
return false;
|
|
283
|
-
}
|
|
269
|
+
const url = buildUrl(config.endpoint, 'sys_properties', undefined, ['name']);
|
|
270
|
+
const parsed = new URL(url);
|
|
271
|
+
parsed.searchParams.set('sysparm_limit', '1');
|
|
272
|
+
const headers: Record<string, string> = {
|
|
273
|
+
Accept: 'application/json',
|
|
274
|
+
...buildAuthHeaders(credentials),
|
|
275
|
+
...config.headers,
|
|
276
|
+
};
|
|
277
|
+
const res = await fetchFn(parsed.toString(), { headers });
|
|
278
|
+
return res.ok;
|
|
284
279
|
},
|
|
285
280
|
};
|
|
@@ -141,10 +141,10 @@ describe('splunk pack', () => {
|
|
|
141
141
|
expect(result).toBe(false);
|
|
142
142
|
});
|
|
143
143
|
|
|
144
|
-
it('
|
|
144
|
+
it('throws on network error', async () => {
|
|
145
145
|
const fetchFn = vi.fn().mockRejectedValue(new Error('ECONNREFUSED'));
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
await expect(splunkPack.testConnection(splunkConfig, tokenCreds, fetchFn))
|
|
147
|
+
.rejects.toThrow('ECONNREFUSED');
|
|
148
148
|
});
|
|
149
149
|
});
|
|
150
150
|
|
|
@@ -339,18 +339,14 @@ export const splunkPack: IntegrationPack = {
|
|
|
339
339
|
},
|
|
340
340
|
|
|
341
341
|
testConnection: async (config, credentials, fetchFn) => {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
return res.ok;
|
|
352
|
-
} catch {
|
|
353
|
-
return false;
|
|
354
|
-
}
|
|
342
|
+
const url = splunkUrl(config.endpoint, '/services/server/info');
|
|
343
|
+
const headers: Record<string, string> = {
|
|
344
|
+
Accept: 'application/json',
|
|
345
|
+
...buildAuthHeaders(credentials),
|
|
346
|
+
...config.headers,
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const res = await fetchFn(url, { headers });
|
|
350
|
+
return res.ok;
|
|
355
351
|
},
|
|
356
352
|
};
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
FetchFn,
|
|
3
|
+
IntegrationConfig,
|
|
4
|
+
IntegrationCredentials,
|
|
5
|
+
IntegrationPack,
|
|
6
|
+
IntegrationProbeHandler,
|
|
7
|
+
} from '@sonde/shared';
|
|
8
|
+
|
|
9
|
+
// --- Auth helpers ---
|
|
10
|
+
|
|
11
|
+
function buildAuthHeaders(credentials: IntegrationCredentials): Record<string, string> {
|
|
12
|
+
const token = credentials.credentials.token ?? '';
|
|
13
|
+
return { Authorization: `Bearer ${token}` };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// --- REST helper ---
|
|
17
|
+
|
|
18
|
+
async function teGet<T>(
|
|
19
|
+
path: string,
|
|
20
|
+
config: IntegrationConfig,
|
|
21
|
+
credentials: IntegrationCredentials,
|
|
22
|
+
fetchFn: FetchFn,
|
|
23
|
+
params?: Record<string, string>,
|
|
24
|
+
): Promise<T> {
|
|
25
|
+
const base = `${config.endpoint.replace(/\/$/, '')}/v7${path}`;
|
|
26
|
+
const url = new URL(base);
|
|
27
|
+
if (params) {
|
|
28
|
+
for (const [key, value] of Object.entries(params)) {
|
|
29
|
+
url.searchParams.set(key, value);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const headers: Record<string, string> = {
|
|
34
|
+
Accept: 'application/json',
|
|
35
|
+
...buildAuthHeaders(credentials),
|
|
36
|
+
...config.headers,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const res = await fetchFn(url.toString(), { headers });
|
|
40
|
+
if (!res.ok) {
|
|
41
|
+
throw new Error(`ThousandEyes API returned ${res.status}: ${res.statusText}`);
|
|
42
|
+
}
|
|
43
|
+
return (await res.json()) as T;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// --- Probe handlers ---
|
|
47
|
+
|
|
48
|
+
const alertsActive: IntegrationProbeHandler = async (params, config, credentials, fetchFn) => {
|
|
49
|
+
const queryParams: Record<string, string> = {};
|
|
50
|
+
const window = params?.window as string | undefined;
|
|
51
|
+
if (window) queryParams.window = window;
|
|
52
|
+
|
|
53
|
+
const data = await teGet<{
|
|
54
|
+
alerts?: Array<{
|
|
55
|
+
id?: string;
|
|
56
|
+
type?: string;
|
|
57
|
+
severity?: string;
|
|
58
|
+
state?: string;
|
|
59
|
+
startDate?: string;
|
|
60
|
+
violationCount?: number;
|
|
61
|
+
duration?: number;
|
|
62
|
+
}>;
|
|
63
|
+
}>('/alerts', config, credentials, fetchFn, queryParams);
|
|
64
|
+
|
|
65
|
+
const alerts = data.alerts ?? [];
|
|
66
|
+
return {
|
|
67
|
+
alerts: alerts.map((a) => ({
|
|
68
|
+
id: a.id ?? null,
|
|
69
|
+
type: a.type ?? null,
|
|
70
|
+
severity: a.severity ?? null,
|
|
71
|
+
state: a.state ?? null,
|
|
72
|
+
startDate: a.startDate ?? null,
|
|
73
|
+
violationCount: a.violationCount ?? 0,
|
|
74
|
+
duration: a.duration ?? 0,
|
|
75
|
+
})),
|
|
76
|
+
count: alerts.length,
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const testsList: IntegrationProbeHandler = async (params, config, credentials, fetchFn) => {
|
|
81
|
+
const queryParams: Record<string, string> = {};
|
|
82
|
+
const type = params?.type as string | undefined;
|
|
83
|
+
if (type) queryParams.type = type;
|
|
84
|
+
|
|
85
|
+
const data = await teGet<{
|
|
86
|
+
tests?: Array<{
|
|
87
|
+
testId?: string;
|
|
88
|
+
testName?: string;
|
|
89
|
+
type?: string;
|
|
90
|
+
enabled?: boolean;
|
|
91
|
+
server?: string;
|
|
92
|
+
interval?: number;
|
|
93
|
+
agents?: Array<{ agentId?: string; agentName?: string }>;
|
|
94
|
+
}>;
|
|
95
|
+
}>('/tests', config, credentials, fetchFn, queryParams);
|
|
96
|
+
|
|
97
|
+
const tests = data.tests ?? [];
|
|
98
|
+
return {
|
|
99
|
+
tests: tests.map((t) => ({
|
|
100
|
+
testId: t.testId ?? null,
|
|
101
|
+
testName: t.testName ?? null,
|
|
102
|
+
type: t.type ?? null,
|
|
103
|
+
enabled: t.enabled ?? false,
|
|
104
|
+
server: t.server ?? null,
|
|
105
|
+
interval: t.interval ?? 0,
|
|
106
|
+
agents: t.agents ?? [],
|
|
107
|
+
})),
|
|
108
|
+
count: tests.length,
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const networkMetrics: IntegrationProbeHandler = async (params, config, credentials, fetchFn) => {
|
|
113
|
+
const testId = params?.testId as string;
|
|
114
|
+
if (!testId) throw new Error('testId parameter is required');
|
|
115
|
+
|
|
116
|
+
const queryParams: Record<string, string> = {};
|
|
117
|
+
const window = params?.window as string | undefined;
|
|
118
|
+
if (window) queryParams.window = window;
|
|
119
|
+
|
|
120
|
+
const data = await teGet<{
|
|
121
|
+
results?: Array<{
|
|
122
|
+
agent?: { agentId?: string; agentName?: string; location?: string };
|
|
123
|
+
avgLatency?: number;
|
|
124
|
+
loss?: number;
|
|
125
|
+
jitter?: number;
|
|
126
|
+
serverIp?: string;
|
|
127
|
+
}>;
|
|
128
|
+
}>(`/test-results/${encodeURIComponent(testId)}/network`, config, credentials, fetchFn, queryParams);
|
|
129
|
+
|
|
130
|
+
const results = data.results ?? [];
|
|
131
|
+
return {
|
|
132
|
+
metrics: results.map((r) => ({
|
|
133
|
+
agentId: r.agent?.agentId ?? null,
|
|
134
|
+
agentName: r.agent?.agentName ?? null,
|
|
135
|
+
location: r.agent?.location ?? null,
|
|
136
|
+
avgLatency: r.avgLatency ?? null,
|
|
137
|
+
loss: r.loss ?? null,
|
|
138
|
+
jitter: r.jitter ?? null,
|
|
139
|
+
serverIp: r.serverIp ?? null,
|
|
140
|
+
})),
|
|
141
|
+
count: results.length,
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const networkPathVis: IntegrationProbeHandler = async (params, config, credentials, fetchFn) => {
|
|
146
|
+
const testId = params?.testId as string;
|
|
147
|
+
if (!testId) throw new Error('testId parameter is required');
|
|
148
|
+
|
|
149
|
+
const queryParams: Record<string, string> = {};
|
|
150
|
+
const window = params?.window as string | undefined;
|
|
151
|
+
if (window) queryParams.window = window;
|
|
152
|
+
|
|
153
|
+
const data = await teGet<{
|
|
154
|
+
results?: Array<{
|
|
155
|
+
agent?: { agentId?: string; agentName?: string };
|
|
156
|
+
pathTraces?: Array<{
|
|
157
|
+
ipAddress?: string;
|
|
158
|
+
responseTime?: number;
|
|
159
|
+
numberOfHops?: number;
|
|
160
|
+
}>;
|
|
161
|
+
}>;
|
|
162
|
+
}>(`/test-results/${encodeURIComponent(testId)}/path-vis`, config, credentials, fetchFn, queryParams);
|
|
163
|
+
|
|
164
|
+
const results = data.results ?? [];
|
|
165
|
+
return {
|
|
166
|
+
pathVisualizations: results.map((r) => ({
|
|
167
|
+
agentId: r.agent?.agentId ?? null,
|
|
168
|
+
agentName: r.agent?.agentName ?? null,
|
|
169
|
+
pathTraces: (r.pathTraces ?? []).map((hop) => ({
|
|
170
|
+
ipAddress: hop.ipAddress ?? null,
|
|
171
|
+
responseTime: hop.responseTime ?? null,
|
|
172
|
+
numberOfHops: hop.numberOfHops ?? null,
|
|
173
|
+
})),
|
|
174
|
+
})),
|
|
175
|
+
count: results.length,
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const agentsList: IntegrationProbeHandler = async (_params, config, credentials, fetchFn) => {
|
|
180
|
+
const data = await teGet<{
|
|
181
|
+
agents?: Array<{
|
|
182
|
+
agentId?: string;
|
|
183
|
+
agentName?: string;
|
|
184
|
+
agentType?: string;
|
|
185
|
+
location?: string;
|
|
186
|
+
countryId?: string;
|
|
187
|
+
enabled?: boolean;
|
|
188
|
+
}>;
|
|
189
|
+
}>('/agents', config, credentials, fetchFn);
|
|
190
|
+
|
|
191
|
+
const agents = data.agents ?? [];
|
|
192
|
+
return {
|
|
193
|
+
agents: agents.map((a) => ({
|
|
194
|
+
agentId: a.agentId ?? null,
|
|
195
|
+
agentName: a.agentName ?? null,
|
|
196
|
+
agentType: a.agentType ?? null,
|
|
197
|
+
location: a.location ?? null,
|
|
198
|
+
country: a.countryId ?? null,
|
|
199
|
+
enabled: a.enabled ?? false,
|
|
200
|
+
})),
|
|
201
|
+
count: agents.length,
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const outagesNetwork: IntegrationProbeHandler = async (params, config, credentials, fetchFn) => {
|
|
206
|
+
const queryParams: Record<string, string> = {};
|
|
207
|
+
const window = params?.window as string | undefined;
|
|
208
|
+
if (window) queryParams.window = window;
|
|
209
|
+
|
|
210
|
+
const data = await teGet<{
|
|
211
|
+
outages?: Array<{
|
|
212
|
+
type?: string;
|
|
213
|
+
scope?: string;
|
|
214
|
+
startDate?: string;
|
|
215
|
+
endDate?: string;
|
|
216
|
+
affectedTests?: number[];
|
|
217
|
+
}>;
|
|
218
|
+
}>('/internet-insights/outages/network', config, credentials, fetchFn, queryParams);
|
|
219
|
+
|
|
220
|
+
const outages = data.outages ?? [];
|
|
221
|
+
return {
|
|
222
|
+
outages: outages.map((o) => ({
|
|
223
|
+
type: o.type ?? null,
|
|
224
|
+
scope: o.scope ?? null,
|
|
225
|
+
startDate: o.startDate ?? null,
|
|
226
|
+
endDate: o.endDate ?? null,
|
|
227
|
+
affectedTests: o.affectedTests ?? [],
|
|
228
|
+
})),
|
|
229
|
+
count: outages.length,
|
|
230
|
+
};
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// --- Pack definition ---
|
|
234
|
+
|
|
235
|
+
export const thousandeyesPack: IntegrationPack = {
|
|
236
|
+
manifest: {
|
|
237
|
+
name: 'thousandeyes',
|
|
238
|
+
type: 'integration',
|
|
239
|
+
version: '0.1.0',
|
|
240
|
+
description: 'ThousandEyes — network path analysis, latency metrics, and outage detection',
|
|
241
|
+
requires: { groups: [], files: [], commands: [] },
|
|
242
|
+
probes: [
|
|
243
|
+
{
|
|
244
|
+
name: 'alerts.active',
|
|
245
|
+
description: 'List active alerts with severity and violation details',
|
|
246
|
+
capability: 'observe',
|
|
247
|
+
params: {
|
|
248
|
+
window: {
|
|
249
|
+
type: 'string',
|
|
250
|
+
description: 'Time window for alerts (e.g. "12h")',
|
|
251
|
+
required: false,
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
timeout: 15000,
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
name: 'tests.list',
|
|
258
|
+
description: 'List configured tests with type, interval, and assigned agents',
|
|
259
|
+
capability: 'observe',
|
|
260
|
+
params: {
|
|
261
|
+
type: {
|
|
262
|
+
type: 'string',
|
|
263
|
+
description: 'Filter by test type (e.g. "agent-to-server")',
|
|
264
|
+
required: false,
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
timeout: 15000,
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
name: 'network.metrics',
|
|
271
|
+
description: 'Get per-agent network metrics (latency, loss, jitter) for a test',
|
|
272
|
+
capability: 'observe',
|
|
273
|
+
params: {
|
|
274
|
+
testId: {
|
|
275
|
+
type: 'string',
|
|
276
|
+
description: 'ThousandEyes test ID',
|
|
277
|
+
required: true,
|
|
278
|
+
},
|
|
279
|
+
window: {
|
|
280
|
+
type: 'string',
|
|
281
|
+
description: 'Time window for results (e.g. "1h")',
|
|
282
|
+
required: false,
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
timeout: 15000,
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
name: 'network.path-vis',
|
|
289
|
+
description: 'Get hop-by-hop path visualization for a test',
|
|
290
|
+
capability: 'observe',
|
|
291
|
+
params: {
|
|
292
|
+
testId: {
|
|
293
|
+
type: 'string',
|
|
294
|
+
description: 'ThousandEyes test ID',
|
|
295
|
+
required: true,
|
|
296
|
+
},
|
|
297
|
+
window: {
|
|
298
|
+
type: 'string',
|
|
299
|
+
description: 'Time window for results (e.g. "1h")',
|
|
300
|
+
required: false,
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
timeout: 15000,
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: 'agents.list',
|
|
307
|
+
description: 'List ThousandEyes agents with type, location, and status',
|
|
308
|
+
capability: 'observe',
|
|
309
|
+
params: {},
|
|
310
|
+
timeout: 15000,
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
name: 'outages.network',
|
|
314
|
+
description: 'List detected internet outages affecting tests',
|
|
315
|
+
capability: 'observe',
|
|
316
|
+
params: {
|
|
317
|
+
window: {
|
|
318
|
+
type: 'string',
|
|
319
|
+
description: 'Time window for outages (e.g. "24h")',
|
|
320
|
+
required: false,
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
timeout: 15000,
|
|
324
|
+
},
|
|
325
|
+
],
|
|
326
|
+
runbook: {
|
|
327
|
+
category: 'network',
|
|
328
|
+
probes: ['alerts.active', 'agents.list'],
|
|
329
|
+
parallel: true,
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
|
|
333
|
+
handlers: {
|
|
334
|
+
'alerts.active': alertsActive,
|
|
335
|
+
'tests.list': testsList,
|
|
336
|
+
'network.metrics': networkMetrics,
|
|
337
|
+
'network.path-vis': networkPathVis,
|
|
338
|
+
'agents.list': agentsList,
|
|
339
|
+
'outages.network': outagesNetwork,
|
|
340
|
+
},
|
|
341
|
+
|
|
342
|
+
testConnection: async (config, credentials, fetchFn) => {
|
|
343
|
+
const url = `${config.endpoint.replace(/\/$/, '')}/v7/agents`;
|
|
344
|
+
const headers: Record<string, string> = {
|
|
345
|
+
Accept: 'application/json',
|
|
346
|
+
...buildAuthHeaders(credentials),
|
|
347
|
+
...config.headers,
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
const res = await fetchFn(url, { headers });
|
|
351
|
+
return res.ok;
|
|
352
|
+
},
|
|
353
|
+
};
|