@intentius/chant-lexicon-prometheus 0.106.4 → 0.108.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.
Files changed (111) hide show
  1. package/README.md +6 -1
  2. package/dist/api/alertmanager.d.ts +56 -0
  3. package/dist/api/alertmanager.d.ts.map +1 -0
  4. package/dist/api/apply.d.ts +126 -0
  5. package/dist/api/apply.d.ts.map +1 -0
  6. package/dist/api/bind.d.ts +49 -0
  7. package/dist/api/bind.d.ts.map +1 -0
  8. package/dist/api/client.d.ts +76 -0
  9. package/dist/api/client.d.ts.map +1 -0
  10. package/dist/api/evaluated.d.ts +36 -0
  11. package/dist/api/evaluated.d.ts.map +1 -0
  12. package/dist/api/fake-servers.d.ts +74 -0
  13. package/dist/api/fake-servers.d.ts.map +1 -0
  14. package/dist/api/index.d.ts +18 -0
  15. package/dist/api/index.d.ts.map +1 -0
  16. package/dist/api/ruler.d.ts +87 -0
  17. package/dist/api/ruler.d.ts.map +1 -0
  18. package/dist/composites/alert-routing.d.ts +104 -0
  19. package/dist/composites/alert-routing.d.ts.map +1 -0
  20. package/dist/composites/catalog.d.ts.map +1 -1
  21. package/dist/composites/index.d.ts +6 -0
  22. package/dist/composites/index.d.ts.map +1 -1
  23. package/dist/composites/red-alerts.d.ts +96 -0
  24. package/dist/composites/red-alerts.d.ts.map +1 -0
  25. package/dist/composites/watchdog.d.ts +69 -0
  26. package/dist/composites/watchdog.d.ts.map +1 -0
  27. package/dist/config.d.ts +273 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/describe-resources.d.ts +48 -0
  30. package/dist/describe-resources.d.ts.map +1 -0
  31. package/dist/export-resources.d.ts +41 -0
  32. package/dist/export-resources.d.ts.map +1 -0
  33. package/dist/import/alertmanager-live.d.ts +35 -0
  34. package/dist/import/alertmanager-live.d.ts.map +1 -0
  35. package/dist/import/parser.d.ts +12 -0
  36. package/dist/import/parser.d.ts.map +1 -1
  37. package/dist/index.d.ts +6 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/integrity.json +3 -3
  40. package/dist/lint/post-synth/prom-helpers.d.ts +11 -3
  41. package/dist/lint/post-synth/prom-helpers.d.ts.map +1 -1
  42. package/dist/manifest.json +1 -1
  43. package/dist/op/activities/index.d.ts +25 -0
  44. package/dist/op/activities/index.d.ts.map +1 -0
  45. package/dist/op/activities/promtool.d.ts +78 -0
  46. package/dist/op/activities/promtool.d.ts.map +1 -0
  47. package/dist/op/activities/rule-audit.d.ts +65 -0
  48. package/dist/op/activities/rule-audit.d.ts.map +1 -0
  49. package/dist/op/activities/rules-loaded.d.ts +60 -0
  50. package/dist/op/activities/rules-loaded.d.ts.map +1 -0
  51. package/dist/op/activities/silence.d.ts +80 -0
  52. package/dist/op/activities/silence.d.ts.map +1 -0
  53. package/dist/op/activity-contracts.d.ts +113 -0
  54. package/dist/op/activity-contracts.d.ts.map +1 -0
  55. package/dist/op/audit-op.d.ts +38 -0
  56. package/dist/op/audit-op.d.ts.map +1 -0
  57. package/dist/op/builders.d.ts +57 -0
  58. package/dist/op/builders.d.ts.map +1 -0
  59. package/dist/op/slo-rule-tests.d.ts +44 -0
  60. package/dist/op/slo-rule-tests.d.ts.map +1 -0
  61. package/dist/plugin.d.ts.map +1 -1
  62. package/dist/rules/prom-helpers.ts +38 -3
  63. package/package.json +19 -3
  64. package/src/api/alertmanager.ts +122 -0
  65. package/src/api/apply.test.ts +218 -0
  66. package/src/api/apply.ts +375 -0
  67. package/src/api/bind.ts +87 -0
  68. package/src/api/client.ts +138 -0
  69. package/src/api/evaluated.test.ts +78 -0
  70. package/src/api/evaluated.ts +106 -0
  71. package/src/api/fake-servers.ts +209 -0
  72. package/src/api/index.ts +29 -0
  73. package/src/api/ruler.ts +168 -0
  74. package/src/api/testdata/am-status-original.yml +85 -0
  75. package/src/composites/alert-routing.test.ts +163 -0
  76. package/src/composites/alert-routing.ts +277 -0
  77. package/src/composites/catalog.test.ts +10 -2
  78. package/src/composites/catalog.ts +214 -0
  79. package/src/composites/index.ts +14 -0
  80. package/src/composites/red-alerts.test.ts +182 -0
  81. package/src/composites/red-alerts.ts +214 -0
  82. package/src/composites/watchdog.test.ts +85 -0
  83. package/src/composites/watchdog.ts +142 -0
  84. package/src/config.test.ts +93 -0
  85. package/src/config.ts +288 -0
  86. package/src/describe-resources.test.ts +325 -0
  87. package/src/describe-resources.ts +328 -0
  88. package/src/export-resources.test.ts +253 -0
  89. package/src/export-resources.ts +193 -0
  90. package/src/import/alertmanager-live.test.ts +66 -0
  91. package/src/import/alertmanager-live.ts +291 -0
  92. package/src/import/parser.ts +18 -1
  93. package/src/import/roundtrip.test.ts +1 -0
  94. package/src/index.ts +37 -0
  95. package/src/lint/post-synth/prom-helpers.ts +38 -3
  96. package/src/op/activities/index.ts +31 -0
  97. package/src/op/activities/promtool.test.ts +107 -0
  98. package/src/op/activities/promtool.ts +149 -0
  99. package/src/op/activities/rule-audit.test.ts +89 -0
  100. package/src/op/activities/rule-audit.ts +168 -0
  101. package/src/op/activities/rules-loaded.test.ts +61 -0
  102. package/src/op/activities/rules-loaded.ts +98 -0
  103. package/src/op/activities/silence.test.ts +107 -0
  104. package/src/op/activities/silence.ts +175 -0
  105. package/src/op/activity-contracts.test.ts +141 -0
  106. package/src/op/activity-contracts.ts +96 -0
  107. package/src/op/audit-op.ts +54 -0
  108. package/src/op/builders.ts +82 -0
  109. package/src/op/slo-rule-tests.test.ts +84 -0
  110. package/src/op/slo-rule-tests.ts +173 -0
  111. package/src/plugin.ts +16 -0
