@intentius/chant-lexicon-prometheus 0.97.0 → 0.99.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/README.md +6 -1
- package/dist/alertmanager.d.ts +4 -2
- package/dist/alertmanager.d.ts.map +1 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/import/embedded.d.ts +14 -0
- package/dist/import/embedded.d.ts.map +1 -0
- package/dist/import/generator.d.ts +50 -0
- package/dist/import/generator.d.ts.map +1 -0
- package/dist/import/parser.d.ts +52 -0
- package/dist/import/parser.d.ts.map +1 -0
- package/dist/import/slo.d.ts +15 -0
- package/dist/import/slo.d.ts.map +1 -0
- package/dist/integrations.d.ts +531 -0
- package/dist/integrations.d.ts.map +1 -0
- package/dist/integrity.json +7 -7
- package/dist/lint/rules/literal-credential.d.ts.map +1 -1
- package/dist/lint/rules/prom-ast.d.ts +8 -0
- package/dist/lint/rules/prom-ast.d.ts.map +1 -1
- package/dist/lint/rules/promql-literal.d.ts.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/model.d.ts +77 -121
- package/dist/model.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/rules/literal-credential.ts +52 -15
- package/dist/rules/prom-ast.ts +36 -0
- package/dist/rules/promql-literal.ts +15 -1
- package/dist/skills/chant-prometheus-alertmanager.md +4 -0
- package/dist/skills/chant-prometheus.md +11 -0
- package/package.json +2 -2
- package/src/alertmanager.ts +4 -1
- package/src/build.ts +2 -0
- package/src/codegen/docs.ts +5 -1
- package/src/import/cli.test.ts +98 -0
- package/src/import/embedded.test.ts +56 -0
- package/src/import/embedded.ts +44 -0
- package/src/import/generated-types.e2e.test.ts +77 -0
- package/src/import/generator.test.ts +138 -0
- package/src/import/generator.ts +578 -0
- package/src/import/parser.test.ts +133 -0
- package/src/import/parser.ts +365 -0
- package/src/import/roundtrip.test.ts +358 -0
- package/src/import/slo.ts +175 -0
- package/src/import/testdata/alertmanager-full.yml +89 -0
- package/src/import/testdata/alertmanager-integrations.yml +215 -0
- package/src/import/testdata/fixtures.ts +122 -0
- package/src/import/testdata/rules-full.yml +42 -0
- package/src/import/testdata/upstream/alertmanager-conf-good.yml +120 -0
- package/src/import/testdata/upstream/alertmanager-mattermost-default-webhook-url-file.yml +16 -0
- package/src/import/testdata/upstream/alertmanager-opsgenie-default-apikey-file.yml +27 -0
- package/src/import/testdata/upstream/alertmanager-rocketchat-default-token-file.yml +25 -0
- package/src/import/testdata/upstream/alertmanager-route-labels.yml +65 -0
- package/src/import/testdata/upstream/alertmanager-simple.yml +130 -0
- package/src/import/testdata/upstream/alertmanager-sns-topic-arn.yml +17 -0
- package/src/import/testdata/upstream/alertmanager-telegram-default-bot-token-file.yml +16 -0
- package/src/import/testdata/upstream/alertmanager-victorops-default-apikey-file.yml +23 -0
- package/src/import/testdata/upstream/alertmanager-wechat-default-api-secret-file.yml +18 -0
- package/src/import/testdata/upstream/prometheus-alerting-rules.yml +15 -0
- package/src/import/testdata/upstream/prometheus-alerting-templates.yml +23 -0
- package/src/import/testdata/upstream/prometheus-recording-rules.yml +7 -0
- package/src/integrations.ts +538 -0
- package/src/lint/rules/literal-credential.ts +52 -15
- package/src/lint/rules/prom-ast.ts +36 -0
- package/src/lint/rules/promql-literal.ts +15 -1
- package/src/lint/rules/rules.test.ts +58 -0
- package/src/model.ts +157 -109
- package/src/plugin.ts +15 -0
- package/src/skills/chant-prometheus-alertmanager.md +4 -0
- package/src/skills/chant-prometheus.md +11 -0
package/dist/model.d.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* so a declaration reads the same as the file it produces and the upstream
|
|
13
13
|
* docs apply word for word.
|
|
14
14
|
*/
|
|
15
|
+
import { type DiscordConfig, type EmailConfig, type HttpClientConfig, type IncidentioConfig, type JiraConfig, type MattermostConfig, type MSTeamsConfig, type MSTeamsV2Config, type OpsGenieConfig, type PagerDutyConfig, type PushoverConfig, type ReceiverIntegration, type RocketchatConfig, type SlackConfig, type SNSConfig, type TelegramConfig, type TlsConfig, type VictorOpsConfig, type WebexConfig, type WebhookConfig, type WechatConfig } from "./integrations.js";
|
|
15
16
|
/** Labels or annotations: string keys to string values. */
|
|
16
17
|
export type LabelSet = Record<string, string>;
|
|
17
18
|
/** A recording rule: evaluates `expr` and stores the result as the series `record`. */
|
|
@@ -60,126 +61,30 @@ export declare function isRecordingRuleConfig(rule: unknown): rule is RecordingR
|
|
|
60
61
|
export declare function isAlertingRuleConfig(rule: unknown): rule is AlertingRuleConfig;
|
|
61
62
|
/** The rule's name: `record` for a recording rule, `alert` for an alerting rule. */
|
|
62
63
|
export declare function ruleName(rule: RuleConfig): string;
|
|
63
|
-
|
|
64
|
-
export interface HttpClientConfig {
|
|
65
|
-
basic_auth?: {
|
|
66
|
-
username?: string;
|
|
67
|
-
username_file?: string;
|
|
68
|
-
password?: string;
|
|
69
|
-
password_file?: string;
|
|
70
|
-
};
|
|
71
|
-
authorization?: {
|
|
72
|
-
type?: string;
|
|
73
|
-
credentials?: string;
|
|
74
|
-
credentials_file?: string;
|
|
75
|
-
};
|
|
76
|
-
bearer_token?: string;
|
|
77
|
-
bearer_token_file?: string;
|
|
78
|
-
oauth2?: Record<string, unknown>;
|
|
79
|
-
proxy_url?: string;
|
|
80
|
-
follow_redirects?: boolean;
|
|
81
|
-
enable_http2?: boolean;
|
|
82
|
-
tls_config?: {
|
|
83
|
-
ca_file?: string;
|
|
84
|
-
cert_file?: string;
|
|
85
|
-
key_file?: string;
|
|
86
|
-
server_name?: string;
|
|
87
|
-
insecure_skip_verify?: boolean;
|
|
88
|
-
min_version?: string;
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
interface NotifierBase {
|
|
92
|
-
/** Whether to notify about resolved alerts too. */
|
|
93
|
-
send_resolved?: boolean;
|
|
94
|
-
}
|
|
95
|
-
export interface WebhookConfig extends NotifierBase {
|
|
96
|
-
/** Where alerts are POSTed. Set this or `url_file`. */
|
|
97
|
-
url?: string;
|
|
98
|
-
url_file?: string;
|
|
99
|
-
http_config?: HttpClientConfig;
|
|
100
|
-
/** Most alerts per message; 0 sends them all. */
|
|
101
|
-
max_alerts?: number;
|
|
102
|
-
timeout?: string;
|
|
103
|
-
}
|
|
104
|
-
export interface EmailConfig extends NotifierBase {
|
|
105
|
-
to: string;
|
|
106
|
-
from?: string;
|
|
107
|
-
/** `host:port` of the SMTP server. Falls back to `global.smtp_smarthost`. */
|
|
108
|
-
smarthost?: string;
|
|
109
|
-
hello?: string;
|
|
110
|
-
auth_username?: string;
|
|
111
|
-
auth_password?: string;
|
|
112
|
-
auth_password_file?: string;
|
|
113
|
-
auth_secret?: string;
|
|
114
|
-
auth_secret_file?: string;
|
|
115
|
-
auth_identity?: string;
|
|
116
|
-
require_tls?: boolean;
|
|
117
|
-
tls_config?: HttpClientConfig["tls_config"];
|
|
118
|
-
html?: string;
|
|
119
|
-
text?: string;
|
|
120
|
-
headers?: Record<string, string>;
|
|
121
|
-
}
|
|
122
|
-
export interface SlackConfig extends NotifierBase {
|
|
123
|
-
/** The incoming-webhook URL. It is a credential: prefer `api_url_file`. */
|
|
124
|
-
api_url?: string;
|
|
125
|
-
api_url_file?: string;
|
|
126
|
-
channel?: string;
|
|
127
|
-
username?: string;
|
|
128
|
-
color?: string;
|
|
129
|
-
title?: string;
|
|
130
|
-
title_link?: string;
|
|
131
|
-
pretext?: string;
|
|
132
|
-
text?: string;
|
|
133
|
-
footer?: string;
|
|
134
|
-
fallback?: string;
|
|
135
|
-
icon_emoji?: string;
|
|
136
|
-
icon_url?: string;
|
|
137
|
-
link_names?: boolean;
|
|
138
|
-
short_fields?: boolean;
|
|
139
|
-
mrkdwn_in?: string[];
|
|
140
|
-
fields?: Array<{
|
|
141
|
-
title: string;
|
|
142
|
-
value: string;
|
|
143
|
-
short?: boolean;
|
|
144
|
-
}>;
|
|
145
|
-
actions?: Array<Record<string, unknown>>;
|
|
146
|
-
http_config?: HttpClientConfig;
|
|
147
|
-
}
|
|
148
|
-
export interface PagerDutyConfig extends NotifierBase {
|
|
149
|
-
/** Events API v2 integration key. A credential: prefer `routing_key_file`. */
|
|
150
|
-
routing_key?: string;
|
|
151
|
-
routing_key_file?: string;
|
|
152
|
-
/** Events API v1 integration key. A credential: prefer `service_key_file`. */
|
|
153
|
-
service_key?: string;
|
|
154
|
-
service_key_file?: string;
|
|
155
|
-
url?: string;
|
|
156
|
-
client?: string;
|
|
157
|
-
client_url?: string;
|
|
158
|
-
description?: string;
|
|
159
|
-
severity?: string;
|
|
160
|
-
class?: string;
|
|
161
|
-
component?: string;
|
|
162
|
-
group?: string;
|
|
163
|
-
source?: string;
|
|
164
|
-
details?: Record<string, string>;
|
|
165
|
-
links?: Array<{
|
|
166
|
-
href: string;
|
|
167
|
-
text?: string;
|
|
168
|
-
}>;
|
|
169
|
-
images?: Array<{
|
|
170
|
-
src: string;
|
|
171
|
-
alt?: string;
|
|
172
|
-
href?: string;
|
|
173
|
-
}>;
|
|
174
|
-
http_config?: HttpClientConfig;
|
|
175
|
-
}
|
|
64
|
+
export * from "./integrations.js";
|
|
176
65
|
/** One entry under `receivers:`. */
|
|
177
66
|
export interface ReceiverConfig {
|
|
178
67
|
name: string;
|
|
179
|
-
|
|
68
|
+
/** Labels on the receiver, exposed to notification templates. */
|
|
69
|
+
labels?: LabelSet;
|
|
70
|
+
discord_configs?: DiscordConfig[];
|
|
180
71
|
email_configs?: EmailConfig[];
|
|
181
|
-
|
|
72
|
+
incidentio_configs?: IncidentioConfig[];
|
|
182
73
|
pagerduty_configs?: PagerDutyConfig[];
|
|
74
|
+
slack_configs?: SlackConfig[];
|
|
75
|
+
webhook_configs?: WebhookConfig[];
|
|
76
|
+
opsgenie_configs?: OpsGenieConfig[];
|
|
77
|
+
wechat_configs?: WechatConfig[];
|
|
78
|
+
pushover_configs?: PushoverConfig[];
|
|
79
|
+
victorops_configs?: VictorOpsConfig[];
|
|
80
|
+
sns_configs?: SNSConfig[];
|
|
81
|
+
telegram_configs?: TelegramConfig[];
|
|
82
|
+
webex_configs?: WebexConfig[];
|
|
83
|
+
msteams_configs?: MSTeamsConfig[];
|
|
84
|
+
msteamsv2_configs?: MSTeamsV2Config[];
|
|
85
|
+
jira_configs?: JiraConfig[];
|
|
86
|
+
rocketchat_configs?: RocketchatConfig[];
|
|
87
|
+
mattermost_configs?: MattermostConfig[];
|
|
183
88
|
}
|
|
184
89
|
/** A route in the routing tree. The top-level `route:` is the root. */
|
|
185
90
|
export interface RouteConfig {
|
|
@@ -193,10 +98,17 @@ export interface RouteConfig {
|
|
|
193
98
|
repeat_interval?: string;
|
|
194
99
|
mute_time_intervals?: string[];
|
|
195
100
|
active_time_intervals?: string[];
|
|
101
|
+
/**
|
|
102
|
+
* Labels on the route, inherited by child routes and exposed to
|
|
103
|
+
* notification templates as `routeLabels`. Values may be Go templates.
|
|
104
|
+
*/
|
|
105
|
+
labels?: LabelSet;
|
|
196
106
|
routes?: RouteConfig[];
|
|
197
107
|
}
|
|
198
108
|
/** One entry under `inhibit_rules:`. */
|
|
199
109
|
export interface InhibitRuleConfig {
|
|
110
|
+
/** A name for the rule, shown in Alertmanager's logs and metrics. */
|
|
111
|
+
name?: string;
|
|
200
112
|
source_matchers?: string[];
|
|
201
113
|
target_matchers?: string[];
|
|
202
114
|
/** Labels that must be equal on source and target for the inhibition to apply. */
|
|
@@ -225,12 +137,18 @@ export interface TimeIntervalConfig {
|
|
|
225
137
|
name: string;
|
|
226
138
|
time_intervals: TimePeriodConfig[];
|
|
227
139
|
}
|
|
228
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* `global:` settings: defaults the receivers fall back to. Credentials with
|
|
142
|
+
* a `*_file` sibling are best set through it; PROM001 flags a literal.
|
|
143
|
+
*/
|
|
229
144
|
export interface AlertmanagerGlobalConfig {
|
|
145
|
+
/** How long an alert that stops being updated stays firing. */
|
|
230
146
|
resolve_timeout?: string;
|
|
147
|
+
http_config?: HttpClientConfig;
|
|
148
|
+
jira_api_url?: string;
|
|
231
149
|
smtp_from?: string;
|
|
232
|
-
smtp_smarthost?: string;
|
|
233
150
|
smtp_hello?: string;
|
|
151
|
+
smtp_smarthost?: string;
|
|
234
152
|
smtp_auth_username?: string;
|
|
235
153
|
smtp_auth_password?: string;
|
|
236
154
|
smtp_auth_password_file?: string;
|
|
@@ -238,10 +156,48 @@ export interface AlertmanagerGlobalConfig {
|
|
|
238
156
|
smtp_auth_secret_file?: string;
|
|
239
157
|
smtp_auth_identity?: string;
|
|
240
158
|
smtp_require_tls?: boolean;
|
|
159
|
+
smtp_tls_config?: TlsConfig;
|
|
160
|
+
smtp_force_implicit_tls?: boolean;
|
|
241
161
|
slack_api_url?: string;
|
|
242
162
|
slack_api_url_file?: string;
|
|
163
|
+
slack_app_token?: string;
|
|
164
|
+
slack_app_token_file?: string;
|
|
165
|
+
slack_app_url?: string;
|
|
243
166
|
pagerduty_url?: string;
|
|
244
|
-
|
|
167
|
+
opsgenie_api_url?: string;
|
|
168
|
+
opsgenie_api_key?: string;
|
|
169
|
+
opsgenie_api_key_file?: string;
|
|
170
|
+
wechat_api_url?: string;
|
|
171
|
+
wechat_api_secret?: string;
|
|
172
|
+
wechat_api_secret_file?: string;
|
|
173
|
+
wechat_api_corp_id?: string;
|
|
174
|
+
victorops_api_url?: string;
|
|
175
|
+
victorops_api_key?: string;
|
|
176
|
+
victorops_api_key_file?: string;
|
|
177
|
+
telegram_api_url?: string;
|
|
178
|
+
telegram_bot_token?: string;
|
|
179
|
+
telegram_bot_token_file?: string;
|
|
180
|
+
webex_api_url?: string;
|
|
181
|
+
rocketchat_api_url?: string;
|
|
182
|
+
rocketchat_token?: string;
|
|
183
|
+
rocketchat_token_file?: string;
|
|
184
|
+
rocketchat_token_id?: string;
|
|
185
|
+
rocketchat_token_id_file?: string;
|
|
186
|
+
mattermost_webhook_url?: string;
|
|
187
|
+
mattermost_webhook_url_file?: string;
|
|
188
|
+
}
|
|
189
|
+
/** Every `global:` field, as a list, for code that reads a parsed file. */
|
|
190
|
+
export declare const ALERTMANAGER_GLOBAL_FIELDS: readonly (keyof AlertmanagerGlobalConfig)[];
|
|
191
|
+
/** `tracing:` settings: where Alertmanager sends its own traces. */
|
|
192
|
+
export interface AlertmanagerTracingConfig {
|
|
193
|
+
client_type?: "grpc" | "http";
|
|
194
|
+
endpoint?: string;
|
|
195
|
+
sampling_fraction?: number;
|
|
196
|
+
insecure?: boolean;
|
|
197
|
+
headers?: Record<string, string>;
|
|
198
|
+
compression?: string;
|
|
199
|
+
timeout?: string;
|
|
200
|
+
tls_config?: TlsConfig;
|
|
245
201
|
}
|
|
246
202
|
/** A whole `alertmanager.yml`, the file `amtool check-config` reads. */
|
|
247
203
|
export interface AlertmanagerConfig {
|
|
@@ -251,12 +207,12 @@ export interface AlertmanagerConfig {
|
|
|
251
207
|
inhibit_rules?: InhibitRuleConfig[];
|
|
252
208
|
receivers?: ReceiverConfig[];
|
|
253
209
|
time_intervals?: TimeIntervalConfig[];
|
|
210
|
+
tracing?: AlertmanagerTracingConfig;
|
|
254
211
|
}
|
|
255
|
-
/** The
|
|
256
|
-
export declare const RECEIVER_INTEGRATIONS: readonly [
|
|
212
|
+
/** The receiver integrations, every one Alertmanager defines. */
|
|
213
|
+
export declare const RECEIVER_INTEGRATIONS: readonly ReceiverIntegration[];
|
|
257
214
|
/** True when a parsed document has the shape of a Prometheus rule file. */
|
|
258
215
|
export declare function looksLikeRuleFile(value: unknown): value is RuleFileConfig;
|
|
259
216
|
/** True when a parsed document has the shape of an `alertmanager.yml`. */
|
|
260
217
|
export declare function looksLikeAlertmanagerConfig(value: unknown): value is AlertmanagerConfig;
|
|
261
|
-
export {};
|
|
262
218
|
//# sourceMappingURL=model.d.ts.map
|
package/dist/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,2DAA2D;AAC3D,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9C,uFAAuF;AACvF,MAAM,WAAW,mBAAmB;IAClC,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,MAAM,CAAC,EAAE,QAAQ,CAAC;CACnB;AAED,0EAA0E;AAC1E,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,oFAAoF;IACpF,WAAW,CAAC,EAAE,QAAQ,CAAC;CACxB;AAED,MAAM,MAAM,UAAU,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;AAElE,qGAAqG;AACrG,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oGAAoG;IACpG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,4FAA4F;AAC5F,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,mBAAmB,CAEhF;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,kBAAkB,CAE9E;AAED,oFAAoF;AACpF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAEjD;AAID,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AA+B9D;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,aAyG9B,CAAC"}
|
|
@@ -1,26 +1,53 @@
|
|
|
1
1
|
import * as ts from "typescript";
|
|
2
2
|
import type { LintRule, LintDiagnostic, LintContext } from "@intentius/chant/lint/rule";
|
|
3
|
-
import { calleeName, CREDENTIAL_CLASS, literalText, position, propertyName } from "./prom-ast";
|
|
3
|
+
import { calleeName, constInitializers, CREDENTIAL_CLASS, literalText, position, propertyName, resolveConst } from "./prom-ast";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Alertmanager fields that hold a secret, each with a `*_file` sibling that
|
|
7
7
|
* reads it from a mounted file instead.
|
|
8
8
|
*/
|
|
9
9
|
export const SECRET_FIELDS = new Set([
|
|
10
|
-
"api_url", // slack_configs: the incoming-webhook URL is the credential
|
|
11
|
-
"
|
|
12
|
-
"
|
|
10
|
+
"api_url", // slack_configs only: the incoming-webhook URL is the credential (see SECRET_ONLY_IN)
|
|
11
|
+
"webhook_url", // discord, msteams, msteamsv2 and mattermost
|
|
12
|
+
"app_token",
|
|
13
|
+
"routing_key", // pagerduty (victorops' routing_key names a route, see SECRET_ONLY_IN)
|
|
13
14
|
"service_key",
|
|
15
|
+
"api_key",
|
|
16
|
+
"api_secret",
|
|
17
|
+
"bot_token",
|
|
18
|
+
"token",
|
|
19
|
+
"token_id",
|
|
20
|
+
"user_key",
|
|
21
|
+
"alert_source_token",
|
|
14
22
|
"auth_password",
|
|
15
23
|
"auth_secret",
|
|
16
24
|
"smtp_auth_password",
|
|
17
25
|
"smtp_auth_secret",
|
|
26
|
+
"slack_api_url",
|
|
27
|
+
"slack_app_token",
|
|
28
|
+
"opsgenie_api_key",
|
|
29
|
+
"wechat_api_secret",
|
|
30
|
+
"victorops_api_key",
|
|
31
|
+
"telegram_bot_token",
|
|
32
|
+
"rocketchat_token",
|
|
33
|
+
"rocketchat_token_id",
|
|
34
|
+
"mattermost_webhook_url",
|
|
18
35
|
"password",
|
|
19
36
|
"credentials",
|
|
20
37
|
"bearer_token",
|
|
21
38
|
"client_secret",
|
|
22
39
|
]);
|
|
23
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Fields that are a secret in one integration and plain elsewhere: `api_url`
|
|
43
|
+
* is Slack's webhook credential but only an endpoint for the others, and a
|
|
44
|
+
* VictorOps `routing_key` names a route.
|
|
45
|
+
*/
|
|
46
|
+
const SECRET_ONLY_IN: Record<string, string> = {
|
|
47
|
+
api_url: "slack_configs",
|
|
48
|
+
routing_key: "pagerduty_configs",
|
|
49
|
+
};
|
|
50
|
+
|
|
24
51
|
/**
|
|
25
52
|
* PROM001: a credential written as a literal in a `Receiver` or
|
|
26
53
|
* `AlertmanagerSettings`.
|
|
@@ -41,16 +68,25 @@ export const literalCredentialRule: LintRule = {
|
|
|
41
68
|
const diagnostics: LintDiagnostic[] = [];
|
|
42
69
|
const source = context.sourceFile;
|
|
43
70
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
71
|
+
const consts = constInitializers(source);
|
|
72
|
+
const scanned = new Set<ts.Node>();
|
|
73
|
+
|
|
74
|
+
// A value is followed to the const it names, so a list lifted out of the
|
|
75
|
+
// constructor (`email_configs: heartbeatEmail`) is scanned where it is used.
|
|
76
|
+
// `integration` is the `*_configs` list a value sits in, when that is known.
|
|
77
|
+
const scanValue = (key: string | undefined, value: ts.Expression, integration?: string) => {
|
|
78
|
+
const init = resolveConst(value, consts);
|
|
79
|
+
const within = key?.endsWith("_configs") ? key : integration;
|
|
80
|
+
if (ts.isObjectLiteralExpression(init) || ts.isArrayLiteralExpression(init)) {
|
|
81
|
+
if (scanned.has(init)) return;
|
|
82
|
+
scanned.add(init);
|
|
83
|
+
if (ts.isObjectLiteralExpression(init)) scan(init, within);
|
|
84
|
+
else for (const el of init.elements) scanValue(undefined, el, within);
|
|
51
85
|
return;
|
|
52
86
|
}
|
|
53
87
|
if (!key || !SECRET_FIELDS.has(key)) return;
|
|
88
|
+
const only = SECRET_ONLY_IN[key];
|
|
89
|
+
if (only && integration !== undefined && integration !== only) return;
|
|
54
90
|
const text = literalText(init);
|
|
55
91
|
if (text === undefined || text === "") return;
|
|
56
92
|
diagnostics.push({
|
|
@@ -62,10 +98,11 @@ export const literalCredentialRule: LintRule = {
|
|
|
62
98
|
});
|
|
63
99
|
};
|
|
64
100
|
|
|
65
|
-
const scan = (obj: ts.ObjectLiteralExpression) => {
|
|
101
|
+
const scan = (obj: ts.ObjectLiteralExpression, integration?: string) => {
|
|
66
102
|
for (const prop of obj.properties) {
|
|
67
|
-
if (
|
|
68
|
-
|
|
103
|
+
if (ts.isPropertyAssignment(prop)) scanValue(propertyName(prop), prop.initializer, integration);
|
|
104
|
+
else if (ts.isShorthandPropertyAssignment(prop)) scanValue(prop.name.text, prop.name, integration);
|
|
105
|
+
else if (ts.isSpreadAssignment(prop)) scanValue(undefined, prop.expression, integration);
|
|
69
106
|
}
|
|
70
107
|
};
|
|
71
108
|
|
|
@@ -73,7 +110,7 @@ export const literalCredentialRule: LintRule = {
|
|
|
73
110
|
if (ts.isNewExpression(node) || ts.isCallExpression(node)) {
|
|
74
111
|
const name = calleeName(node);
|
|
75
112
|
const arg = node.arguments?.[0];
|
|
76
|
-
if (name && CREDENTIAL_CLASS.test(name) && arg
|
|
113
|
+
if (name && CREDENTIAL_CLASS.test(name) && arg) scanValue(undefined, arg);
|
|
77
114
|
}
|
|
78
115
|
ts.forEachChild(node, visit);
|
|
79
116
|
};
|
package/dist/rules/prom-ast.ts
CHANGED
|
@@ -28,3 +28,39 @@ export function position(source: ts.SourceFile, node: ts.Node): { line: number;
|
|
|
28
28
|
const { line, character } = source.getLineAndCharacterOfPosition(node.getStart(source));
|
|
29
29
|
return { line: line + 1, column: character + 1 };
|
|
30
30
|
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Every `const name = <initializer>` in the file, so a rule can follow a
|
|
34
|
+
* value lifted out of a constructor into a named const (the way COR001 asks
|
|
35
|
+
* for it, and the way `chant import` writes it) back to its literal.
|
|
36
|
+
*/
|
|
37
|
+
export function constInitializers(source: ts.SourceFile): Map<string, ts.Expression> {
|
|
38
|
+
const consts = new Map<string, ts.Expression>();
|
|
39
|
+
const collect = (node: ts.Node) => {
|
|
40
|
+
if (ts.isVariableDeclarationList(node) && node.flags & ts.NodeFlags.Const) {
|
|
41
|
+
for (const d of node.declarations) {
|
|
42
|
+
if (ts.isIdentifier(d.name) && d.initializer) consts.set(d.name.text, d.initializer);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
ts.forEachChild(node, collect);
|
|
46
|
+
};
|
|
47
|
+
collect(source);
|
|
48
|
+
return consts;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** `expr` itself, or the initializer of the const it names (followed through `as` and `satisfies`). */
|
|
52
|
+
export function resolveConst(expr: ts.Expression, consts: Map<string, ts.Expression>): ts.Expression {
|
|
53
|
+
let cur = expr;
|
|
54
|
+
for (let hops = 0; hops < 8; hops++) {
|
|
55
|
+
if (ts.isAsExpression(cur) || ts.isSatisfiesExpression(cur) || ts.isParenthesizedExpression(cur)) {
|
|
56
|
+
cur = cur.expression;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (ts.isIdentifier(cur) && consts.has(cur.text)) {
|
|
60
|
+
cur = consts.get(cur.text)!;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
return cur;
|
|
66
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as ts from "typescript";
|
|
2
2
|
import type { LintRule, LintDiagnostic, LintContext } from "@intentius/chant/lint/rule";
|
|
3
|
-
import { calleeName, literalText, position, propertyName } from "./prom-ast";
|
|
3
|
+
import { calleeName, constInitializers, literalText, position, propertyName, resolveConst } from "./prom-ast";
|
|
4
4
|
import { checkPromql } from "../../promql";
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -21,7 +21,21 @@ export const promqlLiteralRule: LintRule = {
|
|
|
21
21
|
const diagnostics: LintDiagnostic[] = [];
|
|
22
22
|
const source = context.sourceFile;
|
|
23
23
|
|
|
24
|
+
const consts = constInitializers(source);
|
|
25
|
+
const scanned = new Set<ts.Node>();
|
|
26
|
+
|
|
27
|
+
// Rules lifted into a const (`rules: apiRules`) are followed to it and
|
|
28
|
+
// checked where the group uses them.
|
|
29
|
+
const follow = (value: ts.Expression) => {
|
|
30
|
+
const init = resolveConst(value, consts);
|
|
31
|
+
if (init !== value && !scanned.has(init)) {
|
|
32
|
+
scanned.add(init);
|
|
33
|
+
scan(init);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
24
36
|
const scan = (node: ts.Node) => {
|
|
37
|
+
if (ts.isShorthandPropertyAssignment(node)) follow(node.name);
|
|
38
|
+
if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.initializer)) follow(node.initializer);
|
|
25
39
|
if (ts.isPropertyAssignment(node) && propertyName(node) === "expr") {
|
|
26
40
|
const text = literalText(node.initializer);
|
|
27
41
|
if (text !== undefined) {
|
|
@@ -47,6 +47,10 @@ export const pageMutesTicket = new InhibitRule({
|
|
|
47
47
|
});
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
## Starting from an existing alertmanager.yml
|
|
51
|
+
|
|
52
|
+
Import it rather than retyping it: `chant import alertmanager.yml --output src` (with `--lexicon prometheus` outside a chant project). The importer writes `receivers.ts`, `time-intervals.ts`, `routes.ts` (the root `Route`, children as `RouteProps` that reference receivers and time intervals by variable), `inhibit-rules.ts` and `settings.ts`. `*_file` paths and Go templates are kept as written; a literal credential is imported as found and PROM001 reports it, so offer to move it to the `*_file` field. Every integration comes back typed (`OpsGenieConfig[]`, `MSTeamsV2Config[]`, ...); a receiver or `global` key Alertmanager doesn't define is spread in from an untyped const, with a warning. `match`/`match_re` and the top-level `mute_time_intervals` come back in their current spelling (`matchers`, `time_intervals`), and `chant import` prints a warning for each.
|
|
53
|
+
|
|
50
54
|
## What the checks hold you to
|
|
51
55
|
|
|
52
56
|
- One root route (the `Route` no other route nests), with a receiver and no matchers (PROM205).
|
|
@@ -15,6 +15,17 @@ The prometheus lexicon (`@intentius/chant-lexicon-prometheus`) types Prometheus
|
|
|
15
15
|
export default { lexicons: ["prometheus"] };
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
## Starting from an existing rule file
|
|
19
|
+
|
|
20
|
+
When the user already has a rule file, import it rather than retyping it:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
chant import rules.yml --output src # add --lexicon prometheus outside a chant project
|
|
24
|
+
chant build src --lexicon prometheus -o rules.yml # the same groups back
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The importer writes `rules.ts` (per group, a `Rule[]` const of plain objects and a `RuleGroup`) and `slos.ts` for any group an `Slo()` built, as the `Slo` call. Multi-line expressions become template literals and Go templates in annotations stay as written. Read the warnings `chant import` prints: they name any field Prometheus doesn't define, which is not carried.
|
|
28
|
+
|
|
18
29
|
## Declaring a group
|
|
19
30
|
|
|
20
31
|
A group takes the rule file's own keys (`name`, `interval`, `query_offset`, `limit`, `labels`, `rules`). Rules are plain objects: `record` + `expr` for a recording rule, `alert` + `expr` (+ `for`, `keep_firing_for`, `labels`, `annotations`) for an alerting rule.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-prometheus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.99.0",
|
|
4
4
|
"description": "Prometheus lexicon for chant — typed recording and alerting rule groups and Alertmanager routing, serialized to a rule file and alertmanager.yml",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"typescript": "^5.9.3"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
|
-
"@intentius/chant": "^0.
|
|
74
|
+
"@intentius/chant": "^0.99.0",
|
|
75
75
|
"typescript": "^5.9.3"
|
|
76
76
|
}
|
|
77
77
|
}
|
package/src/alertmanager.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { createResource } from "@intentius/chant/runtime";
|
|
|
16
16
|
import type { Declarable } from "@intentius/chant/declarable";
|
|
17
17
|
import type {
|
|
18
18
|
AlertmanagerGlobalConfig,
|
|
19
|
+
AlertmanagerTracingConfig,
|
|
19
20
|
InhibitRuleConfig,
|
|
20
21
|
ReceiverConfig,
|
|
21
22
|
RouteConfig,
|
|
@@ -112,13 +113,15 @@ export interface AlertmanagerSettingsProps {
|
|
|
112
113
|
global?: AlertmanagerGlobalConfig;
|
|
113
114
|
/** Paths of notification template files. */
|
|
114
115
|
templates?: string[];
|
|
116
|
+
/** Where Alertmanager sends its own traces. */
|
|
117
|
+
tracing?: AlertmanagerTracingConfig;
|
|
115
118
|
}
|
|
116
119
|
|
|
117
120
|
export interface AlertmanagerSettingsEntity extends Declarable {
|
|
118
121
|
readonly props: AlertmanagerSettingsProps;
|
|
119
122
|
}
|
|
120
123
|
|
|
121
|
-
/** The `global:` block and `
|
|
124
|
+
/** The `global:` block, `templates:` list and `tracing:` block. Optional; declare at most one. */
|
|
122
125
|
export const AlertmanagerSettings = entityClass<AlertmanagerSettingsProps, AlertmanagerSettingsEntity>(
|
|
123
126
|
SETTINGS_TYPE,
|
|
124
127
|
"AlertmanagerSettings",
|
package/src/build.ts
CHANGED
|
@@ -109,6 +109,7 @@ function routeConfig(route: RouteEntity | RouteProps): RouteConfig {
|
|
|
109
109
|
if (p.repeat_interval !== undefined) out.repeat_interval = p.repeat_interval;
|
|
110
110
|
if (p.mute_time_intervals !== undefined) out.mute_time_intervals = p.mute_time_intervals.map(intervalName);
|
|
111
111
|
if (p.active_time_intervals !== undefined) out.active_time_intervals = p.active_time_intervals.map(intervalName);
|
|
112
|
+
if (p.labels !== undefined) out.labels = { ...p.labels };
|
|
112
113
|
if (p.routes !== undefined) out.routes = p.routes.map(routeConfig);
|
|
113
114
|
return out;
|
|
114
115
|
}
|
|
@@ -177,6 +178,7 @@ export function buildAlertmanagerConfig(entities: Iterable<Declarable> | Map<str
|
|
|
177
178
|
intervals.sort((a, b) => byName(a.props.name, b.props.name));
|
|
178
179
|
if (receivers.length > 0) config.receivers = receivers.map((r) => plain(r.props) as ReceiverConfig);
|
|
179
180
|
if (intervals.length > 0) config.time_intervals = intervals.map((t) => plain(t.props) as TimeIntervalConfig);
|
|
181
|
+
if (settings?.props.tracing) config.tracing = plain(settings.props.tracing) as AlertmanagerConfig["tracing"];
|
|
180
182
|
|
|
181
183
|
return { config, warnings, count };
|
|
182
184
|
}
|
package/src/codegen/docs.ts
CHANGED
|
@@ -47,6 +47,10 @@ group names (PROM101), valid durations (PROM103), routes that name
|
|
|
47
47
|
declared receivers (PROM201), and every alert severity routed by some route
|
|
48
48
|
(PROM202). \`promtool check rules\` and \`amtool check-config\` are wrapped as
|
|
49
49
|
helpers for tests and CI, and run when installed.
|
|
50
|
+
|
|
51
|
+
\`chant import\` turns an existing rule file or \`alertmanager.yml\` into this
|
|
52
|
+
TypeScript, and \`chant build\` on the result gives the file back (see
|
|
53
|
+
Importing Rule Files and alertmanager.yml).
|
|
50
54
|
`;
|
|
51
55
|
|
|
52
56
|
const outputFormat = `The prometheus lexicon serializes two files:
|
|
@@ -58,7 +62,7 @@ const outputFormat = `The prometheus lexicon serializes two files:
|
|
|
58
62
|
- **\`alertmanager.yml\`**, from the \`AlertmanagerSettings\`, \`Route\`,
|
|
59
63
|
\`InhibitRule\`, \`Receiver\` and \`TimeInterval\` entities, in that section
|
|
60
64
|
order: \`global\`, \`templates\`, \`route\`, \`inhibit_rules\`, \`receivers\`,
|
|
61
|
-
\`time_intervals\`.
|
|
65
|
+
\`time_intervals\`, \`tracing\`.
|
|
62
66
|
|
|
63
67
|
The rule file is the primary output when the build declares any rule
|
|
64
68
|
groups, and \`alertmanager.yml\` is written beside it (\`-o dist/rules.yml\`
|