@sanoma-ai/workflows 0.1.0 → 0.2.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 +72 -21
- package/dist/apply-steps.d.ts +6 -0
- package/dist/apply-steps.js +93 -0
- package/dist/apply-steps.js.map +1 -0
- package/dist/apply.d.ts +197 -0
- package/dist/apply.js +470 -0
- package/dist/apply.js.map +1 -0
- package/dist/call.d.ts +4 -0
- package/dist/call.js +19 -4
- package/dist/call.js.map +1 -1
- package/dist/client.d.ts +38 -2
- package/dist/client.js +67 -10
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +3 -3
- package/dist/config.js +33 -16
- package/dist/config.js.map +1 -1
- package/dist/credentials.d.ts +25 -0
- package/dist/credentials.js +73 -5
- package/dist/credentials.js.map +1 -1
- package/dist/datafile.d.ts +11 -2
- package/dist/datafile.js +56 -2
- package/dist/datafile.js.map +1 -1
- package/dist/describe.d.ts +11 -5
- package/dist/describe.js +13 -5
- package/dist/describe.js.map +1 -1
- package/dist/drift.d.ts +64 -12
- package/dist/drift.js +118 -41
- package/dist/drift.js.map +1 -1
- package/dist/expectations.d.ts +2 -2
- package/dist/expectations.js +28 -3
- package/dist/expectations.js.map +1 -1
- package/dist/host.d.ts +56 -0
- package/dist/host.js +45 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/lockfile.d.ts +36 -0
- package/dist/lockfile.js +69 -0
- package/dist/lockfile.js.map +1 -0
- package/dist/op.d.ts +3 -0
- package/dist/op.js.map +1 -1
- package/dist/resource.d.ts +188 -22
- package/dist/resource.js +173 -28
- package/dist/resource.js.map +1 -1
- package/dist/resources.d.ts +18 -3
- package/dist/resources.js +53 -6
- package/dist/resources.js.map +1 -1
- package/dist/run.d.ts +14 -0
- package/dist/run.js +6 -1
- package/dist/run.js.map +1 -1
- package/dist/sandbox.js +5 -1
- package/dist/sandbox.js.map +1 -1
- package/dist/scenario.d.ts +12 -3
- package/dist/scenario.js +33 -8
- package/dist/scenario.js.map +1 -1
- package/dist/secret.d.ts +42 -0
- package/dist/secret.js +58 -0
- package/dist/secret.js.map +1 -0
- package/dist/shared.d.ts +8 -0
- package/dist/shared.js +7 -0
- package/dist/shared.js.map +1 -1
- package/dist/source.d.ts +58 -0
- package/dist/source.js +54 -0
- package/dist/source.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker.d.ts +3 -0
- package/dist/worker.js +13 -4
- package/dist/worker.js.map +1 -1
- package/dist/writer.d.ts +35 -0
- package/dist/writer.js +201 -0
- package/dist/writer.js.map +1 -0
- package/package.json +6 -1
- package/src/apply-steps.ts +110 -0
- package/src/apply.ts +626 -0
- package/src/call.ts +19 -4
- package/src/client.ts +83 -13
- package/src/config.ts +48 -25
- package/src/credentials.ts +90 -5
- package/src/datafile.ts +76 -4
- package/src/describe.ts +36 -16
- package/src/drift.ts +155 -45
- package/src/expectations.ts +30 -4
- package/src/host.ts +96 -0
- package/src/index.ts +24 -1
- package/src/lockfile.ts +95 -0
- package/src/op.ts +3 -0
- package/src/resource.ts +270 -47
- package/src/resources.ts +63 -8
- package/src/run.ts +15 -0
- package/src/sandbox.ts +5 -1
- package/src/scenario.ts +50 -13
- package/src/secret.ts +92 -0
- package/src/shared.ts +10 -0
- package/src/source.ts +82 -0
- package/src/version.ts +1 -1
- package/src/worker.ts +16 -5
- package/src/writer.ts +225 -0
package/dist/apply.js
ADDED
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { defineWorkflow } from "./define.js";
|
|
3
|
+
import { compare, importsOf, observeBy, observed, sourceUrl, } from "./drift.js";
|
|
4
|
+
import { isRunControlError } from "./errors.js";
|
|
5
|
+
import { fieldPathOf, holderOf, valueAt } from "./resource.js";
|
|
6
|
+
import { errorMessage } from "./shared.js";
|
|
7
|
+
import { SOURCE_RESOLVE } from "./source.js";
|
|
8
|
+
export { APPLY_WORKFLOW } from "./shared.js";
|
|
9
|
+
// The built-in `apply` workflow: it observes the declared resources as drift does, plans what
|
|
10
|
+
// would make each match its declaration, asks one approval wherever the policy holds a change,
|
|
11
|
+
// then makes the changes in dependency order, keeping the lockfile's bindings as it goes. It is a
|
|
12
|
+
// workflow like any other, held to the same lint, so every vendor call goes through `ctx`. Only
|
|
13
|
+
// it may call a writable type's change operations (`isChangeOp`).
|
|
14
|
+
/** What a person answers for a bound object the vendor no longer has (`gone`), or a binding no declaration has (`orphan`). */
|
|
15
|
+
export const PLAN_ANSWERS = ["recreate", "forget", "delete"];
|
|
16
|
+
/**
|
|
17
|
+
* The apply workflow's input: `only` the declared ids (`<file>#<export>`) or orphaned lockfile
|
|
18
|
+
* keys to plan, else all; `bind`, a declared id to the vendor's id of the object to bind it to;
|
|
19
|
+
* `answers`, by declared id or orphaned key: `recreate` or `forget` a gone object, `forget` or
|
|
20
|
+
* `delete` an orphaned binding's.
|
|
21
|
+
*/
|
|
22
|
+
export const ApplyInput = z.strictObject({
|
|
23
|
+
only: z.array(z.string()).optional(),
|
|
24
|
+
bind: z.record(z.string(), z.string().min(1)).optional(),
|
|
25
|
+
answers: z.record(z.string(), z.enum(PLAN_ANSWERS)).optional(),
|
|
26
|
+
});
|
|
27
|
+
/** How long apply waits between calls of an `afterCreate` operation with `until`, and how many calls it makes. */
|
|
28
|
+
const AFTER_CREATE_SECONDS = 5;
|
|
29
|
+
const AFTER_CREATE_CALLS = 120;
|
|
30
|
+
/** What a step's resource is called in a problem: its file, and its export. */
|
|
31
|
+
const problemOf = (id, message) => ({
|
|
32
|
+
file: id.slice(0, id.indexOf("#")),
|
|
33
|
+
message: `${id.slice(id.indexOf("#") + 1)}: ${message}`,
|
|
34
|
+
});
|
|
35
|
+
/** Each resource after the ones it names, otherwise in the files' order. */
|
|
36
|
+
function inDependencyOrder(list) {
|
|
37
|
+
const byId = new Map(list.map((r) => [r.id, r]));
|
|
38
|
+
const out = [];
|
|
39
|
+
const seen = new Set();
|
|
40
|
+
const visit = (r) => {
|
|
41
|
+
if (seen.has(r.id))
|
|
42
|
+
return;
|
|
43
|
+
seen.add(r.id);
|
|
44
|
+
for (const target of Object.values(r.refs)) {
|
|
45
|
+
const named = byId.get(target);
|
|
46
|
+
if (named)
|
|
47
|
+
visit(named);
|
|
48
|
+
}
|
|
49
|
+
out.push(r);
|
|
50
|
+
};
|
|
51
|
+
list.forEach(visit);
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* What a change operation is given of a declaration: its fields, where it names a resource the
|
|
56
|
+
* vendor may hold by another field (`by`, as a repository's node id), that resource's binding id
|
|
57
|
+
* when it has one, made in this run or before.
|
|
58
|
+
*/
|
|
59
|
+
function desiredOf(r, types, bindings, hosts) {
|
|
60
|
+
const { fields, host } = types.get(`${r.vendor}.${r.type}`);
|
|
61
|
+
const { references = {} } = fields;
|
|
62
|
+
const out = structuredClone(r.desired);
|
|
63
|
+
for (const [at, target] of Object.entries(r.refs)) {
|
|
64
|
+
const bound = bindings[target]?.id;
|
|
65
|
+
const place = holderOf(out, at);
|
|
66
|
+
if (references[fieldPathOf(at)]?.by?.length && bound !== undefined && place)
|
|
67
|
+
place.holder[place.key] = bound;
|
|
68
|
+
}
|
|
69
|
+
// A host is given its source's clone URL and the commit its ref names now.
|
|
70
|
+
const run = hosts.get(r.id);
|
|
71
|
+
if (host && run) {
|
|
72
|
+
for (const [path, value] of [
|
|
73
|
+
[host.inputs.source, run.source],
|
|
74
|
+
[host.revision, run.revision],
|
|
75
|
+
]) {
|
|
76
|
+
const place = holderOf(out, path);
|
|
77
|
+
if (place)
|
|
78
|
+
place.holder[place.key] = value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
/** Why apply cannot `what` (create, update, delete) an object of a type. */
|
|
84
|
+
const cannotChange = (type, what) => type?.writable
|
|
85
|
+
? `apply cannot ${what} a ${type.vendor}.${type.type}: no driver does`
|
|
86
|
+
: `apply cannot ${what} it: ${type ? `a ${type.vendor}.${type.type}` : "its type"} is read-only`;
|
|
87
|
+
/** The ids in `list` that `known` refuses, as problems of the input's field `what`. */
|
|
88
|
+
const unknown = (what, list, known) => list.filter((id) => !known(id)).map((id) => ({ message: `${what}: ${id} is no declared resource` }));
|
|
89
|
+
/** What the input names that is neither declared nor an orphaned binding. */
|
|
90
|
+
function inputProblems(input, ids, orphans) {
|
|
91
|
+
return [
|
|
92
|
+
...unknown("only", input.only ?? [], (id) => ids.has(id) || orphans.has(id)),
|
|
93
|
+
...unknown("bind", Object.keys(input.bind ?? {}), (id) => ids.has(id)),
|
|
94
|
+
...unknown("answers", Object.keys(input.answers ?? {}), (id) => ids.has(id) || orphans.has(id)),
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* What to do with one declared resource, from what observing it found: a step, a problem, or
|
|
99
|
+
* both, or `ask`: the input to its type's `plan`, whose answer `fromPlan` reads.
|
|
100
|
+
*/
|
|
101
|
+
function decide(r, result, now, input, desired, types, usable) {
|
|
102
|
+
const head = { id: r.id, vendor: r.vendor, type: r.type };
|
|
103
|
+
const key = `${r.vendor}.${r.type}`;
|
|
104
|
+
const may = (name) => usable.has(`${key}.${name}`);
|
|
105
|
+
const cannot = (what) => problemOf(r.id, cannotChange(types.get(key), what));
|
|
106
|
+
const given = input.bind?.[r.id];
|
|
107
|
+
if (given !== undefined) {
|
|
108
|
+
if (!("state" in now))
|
|
109
|
+
return { problem: problemOf(r.id, "error" in now ? now.error : `no ${key} ${given} to bind`) };
|
|
110
|
+
return { step: { ...head, action: "bind", binding: types.get(key).bindingId(now.state), source: "given" } };
|
|
111
|
+
}
|
|
112
|
+
if (result.status === "error")
|
|
113
|
+
return { problem: problemOf(r.id, result.error ?? "could not be read") };
|
|
114
|
+
if (result.status === "absent") {
|
|
115
|
+
if (result.found !== undefined)
|
|
116
|
+
return { step: { ...head, action: "bind", binding: result.found, source: "found" } };
|
|
117
|
+
return may("create") ? { ask: { desired } } : { problem: cannot("create") };
|
|
118
|
+
}
|
|
119
|
+
const binding = result.binding;
|
|
120
|
+
if (result.status === "gone") {
|
|
121
|
+
const answer = input.answers?.[r.id];
|
|
122
|
+
// An object that holds no data is made again, unless answered otherwise; anything else, a person decides.
|
|
123
|
+
if (answer === undefined && types.get(key).stateless && may("create"))
|
|
124
|
+
return { ask: { desired } };
|
|
125
|
+
const step = { ...head, action: "gone", binding };
|
|
126
|
+
if (answer === "recreate" && !may("create"))
|
|
127
|
+
return { step, problem: cannot("create") };
|
|
128
|
+
if (answer === "recreate" || answer === "forget")
|
|
129
|
+
return { step: { ...step, answer } };
|
|
130
|
+
return answer === undefined
|
|
131
|
+
? { step }
|
|
132
|
+
: { step, problem: problemOf(r.id, `a gone object is recreated or forgotten, not ${answer}d`) };
|
|
133
|
+
}
|
|
134
|
+
if (may("plan"))
|
|
135
|
+
return { ask: { id: binding, desired } };
|
|
136
|
+
const step = { ...head, action: "none", binding };
|
|
137
|
+
return result.status === "drifted" ? { step, problem: cannot("update") } : { step };
|
|
138
|
+
}
|
|
139
|
+
/** The step a `plan` answer makes of a declared resource: a create for one unbound or gone, else an update, a replace or none. */
|
|
140
|
+
function fromPlan(r, result, p) {
|
|
141
|
+
const head = { id: r.id, vendor: r.vendor, type: r.type };
|
|
142
|
+
const creating = result.status === "absent" || result.status === "gone";
|
|
143
|
+
if (creating && p.action === "create") {
|
|
144
|
+
return { step: { ...head, action: "create", planned: p.planned ?? {}, unknown: p.unknown } };
|
|
145
|
+
}
|
|
146
|
+
if (!creating && (p.action === "update" || p.action === "replace")) {
|
|
147
|
+
return { step: { ...head, action: p.action, binding: result.binding, fields: result.fields, replace: p.replace } };
|
|
148
|
+
}
|
|
149
|
+
if (!creating && p.action === "none")
|
|
150
|
+
return { step: { ...head, action: "none", binding: result.binding } };
|
|
151
|
+
return { problem: problemOf(r.id, `the vendor plans to ${p.action} it, which apply does not do here`) };
|
|
152
|
+
}
|
|
153
|
+
/** Each orphaned binding the input wants, after the declarations, and the answers that cannot be done. */
|
|
154
|
+
function orphansOf(orphans, input, wanted, usable, types) {
|
|
155
|
+
const steps = [];
|
|
156
|
+
const problems = [];
|
|
157
|
+
for (const { key, type, id } of orphans.filter((o) => wanted(o.key))) {
|
|
158
|
+
const answer = input.answers?.[key];
|
|
159
|
+
const [vendor = "", name = ""] = type.split(".");
|
|
160
|
+
const step = { id: key, vendor, type: name, action: "orphan", key, binding: id };
|
|
161
|
+
const why = answer === "recreate"
|
|
162
|
+
? "an orphaned binding is forgotten or its object deleted, not recreated"
|
|
163
|
+
: answer === "delete" && !usable.has(`${type}.delete`)
|
|
164
|
+
? cannotChange(types.get(type), "delete")
|
|
165
|
+
: undefined;
|
|
166
|
+
if (why)
|
|
167
|
+
problems.push(problemOf(key, why));
|
|
168
|
+
steps.push(answer === undefined || why ? step : { ...step, answer });
|
|
169
|
+
}
|
|
170
|
+
return { steps, problems };
|
|
171
|
+
}
|
|
172
|
+
/** What running a step does: a change operation, a change to the lockfile only, nothing, or nothing as it waits for an answer. */
|
|
173
|
+
function runOf(step) {
|
|
174
|
+
switch (step.action) {
|
|
175
|
+
case "create":
|
|
176
|
+
return "create";
|
|
177
|
+
case "update":
|
|
178
|
+
case "replace":
|
|
179
|
+
return "update";
|
|
180
|
+
case "bind":
|
|
181
|
+
case "none":
|
|
182
|
+
return step.action;
|
|
183
|
+
case "gone":
|
|
184
|
+
return step.answer === "recreate" ? "create" : step.answer === "forget" ? "forget" : "skip";
|
|
185
|
+
case "orphan":
|
|
186
|
+
return step.answer === "delete" ? "delete" : step.answer === "forget" ? "forget" : "skip";
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* The change calls the plan would make, as the policy would see them, with the declarations'
|
|
191
|
+
* fields as planned: a create's `afterCreate` writes too, for an object with no id yet.
|
|
192
|
+
*/
|
|
193
|
+
function writesOf(plan, desired, types, ops) {
|
|
194
|
+
return plan.steps.flatMap((step) => {
|
|
195
|
+
const at = `${step.vendor}.${step.type}`;
|
|
196
|
+
const run = runOf(step);
|
|
197
|
+
if (run === "create") {
|
|
198
|
+
const made = { id: `new:${at}`, export: exportOf(keyOf(step)) };
|
|
199
|
+
const after = (types.get(at)?.afterCreate ?? [])
|
|
200
|
+
.filter((hook) => ops.get(hook.op)?.effect === "write")
|
|
201
|
+
.map((hook) => ({ op: hook.op, input: hook.input(made) }));
|
|
202
|
+
return [{ op: `${at}.create`, input: { desired: desired.get(step.id) } }, ...after];
|
|
203
|
+
}
|
|
204
|
+
if (run === "delete" && "binding" in step)
|
|
205
|
+
return [{ op: `${at}.delete`, input: { id: step.binding } }];
|
|
206
|
+
if (run !== "update" || (step.action !== "update" && step.action !== "replace"))
|
|
207
|
+
return [];
|
|
208
|
+
const expect = { action: step.action, replace: step.replace };
|
|
209
|
+
return [{ op: `${at}.update`, input: { id: step.binding, desired: desired.get(step.id), expect } }];
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/** The lockfile's key a step binds: a declaration's id, or an orphan's key. */
|
|
213
|
+
const keyOf = (step) => (step.action === "orphan" ? step.key : step.id);
|
|
214
|
+
/** The export a lockfile key names: `store` of `resources/sanoma/infra.ts#store`. */
|
|
215
|
+
const exportOf = (key) => key.slice(key.indexOf("#") + 1);
|
|
216
|
+
/** The commit message for a step's change to the lockfile. */
|
|
217
|
+
function messageOf(step, before, after) {
|
|
218
|
+
const key = keyOf(step);
|
|
219
|
+
if (!after)
|
|
220
|
+
return `Apply: unbind ${key} (${before?.type} ${before?.id})`;
|
|
221
|
+
const what = runOf(step) === "create" ? "create" : before ? "rebind" : "bind";
|
|
222
|
+
return `Apply: ${what} ${key} (${after.type} ${after.id})`;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* The apply workflow for a config: it `uses` the `import` of every resource type the connectors
|
|
226
|
+
* declare that has a driver, and the change operations (`plan`, `create`, `update`, `delete`) of
|
|
227
|
+
* each writable one, and `approval`. `resolveConfig` adds it beside drift, with `steps`, the
|
|
228
|
+
* steps that read the data files, ask the policy and write the lockfile.
|
|
229
|
+
*
|
|
230
|
+
* A run reads the data files, the lockfile and its rebinds (`steps.declared`), and observes each
|
|
231
|
+
* declared resource as drift does: one import each, by the binding the input gives, else the
|
|
232
|
+
* lockfile's, else its identity. Then, for each resource the input wants (`only`), each after the
|
|
233
|
+
* ones it names, it plans:
|
|
234
|
+
*
|
|
235
|
+
* - `bind` when the input gives an object (`bind`) or, unbound, its identity finds one;
|
|
236
|
+
* - `create` when unbound and nothing is found, as its type's `plan` says (a gone object of a
|
|
237
|
+
* `stateless` type too, unless answered);
|
|
238
|
+
* - `gone` when its bound object is no longer there: skipped unless `answers` says `recreate`
|
|
239
|
+
* (created again) or `forget` (unbound);
|
|
240
|
+
* - `update`, `replace` or `none`, as its type's `plan` says for its bound object;
|
|
241
|
+
* - `orphan` for a binding no declaration has: skipped unless `answers` says `forget` (unbound) or
|
|
242
|
+
* `delete` (deleted at the vendor, then unbound).
|
|
243
|
+
*
|
|
244
|
+
* What cannot be planned is a problem, and has no step. When the policy would hold any of the
|
|
245
|
+
* change calls the plan makes (`steps.holds`), one approval asks for them all, covering each
|
|
246
|
+
* change operation, with the plan as its details. Then each step runs in order: a change call,
|
|
247
|
+
* and right after one that changes a binding, the lockfile written and committed
|
|
248
|
+
* (`steps.write`), so an object made is never left unbound. An update is given the plan's action
|
|
249
|
+
* and replace (`expect`), and refuses (`plan_changed`) when the vendor now plans otherwise; a
|
|
250
|
+
* reference to a resource made in this run is given its new binding. A failed step is reported
|
|
251
|
+
* and the run goes on; a failure that ends the run (`isRunControlError`) ends it.
|
|
252
|
+
*/
|
|
253
|
+
export function applyWorkflow(types, ops, drivers, steps) {
|
|
254
|
+
const imports = importsOf(types, ops, drivers);
|
|
255
|
+
const changes = [...types.values()]
|
|
256
|
+
.filter((r) => r.writable)
|
|
257
|
+
.flatMap((r) => ["plan", "create", "update", "delete"].map((name) => ops.get(`${r.vendor}.${r.type}.${name}`)))
|
|
258
|
+
.filter((op) => op !== undefined && drivers.has(op.id))
|
|
259
|
+
.toSorted((a, b) => a.id.localeCompare(b.id));
|
|
260
|
+
const usable = new Set(changes.map((op) => op.id));
|
|
261
|
+
const resolve = ops.get(SOURCE_RESOLVE);
|
|
262
|
+
const hooks = [...new Set([...types.values()].flatMap((r) => (r.afterCreate ?? []).map((hook) => hook.op)))]
|
|
263
|
+
.toSorted()
|
|
264
|
+
.flatMap((id) => {
|
|
265
|
+
const op = ops.get(id);
|
|
266
|
+
return op && drivers.has(id) ? [op] : [];
|
|
267
|
+
});
|
|
268
|
+
return defineWorkflow({
|
|
269
|
+
// The literal, held to the one name: the outline finds a workflow by a string, or a const of its own file.
|
|
270
|
+
name: "apply",
|
|
271
|
+
title: "Apply resources",
|
|
272
|
+
trigger: "manual",
|
|
273
|
+
input: ApplyInput,
|
|
274
|
+
uses: [
|
|
275
|
+
...imports,
|
|
276
|
+
...changes,
|
|
277
|
+
...(resolve ? [resolve] : []),
|
|
278
|
+
...hooks,
|
|
279
|
+
"approval",
|
|
280
|
+
...(hooks.length ? ["sleep"] : []),
|
|
281
|
+
],
|
|
282
|
+
run: async (ctx, input) => {
|
|
283
|
+
const { resources, problems: read, bindings: locked, orphans, rebinds } = await steps.declared();
|
|
284
|
+
const wanted = (id) => input.only === undefined || input.only.includes(id);
|
|
285
|
+
const declarations = new Map(resources.map((r) => [r.id, r]));
|
|
286
|
+
const problems = [...read, ...inputProblems(input, declarations, new Set(orphans.map((o) => o.key)))];
|
|
287
|
+
// Observed as drift does, every import first, by the binding given before the lockfile's.
|
|
288
|
+
const found = new Map();
|
|
289
|
+
for (const resource of resources) {
|
|
290
|
+
const by = observeBy(resource, types, imports, input.bind?.[resource.id] ?? resource.binding ?? resource.identity);
|
|
291
|
+
if (!("id" in by))
|
|
292
|
+
found.set(resource.id, by);
|
|
293
|
+
else {
|
|
294
|
+
try {
|
|
295
|
+
found.set(resource.id, observed(await ctx[resource.vendor][resource.type].import({ id: by.id })));
|
|
296
|
+
}
|
|
297
|
+
catch (err) {
|
|
298
|
+
if (isRunControlError(err))
|
|
299
|
+
throw err;
|
|
300
|
+
found.set(resource.id, { error: errorMessage(err) });
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
// A host wanted runs the commit its ref names now, resolved before planning: a merge is a change
|
|
305
|
+
// to it. One bound by the input needs none.
|
|
306
|
+
const revisions = new Map();
|
|
307
|
+
const hosts = new Map();
|
|
308
|
+
for (const { id, vendor, type, desired, refs } of resources.filter((r) => wanted(r.id) && input.bind?.[r.id] === undefined)) {
|
|
309
|
+
const resource = types.get(`${vendor}.${type}`);
|
|
310
|
+
const host = resource?.host;
|
|
311
|
+
const source = host && sourceUrl(desired, refs[host.inputs.source], resource, found);
|
|
312
|
+
const ref = host && valueAt(desired, host.inputs.ref);
|
|
313
|
+
if (host && source !== undefined && typeof ref === "string" && ref) {
|
|
314
|
+
try {
|
|
315
|
+
const { revision } = await ctx.sanoma.source.resolve({ url: source, ref });
|
|
316
|
+
revisions.set(id, { revision });
|
|
317
|
+
hosts.set(id, { source, revision });
|
|
318
|
+
}
|
|
319
|
+
catch (err) {
|
|
320
|
+
if (isRunControlError(err))
|
|
321
|
+
throw err;
|
|
322
|
+
revisions.set(id, { error: errorMessage(err) });
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
else if (host && source === undefined) {
|
|
326
|
+
revisions.set(id, { error: "its source has no clone URL yet: apply the repository it names first" });
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
const drift = new Map(compare(types, resources, found, revisions).map((result) => [result.id, result]));
|
|
330
|
+
const desired = new Map(resources.map((r) => [r.id, desiredOf(r, types, locked, hosts)]));
|
|
331
|
+
const planned = [];
|
|
332
|
+
for (const resource of inDependencyOrder(resources).filter((r) => wanted(r.id))) {
|
|
333
|
+
const result = drift.get(resource.id);
|
|
334
|
+
const unresolved = revisions.get(resource.id);
|
|
335
|
+
// A host whose ref could not be resolved has no commit to run (compare says so only for one it found).
|
|
336
|
+
const next = unresolved && "error" in unresolved && result.status !== "error"
|
|
337
|
+
? { problem: problemOf(resource.id, unresolved.error) }
|
|
338
|
+
: decide(resource, result, found.get(resource.id), input, desired.get(resource.id), types, usable);
|
|
339
|
+
if (next.ask !== undefined) {
|
|
340
|
+
try {
|
|
341
|
+
const answer = fromPlan(resource, result, await ctx[resource.vendor][resource.type].plan(next.ask));
|
|
342
|
+
if (answer.step)
|
|
343
|
+
planned.push(answer.step);
|
|
344
|
+
if (answer.problem)
|
|
345
|
+
problems.push(answer.problem);
|
|
346
|
+
}
|
|
347
|
+
catch (err) {
|
|
348
|
+
if (isRunControlError(err))
|
|
349
|
+
throw err;
|
|
350
|
+
problems.push(problemOf(resource.id, `could not be planned: ${errorMessage(err)}`));
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
if (next.step)
|
|
354
|
+
planned.push(next.step);
|
|
355
|
+
if (next.problem)
|
|
356
|
+
problems.push(next.problem);
|
|
357
|
+
}
|
|
358
|
+
const orphaned = orphansOf(orphans, input, wanted, usable, types);
|
|
359
|
+
const plan = {
|
|
360
|
+
problems: [...problems, ...orphaned.problems],
|
|
361
|
+
rebinds,
|
|
362
|
+
steps: [...planned, ...orphaned.steps],
|
|
363
|
+
};
|
|
364
|
+
const writes = writesOf(plan, desired, types, ops);
|
|
365
|
+
const approver = writes.length ? await steps.holds(writes) : undefined;
|
|
366
|
+
if (approver !== undefined) {
|
|
367
|
+
const covers = [...new Set(writes.map((w) => w.op))].map((id) => ops.get(id));
|
|
368
|
+
await ctx.approval("Apply resource changes", { approver, covers, details: JSON.stringify(plan, null, 2) });
|
|
369
|
+
}
|
|
370
|
+
const bindings = { ...locked };
|
|
371
|
+
const results = [];
|
|
372
|
+
let written = false;
|
|
373
|
+
let revision;
|
|
374
|
+
for (const step of plan.steps) {
|
|
375
|
+
const todo = runOf(step);
|
|
376
|
+
const key = keyOf(step);
|
|
377
|
+
const type = `${step.vendor}.${step.type}`;
|
|
378
|
+
const before = bindings[key];
|
|
379
|
+
const binding = "binding" in step ? step.binding : "";
|
|
380
|
+
const declared = declarations.get(step.id);
|
|
381
|
+
const spec = types.get(type);
|
|
382
|
+
let state;
|
|
383
|
+
try {
|
|
384
|
+
if (todo === "create") {
|
|
385
|
+
const made = await ctx[step.vendor][step.type].create({
|
|
386
|
+
desired: desiredOf(declared, types, bindings, hosts),
|
|
387
|
+
});
|
|
388
|
+
bindings[key] = { type, id: made.id };
|
|
389
|
+
state = made.state;
|
|
390
|
+
}
|
|
391
|
+
else if (todo === "update" && (step.action === "update" || step.action === "replace")) {
|
|
392
|
+
const expect = { action: step.action, replace: step.replace };
|
|
393
|
+
const changed = await ctx[step.vendor][step.type].update({
|
|
394
|
+
id: binding,
|
|
395
|
+
desired: desiredOf(declared, types, bindings, hosts),
|
|
396
|
+
expect,
|
|
397
|
+
});
|
|
398
|
+
bindings[key] = { type, id: changed.id };
|
|
399
|
+
state = changed.state;
|
|
400
|
+
}
|
|
401
|
+
else if (todo === "delete") {
|
|
402
|
+
await ctx[step.vendor][step.type].delete({ id: binding });
|
|
403
|
+
delete bindings[key];
|
|
404
|
+
}
|
|
405
|
+
else if (todo === "bind")
|
|
406
|
+
bindings[key] = { type, id: binding };
|
|
407
|
+
else if (todo === "forget")
|
|
408
|
+
delete bindings[key];
|
|
409
|
+
const after = bindings[key];
|
|
410
|
+
if (after?.id !== before?.id) {
|
|
411
|
+
const wrote = await steps.write(key, after, messageOf(step, before, after));
|
|
412
|
+
written ||= wrote.written;
|
|
413
|
+
revision = wrote.revision ?? revision;
|
|
414
|
+
}
|
|
415
|
+
// Bound first, so an object made is kept whatever its `afterCreate` calls do: each by its
|
|
416
|
+
// id, again every few seconds until its output passes `until`; one that never does fails
|
|
417
|
+
// the step, and the rest are not called.
|
|
418
|
+
let stuck;
|
|
419
|
+
for (const hook of todo === "create" ? (spec?.afterCreate ?? []) : []) {
|
|
420
|
+
if (stuck === undefined) {
|
|
421
|
+
const [vendor = "", group = "", name = ""] = hook.op.split(".");
|
|
422
|
+
const given = hook.input({ id: after.id, export: exportOf(key) });
|
|
423
|
+
// With `until`, a failure is one more call that did not pass (a new object's vendor may
|
|
424
|
+
// not know it yet); without, it fails the step.
|
|
425
|
+
let output;
|
|
426
|
+
for (let call = 0; call < AFTER_CREATE_CALLS && (call === 0 || (hook.until && !hook.until(output))); call++) {
|
|
427
|
+
if (call > 0)
|
|
428
|
+
await ctx.sleep({ seconds: AFTER_CREATE_SECONDS });
|
|
429
|
+
try {
|
|
430
|
+
output = await ctx[vendor][group][name](given);
|
|
431
|
+
}
|
|
432
|
+
catch (err) {
|
|
433
|
+
if (isRunControlError(err) || !hook.until)
|
|
434
|
+
throw err;
|
|
435
|
+
output = undefined;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (hook.until && !hook.until(output)) {
|
|
439
|
+
stuck = `${hook.op} did not pass in ${(AFTER_CREATE_CALLS * AFTER_CREATE_SECONDS) / 60} minutes`;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
results.push({
|
|
444
|
+
id: step.id,
|
|
445
|
+
action: step.action,
|
|
446
|
+
status: stuck !== undefined ? "failed" : todo === "skip" ? "skipped" : "done",
|
|
447
|
+
...(after && { binding: after.id }),
|
|
448
|
+
...(spec?.host && state && { host: spec.host.outputs(state) }),
|
|
449
|
+
...(stuck !== undefined && { error: stuck }),
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
catch (err) {
|
|
453
|
+
if (isRunControlError(err))
|
|
454
|
+
throw err;
|
|
455
|
+
const left = bindings[key];
|
|
456
|
+
results.push({
|
|
457
|
+
id: step.id,
|
|
458
|
+
action: step.action,
|
|
459
|
+
status: "failed",
|
|
460
|
+
...(left && { binding: left.id }),
|
|
461
|
+
error: errorMessage(err),
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
const lockfile = { written, ...(revision !== undefined && { revision }), bindings };
|
|
466
|
+
return { plan, results, lockfile };
|
|
467
|
+
},
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
//# sourceMappingURL=apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../src/apply.ts"],"names":[],"mappings":"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"}
|
package/dist/call.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type WorkflowDefinition } from "./define.ts";
|
|
2
|
+
import { type Op } from "./op.ts";
|
|
3
|
+
import { type RecordedDecision } from "./policy.ts";
|
|
2
4
|
import type { Run, WorkerState } from "./run.ts";
|
|
3
5
|
/**
|
|
4
6
|
* True for a failure that is not the run's outcome, so the ledger does not record it: DBOS
|
|
@@ -31,3 +33,5 @@ export interface Placed {
|
|
|
31
33
|
* queued behind it, would never start.
|
|
32
34
|
*/
|
|
33
35
|
export declare function buildCtx(wf: WorkflowDefinition<any, any>, run: Run): any;
|
|
36
|
+
/** Asks the policy about one call, and checks its answer. Runs inside a step, so it must have no side effects of its own. */
|
|
37
|
+
export declare function decide(run: Run, op: Op, input: unknown): Promise<RecordedDecision>;
|
package/dist/call.js
CHANGED
|
@@ -8,7 +8,8 @@ import { shown } from "./log.js";
|
|
|
8
8
|
import { isOp } from "./op.js";
|
|
9
9
|
import { callAt, callName } from "./outline.js";
|
|
10
10
|
import { DecisionSchema, policyOpOf } from "./policy.js";
|
|
11
|
-
import {
|
|
11
|
+
import { isChangeOp } from "./resource.js";
|
|
12
|
+
import { APPLY_WORKFLOW, approverLabel, errorMessage, fitsOp } from "./shared.js";
|
|
12
13
|
/** DBOS took the run from this execution: it cancelled the run, or another process took it over. */
|
|
13
14
|
const takenByDbos = (err) => causes(err).some((e) => e instanceof DBOSErrors.DBOSWorkflowCancelledError || e instanceof DBOSWorkflowConflictError);
|
|
14
15
|
/**
|
|
@@ -212,8 +213,8 @@ function targetOf(op, input) {
|
|
|
212
213
|
}
|
|
213
214
|
return { target };
|
|
214
215
|
}
|
|
215
|
-
/** Asks the policy. Runs inside a step, so it must have no side effects of its own. */
|
|
216
|
-
async function decide(run, op, input) {
|
|
216
|
+
/** Asks the policy about one call, and checks its answer. Runs inside a step, so it must have no side effects of its own. */
|
|
217
|
+
export async function decide(run, op, input) {
|
|
217
218
|
const call = {
|
|
218
219
|
op: policyOpOf(op),
|
|
219
220
|
effect: op.effect,
|
|
@@ -247,6 +248,13 @@ async function callOp(run, id, input, place) {
|
|
|
247
248
|
? `No connector or driver for ${id} in this worker`
|
|
248
249
|
: `No connector or fake for ${id} in this worker: no fake its connectors attach implements it`);
|
|
249
250
|
}
|
|
251
|
+
// Only apply changes a declared resource; `resolveConfig` refuses any other workflow that uses such an operation.
|
|
252
|
+
if (isChangeOp(op, run.state.types) && run.workflow !== APPLY_WORKFLOW) {
|
|
253
|
+
throw new SanomaError("invalid_input", `${op.id} changes a declared resource, which only ${APPLY_WORKFLOW} does`, {
|
|
254
|
+
op: op.id,
|
|
255
|
+
workflow: run.workflow,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
250
258
|
const parsed = parseOrThrow(op.input, input, `The input to ${op.id} does not match its schema`, { op: op.id });
|
|
251
259
|
// The call's identity (its ledger seq and id, and the driver's idempotency key) is taken
|
|
252
260
|
// before the first await, so it depends only on the order the workflow made its calls. A
|
|
@@ -293,7 +301,14 @@ async function callOp(run, id, input, place) {
|
|
|
293
301
|
result = await DBOS.runStep(async () => {
|
|
294
302
|
const at = Date.now();
|
|
295
303
|
attempt = DBOS.stepStatus?.currentAttempt ?? 1;
|
|
296
|
-
const
|
|
304
|
+
const secrets = run.sandbox === undefined ? run.state.secrets : run.fakeSecrets;
|
|
305
|
+
const context = {
|
|
306
|
+
idempotencyKey: `${run.id}:${seq}`,
|
|
307
|
+
runId: run.id,
|
|
308
|
+
opId: op.id,
|
|
309
|
+
attempt,
|
|
310
|
+
secrets,
|
|
311
|
+
};
|
|
297
312
|
// A live driver's `env` is checked here, inside the step, by the guard `indexDrivers` put
|
|
298
313
|
// on its function: the refusal is the call's failure, recorded and never retried.
|
|
299
314
|
const output = op.output.parse(await fn(parsed, context));
|