package/README.md CHANGED
@@ -28,6 +28,9 @@ export { api, oncall, fallback, root };
28
28
  | `RuleGroup` | rule file |
29
29
  | `Slo` (composite) | rule file: SLI recording rules, error budget and multiwindow burn-rate alerts |
30
30
  | `GenAiRules` (composite) | rule file: request, error, latency, token and cost rules and opt-in alerts for the otel GenAI preset |
31
+ | `RedAlerts` (composite) | rule file: error-ratio and latency alerts per service over a spanmetrics connector's metrics |
32
+ | `Watchdog` (composite) | rule file and `alertmanager.yml`: an always-firing alert, its heartbeat route and receiver |
33
+ | `AlertRouting` (composite) | `alertmanager.yml`: a route tree by team and severity, inhibit rules between levels, receivers |
31
34
  | `ScrapeConfig`, `PrometheusConfig` | `prometheus.yml`: scrape jobs with relabelling and typed kubernetes, file, http, dns, ec2 and consul discovery (other `*_sd_configs` kinds pass through untyped), plus `global`, `alerting`, `rule_files`, `remote_write`, `remote_read` and `otlp` |
32
35
  | `Route`, `Receiver` (every Alertmanager integration), `InhibitRule`, `TimeInterval`, `AlertmanagerSettings` | `alertmanager.yml` |
33
36
 
@@ -62,10 +65,12 @@ PromQL is parsed with `@prometheus-io/lezer-promql`, the Prometheus project's ow
62
65
  - `src/alertmanager.ts`: the Alertmanager entities
63
66
  - `src/composites/slo.ts`: `Slo` and `sloMetrics`
64
67
  - `src/composites/genai.ts`: `GenAiRules` and `genAiRuleMetrics`
68
+ - `src/composites/red-alerts.ts`: `RedAlerts` and `redAlertRules`
69
+ - `src/composites/watchdog.ts`, `src/composites/alert-routing.ts`: `Watchdog` and `AlertRouting`
65
70
  - `src/build.ts`: entities to config to YAML
66
71
  - `src/promql.ts`, `src/matchers.ts`, `src/duration.ts`: parsing
67
72
  - `src/validate-config.ts`, `src/lint/`: checks
68
73
  - `src/tools.ts`: promtool and amtool
69
74
  - `src/import/`: `chant import` for rule files and `alertmanager.yml` (parser, generator, `Slo` recognition, round-trip tests and fixtures)
70
75
  - `src/rule-eval.ts`: a small rule evaluator the SLO and GenAI tests run over synthetic series
