@homeflare/alchemy 0.33.0 → 0.34.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/grafana/alerting-provenance.d.ts +80 -0
- package/dist/grafana/alerting-provenance.d.ts.map +1 -0
- package/dist/grafana/contact-point-fixtures.d.ts +28 -0
- package/dist/grafana/contact-point-fixtures.d.ts.map +1 -0
- package/dist/grafana/contact-point.d.ts +99 -0
- package/dist/grafana/contact-point.d.ts.map +1 -0
- package/dist/grafana/dashboard-model.d.ts +8 -38
- package/dist/grafana/dashboard-model.d.ts.map +1 -1
- package/dist/grafana/datasource.d.ts +2 -9
- package/dist/grafana/datasource.d.ts.map +1 -1
- package/dist/grafana/index.d.ts +10 -4
- package/dist/grafana/index.d.ts.map +1 -1
- package/dist/grafana/index.js +198 -41
- package/dist/grafana/index.js.map +12 -6
- package/dist/grafana/message-template.d.ts +70 -0
- package/dist/grafana/message-template.d.ts.map +1 -0
- package/dist/grafana/mute-timing.d.ts +112 -0
- package/dist/grafana/mute-timing.d.ts.map +1 -0
- package/dist/grafana/providers.d.ts +1 -1
- package/dist/grafana/providers.d.ts.map +1 -1
- package/dist/grafana/secret-refs.d.ts +19 -0
- package/dist/grafana/secret-refs.d.ts.map +1 -0
- package/dist/grafana/subset-match.d.ts +2 -0
- package/dist/grafana/subset-match.d.ts.map +1 -0
- package/dist/linux/index.d.ts +1 -1
- package/dist/linux/index.d.ts.map +1 -1
- package/dist/linux/index.js +3 -1
- package/dist/linux/index.js.map +1 -1
- package/docs/grafana-alerting.md +145 -0
- package/docs/grafana.md +4 -3
- package/docs/upstream-conformance.md +26 -4
- package/package.json +1 -1
- package/src/grafana/alerting-provenance.ts +109 -0
- package/src/grafana/contact-point-fixtures.ts +25 -0
- package/src/grafana/contact-point-provenance.test.ts +113 -0
- package/src/grafana/contact-point-secrets.test.ts +117 -0
- package/src/grafana/contact-point.test.ts +123 -0
- package/src/grafana/contact-point.ts +179 -0
- package/src/grafana/dashboard-model.ts +8 -57
- package/src/grafana/datasource.ts +5 -27
- package/src/grafana/index.ts +24 -4
- package/src/grafana/message-template.test.ts +212 -0
- package/src/grafana/message-template.ts +114 -0
- package/src/grafana/mute-timing.test.ts +227 -0
- package/src/grafana/mute-timing.ts +160 -0
- package/src/grafana/providers.ts +6 -0
- package/src/grafana/secret-refs.ts +48 -0
- package/src/grafana/subset-match.ts +71 -0
- package/src/linux/index-export.test.ts +25 -0
- package/src/linux/index.ts +15 -1
package/dist/grafana/index.js
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
import { Resource } from "alchemy";
|
|
3
3
|
import * as Provider from "alchemy/Provider";
|
|
4
4
|
import * as grafana from "@distilled.cloud/grafana";
|
|
5
|
-
import * as
|
|
6
|
-
import * as Effect2 from "effect/Effect";
|
|
5
|
+
import * as Effect3 from "effect/Effect";
|
|
7
6
|
|
|
8
7
|
// src/grafana/resource.ts
|
|
9
8
|
import { isResolved } from "alchemy/Diff";
|
|
@@ -57,12 +56,13 @@ var grafanaHandlers = (spec) => {
|
|
|
57
56
|
};
|
|
58
57
|
};
|
|
59
58
|
|
|
60
|
-
// src/grafana/
|
|
61
|
-
|
|
59
|
+
// src/grafana/secret-refs.ts
|
|
60
|
+
import * as Data from "effect/Data";
|
|
61
|
+
import * as Effect2 from "effect/Effect";
|
|
62
62
|
|
|
63
63
|
class GrafanaSecretRefUnsetError extends Data.TaggedError("GrafanaSecretRefUnsetError") {
|
|
64
64
|
}
|
|
65
|
-
var
|
|
65
|
+
var resolveSecretRefs = (refs, describeField) => Effect2.gen(function* () {
|
|
66
66
|
if (refs === undefined)
|
|
67
67
|
return;
|
|
68
68
|
const out = {};
|
|
@@ -70,13 +70,17 @@ var resolveSecureJsonData = (refs) => Effect2.gen(function* () {
|
|
|
70
70
|
const raw = process.env[envVar];
|
|
71
71
|
if (raw === undefined || raw.trim() === "") {
|
|
72
72
|
return yield* Effect2.fail(new GrafanaSecretRefUnsetError({
|
|
73
|
-
message: `${envVar} is unset. Export the value of
|
|
73
|
+
message: `${envVar} is unset. Export the value of ${describeField(field)} there — ` + "never as an Alchemy prop."
|
|
74
74
|
}));
|
|
75
75
|
}
|
|
76
76
|
out[field] = raw.trim();
|
|
77
77
|
}
|
|
78
78
|
return out;
|
|
79
79
|
});
|
|
80
|
+
|
|
81
|
+
// src/grafana/datasource.ts
|
|
82
|
+
var GrafanaDatasource = Resource("Grafana.Datasource");
|
|
83
|
+
var resolveSecureJsonData = (refs) => resolveSecretRefs(refs, (field) => `secureJsonData.${field}`);
|
|
80
84
|
var fields = (props) => ({
|
|
81
85
|
name: props.name,
|
|
82
86
|
type: props.type,
|
|
@@ -103,15 +107,15 @@ var spec = {
|
|
|
103
107
|
url: live.url ?? "",
|
|
104
108
|
version: live.version ?? 0
|
|
105
109
|
}),
|
|
106
|
-
create: (props) =>
|
|
110
|
+
create: (props) => Effect3.flatMap(resolveSecureJsonData(props.secureJsonDataRefs), (secureJsonData) => grafana.addDataSource({
|
|
107
111
|
...fields(props),
|
|
108
112
|
...secureJsonData === undefined ? {} : { secureJsonData },
|
|
109
113
|
uid: props.uid
|
|
110
114
|
})),
|
|
111
115
|
destroy: (props) => grafana.deleteDataSourceByUID({ uid: props.uid }),
|
|
112
|
-
fetchLive: (props) => grafana.getDataSourceByUID({ uid: props.uid }).pipe(
|
|
116
|
+
fetchLive: (props) => grafana.getDataSourceByUID({ uid: props.uid }).pipe(Effect3.catchTag("NotFound", () => Effect3.succeed(undefined))),
|
|
113
117
|
matches: (attributes, props) => (props.name === undefined || attributes.name === props.name) && (props.type === undefined || attributes.type === props.type) && (props.url === undefined || attributes.url === props.url) && (props.access === undefined || attributes.access === props.access) && (props.isDefault === undefined || attributes.isDefault === props.isDefault),
|
|
114
|
-
update: (props, live) =>
|
|
118
|
+
update: (props, live) => Effect3.flatMap(resolveSecureJsonData(props.secureJsonDataRefs), (secureJsonData) => grafana.updateDataSourceByUID({
|
|
115
119
|
...fields(props),
|
|
116
120
|
...secureJsonData === undefined ? {} : { secureJsonData },
|
|
117
121
|
...live.version === undefined ? {} : { version: live.version },
|
|
@@ -119,12 +123,26 @@ var spec = {
|
|
|
119
123
|
}))
|
|
120
124
|
};
|
|
121
125
|
var handlers = grafanaHandlers(spec);
|
|
122
|
-
var GrafanaDatasourceProvider = () => Provider.effect(GrafanaDatasource,
|
|
126
|
+
var GrafanaDatasourceProvider = () => Provider.effect(GrafanaDatasource, Effect3.succeed(GrafanaDatasource.Provider.of(handlers)));
|
|
123
127
|
// src/grafana/dashboard.ts
|
|
124
128
|
import { Resource as Resource2 } from "alchemy";
|
|
125
129
|
import * as Provider2 from "alchemy/Provider";
|
|
126
130
|
import * as grafana2 from "@distilled.cloud/grafana";
|
|
127
|
-
import * as
|
|
131
|
+
import * as Effect5 from "effect/Effect";
|
|
132
|
+
|
|
133
|
+
// src/grafana/subset-match.ts
|
|
134
|
+
var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
135
|
+
var declaredContentMatches = (declared, live) => {
|
|
136
|
+
if (declared == null)
|
|
137
|
+
return true;
|
|
138
|
+
if (Array.isArray(declared)) {
|
|
139
|
+
return Array.isArray(live) && declared.length === live.length && declared.every((item, index) => declaredContentMatches(item, live[index]));
|
|
140
|
+
}
|
|
141
|
+
if (isPlainObject(declared)) {
|
|
142
|
+
return isPlainObject(live) && Object.entries(declared).every(([key, value]) => declaredContentMatches(value, live[key]));
|
|
143
|
+
}
|
|
144
|
+
return declared === live;
|
|
145
|
+
};
|
|
128
146
|
|
|
129
147
|
// src/grafana/dashboard-model.ts
|
|
130
148
|
var VOLATILE_FIELDS = ["id", "version", "iteration"];
|
|
@@ -141,28 +159,16 @@ var normalizeModel = (model, uid) => {
|
|
|
141
159
|
return normalized;
|
|
142
160
|
};
|
|
143
161
|
var modelTitle = (model) => typeof model.title === "string" ? model.title : "";
|
|
144
|
-
var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
145
|
-
var declaredContentMatches = (declared, live) => {
|
|
146
|
-
if (declared == null)
|
|
147
|
-
return true;
|
|
148
|
-
if (Array.isArray(declared)) {
|
|
149
|
-
return Array.isArray(live) && declared.length === live.length && declared.every((item, index) => declaredContentMatches(item, live[index]));
|
|
150
|
-
}
|
|
151
|
-
if (isPlainObject(declared)) {
|
|
152
|
-
return isPlainObject(live) && Object.entries(declared).every(([key, value]) => declaredContentMatches(value, live[key]));
|
|
153
|
-
}
|
|
154
|
-
return declared === live;
|
|
155
|
-
};
|
|
156
162
|
|
|
157
163
|
// src/grafana/provisioned.ts
|
|
158
164
|
import * as Data2 from "effect/Data";
|
|
159
|
-
import * as
|
|
165
|
+
import * as Effect4 from "effect/Effect";
|
|
160
166
|
|
|
161
167
|
class GrafanaProvisionedObjectError extends Data2.TaggedError("GrafanaProvisionedObjectError") {
|
|
162
168
|
}
|
|
163
169
|
var refuseIfProvisioned = (kind, uid, owner) => {
|
|
164
170
|
const ownerClause = owner === undefined || owner === "" ? `(this Grafana instance did not report an owning file)` : `by ${owner}`;
|
|
165
|
-
return
|
|
171
|
+
return Effect4.fail(new GrafanaProvisionedObjectError({
|
|
166
172
|
message: `${kind} '${uid}' is file-provisioned ${ownerClause} and read-only through the classic ` + `write API this family calls. Edit the provisioning file instead — declaring this ` + `object read-only (a declaration matching what is live) is safe and will never reach ` + `this refusal.`
|
|
167
173
|
}));
|
|
168
174
|
};
|
|
@@ -188,15 +194,15 @@ var spec2 = {
|
|
|
188
194
|
dashboard: normalizeModel(props.dashboard, props.uid),
|
|
189
195
|
...props.folderUid === undefined ? {} : { folderUid: props.folderUid }
|
|
190
196
|
}),
|
|
191
|
-
destroy: (props, live) =>
|
|
197
|
+
destroy: (props, live) => Effect5.gen(function* () {
|
|
192
198
|
if (live.meta?.provisioned) {
|
|
193
199
|
return yield* refuseIfProvisioned("Grafana.Dashboard", props.uid, live.meta.provisionedExternalId);
|
|
194
200
|
}
|
|
195
201
|
yield* grafana2.deleteDashboard({ uid: props.uid });
|
|
196
202
|
}),
|
|
197
|
-
fetchLive: (props) => grafana2.getDashboard({ uid: props.uid }).pipe(
|
|
203
|
+
fetchLive: (props) => grafana2.getDashboard({ uid: props.uid }).pipe(Effect5.catchTag("NotFound", () => Effect5.succeed(undefined))),
|
|
198
204
|
matches: (attributes, props) => (props.folderUid === undefined || attributes.folderUid === props.folderUid) && declaredContentMatches(normalizeModel(props.dashboard, props.uid), attributes.dashboard),
|
|
199
|
-
update: (props, live) =>
|
|
205
|
+
update: (props, live) => Effect5.gen(function* () {
|
|
200
206
|
if (live.meta?.provisioned) {
|
|
201
207
|
return yield* refuseIfProvisioned("Grafana.Dashboard", props.uid, live.meta.provisionedExternalId);
|
|
202
208
|
}
|
|
@@ -210,13 +216,13 @@ var spec2 = {
|
|
|
210
216
|
})
|
|
211
217
|
};
|
|
212
218
|
var handlers2 = grafanaHandlers(spec2);
|
|
213
|
-
var GrafanaDashboardProvider = () => Provider2.effect(GrafanaDashboard,
|
|
219
|
+
var GrafanaDashboardProvider = () => Provider2.effect(GrafanaDashboard, Effect5.succeed(GrafanaDashboard.Provider.of(handlers2)));
|
|
214
220
|
// src/grafana/folder.ts
|
|
215
221
|
import { Resource as Resource3 } from "alchemy";
|
|
216
222
|
import * as Provider3 from "alchemy/Provider";
|
|
217
223
|
import * as grafana3 from "@distilled.cloud/grafana";
|
|
218
224
|
import * as Data3 from "effect/Data";
|
|
219
|
-
import * as
|
|
225
|
+
import * as Effect6 from "effect/Effect";
|
|
220
226
|
var GrafanaFolder = Resource3("Grafana.Folder", {
|
|
221
227
|
defaultRemovalPolicy: "retain"
|
|
222
228
|
});
|
|
@@ -239,20 +245,20 @@ var spec3 = {
|
|
|
239
245
|
...props.description === undefined ? {} : { description: props.description },
|
|
240
246
|
...props.parentUid === undefined ? {} : { parentUid: props.parentUid }
|
|
241
247
|
}),
|
|
242
|
-
destroy: (props, live) =>
|
|
248
|
+
destroy: (props, live) => Effect6.gen(function* () {
|
|
243
249
|
if (live.managedBy) {
|
|
244
250
|
return yield* refuseIfProvisioned("Grafana.Folder", props.uid, live.managedBy);
|
|
245
251
|
}
|
|
246
252
|
yield* grafana3.deleteFolder({ folder_uid: props.uid });
|
|
247
253
|
}),
|
|
248
|
-
fetchLive: (props) => grafana3.getFolderByUID({ folder_uid: props.uid }).pipe(
|
|
254
|
+
fetchLive: (props) => grafana3.getFolderByUID({ folder_uid: props.uid }).pipe(Effect6.catchTag("NotFound", () => Effect6.succeed(undefined))),
|
|
249
255
|
matches: (attributes, props) => attributes.title === props.title && (props.parentUid === undefined || attributes.parentUid === props.parentUid),
|
|
250
|
-
update: (props, live) =>
|
|
256
|
+
update: (props, live) => Effect6.gen(function* () {
|
|
251
257
|
if (live.managedBy) {
|
|
252
258
|
return yield* refuseIfProvisioned("Grafana.Folder", props.uid, live.managedBy);
|
|
253
259
|
}
|
|
254
260
|
if (props.parentUid !== undefined && props.parentUid !== (live.parentUid ?? undefined)) {
|
|
255
|
-
return yield*
|
|
261
|
+
return yield* Effect6.fail(new GrafanaFolderReparentError({
|
|
256
262
|
message: `Grafana.Folder '${props.uid}' declares parentUid '${props.parentUid}' but is ` + `live under '${live.parentUid ?? "(root)"}'. PUT /folders/{uid} cannot reparent a ` + `folder — move it by hand in Grafana, then update the declaration to match.`
|
|
257
263
|
}));
|
|
258
264
|
}
|
|
@@ -265,25 +271,172 @@ var spec3 = {
|
|
|
265
271
|
})
|
|
266
272
|
};
|
|
267
273
|
var handlers3 = grafanaHandlers(spec3);
|
|
268
|
-
var GrafanaFolderProvider = () => Provider3.effect(GrafanaFolder,
|
|
274
|
+
var GrafanaFolderProvider = () => Provider3.effect(GrafanaFolder, Effect6.succeed(GrafanaFolder.Provider.of(handlers3)));
|
|
275
|
+
// src/grafana/contact-point.ts
|
|
276
|
+
import { Resource as Resource4 } from "alchemy";
|
|
277
|
+
import * as Provider4 from "alchemy/Provider";
|
|
278
|
+
import * as grafana4 from "@distilled.cloud/grafana";
|
|
279
|
+
import * as Effect8 from "effect/Effect";
|
|
280
|
+
|
|
281
|
+
// src/grafana/alerting-provenance.ts
|
|
282
|
+
import * as Effect7 from "effect/Effect";
|
|
283
|
+
var WRITABLE_PROVENANCES = new Set(["", "api"]);
|
|
284
|
+
var isForeignProvenance = (provenance) => provenance === undefined || !WRITABLE_PROVENANCES.has(provenance);
|
|
285
|
+
var refuseIfForeignProvenance = (kind, id, provenance) => {
|
|
286
|
+
const reason = provenance === undefined ? `did not report a provenance at all — this family cannot tell whether it is safe to own` : `has provenance '${provenance}', not '(none)' or 'api'`;
|
|
287
|
+
return Effect7.fail(new GrafanaProvisionedObjectError({
|
|
288
|
+
message: `${kind} '${id}' ${reason} — something other than this API may own it (file ` + `provisioning, the Prometheus-rules importer, or similar), and writing here could take ` + `over or corrupt an object this family does not actually control. Edit it at its actual ` + `source instead — declaring this object read-only (a declaration matching what is live) ` + `is safe and will never reach this refusal.`
|
|
289
|
+
}));
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// src/grafana/contact-point.ts
|
|
293
|
+
var GrafanaContactPoint = Resource4("Grafana.ContactPoint");
|
|
294
|
+
var nonSecretSettings = (props) => {
|
|
295
|
+
const refs = props.secureSettingsRefs;
|
|
296
|
+
if (refs === undefined)
|
|
297
|
+
return props.settings;
|
|
298
|
+
const out = {};
|
|
299
|
+
for (const [key, value] of Object.entries(props.settings)) {
|
|
300
|
+
if (!(key in refs))
|
|
301
|
+
out[key] = value;
|
|
302
|
+
}
|
|
303
|
+
return out;
|
|
304
|
+
};
|
|
305
|
+
var resolveSettings = (props) => Effect8.map(resolveSecretRefs(props.secureSettingsRefs, (field) => `settings.${field}`), (secrets) => secrets === undefined ? props.settings : { ...props.settings, ...secrets });
|
|
306
|
+
var spec4 = {
|
|
307
|
+
attributes: (live) => ({
|
|
308
|
+
disableResolveMessage: live.disableResolveMessage ?? false,
|
|
309
|
+
name: live.name ?? "",
|
|
310
|
+
provenance: live.provenance,
|
|
311
|
+
settings: live.settings ?? {},
|
|
312
|
+
type: live.type,
|
|
313
|
+
uid: live.uid ?? ""
|
|
314
|
+
}),
|
|
315
|
+
create: (props) => Effect8.flatMap(resolveSettings(props), (settings) => grafana4.routePostContactpoints({
|
|
316
|
+
name: props.name,
|
|
317
|
+
settings,
|
|
318
|
+
type: props.type,
|
|
319
|
+
uid: props.uid,
|
|
320
|
+
...props.disableResolveMessage === undefined ? {} : { disableResolveMessage: props.disableResolveMessage }
|
|
321
|
+
})),
|
|
322
|
+
destroy: (props, live) => Effect8.gen(function* () {
|
|
323
|
+
if (isForeignProvenance(live.provenance)) {
|
|
324
|
+
return yield* refuseIfForeignProvenance("Grafana.ContactPoint", props.uid, live.provenance);
|
|
325
|
+
}
|
|
326
|
+
yield* grafana4.routeDeleteContactpoints({ UID: props.uid });
|
|
327
|
+
}),
|
|
328
|
+
fetchLive: (props) => grafana4.routeGetContactpoints({}).pipe(Effect8.map((points) => points.find((point) => point.uid === props.uid))),
|
|
329
|
+
matches: (attributes, props) => attributes.name === props.name && attributes.type === props.type && attributes.disableResolveMessage === (props.disableResolveMessage ?? false) && declaredContentMatches(nonSecretSettings(props), attributes.settings),
|
|
330
|
+
update: (props, live) => Effect8.gen(function* () {
|
|
331
|
+
if (isForeignProvenance(live.provenance)) {
|
|
332
|
+
return yield* refuseIfForeignProvenance("Grafana.ContactPoint", props.uid, live.provenance);
|
|
333
|
+
}
|
|
334
|
+
const settings = yield* resolveSettings(props);
|
|
335
|
+
yield* grafana4.routePutContactpoint({
|
|
336
|
+
UID: props.uid,
|
|
337
|
+
name: props.name,
|
|
338
|
+
settings,
|
|
339
|
+
type: props.type,
|
|
340
|
+
uid: props.uid,
|
|
341
|
+
...props.disableResolveMessage === undefined ? {} : { disableResolveMessage: props.disableResolveMessage }
|
|
342
|
+
});
|
|
343
|
+
})
|
|
344
|
+
};
|
|
345
|
+
var handlers4 = grafanaHandlers(spec4);
|
|
346
|
+
var GrafanaContactPointProvider = () => Provider4.effect(GrafanaContactPoint, Effect8.succeed(GrafanaContactPoint.Provider.of(handlers4)));
|
|
347
|
+
// src/grafana/message-template.ts
|
|
348
|
+
import { Resource as Resource5 } from "alchemy";
|
|
349
|
+
import * as Provider5 from "alchemy/Provider";
|
|
350
|
+
import * as grafana5 from "@distilled.cloud/grafana";
|
|
351
|
+
import * as Effect9 from "effect/Effect";
|
|
352
|
+
var GrafanaMessageTemplate = Resource5("Grafana.MessageTemplate");
|
|
353
|
+
var spec5 = {
|
|
354
|
+
attributes: (live) => ({
|
|
355
|
+
name: live.name ?? "",
|
|
356
|
+
provenance: live.provenance,
|
|
357
|
+
template: live.template ?? ""
|
|
358
|
+
}),
|
|
359
|
+
create: (props) => grafana5.routePutTemplate({ name: props.name, template: props.template }),
|
|
360
|
+
destroy: (props, live) => Effect9.gen(function* () {
|
|
361
|
+
if (isForeignProvenance(live.provenance)) {
|
|
362
|
+
return yield* refuseIfForeignProvenance("Grafana.MessageTemplate", props.name, live.provenance);
|
|
363
|
+
}
|
|
364
|
+
yield* grafana5.routeDeleteTemplate({ name: props.name });
|
|
365
|
+
}),
|
|
366
|
+
fetchLive: (props) => grafana5.routeGetTemplate({ name: props.name }).pipe(Effect9.catchTag("NotFound", () => Effect9.succeed(undefined))),
|
|
367
|
+
matches: (attributes, props) => attributes.template === props.template,
|
|
368
|
+
update: (props, live) => Effect9.gen(function* () {
|
|
369
|
+
if (isForeignProvenance(live.provenance)) {
|
|
370
|
+
return yield* refuseIfForeignProvenance("Grafana.MessageTemplate", props.name, live.provenance);
|
|
371
|
+
}
|
|
372
|
+
yield* grafana5.routePutTemplate({
|
|
373
|
+
name: props.name,
|
|
374
|
+
template: props.template,
|
|
375
|
+
...live.version === undefined ? {} : { version: live.version }
|
|
376
|
+
});
|
|
377
|
+
})
|
|
378
|
+
};
|
|
379
|
+
var handlers5 = grafanaHandlers(spec5);
|
|
380
|
+
var GrafanaMessageTemplateProvider = () => Provider5.effect(GrafanaMessageTemplate, Effect9.succeed(GrafanaMessageTemplate.Provider.of(handlers5)));
|
|
381
|
+
// src/grafana/mute-timing.ts
|
|
382
|
+
import { Resource as Resource6 } from "alchemy";
|
|
383
|
+
import * as Provider6 from "alchemy/Provider";
|
|
384
|
+
import * as grafana6 from "@distilled.cloud/grafana";
|
|
385
|
+
import * as Effect10 from "effect/Effect";
|
|
386
|
+
var GrafanaMuteTiming = Resource6("Grafana.MuteTiming");
|
|
387
|
+
var spec6 = {
|
|
388
|
+
attributes: (live) => ({
|
|
389
|
+
name: live.name ?? "",
|
|
390
|
+
provenance: live.provenance,
|
|
391
|
+
timeIntervals: live.time_intervals ?? []
|
|
392
|
+
}),
|
|
393
|
+
create: (props) => grafana6.routePostMuteTiming({
|
|
394
|
+
name: props.name,
|
|
395
|
+
time_intervals: props.timeIntervals
|
|
396
|
+
}),
|
|
397
|
+
destroy: (props, live) => Effect10.gen(function* () {
|
|
398
|
+
if (isForeignProvenance(live.provenance)) {
|
|
399
|
+
return yield* refuseIfForeignProvenance("Grafana.MuteTiming", props.name, live.provenance);
|
|
400
|
+
}
|
|
401
|
+
yield* grafana6.routeDeleteMuteTiming({
|
|
402
|
+
name: props.name,
|
|
403
|
+
...live.version === undefined ? {} : { version: live.version }
|
|
404
|
+
});
|
|
405
|
+
}),
|
|
406
|
+
fetchLive: (props) => grafana6.routeGetMuteTiming({ name: props.name }).pipe(Effect10.map((live) => live), Effect10.catchTag("NotFound", () => Effect10.succeed(undefined))),
|
|
407
|
+
matches: (attributes, props) => declaredContentMatches(props.timeIntervals, attributes.timeIntervals),
|
|
408
|
+
update: (props, live) => Effect10.gen(function* () {
|
|
409
|
+
if (isForeignProvenance(live.provenance)) {
|
|
410
|
+
return yield* refuseIfForeignProvenance("Grafana.MuteTiming", props.name, live.provenance);
|
|
411
|
+
}
|
|
412
|
+
yield* grafana6.routePutMuteTiming({
|
|
413
|
+
name: props.name,
|
|
414
|
+
time_intervals: props.timeIntervals
|
|
415
|
+
});
|
|
416
|
+
})
|
|
417
|
+
};
|
|
418
|
+
var handlers6 = grafanaHandlers(spec6);
|
|
419
|
+
var GrafanaMuteTimingProvider = () => Provider6.effect(GrafanaMuteTiming, Effect10.succeed(GrafanaMuteTiming.Provider.of(handlers6)));
|
|
269
420
|
// src/grafana/credentials.ts
|
|
270
421
|
import { Credentials } from "@distilled.cloud/grafana/Credentials";
|
|
271
422
|
import { ConfigError } from "@distilled.cloud/grafana/Errors";
|
|
272
|
-
import * as
|
|
423
|
+
import * as Effect11 from "effect/Effect";
|
|
273
424
|
import * as Layer from "effect/Layer";
|
|
274
425
|
import * as Redacted from "effect/Redacted";
|
|
275
|
-
var resolve = (target) =>
|
|
426
|
+
var resolve = (target) => Effect11.sync(() => process.env[target.tokenEnv]).pipe(Effect11.flatMap((raw) => raw === undefined || raw.trim() === "" ? Effect11.fail(new ConfigError({
|
|
276
427
|
message: `${target.tokenEnv} is not set. Export the Grafana service-account token there ` + `— never as an Alchemy prop — before running a stack that declares a resource ` + `against ${target.baseUrl}.`
|
|
277
|
-
})) :
|
|
428
|
+
})) : Effect11.succeed({
|
|
278
429
|
apiBaseUrl: target.baseUrl.replace(/\/+$/, ""),
|
|
279
430
|
token: Redacted.make(raw.trim()),
|
|
280
431
|
...target.orgId === undefined ? {} : { orgId: target.orgId }
|
|
281
|
-
})),
|
|
432
|
+
})), Effect11.orDie);
|
|
282
433
|
var grafanaCredentials = (target) => Layer.succeed(Credentials, resolve(target));
|
|
283
434
|
// src/grafana/providers.ts
|
|
284
435
|
import * as Layer2 from "effect/Layer";
|
|
285
|
-
var grafanaProviders = (target) => Layer2.mergeAll(GrafanaDatasourceProvider(), GrafanaFolderProvider(), GrafanaDashboardProvider()).pipe(Layer2.provide(grafanaCredentials(target)));
|
|
436
|
+
var grafanaProviders = (target) => Layer2.mergeAll(GrafanaDatasourceProvider(), GrafanaFolderProvider(), GrafanaDashboardProvider(), GrafanaContactPointProvider(), GrafanaMuteTimingProvider(), GrafanaMessageTemplateProvider()).pipe(Layer2.provide(grafanaCredentials(target)));
|
|
286
437
|
export {
|
|
438
|
+
GrafanaContactPoint,
|
|
439
|
+
GrafanaContactPointProvider,
|
|
287
440
|
GrafanaDashboard,
|
|
288
441
|
GrafanaDashboardProvider,
|
|
289
442
|
GrafanaDatasource,
|
|
@@ -291,11 +444,15 @@ export {
|
|
|
291
444
|
GrafanaFolder,
|
|
292
445
|
GrafanaFolderProvider,
|
|
293
446
|
GrafanaFolderReparentError,
|
|
447
|
+
GrafanaMessageTemplate,
|
|
448
|
+
GrafanaMessageTemplateProvider,
|
|
449
|
+
GrafanaMuteTiming,
|
|
450
|
+
GrafanaMuteTimingProvider,
|
|
294
451
|
GrafanaProvisionedObjectError,
|
|
295
452
|
GrafanaSecretRefUnsetError,
|
|
296
453
|
grafanaCredentials,
|
|
297
454
|
grafanaProviders
|
|
298
455
|
};
|
|
299
456
|
|
|
300
|
-
//# debugId=
|
|
457
|
+
//# debugId=D93AD79265681B5F64756E2164756E21
|
|
301
458
|
//# sourceMappingURL=index.js.map
|