@alertee/cli 0.3.0 → 0.5.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/dist/api.d.ts +180 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +25 -2
- package/dist/api.js.map +1 -1
- package/dist/commands/alert-groups/add-email-group.d.ts +9 -0
- package/dist/commands/alert-groups/add-email-group.d.ts.map +1 -0
- package/dist/commands/alert-groups/add-email-group.js +33 -0
- package/dist/commands/alert-groups/add-email-group.js.map +1 -0
- package/dist/commands/alert-groups/add-webhook.d.ts +8 -0
- package/dist/commands/alert-groups/add-webhook.d.ts.map +1 -0
- package/dist/commands/alert-groups/add-webhook.js +64 -0
- package/dist/commands/alert-groups/add-webhook.js.map +1 -0
- package/dist/commands/alert-groups/create.d.ts +11 -0
- package/dist/commands/alert-groups/create.d.ts.map +1 -0
- package/dist/commands/alert-groups/create.js +31 -0
- package/dist/commands/alert-groups/create.js.map +1 -0
- package/dist/commands/alert-groups/delete.d.ts +5 -0
- package/dist/commands/alert-groups/delete.d.ts.map +1 -0
- package/dist/commands/alert-groups/delete.js +35 -0
- package/dist/commands/alert-groups/delete.js.map +1 -0
- package/dist/commands/alert-groups/list.d.ts +5 -0
- package/dist/commands/alert-groups/list.d.ts.map +1 -0
- package/dist/commands/alert-groups/list.js +35 -0
- package/dist/commands/alert-groups/list.js.map +1 -0
- package/dist/commands/alert-groups/recipients.d.ts +5 -0
- package/dist/commands/alert-groups/recipients.d.ts.map +1 -0
- package/dist/commands/alert-groups/recipients.js +62 -0
- package/dist/commands/alert-groups/recipients.js.map +1 -0
- package/dist/commands/alert-groups/remove-recipient.d.ts +8 -0
- package/dist/commands/alert-groups/remove-recipient.d.ts.map +1 -0
- package/dist/commands/alert-groups/remove-recipient.js +33 -0
- package/dist/commands/alert-groups/remove-recipient.js.map +1 -0
- package/dist/commands/alert-groups/resolve.d.ts +6 -0
- package/dist/commands/alert-groups/resolve.d.ts.map +1 -0
- package/dist/commands/alert-groups/resolve.js +27 -0
- package/dist/commands/alert-groups/resolve.js.map +1 -0
- package/dist/commands/alert-groups/test.d.ts +3 -0
- package/dist/commands/alert-groups/test.d.ts.map +1 -0
- package/dist/commands/alert-groups/test.js +24 -0
- package/dist/commands/alert-groups/test.js.map +1 -0
- package/dist/commands/alert-groups/update.d.ts +12 -0
- package/dist/commands/alert-groups/update.d.ts.map +1 -0
- package/dist/commands/alert-groups/update.js +46 -0
- package/dist/commands/alert-groups/update.js.map +1 -0
- package/dist/commands/checks/create.d.ts +25 -1
- package/dist/commands/checks/create.d.ts.map +1 -1
- package/dist/commands/checks/create.js +141 -82
- package/dist/commands/checks/create.js.map +1 -1
- package/dist/commands/checks/update.d.ts +3 -2
- package/dist/commands/checks/update.d.ts.map +1 -1
- package/dist/commands/checks/update.js +79 -19
- package/dist/commands/checks/update.js.map +1 -1
- package/dist/commands/connections/create.d.ts +14 -0
- package/dist/commands/connections/create.d.ts.map +1 -0
- package/dist/commands/connections/create.js +52 -0
- package/dist/commands/connections/create.js.map +1 -0
- package/dist/commands/connections/delete.d.ts +5 -0
- package/dist/commands/connections/delete.d.ts.map +1 -0
- package/dist/commands/connections/delete.js +35 -0
- package/dist/commands/connections/delete.js.map +1 -0
- package/dist/commands/connections/resolve.d.ts +9 -0
- package/dist/commands/connections/resolve.d.ts.map +1 -0
- package/dist/commands/connections/resolve.js +30 -0
- package/dist/commands/connections/resolve.js.map +1 -0
- package/dist/commands/connections/test.d.ts +3 -0
- package/dist/commands/connections/test.d.ts.map +1 -0
- package/dist/commands/connections/test.js +28 -0
- package/dist/commands/connections/test.js.map +1 -0
- package/dist/commands/email-groups/add.d.ts +3 -0
- package/dist/commands/email-groups/add.d.ts.map +1 -0
- package/dist/commands/email-groups/add.js +23 -0
- package/dist/commands/email-groups/add.js.map +1 -0
- package/dist/commands/email-groups/create.d.ts +8 -0
- package/dist/commands/email-groups/create.d.ts.map +1 -0
- package/dist/commands/email-groups/create.js +28 -0
- package/dist/commands/email-groups/create.js.map +1 -0
- package/dist/commands/email-groups/delete.d.ts +5 -0
- package/dist/commands/email-groups/delete.d.ts.map +1 -0
- package/dist/commands/email-groups/delete.js +35 -0
- package/dist/commands/email-groups/delete.js.map +1 -0
- package/dist/commands/email-groups/list.d.ts +5 -0
- package/dist/commands/email-groups/list.d.ts.map +1 -0
- package/dist/commands/email-groups/list.js +36 -0
- package/dist/commands/email-groups/list.js.map +1 -0
- package/dist/commands/email-groups/members.d.ts +5 -0
- package/dist/commands/email-groups/members.d.ts.map +1 -0
- package/dist/commands/email-groups/members.js +42 -0
- package/dist/commands/email-groups/members.js.map +1 -0
- package/dist/commands/email-groups/remove.d.ts +3 -0
- package/dist/commands/email-groups/remove.d.ts.map +1 -0
- package/dist/commands/email-groups/remove.js +19 -0
- package/dist/commands/email-groups/remove.js.map +1 -0
- package/dist/commands/email-groups/resolve.d.ts +6 -0
- package/dist/commands/email-groups/resolve.d.ts.map +1 -0
- package/dist/commands/email-groups/resolve.js +27 -0
- package/dist/commands/email-groups/resolve.js.map +1 -0
- package/dist/commands/org/create.d.ts +12 -0
- package/dist/commands/org/create.d.ts.map +1 -0
- package/dist/commands/org/create.js +33 -0
- package/dist/commands/org/create.js.map +1 -0
- package/dist/commands/org/list.d.ts +5 -0
- package/dist/commands/org/list.d.ts.map +1 -0
- package/dist/commands/org/list.js +35 -0
- package/dist/commands/org/list.js.map +1 -0
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/index.js +159 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +343 -2
- package/dist/mcp.js.map +1 -1
- package/dist/prompts.d.ts +15 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +25 -0
- package/dist/prompts.js.map +1 -0
- package/dist/uuid.d.ts +13 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +13 -0
- package/dist/uuid.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createClient } from '../../api.js';
|
|
2
|
+
import { requireConfig, requireOrg } from '../../config.js';
|
|
3
|
+
import { printJson, resolveFormat } from '../../output.js';
|
|
4
|
+
import { uuidValue } from '../../uuid.js';
|
|
5
|
+
import { resolveAlertGroupId } from './resolve.js';
|
|
6
|
+
/** List the recipients (channels) in an alert group. */
|
|
7
|
+
export async function listRecipients(nameOrId, opts = {}) {
|
|
8
|
+
const format = resolveFormat(opts.format);
|
|
9
|
+
const config = requireConfig();
|
|
10
|
+
requireOrg(config);
|
|
11
|
+
const client = createClient(config);
|
|
12
|
+
const groupId = await resolveAlertGroupId(client, nameOrId);
|
|
13
|
+
let channels;
|
|
14
|
+
try {
|
|
15
|
+
channels = (await client.listAlertChannels(groupId)).channels;
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
console.error('Failed to list recipients:', err.message);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
if (format === 'json') {
|
|
22
|
+
printJson(channels);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (channels.length === 0) {
|
|
26
|
+
console.log('No recipients. Add one: alertee alert-groups add-webhook <group> --url …');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// Resolve email-group ids to names for a friendlier summary (best-effort).
|
|
30
|
+
const emailGroupNames = new Map();
|
|
31
|
+
if (channels.some((c) => c.channel_type === 'email_group')) {
|
|
32
|
+
try {
|
|
33
|
+
for (const g of (await client.listEmailGroups()).groups)
|
|
34
|
+
emailGroupNames.set(g.id, g.name);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// non-fatal — fall back to showing the id
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const header = `TYPE ENABLED SUMMARY${' '.repeat(33)}ID`;
|
|
41
|
+
console.log(header);
|
|
42
|
+
console.log('─'.repeat(header.length));
|
|
43
|
+
for (const c of channels) {
|
|
44
|
+
const summary = summarize(c, emailGroupNames);
|
|
45
|
+
console.log(`${c.channel_type.padEnd(12)} ${(c.enabled ? 'yes' : 'no').padEnd(7)} ${summary.padEnd(38)} ${c.id}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function summarize(c, emailGroupNames) {
|
|
49
|
+
if (c.channel_type === 'email_group') {
|
|
50
|
+
const id = uuidValue(c.email_group_id);
|
|
51
|
+
return (id ? emailGroupNames.get(id) ?? id : undefined) ?? '—';
|
|
52
|
+
}
|
|
53
|
+
const config = (c.config ?? {});
|
|
54
|
+
if (c.channel_type === 'webhook')
|
|
55
|
+
return String(config.url ?? '—');
|
|
56
|
+
if (c.channel_type === 'slack')
|
|
57
|
+
return String(config.channel ?? '—');
|
|
58
|
+
if (c.channel_type === 'email')
|
|
59
|
+
return String(config.address ?? config.email ?? '—');
|
|
60
|
+
return '—';
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=recipients.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipients.js","sourceRoot":"","sources":["../../../src/commands/alert-groups/recipients.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,YAAY,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAElD,wDAAwD;AACxD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,OAA4B,EAAE;IAE9B,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACzC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;IAC9B,UAAU,CAAC,MAAM,CAAC,CAAA;IAClB,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;IACnC,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAE3D,IAAI,QAA4B,CAAA;IAChC,IAAI,CAAC;QACH,QAAQ,GAAG,CAAC,MAAM,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAA;IAC/D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAG,GAAa,CAAC,OAAO,CAAC,CAAA;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,SAAS,CAAC,QAAQ,CAAC,CAAA;QACnB,OAAM;IACR,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAA;QACvF,OAAM;IACR,CAAC;IAED,2EAA2E;IAC3E,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAA;IACjD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,aAAa,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC;YACH,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,MAAM;gBAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;QAC5F,CAAC;QAAC,MAAM,CAAC;YACP,0CAA0C;QAC5C,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,gCAAgC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAA;IACjE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACnB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IACtC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,EAAE,eAAe,CAAC,CAAA;QAC7C,OAAO,CAAC,GAAG,CACT,GAAG,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CACtG,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,CAAmB,EAAE,eAAoC;IAC1E,IAAI,CAAC,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAA;QACtC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,GAAG,CAAA;IAChE,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAA4B,CAAA;IAC1D,IAAI,CAAC,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAA;IAClE,IAAI,CAAC,CAAC,YAAY,KAAK,OAAO;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC,CAAA;IACpE,IAAI,CAAC,CAAC,YAAY,KAAK,OAAO;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,CAAA;IACpF,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove a recipient (channel) from an alert group by its channel ID — get IDs
|
|
3
|
+
* from `alertee alert-groups recipients <group>`.
|
|
4
|
+
*/
|
|
5
|
+
export declare function removeRecipient(channelId: string, opts?: {
|
|
6
|
+
yes?: boolean;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=remove-recipient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove-recipient.d.ts","sourceRoot":"","sources":["../../../src/commands/alert-groups/remove-recipient.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3B,OAAO,CAAC,IAAI,CAAC,CAwBf"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { confirm } from '@inquirer/prompts';
|
|
2
|
+
import { createClient } from '../../api.js';
|
|
3
|
+
import { requireConfig, requireOrg } from '../../config.js';
|
|
4
|
+
import { isInteractive } from '../../prompts.js';
|
|
5
|
+
/**
|
|
6
|
+
* Remove a recipient (channel) from an alert group by its channel ID — get IDs
|
|
7
|
+
* from `alertee alert-groups recipients <group>`.
|
|
8
|
+
*/
|
|
9
|
+
export async function removeRecipient(channelId, opts = {}) {
|
|
10
|
+
const config = requireConfig();
|
|
11
|
+
requireOrg(config);
|
|
12
|
+
const client = createClient(config);
|
|
13
|
+
if (!opts.yes) {
|
|
14
|
+
if (!isInteractive()) {
|
|
15
|
+
console.error('Refusing to remove without confirmation. Pass --yes.');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const ok = await confirm({ message: `Remove recipient ${channelId}?`, default: false });
|
|
19
|
+
if (!ok) {
|
|
20
|
+
console.log('Aborted.');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
await client.deleteAlertChannel(channelId);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error('Failed to remove recipient:', err.message);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
console.log(`Removed recipient ${channelId}.`);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=remove-recipient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove-recipient.js","sourceRoot":"","sources":["../../../src/commands/alert-groups/remove-recipient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAAiB,EACjB,OAA0B,EAAE;IAE5B,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;IAC9B,UAAU,CAAC,MAAM,CAAC,CAAA;IAClB,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;IAEnC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACd,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAA;YACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QACD,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,EAAE,OAAO,EAAE,oBAAoB,SAAS,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;QACvF,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;YACvB,OAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAA;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAG,GAAa,CAAC,OAAO,CAAC,CAAA;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,qBAAqB,SAAS,GAAG,CAAC,CAAA;AAChD,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { createClient } from '../../api.js';
|
|
2
|
+
type Client = ReturnType<typeof createClient>;
|
|
3
|
+
/** Resolve an alert group argument (UUID or case-insensitive name) to its ID. */
|
|
4
|
+
export declare function resolveAlertGroupId(client: Client, nameOrId: string): Promise<string>;
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/commands/alert-groups/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEhD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA;AAK7C,iFAAiF;AACjF,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAyBjB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2
|
+
/** Resolve an alert group argument (UUID or case-insensitive name) to its ID. */
|
|
3
|
+
export async function resolveAlertGroupId(client, nameOrId) {
|
|
4
|
+
if (UUID_RE.test(nameOrId.trim())) {
|
|
5
|
+
return nameOrId.trim();
|
|
6
|
+
}
|
|
7
|
+
let groups;
|
|
8
|
+
try {
|
|
9
|
+
groups = (await client.listAlertGroups()).alert_groups;
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
console.error('Failed to list alert groups:', err.message);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const needle = nameOrId.trim().toLowerCase();
|
|
16
|
+
const matches = groups.filter((g) => g.Name.toLowerCase() === needle);
|
|
17
|
+
if (matches.length === 0) {
|
|
18
|
+
console.error(`No alert group named "${nameOrId}". Run \`alertee alert-groups list\`.`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
if (matches.length > 1) {
|
|
22
|
+
console.error(`"${nameOrId}" matches ${matches.length} alert groups; pass the ID instead.`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
return matches[0].ID;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/commands/alert-groups/resolve.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,GACX,iEAAiE,CAAA;AAEnE,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAc,EACd,QAAgB;IAEhB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAClC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;IACxB,CAAC;IAED,IAAI,MAA0E,CAAA;IAC9E,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,YAAY,CAAA;IACxD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAG,GAAa,CAAC,OAAO,CAAC,CAAA;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAA;IAErE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,yBAAyB,QAAQ,uCAAuC,CAAC,CAAA;QACvF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,IAAI,QAAQ,aAAa,OAAO,CAAC,MAAM,qCAAqC,CAAC,CAAA;QAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACtB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../../src/commands/alert-groups/test.ts"],"names":[],"mappings":"AAIA,4EAA4E;AAC5E,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBpE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createClient } from '../../api.js';
|
|
2
|
+
import { requireConfig, requireOrg } from '../../config.js';
|
|
3
|
+
import { resolveAlertGroupId } from './resolve.js';
|
|
4
|
+
/** Send a test alert through every recipient in a group (by name or ID). */
|
|
5
|
+
export async function testAlertGroup(nameOrId) {
|
|
6
|
+
const config = requireConfig();
|
|
7
|
+
requireOrg(config);
|
|
8
|
+
const client = createClient(config);
|
|
9
|
+
const id = await resolveAlertGroupId(client, nameOrId);
|
|
10
|
+
let res;
|
|
11
|
+
try {
|
|
12
|
+
res = await client.sendTestAlert(id, { alert_group_id: id });
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
console.error('Failed to send test alert:', err.message);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
if (!res.success) {
|
|
19
|
+
console.error(`✗ ${res.message || 'Test alert failed.'}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
console.log(`✓ ${res.message || 'Test alert sent.'}`);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../../src/commands/alert-groups/test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAElD,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;IAC9B,UAAU,CAAC,MAAM,CAAC,CAAA;IAClB,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;IACnC,MAAM,EAAE,GAAG,MAAM,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAEtD,IAAI,GAAqD,CAAA;IACzD,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAA;IAC9D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAG,GAAa,CAAC,OAAO,CAAC,CAAA;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,OAAO,IAAI,oBAAoB,EAAE,CAAC,CAAA;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,OAAO,IAAI,kBAAkB,EAAE,CAAC,CAAA;AACvD,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface UpdateAlertGroupOptions {
|
|
2
|
+
name?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
default?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Rename / re-describe an alert group, or set it as the default. The PUT
|
|
8
|
+
* endpoint replaces all fields, so we read the current group first and apply
|
|
9
|
+
* only the flags you pass.
|
|
10
|
+
*/
|
|
11
|
+
export declare function updateAlertGroup(nameOrId: string, opts: UpdateAlertGroupOptions): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/alert-groups/update.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAKD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAuCf"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createClient } from '../../api.js';
|
|
2
|
+
import { requireConfig, requireOrg } from '../../config.js';
|
|
3
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
4
|
+
/**
|
|
5
|
+
* Rename / re-describe an alert group, or set it as the default. The PUT
|
|
6
|
+
* endpoint replaces all fields, so we read the current group first and apply
|
|
7
|
+
* only the flags you pass.
|
|
8
|
+
*/
|
|
9
|
+
export async function updateAlertGroup(nameOrId, opts) {
|
|
10
|
+
if (opts.name === undefined && opts.description === undefined && opts.default === undefined) {
|
|
11
|
+
console.error('Nothing to update. Pass --name, --description, or --default.');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const config = requireConfig();
|
|
15
|
+
requireOrg(config);
|
|
16
|
+
const client = createClient(config);
|
|
17
|
+
let groups;
|
|
18
|
+
try {
|
|
19
|
+
groups = (await client.listAlertGroups()).alert_groups;
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
console.error('Failed to list alert groups:', err.message);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
const needle = nameOrId.trim().toLowerCase();
|
|
26
|
+
const current = UUID_RE.test(nameOrId.trim())
|
|
27
|
+
? groups.find((g) => g.ID === nameOrId.trim())
|
|
28
|
+
: groups.find((g) => g.Name.toLowerCase() === needle);
|
|
29
|
+
if (!current) {
|
|
30
|
+
console.error(`No alert group "${nameOrId}". Run \`alertee alert-groups list\`.`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
await client.updateAlertGroup(current.ID, {
|
|
35
|
+
name: opts.name ?? current.Name,
|
|
36
|
+
description: opts.description ?? current.Description?.String ?? '',
|
|
37
|
+
is_default: opts.default ?? current.IsDefault?.Bool ?? false,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
console.error('Failed to update alert group:', err.message);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
console.log(`Updated alert group ${current.ID}.`);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/commands/alert-groups/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAQ3D,MAAM,OAAO,GACX,iEAAiE,CAAA;AAEnE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,IAA6B;IAE7B,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC5F,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAA;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;IAC9B,UAAU,CAAC,MAAM,CAAC,CAAA;IAClB,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;IAEnC,IAAI,MAA0E,CAAA;IAC9E,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,YAAY,CAAA;IACxD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAG,GAAa,CAAC,OAAO,CAAC,CAAA;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC3C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC9C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAA;IAEvD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,mBAAmB,QAAQ,uCAAuC,CAAC,CAAA;QACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,EAAE;YACxC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;YAC/B,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,MAAM,IAAI,EAAE;YAClE,UAAU,EAAE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,EAAE,IAAI,IAAI,KAAK;SAC7D,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAG,GAAa,CAAC,OAAO,CAAC,CAAA;QACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,CAAC,EAAE,GAAG,CAAC,CAAA;AACnD,CAAC"}
|
|
@@ -1,2 +1,26 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface CreateCheckOptions {
|
|
2
|
+
name?: string;
|
|
3
|
+
/** Connection name or ID. */
|
|
4
|
+
connection?: string;
|
|
5
|
+
query?: string;
|
|
6
|
+
/** Force a grid (multi-dimensional) check. */
|
|
7
|
+
grid?: boolean;
|
|
8
|
+
evaluationType?: string;
|
|
9
|
+
/** Comparison for single-value / per-cell conditions. */
|
|
10
|
+
condition?: string;
|
|
11
|
+
threshold?: number;
|
|
12
|
+
severity?: string;
|
|
13
|
+
labelQuery?: string;
|
|
14
|
+
interval?: string;
|
|
15
|
+
alertLevel?: string;
|
|
16
|
+
/** Route this check's alerts to a specific alert group (name or ID). */
|
|
17
|
+
alertGroup?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create a check, psql-style: pass everything as flags for non-interactive use
|
|
21
|
+
* (CI, or Claude driving the CLI), or omit flags to be prompted for each field
|
|
22
|
+
* at a terminal. The check type is single-value unless --grid or
|
|
23
|
+
* --evaluation-type is given.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createCheck(opts?: CreateCheckOptions): Promise<void>;
|
|
2
26
|
//# sourceMappingURL=create.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/checks/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/checks/create.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2D9E"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { confirm, input, number, select } from '@inquirer/prompts';
|
|
2
2
|
import { createClient } from '../../api.js';
|
|
3
|
-
import { requireConfig,
|
|
3
|
+
import { requireConfig, requireOrg, resolveWebUrl } from '../../config.js';
|
|
4
4
|
import { INTERVAL_CHOICES } from '../../intervals.js';
|
|
5
|
+
import { isInteractive, requireValue } from '../../prompts.js';
|
|
6
|
+
import { resolveAlertGroupId } from '../alert-groups/resolve.js';
|
|
7
|
+
import { resolveConnectionId } from '../connections/resolve.js';
|
|
5
8
|
const CELL_COMPARISONS = [
|
|
6
9
|
{ name: 'Greater than', value: 'greater_than' },
|
|
7
10
|
{ name: 'Less than', value: 'less_than' },
|
|
@@ -10,32 +13,69 @@ const CELL_COMPARISONS = [
|
|
|
10
13
|
{ name: 'Equal to', value: 'equals' },
|
|
11
14
|
{ name: 'Not equal to', value: 'not_equals' },
|
|
12
15
|
];
|
|
13
|
-
|
|
16
|
+
const VALID_COMPARISONS = CELL_COMPARISONS.map((c) => c.value);
|
|
17
|
+
const EVALUATION_TYPES = ['all_cells', 'any_cell', 'dimension_missing', 'dimension_added'];
|
|
18
|
+
const VALID_INTERVALS = INTERVAL_CHOICES.map((c) => c.value);
|
|
19
|
+
const VALID_SEVERITIES = ['info', 'warning', 'critical'];
|
|
20
|
+
/**
|
|
21
|
+
* Create a check, psql-style: pass everything as flags for non-interactive use
|
|
22
|
+
* (CI, or Claude driving the CLI), or omit flags to be prompted for each field
|
|
23
|
+
* at a terminal. The check type is single-value unless --grid or
|
|
24
|
+
* --evaluation-type is given.
|
|
25
|
+
*/
|
|
26
|
+
export async function createCheck(opts = {}) {
|
|
14
27
|
const config = requireConfig();
|
|
15
|
-
|
|
16
|
-
|
|
28
|
+
requireOrg(config);
|
|
29
|
+
const client = createClient(config);
|
|
30
|
+
const isGrid = await resolveMode(opts);
|
|
31
|
+
const name = await requireValue(opts.name, () => input({ message: 'Check name:', validate: (v) => v.trim().length > 0 || 'Required' }), 'Check name required. Pass --name.');
|
|
32
|
+
const connectionId = await resolveConnection(client, opts.connection);
|
|
33
|
+
const query = await requireValue(opts.query, () => input({
|
|
34
|
+
message: isGrid
|
|
35
|
+
? 'SQL query (must return `name` and `value` columns, one row per dimension):'
|
|
36
|
+
: 'SQL query (must return a single numeric value):',
|
|
37
|
+
validate: (v) => v.trim().length > 0 || 'Query is required',
|
|
38
|
+
}), 'SQL query required. Pass --query.');
|
|
39
|
+
const { condition, labelQuery } = isGrid
|
|
40
|
+
? await buildGridCondition(opts)
|
|
41
|
+
: { condition: await buildSingleCondition(opts), labelQuery: undefined };
|
|
42
|
+
const interval = await requireValue(opts.interval, () => select({ message: 'Check interval:', choices: INTERVAL_CHOICES }), 'Interval required. Pass --interval (e.g. five_minutes).');
|
|
43
|
+
if (!VALID_INTERVALS.includes(interval)) {
|
|
44
|
+
console.error(`Invalid --interval "${interval}". One of: ${VALID_INTERVALS.join(', ')}.`);
|
|
17
45
|
process.exit(1);
|
|
18
46
|
}
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
47
|
+
const alertGroupId = opts.alertGroup
|
|
48
|
+
? await resolveAlertGroupId(client, opts.alertGroup)
|
|
49
|
+
: undefined;
|
|
22
50
|
try {
|
|
23
|
-
const resp = await client.
|
|
24
|
-
|
|
51
|
+
const resp = await client.createCheck({
|
|
52
|
+
name,
|
|
53
|
+
connection_id: connectionId,
|
|
54
|
+
query,
|
|
55
|
+
condition,
|
|
56
|
+
interval,
|
|
57
|
+
alert_level: opts.alertLevel,
|
|
58
|
+
alert_group_id: alertGroupId,
|
|
59
|
+
label_query: labelQuery,
|
|
60
|
+
});
|
|
61
|
+
console.log(`\nCheck created: ${resp.check.ID}`);
|
|
62
|
+
console.log(`View at: ${resolveWebUrl()}/checks/${resp.check.ID}`);
|
|
25
63
|
}
|
|
26
64
|
catch (err) {
|
|
27
|
-
console.error('Failed to
|
|
65
|
+
console.error('Failed to create check:', err.message);
|
|
28
66
|
process.exit(1);
|
|
29
67
|
}
|
|
30
|
-
|
|
31
|
-
|
|
68
|
+
}
|
|
69
|
+
/** Decide single vs grid from flags, prompting only when ambiguous + interactive. */
|
|
70
|
+
async function resolveMode(opts) {
|
|
71
|
+
if (opts.grid || opts.evaluationType)
|
|
72
|
+
return true;
|
|
73
|
+
if (opts.condition || opts.threshold !== undefined)
|
|
74
|
+
return false;
|
|
75
|
+
if (!isInteractive()) {
|
|
76
|
+
console.error('Specify the check type: --condition + --threshold (single-value), or --grid / --evaluation-type (grid).');
|
|
32
77
|
process.exit(1);
|
|
33
78
|
}
|
|
34
|
-
const name = await input({ message: 'Check name:' });
|
|
35
|
-
const connectionId = await select({
|
|
36
|
-
message: 'Database connection:',
|
|
37
|
-
choices: connections.map((c) => ({ name: `${c.name} (${c.type})`, value: c.id })),
|
|
38
|
-
});
|
|
39
79
|
const mode = await select({
|
|
40
80
|
message: 'Evaluation:',
|
|
41
81
|
choices: [
|
|
@@ -43,45 +83,86 @@ export async function createCheck() {
|
|
|
43
83
|
{ name: 'Multi-dimensional / grid (query returns name + value rows)', value: 'grid' },
|
|
44
84
|
],
|
|
45
85
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
86
|
+
return mode === 'grid';
|
|
87
|
+
}
|
|
88
|
+
async function resolveConnection(client, connection) {
|
|
89
|
+
if (connection)
|
|
90
|
+
return resolveConnectionId(client, connection);
|
|
91
|
+
if (!isInteractive()) {
|
|
92
|
+
console.error('Connection required. Pass --connection <name|id> (see: alertee connections list).');
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
const connections = (await client.listConnections()).connections;
|
|
96
|
+
if (connections.length === 0) {
|
|
97
|
+
console.error('No database connections found. Create one: alertee connections create');
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
return select({
|
|
101
|
+
message: 'Database connection:',
|
|
102
|
+
choices: connections.map((c) => ({ name: `${c.name} (${c.type})`, value: c.id })),
|
|
51
103
|
});
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
104
|
+
}
|
|
105
|
+
async function buildSingleCondition(opts) {
|
|
106
|
+
const comparison = await requireValue(opts.condition, () => select({
|
|
107
|
+
message: 'Condition type:',
|
|
108
|
+
choices: CELL_COMPARISONS,
|
|
109
|
+
}), 'Condition required. Pass --condition (e.g. less_than).');
|
|
110
|
+
if (!VALID_COMPARISONS.includes(comparison)) {
|
|
111
|
+
console.error(`Invalid --condition "${comparison}". One of: ${VALID_COMPARISONS.join(', ')}.`);
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
const threshold = await requireThreshold(opts);
|
|
115
|
+
return { type: comparison, value: String(threshold) };
|
|
116
|
+
}
|
|
117
|
+
async function buildGridCondition(opts) {
|
|
118
|
+
const evaluationType = await requireValue(opts.evaluationType, () => select({
|
|
119
|
+
message: 'Grid evaluation type:',
|
|
120
|
+
choices: [
|
|
121
|
+
{ name: 'Every cell must satisfy a condition (alert if any fails)', value: 'all_cells' },
|
|
122
|
+
{ name: 'At least one cell must satisfy a condition (alert if none do)', value: 'any_cell' },
|
|
123
|
+
{ name: 'A dimension goes missing', value: 'dimension_missing' },
|
|
124
|
+
{ name: 'A new dimension appears', value: 'dimension_added' },
|
|
125
|
+
],
|
|
126
|
+
}), 'Grid evaluation type required. Pass --evaluation-type (e.g. any_cell).');
|
|
127
|
+
if (!EVALUATION_TYPES.includes(evaluationType)) {
|
|
128
|
+
console.error(`Invalid --evaluation-type "${evaluationType}". One of: ${EVALUATION_TYPES.join(', ')}.`);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
const condition = {
|
|
132
|
+
evaluation_type: evaluationType,
|
|
133
|
+
};
|
|
134
|
+
if (evaluationType === 'any_cell' || evaluationType === 'all_cells') {
|
|
135
|
+
const comparison = await requireValue(opts.condition, () => select({
|
|
136
|
+
message: "Each cell's value should be (healthy state; alert on cells that don't match):",
|
|
137
|
+
choices: CELL_COMPARISONS,
|
|
138
|
+
}), 'Per-cell condition required. Pass --condition (e.g. greater_or_equal).');
|
|
139
|
+
if (!VALID_COMPARISONS.includes(comparison)) {
|
|
140
|
+
console.error(`Invalid --condition "${comparison}". One of: ${VALID_COMPARISONS.join(', ')}.`);
|
|
141
|
+
process.exit(1);
|
|
76
142
|
}
|
|
77
|
-
condition.
|
|
143
|
+
condition.type = comparison;
|
|
144
|
+
condition.value = String(await requireThreshold(opts));
|
|
145
|
+
}
|
|
146
|
+
// Severity defaults to the backend default (warning) when omitted non-interactively.
|
|
147
|
+
if (opts.severity) {
|
|
148
|
+
if (!VALID_SEVERITIES.includes(opts.severity)) {
|
|
149
|
+
console.error(`Invalid --severity "${opts.severity}". One of: ${VALID_SEVERITIES.join(', ')}.`);
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
condition.severity = opts.severity;
|
|
153
|
+
}
|
|
154
|
+
else if (isInteractive()) {
|
|
155
|
+
condition.severity = (await select({
|
|
78
156
|
message: 'Cell severity when matched:',
|
|
79
157
|
choices: [
|
|
80
158
|
{ name: 'Warning', value: 'warning' },
|
|
81
159
|
{ name: 'Critical', value: 'critical' },
|
|
82
160
|
{ name: 'Info', value: 'info' },
|
|
83
161
|
],
|
|
84
|
-
});
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
let labelQuery = opts.labelQuery;
|
|
165
|
+
if (!labelQuery && isInteractive()) {
|
|
85
166
|
const wantsLabels = await confirm({
|
|
86
167
|
message: 'Add a label query (map dimension keys to display names)?',
|
|
87
168
|
default: false,
|
|
@@ -93,41 +174,19 @@ export async function createCheck() {
|
|
|
93
174
|
});
|
|
94
175
|
}
|
|
95
176
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
{ name: 'Not equal to', value: 'not_equals' },
|
|
104
|
-
],
|
|
105
|
-
});
|
|
106
|
-
const threshold = await number({
|
|
107
|
-
message: 'Threshold value:',
|
|
108
|
-
validate: (v) => v !== undefined || 'Required',
|
|
109
|
-
});
|
|
110
|
-
condition = { type: conditionType, value: String(threshold) };
|
|
111
|
-
}
|
|
112
|
-
const interval = await select({
|
|
113
|
-
message: 'Check interval:',
|
|
114
|
-
choices: INTERVAL_CHOICES,
|
|
115
|
-
});
|
|
116
|
-
try {
|
|
117
|
-
const resp = await client.createCheck({
|
|
118
|
-
name,
|
|
119
|
-
connection_id: connectionId,
|
|
120
|
-
query,
|
|
121
|
-
condition,
|
|
122
|
-
interval,
|
|
123
|
-
label_query: labelQuery,
|
|
124
|
-
});
|
|
125
|
-
console.log(`\nCheck created: ${resp.check.ID}`);
|
|
126
|
-
console.log(`View at: ${resolveWebUrl()}/checks/${resp.check.ID}`);
|
|
127
|
-
}
|
|
128
|
-
catch (err) {
|
|
129
|
-
console.error('Failed to create check:', err.message);
|
|
177
|
+
return { condition, labelQuery };
|
|
178
|
+
}
|
|
179
|
+
async function requireThreshold(opts) {
|
|
180
|
+
if (opts.threshold !== undefined)
|
|
181
|
+
return opts.threshold;
|
|
182
|
+
if (!isInteractive()) {
|
|
183
|
+
console.error('Threshold required. Pass --threshold <number>.');
|
|
130
184
|
process.exit(1);
|
|
131
185
|
}
|
|
186
|
+
const value = await number({
|
|
187
|
+
message: 'Threshold value:',
|
|
188
|
+
validate: (v) => v !== undefined || 'Required',
|
|
189
|
+
});
|
|
190
|
+
return value;
|
|
132
191
|
}
|
|
133
192
|
//# sourceMappingURL=create.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/checks/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EAAiB,YAAY,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/checks/create.ts"],"names":[],"mappings":"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"}
|