71
- - `examples/`: getting-started, alerting, rules-from-data, slo, k3d-stack
76
+ - `examples/`: getting-started, alerting, rules-from-data, slo, k3d-stack, observe-converge
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The Alertmanager config APIs (#3371).
3
+ *
4
+ * | Kind | Config | Health |
5
+ * |---|---|---|
6
+ * | `alertmanager` | `/api/v2/status` `config.original` | the same answer: `cluster.status`, `versionInfo.version` |
7
+ * | `mimir`, `cortex` | `/api/v1/alerts` (YAML: `alertmanager_config`, `template_files`) | `<prefix>/api/v2/status`, best effort |
8
+ *
9
+ * A plain Alertmanager's `config.original` is not the file it loaded. It is
10
+ * the loaded config marshalled again (`Config.String()` in Alertmanager's
11
+ * `config/config.go`): secrets read `<secret>`, the global defaults are
12
+ * written out, and every receiver carries the settings it inherited from
13
+ * `global:`. ../import/alertmanager-live.ts takes those back out. Mimir and
14
+ * Cortex return the config as the tenant uploaded it.
15
+ *
16
+ * `setConfig` is for the ruler apply target (#3372): `POST /api/v1/alerts`,
17
+ * which Mimir and Cortex serve with `-alertmanager.enable-api`. A plain
18
+ * Alertmanager has no config write API.
19
+ */
20
+ import type { AlertmanagerTarget } from "../config.js";
21
+ import { type PromClient } from "./client.js";
22
+ /** What `/api/v2/status` says about the Alertmanager itself. */
23
+ export interface AlertmanagerHealth {
24
+ /** `ready`, `settling` or `disabled` (no clustering). */
25
+ cluster?: string;
26
+ peers?: number;
27
+ version?: string;
28
+ }
29
+ /** A live Alertmanager config, as text, with where it came from. */
30
+ export interface LiveAlertmanagerConfig {
31
+ /** The config YAML. */
32
+ text: string;
33
+ /** Where it was read. */
34
+ address: string;
35
+ /** True when it is Alertmanager's own re-marshalled form (`/api/v2/status`), with defaults written out and secrets masked. */
36
+ remarshalled: boolean;
37
+ /** Mimir and Cortex: the notification templates uploaded with it, by file name. */
38
+ templateFiles?: Record<string, string>;
39
+ }
40
+ /** A bound Alertmanager: the transport and the target it reaches. */
41
+ export declare class AlertmanagerApi {
42
+ readonly client: PromClient;
43
+ readonly target: AlertmanagerTarget;
44
+ constructor(client: PromClient, target: AlertmanagerTarget);
45
+ /** Where `/api/v2/status` is served. */
46
+ get statusPath(): string;
47
+ /** The status answer, read once per client; undefined on 404. */
48
+ private status;
49
+ /** The loaded config; undefined when there is none (Mimir answers 404 for a tenant with no config). */
50
+ readConfig(): Promise<LiveAlertmanagerConfig | undefined>;
51
+ /** Cluster status and version. Never throws: a failed read is no health, since health is an attribute, not presence. */
52
+ health(): Promise<AlertmanagerHealth | undefined>;
53
+ /** Upload a config (Mimir and Cortex, `POST /api/v1/alerts`, 201). */
54
+ setConfig(config: string, templateFiles?: Record<string, string>): Promise<void>;
55
+ }
56
+ //# sourceMappingURL=alertmanager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alertmanager.d.ts","sourceRoot":"","sources":["../../src/api/alertmanager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAEzD,gEAAgE;AAChE,MAAM,WAAW,kBAAkB;IACjC,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,oEAAoE;AACpE,MAAM,WAAW,sBAAsB;IACrC,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,8HAA8H;IAC9H,YAAY,EAAE,OAAO,CAAC;IACtB,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAMD,qEAAqE;AACrE,qBAAa,eAAe;IAExB,QAAQ,CAAC,MAAM,EAAE,UAAU;IAC3B,QAAQ,CAAC,MAAM,EAAE,kBAAkB;IAFrC,YACW,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,kBAAkB,EACjC;IAEJ,wCAAwC;IACxC,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,iEAAiE;IACjE,OAAO,CAAC,MAAM;IAId,uGAAuG;IACjG,UAAU,IAAI,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC,CA0B9D;IAED,wHAAwH;IAClH,MAAM,IAAI,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAetD;IAED,sEAAsE;IAChE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMzF;CACF"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * The ruler apply target (#3372): `nativeApply`'s `ruler` target, reached
3
+ * through `@intentius/chant-lexicon-prometheus/api/apply` the way core
4
+ * reaches the grafana and sql appliers. Core imports no lexicon; it loads
5
+ * this module by name at call time.
6
+ *
7
+ * One transport with observe and export ({@link bindEndpoints}), so the
8
+ * tenant (`X-Scope-OrgID`) and the Mimir, Cortex and Loki path variants are
9
+ * the profile's: `prometheus.profiles.<env>.ruler`.
10
+ *
11
+ * The ownership boundary is {@link declaredNamespaces}. The plan reads only
12
+ * those namespaces, a group is written only into the namespace
13
+ * {@link namespaceOfGroup} gives it, and an owned-only delete removes a
14
+ * group the ruler has and the project does not declare, one group at a
15
+ * time, only inside those namespaces. A namespace the project does not
16
+ * declare is never listed, read, written or deleted. This is the difference
17
+ * from `mimirtool rules sync`, which deletes every remote namespace missing
18
+ * from the local files unless `--namespaces` is set.
19
+ *
20
+ * Rollback re-applies the previous group set. Before the first write an
21
+ * apply saves, beside the build file, what each changed or pruned group
22
+ * looked like (and which groups it creates); {@link rulerRollback} puts the
23
+ * first back and deletes the second.
24
+ */
25
+ import { type AppliedAction, type ApplyResult, type NotAttemptedReason } from "@intentius/chant/apply";
26
+ import { type BindOptions } from "./bind.js";
27
+ import type { RawRuleGroup } from "./ruler.js";
28
+ type Json = Record<string, unknown>;
29
+ export interface RulerApplyArgs {
30
+ /** The build's primary file: the rule file (`groups:`), or an `alertmanager.yml` when no rules are declared. */
31
+ buildPath: string;
32
+ /** The chant environment whose `prometheus.profiles.<env>` names the ruler. */
33
+ environment?: string;
34
+ /** Delete groups the ruler has in a declared namespace and the project does not declare. */
35
+ prune?: boolean;
36
+ }
37
+ export interface RulerApplyDeps extends BindOptions {
38
+ }
39
+ export interface RulerPlanEntry {
40
+ kind: "RuleGroup" | "AlertmanagerConfig";
41
+ /** `<namespace>/<group>`, or the Alertmanager tenant. */
42
+ name: string;
43
+ namespace?: string;
44
+ group?: string;
45
+ action: "create" | "update" | "unchanged" | "delete";
46
+ }
47
+ export interface RulerOutcome {
48
+ applied: Array<{
49
+ kind: string;
50
+ name: string;
51
+ action: AppliedAction;
52
+ }>;
53
+ pruned: Array<{
54
+ kind: string;
55
+ name: string;
56
+ deleted: boolean;
57
+ }>;
58
+ notAttempted: Array<{
59
+ kind: string;
60
+ name: string;
61
+ reason: NotAttemptedReason;
62
+ detail?: string;
63
+ }>;
64
+ }
65
+ /** What a rollback needs: the previous form of what an apply wrote, and what it created. */
66
+ export interface RulerSnapshot {
67
+ environment: string;
68
+ /** The previous form of every group the apply replaced or deleted. */
69
+ restore: Array<{
70
+ namespace: string;
71
+ group: RawRuleGroup;
72
+ }>;
73
+ /** Groups the apply created. */
74
+ remove: Array<{
75
+ namespace: string;
76
+ name: string;
77
+ }>;
78
+ /** The Alertmanager config before an upload, when there was one. */
79
+ alertmanager?: {
80
+ text: string;
81
+ templateFiles?: Record<string, string>;
82
+ };
83
+ }
84
+ interface Built {
85
+ groups: Array<Json & {
86
+ name: string;
87
+ }>;
88
+ alertmanager?: string;
89
+ }
90
+ /** Read the build: the rule groups, and an Alertmanager config (the primary itself, or `alertmanager.yml` beside it). */
91
+ export declare function readBuilt(buildPath: string): Built;
92
+ /**
93
+ * True when every key the declared value carries is in the live one with an
94
+ * equal value. A ruler adds fields of its own to a group it returns
95
+ * (`source_tenants`, say), and those are not a difference.
96
+ */
97
+ export declare function covers(declared: unknown, live: unknown): boolean;
98
+ /** The snapshot file an apply to `environment` writes beside the build file. */
99
+ export declare function snapshotPath(buildPath: string, environment: string): string;
100
+ /** What an apply would do, per declared namespace. Reads the ruler; writes nothing. */
101
+ export declare function planRuler(args: RulerApplyArgs, deps?: RulerApplyDeps): Promise<RulerPlanEntry[]>;
102
+ /** Apply the build to the environment's ruler (and Alertmanager). */
103
+ export declare function rulerApply(args: RulerApplyArgs, deps?: RulerApplyDeps): Promise<RulerOutcome>;
104
+ export interface RulerRollbackOutcome {
105
+ /** Groups put back to their previous form. */
106
+ restored: number;
107
+ /** Groups the apply created, deleted again. */
108
+ removed: number;
109
+ alertmanagerRestored: boolean;
110
+ /** False when no apply to this environment left a snapshot. */
111
+ hadSnapshot: boolean;
112
+ }
113
+ /**
114
+ * Re-apply the previous group set: put back every group the last apply
115
+ * replaced or deleted, and delete the ones it created. Touches only the
116
+ * groups the snapshot names, so a namespace the project does not declare is
117
+ * as untouched here as in the apply.
118
+ */
119
+ export declare function rulerRollback(args: {
120
+ buildPath: string;
121
+ environment?: string;
122
+ }, deps?: RulerApplyDeps): Promise<RulerRollbackOutcome>;
123
+ /** The outcome as core's apply envelope (#1446). */
124
+ export declare function toApplyResult(outcome: RulerOutcome): ApplyResult;
125
+ export {};
126
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/api/apply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Binding the ruler and the Alertmanager for one environment: the config
3
+ * lookup, the targets, the transports. Shared by observe, live export and
4
+ * the ruler apply target (#3372), so all three reach the same endpoints.
5
+ *
6
+ * The two bind independently. A project that declares only rule groups has
7
+ * no Alertmanager to bind, and that must not make its groups unobservable.
8
+ */
9
+ import type { ChantConfig } from "@intentius/chant/config";
10
+ import type { UnobservedReason } from "@intentius/chant/observation";
11
+ import { type PromHttp } from "./client.js";
12
+ import { AlertmanagerApi } from "./alertmanager.js";
13
+ import { RulerApi } from "./ruler.js";
14
+ import { type UnresolvedTarget } from "../config.js";
15
+ /** What callers may inject: tests pass `http` or point the config at a fake server; the CLI passes nothing. */
16
+ export interface BindOptions {
17
+ environment?: string;
18
+ /** The project's config. Loaded from `cwd` (default: the working directory) when omitted. */
19
+ config?: Pick<ChantConfig, "prometheus">;
20
+ cwd?: string;
21
+ env?: Record<string, string | undefined>;
22
+ /** Transport overrides, per endpoint. The targets are still resolved, so a test exercises the binding too. */
23
+ http?: {
24
+ ruler?: PromHttp;
25
+ alertmanager?: PromHttp;
26
+ };
27
+ }
28
+ /** A target that could not be resolved. */
29
+ export declare class PromBindingError extends Error {
30
+ readonly unresolved: UnresolvedTarget;
31
+ constructor(unresolved: UnresolvedTarget);
32
+ }
33
+ /** Both endpoints, each bound or the reason it is not. */
34
+ export interface BoundEndpoints {
35
+ ruler: RulerApi | UnresolvedTarget;
36
+ alertmanager: AlertmanagerApi | UnresolvedTarget;
37
+ }
38
+ /** Resolve both endpoints for an environment. Never throws for a missing binding; each side says why it is unbound. */
39
+ export declare function bindEndpoints(options?: BindOptions): Promise<BoundEndpoints>;
40
+ /** The ruler alone, for a caller (the apply target) that needs it bound. Throws {@link PromBindingError} when there is none. */
41
+ export declare function bindRuler(options?: BindOptions): Promise<RulerApi>;
42
+ /** The Alertmanager alone. Throws {@link PromBindingError} when there is none. */
43
+ export declare function bindAlertmanager(options?: BindOptions): Promise<AlertmanagerApi>;
44
+ /** What a failed bind or read means, in the observation vocabulary. */
45
+ export declare function classifyPromFailure(err: unknown): {
46
+ reason: UnobservedReason;
47
+ detail: string;
48
+ };
49
+ //# sourceMappingURL=bind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../../src/api/bind.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAsC,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAqE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAErH,+GAA+G;AAC/G,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,8GAA8G;IAC9G,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,QAAQ,CAAC;QAAC,YAAY,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;CACtD;AAED,2CAA2C;AAC3C,qBAAa,gBAAiB,SAAQ,KAAK;IAC7B,QAAQ,CAAC,UAAU,EAAE,gBAAgB;IAAjD,YAAqB,UAAU,EAAE,gBAAgB,EAGhD;CACF;AAED,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,QAAQ,GAAG,gBAAgB,CAAC;IACnC,YAAY,EAAE,eAAe,GAAG,gBAAgB,CAAC;CAClD;AAYD,uHAAuH;AACvH,wBAAsB,aAAa,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,CAStF;AAED,gIAAgI;AAChI,wBAAsB,SAAS,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAI5E;AAED,kFAAkF;AAClF,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAI1F;AAED,uEAAuE;AACvE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAQ9F"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The HTTP transport for the ruler and Alertmanager APIs (#3371): one client
3
+ * for observe and live export here, and for the ruler apply target (#3372),
4
+ * so every path reaches the same endpoint with the same tenant and
5
+ * credentials.
6
+ *
7
+ * `PromHttp` is the seam. The default is `fetch` against a resolved target;
8
+ * a test hands in a function, or points the target at a local fake server
9
+ * (./fake-servers.ts).
10
+ *
11
+ * Bodies are text. The ruler's config API speaks YAML both ways, the
12
+ * Prometheus-compatible APIs answer JSON, and Mimir's Alertmanager config
13
+ * API answers YAML, so the caller decides how to read a body.
14
+ *
15
+ * Status mapping is in one place ({@link statusVerdict}): a 404 is the only
16
+ * answer that means "not there", 401 and 403 mean the credentials were
17
+ * refused, anything else that is not a 2xx is a failed read.
18
+ */
19
+ /** How the client authenticates. */
20
+ export type PromAuth = {
21
+ readonly token: string;
22
+ } | {
23
+ readonly user: string;
24
+ readonly password: string;
25
+ };
26
+ /** A resolved endpoint: where, as which tenant, as whom, and where that came from. */
27
+ export interface PromTarget {
28
+ /** Base URL, without a trailing slash. */
29
+ readonly url: string;
30
+ /** `X-Scope-OrgID`, for a multi-tenant Mimir, Cortex or Loki. */
31
+ readonly tenant?: string;
32
+ readonly auth?: PromAuth;
33
+ /** Where the binding came from: `prometheus.profiles.prod.ruler`, `env PROMETHEUS_RULER_URL`. */
34
+ readonly source: string;
35
+ }
36
+ export interface PromResponse {
37
+ readonly status: number;
38
+ readonly text: string;
39
+ }
40
+ /** One request. `path` starts with `/` and is relative to the target's URL. */
41
+ export type PromHttp = (method: string, path: string, body?: {
42
+ text: string;
43
+ contentType: string;
44
+ }) => Promise<PromResponse>;
45
+ /** The default transport: `fetch` against the target, with the tenant header and credentials on every request. */
46
+ export declare function promHttp(target: PromTarget, fetchImpl?: typeof fetch): PromHttp;
47
+ /** What a status means for a read. */
48
+ export type StatusVerdict = "ok" | "not-found" | "refused" | "failed";
49
+ export declare function statusVerdict(status: number): StatusVerdict;
50
+ /** A non-2xx answer, with enough to classify it and to say where it came from. */
51
+ export declare class PromApiError extends Error {
52
+ readonly status: number;
53
+ readonly method: string;
54
+ readonly path: string;
55
+ readonly verdict: StatusVerdict;
56
+ constructor(status: number, method: string, path: string, body: string);
57
+ }
58
+ /** A bound client: the transport, the target it reaches, and a per-client memo so N reads share one lookup. */
59
+ export declare class PromClient {
60
+ readonly http: PromHttp;
61
+ readonly target: PromTarget;
62
+ private readonly memo;
63
+ constructor(http: PromHttp, target: PromTarget);
64
+ /** GET, returning the body text; undefined on 404; throws {@link PromApiError} on any other non-2xx. */
65
+ getText(path: string): Promise<string | undefined>;
66
+ /** GET a JSON body; undefined on 404. A 2xx body that is not JSON is a failed read. */
67
+ getJson<T = unknown>(path: string): Promise<T | undefined>;
68
+ /** A write. Resolves on a 2xx; throws {@link PromApiError} otherwise, a 404 included. */
69
+ send(method: "POST" | "PUT" | "DELETE", path: string, body?: {
70
+ text: string;
71
+ contentType: string;
72
+ }): Promise<PromResponse>;
73
+ /** Run `fn` once per key for this client's lifetime; concurrent callers share the promise. A failure is not cached. */
74
+ once<T>(key: string, fn: () => Promise<T>): Promise<T>;
75
+ }
76
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,oCAAoC;AACpC,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzG,sFAAsF;AACtF,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IACzB,iGAAiG;IACjG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAQ7H,kHAAkH;AAClH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,GAAE,OAAO,KAAa,GAAG,QAAQ,CAetF;AAED,sCAAsC;AACtC,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAK3D;AAED,kFAAkF;AAClF,qBAAa,YAAa,SAAQ,KAAK;IAGnC,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAJvB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,YACW,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,EAMb;CACF;AAED,+GAA+G;AAC/G,qBAAa,UAAU;IAInB,QAAQ,CAAC,IAAI,EAAE,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,UAAU;IAJ7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuC;IAE5D,YACW,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,UAAU,EACzB;IAEJ,wGAAwG;IAClG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAMvD;IAED,uFAAuF;IACjF,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAQ/D;IAED,yFAAyF;IACnF,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAI/H;IAED,uHAAuH;IACvH,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAQrD;CACF"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * What `/api/v1/rules` says about a group, mapped two ways (#3371): to the
3
+ * group's health for `describeResources`, and, for a plain Prometheus,
4
+ * which has no rule group API, back to the rule-file shape for import.
5
+ *
6
+ * The second mapping is lossy, and says so. `/api/v1/rules` reports rules
7
+ * as Prometheus evaluates them, not as the file wrote them: `query` is the
8
+ * expression as PromQL prints it, durations are seconds, and a group's
9
+ * `interval` is the one it runs on, the global `evaluation_interval` when
10
+ * the group set none. A group's `labels` and `query_offset` are not
11
+ * reported at all.
12
+ */
13
+ import type { RuleGroupConfig } from "../model.js";
14
+ import type { EvaluatedGroup } from "./ruler.js";
15
+ /** What the import of evaluated groups leaves out, said once per export. */
16
+ export declare const EVALUATED_IMPORT_WARNING: string;
17
+ /** A group from `/api/v1/rules` in the rule-file shape. */
18
+ export declare function evaluatedToRuleGroup(group: EvaluatedGroup): RuleGroupConfig;
19
+ /** A group's health, from its rules: `err` when any rule failed its last evaluation, `ok` when every rule passed, else `unknown`. */
20
+ export interface GroupHealth {
21
+ health: "ok" | "err" | "unknown";
22
+ /** The first rule error, as `<rule>: <error>`. */
23
+ lastError?: string;
24
+ /** How many rules failed their last evaluation. */
25
+ failing: number;
26
+ /** Alerting rules by state. */
27
+ firing: number;
28
+ pending: number;
29
+ lastEvaluation?: string;
30
+ /** Seconds the last evaluation took. */
31
+ evaluationTime?: number;
32
+ /** Seconds. */
33
+ interval?: number;
34
+ }
35
+ export declare function groupHealth(group: EvaluatedGroup): GroupHealth;
36
+ //# sourceMappingURL=evaluated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluated.d.ts","sourceRoot":"","sources":["../../src/api/evaluated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAc,eAAe,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAc9C,4EAA4E;AAC5E,eAAO,MAAM,wBAAwB,QAEqH,CAAC;AAE3J,2DAA2D;AAC3D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CA0B3E;AAED,qIAAqI;AACrI,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,IAAI,GAAG,KAAK,GAAG,SAAS,CAAC;IACjC,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,WAAW,CAyB9D"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * A ruler and an Alertmanager in memory, for the observe and export tests
3
+ * (#3371), and for the ruler apply target's (#3372).
4
+ *
5
+ * Each fake is a request handler over a state the test sets up. It answers
6
+ * the routes ./ruler.ts and ./alertmanager.ts use, in the shapes the
7
+ * projects document: the ruler config API's YAML (a mapping of namespace to
8
+ * groups; one group alone at `/{namespace}/{group}`; 404 for a namespace or
9
+ * group that is not there), `/api/v1/rules` JSON, Alertmanager's
10
+ * `/api/v2/status` and Mimir's `/api/v1/alerts`. With `tenant` set it
11
+ * answers 401 to a request without that `X-Scope-OrgID`, as Mimir does
12
+ * ("no org id").
13
+ *
14
+ * {@link serveFake} puts a handler behind a real HTTP server on localhost,
15
+ * so a test drives the default `fetch` transport, headers included.
16
+ * {@link fakeHttp} hands the same handler in as a {@link PromHttp}.
17
+ */
18
+ import type { RulerKind } from "../config.js";
19
+ import type { PromHttp } from "./client.js";
20
+ import type { EvaluatedGroup, RawRuleGroup } from "./ruler.js";
21
+ export interface FakeRequest {
22
+ method: string;
23
+ path: string;
24
+ headers: Record<string, string | undefined>;
25
+ body?: string;
26
+ }
27
+ export interface FakeResponse {
28
+ status: number;
29
+ text: string;
30
+ contentType?: string;
31
+ }
32
+ export type FakeHandler = (req: FakeRequest) => FakeResponse;
33
+ export interface FakeRulerState {
34
+ kind: RulerKind;
35
+ /** Groups by namespace (on a plain Prometheus, by rule file). */
36
+ namespaces: Record<string, RawRuleGroup[]>;
37
+ /** What `/api/v1/rules` reports. Defaults to every group, every rule healthy and inactive. */
38
+ evaluated?: EvaluatedGroup[];
39
+ /** Required `X-Scope-OrgID`. */
40
+ tenant?: string;
41
+ /** Answer every request with this status. */
42
+ status?: number;
43
+ /** Answer `/api/v1/rules` with this status (a ruler whose evaluation API is down). */
44
+ evaluatedStatus?: number;
45
+ prometheusPrefix?: string;
46
+ }
47
+ export interface FakeAlertmanagerState {
48
+ kind: "alertmanager" | "mimir" | "cortex";
49
+ /** `/api/v2/status` `config.original`. */
50
+ original?: string;
51
+ /** Mimir and Cortex: the uploaded config, absent for a tenant with none. */
52
+ uploaded?: {
53
+ alertmanager_config: string;
54
+ template_files?: Record<string, string>;
55
+ };
56
+ cluster?: string;
57
+ version?: string;
58
+ tenant?: string;
59
+ status?: number;
60
+ }
61
+ /** What `/api/v1/rules` reports for a group nobody set an evaluation for: every rule healthy. */
62
+ export declare function evaluatedOf(file: string, group: RawRuleGroup): EvaluatedGroup;
63
+ /** A ruler over `state`. Writes change `state`, so a test can read back what an apply did. */
64
+ export declare function fakeRuler(state: FakeRulerState, calls?: string[]): FakeHandler;
65
+ /** An Alertmanager over `state`: a plain one's `/api/v2/status`, or Mimir's and Cortex's `/api/v1/alerts` and per-tenant status. */
66
+ export declare function fakeAlertmanager(state: FakeAlertmanagerState, calls?: string[]): FakeHandler;
67
+ /** A handler as a {@link PromHttp}, with no headers (a tenant-checking fake then refuses; use {@link serveFake} for those). */
68
+ export declare function fakeHttp(handler: FakeHandler, headers?: Record<string, string>): PromHttp;
69
+ /** A handler behind a real HTTP server on 127.0.0.1, on a free port. `close()` stops it. */
70
+ export declare function serveFake(handler: FakeHandler): Promise<{
71
+ url: string;
72
+ close: () => Promise<void>;
73
+ }>;
74
+ //# sourceMappingURL=fake-servers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-servers.d.ts","sourceRoot":"","sources":["../../src/api/fake-servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,WAAW,KAAK,YAAY,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAC3C,8FAA8F;IAC9F,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,gCAAgC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC1C,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE;QAAE,mBAAmB,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAYD,iGAAiG;AACjG,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,cAAc,CAY7E;AAED,8FAA8F;AAC9F,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,GAAE,MAAM,EAAO,GAAG,WAAW,CA8ClF;AAED,oIAAoI;AACpI,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,EAAE,KAAK,GAAE,MAAM,EAAO,GAAG,WAAW,CA8BhG;AAED,+HAA+H;AAC/H,wBAAgB,QAAQ,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,QAAQ,CAK7F;AAYD,4FAA4F;AAC5F,wBAAsB,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAc1G"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The ruler and Alertmanager API clients (#3371), as
3
+ * `@intentius/chant-lexicon-prometheus/api`.
4
+ *
5
+ * One transport for observe, live export and the ruler apply target
6
+ * (#3372): bind with {@link bindEndpoints} (or {@link bindRuler} /
7
+ * {@link bindAlertmanager}), then read and write through {@link RulerApi}
8
+ * and {@link AlertmanagerApi}. The ownership boundary is
9
+ * {@link declaredNamespaces}: nothing outside it is read for import, and an
10
+ * apply must not write or delete outside it.
11
+ */
12
+ export { PromApiError, PromClient, promHttp, statusVerdict, type PromAuth, type PromHttp, type PromResponse, type PromTarget, type StatusVerdict } from "./client.js";
13
+ export { RulerApi, type EvaluatedGroup, type EvaluatedRule, type RawRuleGroup } from "./ruler.js";
14
+ export { AlertmanagerApi, type AlertmanagerHealth, type LiveAlertmanagerConfig } from "./alertmanager.js";
15
+ export { evaluatedToRuleGroup, groupHealth, type GroupHealth } from "./evaluated.js";
16
+ export { bindAlertmanager, bindEndpoints, bindRuler, classifyPromFailure, PromBindingError, type BindOptions, type BoundEndpoints } from "./bind.js";
17
+ export { ALERTMANAGER_KINDS, RULER_KINDS, declaredNamespaces, namespaceOfGroup, resolveAlertmanagerTarget, resolveRulerTarget, type AlertmanagerKind, type AlertmanagerTarget, type RulerKind, type RulerTarget, } from "../config.js";
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AACnK,OAAO,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACvG,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,QAAQ,CAAC;AAClJ,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,WAAW,GACjB,MAAM,WAAW,CAAC"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * The ruler APIs (#3371): Mimir's, Cortex's and Loki's rule group config
3
+ * API, and the Prometheus-compatible `/api/v1/rules` every one of them (and
4
+ * a plain Prometheus) serves with each group's evaluation state.
5
+ *
6
+ * | Kind | Config API (YAML) | Evaluated rules (JSON) |
7
+ * |---|---|---|
8
+ * | `mimir` | `<prefix>/config/v1/rules[/{namespace}[/{group}]]` | `<prefix>/api/v1/rules` |
9
+ * | `cortex` | `/api/v1/rules[/{namespace}[/{group}]]` | `<prefix>/api/v1/rules` |
10
+ * | `loki` | `/loki/api/v1/rules[/{namespace}[/{group}]]` | `/prometheus/api/v1/rules` |
11
+ * | `prometheus` | none: rule files on disk | `/api/v1/rules` |
12
+ *
13
+ * `<prefix>` is `-http.prometheus-http-prefix`, `/prometheus` unless the
14
+ * profile says otherwise. Mimir does not register Cortex's `/api/v1/rules`
15
+ * config path. Every request carries the target's `X-Scope-OrgID`.
16
+ *
17
+ * The writes (`setGroup`, `deleteGroup`) are here for the ruler apply
18
+ * target (#3372), which reuses this module through
19
+ * `@intentius/chant-lexicon-prometheus/api`. Nothing here deletes a
20
+ * namespace: an apply bounded by the declared namespaces deletes groups one
21
+ * by one, and only inside {@link declaredNamespaces}.
22
+ */
23
+ import type { RuleGroupConfig } from "../model.js";
24
+ import type { RulerTarget } from "../config.js";
25
+ import { type PromClient } from "./client.js";
26
+ type Json = Record<string, unknown>;
27
+ /** A rule group as the ruler's config API returns it: the rule-file shape, plus whatever the ruler adds (`source_tenants`, say). */
28
+ export type RawRuleGroup = Json & {
29
+ name: string;
30
+ };
31
+ /** One rule as `/api/v1/rules` reports it. */
32
+ export interface EvaluatedRule {
33
+ type: "alerting" | "recording";
34
+ name: string;
35
+ query: string;
36
+ /** Seconds. Alerting rules only. */
37
+ duration?: number;
38
+ /** Seconds. Alerting rules only. */
39
+ keepFiringFor?: number;
40
+ labels?: Record<string, string>;
41
+ annotations?: Record<string, string>;
42
+ health?: "ok" | "err" | "unknown" | string;
43
+ lastError?: string;
44
+ /** `inactive`, `pending` or `firing`. Alerting rules only. */
45
+ state?: string;
46
+ lastEvaluation?: string;
47
+ evaluationTime?: number;
48
+ }
49
+ /** One group as `/api/v1/rules` reports it. `file` is the rule file on a Prometheus, the namespace on a ruler. */
50
+ export interface EvaluatedGroup {
51
+ name: string;
52
+ file: string;
53
+ /** Seconds. */
54
+ interval?: number;
55
+ limit?: number;
56
+ rules: EvaluatedRule[];
57
+ lastEvaluation?: string;
58
+ evaluationTime?: number;
59
+ }
60
+ /** A bound ruler: the transport and the target it reaches. */
61
+ export declare class RulerApi {
62
+ readonly client: PromClient;
63
+ readonly target: RulerTarget;
64
+ constructor(client: PromClient, target: RulerTarget);
65
+ /** The base of the rule group config API, or undefined for a plain Prometheus, which has none. */
66
+ get configPath(): string | undefined;
67
+ /** The Prometheus-compatible rules endpoint, with evaluation state. */
68
+ get evaluatedPath(): string;
69
+ private requireConfigPath;
70
+ private parseNamespaces;
71
+ /** Every namespace the tenant has, with its groups. A 404 (Mimir: "no rule groups found") is none. */
72
+ listNamespaces(): Promise<Record<string, RawRuleGroup[]>>;
73
+ /** One namespace's groups; undefined when the ruler has no such namespace. */
74
+ readNamespace(namespace: string): Promise<RawRuleGroup[] | undefined>;
75
+ /** The path {@link readGroup} reads, for `queried`. */
76
+ groupPath(namespace: string, group: string): string;
77
+ /** One group; undefined when it is not there. */
78
+ readGroup(namespace: string, group: string): Promise<RawRuleGroup | undefined>;
79
+ /** Create or replace one group in `namespace` (202 on Mimir, Cortex and Loki). */
80
+ setGroup(namespace: string, group: RuleGroupConfig | RawRuleGroup): Promise<void>;
81
+ /** Delete one group from `namespace`. */
82
+ deleteGroup(namespace: string, group: string): Promise<void>;
83
+ /** Every group the ruler evaluates, with its health. Read once per client. */
84
+ evaluated(): Promise<EvaluatedGroup[]>;
85
+ }
86
+ export {};
87
+ //# sourceMappingURL=ruler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ruler.d.ts","sourceRoot":"","sources":["../../src/api/ruler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAEzD,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpC,oIAAoI;AACpI,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,kHAAkH;AAClH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAQD,8DAA8D;AAC9D,qBAAa,QAAQ;IAEjB,QAAQ,CAAC,MAAM,EAAE,UAAU;IAC3B,QAAQ,CAAC,MAAM,EAAE,WAAW;IAF9B,YACW,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,WAAW,EAC1B;IAEJ,kGAAkG;IAClG,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAWnC;IAED,uEAAuE;IACvE,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAUvB,sGAAsG;IAChG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,CAI9D;IAED,8EAA8E;IACxE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,GAAG,SAAS,CAAC,CAK1E;IAED,uDAAuD;IACvD,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;IAED,iDAAiD;IAC3C,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAOnF;IAED,kFAAkF;IAC5E,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtF;IAED,yCAAyC;IACnC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE;IAED,8EAA8E;IACxE,SAAS,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAY3C;CACF"}