@intentius/chant-lexicon-pulumi 0.124.54 → 0.124.55
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 +42 -3
- package/dist/adopt.d.ts +68 -0
- package/dist/adopt.d.ts.map +1 -0
- package/dist/adopt.js +162 -0
- package/dist/capability-plugin.d.ts +3 -0
- package/dist/capability-plugin.d.ts.map +1 -1
- package/dist/capability-plugin.js +8 -1
- package/dist/change-set.d.ts +27 -4
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +15 -5
- package/dist/ci-setup.d.ts +53 -0
- package/dist/ci-setup.d.ts.map +1 -0
- package/dist/ci-setup.js +146 -0
- package/dist/composites/pulumi-adopt-op.d.ts +106 -0
- package/dist/composites/pulumi-adopt-op.d.ts.map +1 -0
- package/dist/composites/pulumi-adopt-op.js +132 -0
- package/dist/engine-events.d.ts +222 -0
- package/dist/engine-events.d.ts.map +1 -0
- package/dist/engine-events.js +280 -0
- package/dist/exit-codes.d.ts +53 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +67 -0
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -2
- package/dist/init-templates.d.ts.map +1 -1
- package/dist/init-templates.js +5 -3
- package/dist/integrity.json +3 -3
- package/dist/lint/post-synth/pul015.d.ts +2 -1
- package/dist/lint/post-synth/pul015.d.ts.map +1 -1
- package/dist/lock-rows.d.ts +32 -0
- package/dist/lock-rows.d.ts.map +1 -0
- package/dist/lock-rows.js +36 -0
- package/dist/manifest.json +1 -1
- package/dist/member-engine.d.ts +27 -2
- package/dist/member-engine.d.ts.map +1 -1
- package/dist/member-engine.js +58 -7
- package/dist/member-outputs.d.ts.map +1 -1
- package/dist/member-outputs.js +4 -4
- package/dist/op/activities/index.d.ts +9 -1
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/index.js +8 -1
- package/dist/op/activities/pulumi-adopt.d.ts +104 -0
- package/dist/op/activities/pulumi-adopt.d.ts.map +1 -0
- package/dist/op/activities/pulumi-adopt.js +216 -0
- package/dist/op/activities/pulumi.d.ts.map +1 -1
- package/dist/op/activities/pulumi.js +2 -1
- package/dist/op/activity-contracts.d.ts +73 -0
- package/dist/op/activity-contracts.d.ts.map +1 -1
- package/dist/op/activity-contracts.js +49 -0
- package/dist/op/builders.d.ts +9 -0
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +20 -0
- package/dist/plan-shape.d.ts +47 -0
- package/dist/plan-shape.d.ts.map +1 -0
- package/dist/plan-shape.js +94 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +25 -4
- package/dist/plunge-timings.d.ts +43 -0
- package/dist/plunge-timings.d.ts.map +1 -0
- package/dist/plunge-timings.js +106 -0
- package/dist/pulumi-up.d.ts +376 -0
- package/dist/pulumi-up.d.ts.map +1 -0
- package/dist/pulumi-up.js +823 -0
- package/dist/release-copy.d.ts +47 -0
- package/dist/release-copy.d.ts.map +1 -0
- package/dist/release-copy.js +131 -0
- package/dist/review-stack.d.ts +92 -0
- package/dist/review-stack.d.ts.map +1 -0
- package/dist/review-stack.js +222 -0
- package/dist/rules/pul015.ts +2 -1
- package/dist/run.d.ts +250 -7
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +432 -26
- package/dist/stack-export-snapshot.d.ts +125 -0
- package/dist/stack-export-snapshot.d.ts.map +1 -0
- package/dist/stack-export-snapshot.js +233 -0
- package/dist/stack-ops.d.ts +175 -0
- package/dist/stack-ops.d.ts.map +1 -0
- package/dist/stack-ops.js +400 -0
- package/dist/stack-references.d.ts +46 -0
- package/dist/stack-references.d.ts.map +1 -0
- package/dist/stack-references.js +88 -0
- package/dist/trace-facts.d.ts +34 -0
- package/dist/trace-facts.d.ts.map +1 -0
- package/dist/trace-facts.js +81 -0
- package/dist/workspace-member.d.ts +13 -2
- package/dist/workspace-member.d.ts.map +1 -1
- package/dist/workspace-member.js +14 -9
- package/package.json +2 -2
- package/src/adopt.ts +202 -0
- package/src/capability-plugin.ts +15 -6
- package/src/change-set.ts +29 -5
- package/src/ci-setup.test.ts +123 -0
- package/src/ci-setup.ts +176 -0
- package/src/composites/pulumi-adopt-op.test.ts +223 -0
- package/src/composites/pulumi-adopt-op.ts +191 -0
- package/src/composites/pulumi-watch-op.test.ts +2 -2
- package/src/engine-events.test.ts +134 -0
- package/src/engine-events.ts +390 -0
- package/src/engine-graph.test.ts +1 -1
- package/src/exit-codes.test.ts +21 -0
- package/src/exit-codes.ts +71 -0
- package/src/index.ts +75 -1
- package/src/init-templates.ts +5 -3
- package/src/lint/post-synth/pul015.ts +2 -1
- package/src/lock-rows.test.ts +60 -0
- package/src/lock-rows.ts +56 -0
- package/src/member-engine.test.ts +112 -0
- package/src/member-engine.ts +73 -6
- package/src/member-outputs.test.ts +2 -2
- package/src/member-outputs.ts +9 -8
- package/src/op/activities/index.ts +19 -1
- package/src/op/activities/pulumi-adopt.ts +334 -0
- package/src/op/activities/pulumi.ts +2 -1
- package/src/op/activity-contracts.ts +75 -0
- package/src/op/builders.ts +37 -0
- package/src/plan-shape.test.ts +91 -0
- package/src/plan-shape.ts +105 -0
- package/src/plugin.test.ts +1 -1
- package/src/plugin.ts +28 -4
- package/src/plunge-timings.test.ts +241 -0
- package/src/plunge-timings.ts +115 -0
- package/src/plunge-up-failed.test.ts +54 -0
- package/src/pr-note.test.ts +87 -0
- package/src/pulumi-up.test.ts +470 -0
- package/src/pulumi-up.ts +1032 -0
- package/src/release-copy.test.ts +74 -0
- package/src/release-copy.ts +142 -0
- package/src/review-stack.test.ts +254 -0
- package/src/review-stack.ts +266 -0
- package/src/run.test.ts +176 -3
- package/src/run.ts +501 -30
- package/src/stack-export-snapshot.test.ts +190 -0
- package/src/stack-export-snapshot.ts +312 -0
- package/src/stack-ops.test.ts +286 -0
- package/src/stack-ops.ts +552 -0
- package/src/stack-references.test.ts +96 -0
- package/src/stack-references.ts +110 -0
- package/src/testdata/pulumi-stream/README.md +16 -0
- package/src/testdata/pulumi-stream/preview-stream.ndjson +42 -0
- package/src/testdata/pulumi-stream/up-failed-plunge.ndjson +5 -0
- package/src/trace-facts.test.ts +38 -0
- package/src/trace-facts.ts +83 -0
- package/src/workspace-member.test.ts +2 -1
- package/src/workspace-member.ts +30 -12
package/dist/member-engine.d.ts
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
1
|
/** What runs a Pulumi member's stack. */
|
|
2
2
|
export type PulumiMemberEngine = "pulumi" | "plunge";
|
|
3
|
-
/**
|
|
4
|
-
export
|
|
3
|
+
/** Where the engine decision came from, first rule that answered. */
|
|
4
|
+
export type PulumiMemberEngineSource = "member-config" | "plywood.yml" | "PULUMI_BACKEND_URL" | "Pulumi.yaml" | "default";
|
|
5
|
+
/** Inputs beyond the member directory. All optional. */
|
|
6
|
+
export interface PulumiMemberEngineOptions {
|
|
7
|
+
/** The job environment; defaults to `process.env`. Only `PULUMI_BACKEND_URL` is read. */
|
|
8
|
+
env?: Record<string, string | undefined>;
|
|
9
|
+
/** Where the search for `plywood.yml` stops (inclusive). Default: the first directory holding `.git`, else the filesystem root. */
|
|
10
|
+
plywoodRoot?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The `engine` and `backend` keys of the nearest `plywood.yml`, looking in
|
|
14
|
+
* `dir` and each parent up to the repository root. plywood passes no
|
|
15
|
+
* detection of its own: the file is read here (chant#4559).
|
|
16
|
+
*/
|
|
17
|
+
export declare function readPlywoodEngine(dir: string, stopAt?: string): {
|
|
18
|
+
file: string;
|
|
19
|
+
engine?: PulumiMemberEngine;
|
|
20
|
+
backend?: string;
|
|
21
|
+
} | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Which engine runs the member, the rule that said so, and where it came from
|
|
24
|
+
* (see `./run.ts`'s module comment). First rule that answers:
|
|
25
|
+
* the member's config, `engine` (then a `plunge+` `backend`) in `plywood.yml`,
|
|
26
|
+
* `PULUMI_BACKEND_URL`, `backend.url` in `Pulumi.yaml`, else pulumi.
|
|
27
|
+
*/
|
|
28
|
+
export declare function pulumiMemberEngine(dir: string, configured?: PulumiMemberEngine, opts?: PulumiMemberEngineOptions): {
|
|
5
29
|
engine: PulumiMemberEngine;
|
|
6
30
|
because: string;
|
|
31
|
+
source: PulumiMemberEngineSource;
|
|
7
32
|
};
|
|
8
33
|
//# sourceMappingURL=member-engine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"member-engine.d.ts","sourceRoot":"","sources":["../src/member-engine.ts"],"names":[],"mappings":"AAWA,yCAAyC;AACzC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErD,
|
|
1
|
+
{"version":3,"file":"member-engine.d.ts","sourceRoot":"","sources":["../src/member-engine.ts"],"names":[],"mappings":"AAWA,yCAAyC;AACzC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErD,qEAAqE;AACrE,MAAM,MAAM,wBAAwB,GAAG,eAAe,GAAG,aAAa,GAAG,oBAAoB,GAAG,aAAa,GAAG,SAAS,CAAC;AAE1H,wDAAwD;AACxD,MAAM,WAAW,yBAAyB;IACxC,yFAAyF;IACzF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,mIAAmI;IACnI,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAuB3I;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE,kBAAkB,EAC/B,IAAI,GAAE,yBAA8B,GACnC;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,wBAAwB,CAAA;CAAE,CA4BnF"}
|
package/dist/member-engine.js
CHANGED
|
@@ -6,24 +6,75 @@
|
|
|
6
6
|
* only a member on plunge has a checked-in `engine-graph.json` read (#4529).
|
|
7
7
|
*/
|
|
8
8
|
import { existsSync, readFileSync } from "node:fs";
|
|
9
|
-
import { join } from "node:path";
|
|
9
|
+
import { dirname, join, resolve } from "node:path";
|
|
10
10
|
import { parseYAML } from "@intentius/chant/yaml";
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const PLUNGE_URL = /^plunge[+:]/;
|
|
12
|
+
const PLYWOOD_FILES = ["plywood.yml", "plywood.yaml"];
|
|
13
|
+
/**
|
|
14
|
+
* The `engine` and `backend` keys of the nearest `plywood.yml`, looking in
|
|
15
|
+
* `dir` and each parent up to the repository root. plywood passes no
|
|
16
|
+
* detection of its own: the file is read here (chant#4559).
|
|
17
|
+
*/
|
|
18
|
+
export function readPlywoodEngine(dir, stopAt) {
|
|
19
|
+
let cur = resolve(dir);
|
|
20
|
+
const stop = stopAt ? resolve(stopAt) : undefined;
|
|
21
|
+
for (let depth = 0; depth < 32; depth++) {
|
|
22
|
+
for (const name of PLYWOOD_FILES) {
|
|
23
|
+
const file = join(cur, name);
|
|
24
|
+
if (!existsSync(file))
|
|
25
|
+
continue;
|
|
26
|
+
try {
|
|
27
|
+
const doc = parseYAML(readFileSync(file, "utf-8"));
|
|
28
|
+
const engine = doc?.engine === "pulumi" || doc?.engine === "plunge" ? doc.engine : undefined;
|
|
29
|
+
const backend = typeof doc?.backend === "string" ? doc.backend : undefined;
|
|
30
|
+
return { file, engine, backend };
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// An unreadable plywood.yml fails plywood's own config check; here it names no engine.
|
|
34
|
+
return { file };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (cur === stop || (!stop && existsSync(join(cur, ".git"))))
|
|
38
|
+
return undefined;
|
|
39
|
+
const parent = dirname(cur);
|
|
40
|
+
if (parent === cur)
|
|
41
|
+
return undefined;
|
|
42
|
+
cur = parent;
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Which engine runs the member, the rule that said so, and where it came from
|
|
48
|
+
* (see `./run.ts`'s module comment). First rule that answers:
|
|
49
|
+
* the member's config, `engine` (then a `plunge+` `backend`) in `plywood.yml`,
|
|
50
|
+
* `PULUMI_BACKEND_URL`, `backend.url` in `Pulumi.yaml`, else pulumi.
|
|
51
|
+
*/
|
|
52
|
+
export function pulumiMemberEngine(dir, configured, opts = {}) {
|
|
13
53
|
if (configured)
|
|
14
|
-
return { engine: configured, because: `the member's config says engine: ${configured}
|
|
54
|
+
return { engine: configured, because: `the member's config says engine: ${configured}`, source: "member-config" };
|
|
55
|
+
const plywood = readPlywoodEngine(dir, opts.plywoodRoot);
|
|
56
|
+
if (plywood?.engine) {
|
|
57
|
+
return { engine: plywood.engine, because: `${plywood.file} says engine: ${plywood.engine}`, source: "plywood.yml" };
|
|
58
|
+
}
|
|
59
|
+
if (plywood?.backend && PLUNGE_URL.test(plywood.backend)) {
|
|
60
|
+
return { engine: "plunge", because: `${plywood.file} names the plunge backend ${plywood.backend}`, source: "plywood.yml" };
|
|
61
|
+
}
|
|
62
|
+
const envUrl = (opts.env ?? process.env).PULUMI_BACKEND_URL;
|
|
63
|
+
if (envUrl && PLUNGE_URL.test(envUrl)) {
|
|
64
|
+
return { engine: "plunge", because: `PULUMI_BACKEND_URL names the plunge backend ${envUrl}`, source: "PULUMI_BACKEND_URL" };
|
|
65
|
+
}
|
|
15
66
|
const file = join(dir, "Pulumi.yaml");
|
|
16
67
|
if (existsSync(file)) {
|
|
17
68
|
try {
|
|
18
69
|
const doc = parseYAML(readFileSync(file, "utf-8"));
|
|
19
70
|
const backend = doc.backend;
|
|
20
71
|
const url = typeof backend?.url === "string" ? backend.url : undefined;
|
|
21
|
-
if (url &&
|
|
22
|
-
return { engine: "plunge", because: `Pulumi.yaml names the plunge backend ${url}
|
|
72
|
+
if (url && PLUNGE_URL.test(url))
|
|
73
|
+
return { engine: "plunge", because: `Pulumi.yaml names the plunge backend ${url}`, source: "Pulumi.yaml" };
|
|
23
74
|
}
|
|
24
75
|
catch {
|
|
25
76
|
// An unreadable Pulumi.yaml fails the member file check; here it just names no backend.
|
|
26
77
|
}
|
|
27
78
|
}
|
|
28
|
-
return { engine: "pulumi", because: "nothing names plunge" };
|
|
79
|
+
return { engine: "pulumi", because: "nothing names plunge", source: "default" };
|
|
29
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"member-outputs.d.ts","sourceRoot":"","sources":["../src/member-outputs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"member-outputs.d.ts","sourceRoot":"","sources":["../src/member-outputs.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAmB,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAC;AAClI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAqE,KAAK,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAItI,sDAAsD;AACtD,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEjD,sGAAsG;AACtG,eAAO,MAAM,0BAA0B,iCAAiC,CAAC;AAEzE,MAAM,WAAW,yBAAyB;IACxC,qHAAqH;IACrH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,oEAAoE;IACpE,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAcD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAGjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,oBAAoB,CAcpJ;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAErF;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,yBAA8B,GAAG,kBAAkB,CAoB9F;AAED,8DAA8D;AAC9D,eAAO,MAAM,uBAAuB,EAAE,kBAAyC,CAAC"}
|
package/dist/member-outputs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { pulumiPlannedStackOutputs, pulumiExportedStackOutputs } from "./stack-outputs.js";
|
|
2
|
-
import { previewPulumiMemberRead, pulumiMemberStackOutputs
|
|
2
|
+
import { memberExportOf, previewPulumiMemberRead, pulumiMemberStackOutputs } from "./run.js";
|
|
3
3
|
import { isSecret } from "./values.js";
|
|
4
4
|
import { PULUMI_EXPORT_FILE } from "./workspace-member.js";
|
|
5
5
|
/** The environment variable that makes the source read applied outputs from the checked-in export. */
|
|
@@ -64,9 +64,9 @@ export function pulumiOutputSource(options = {}) {
|
|
|
64
64
|
kinds: ["pulumi"],
|
|
65
65
|
async applied(_ctx, ref) {
|
|
66
66
|
if (appliedFrom() === "export") {
|
|
67
|
-
const exported =
|
|
67
|
+
const exported = await memberExportOf(ref.dir);
|
|
68
68
|
if (exported === undefined) {
|
|
69
|
-
throw new Error(`member-outputs: Pulumi member "${ref.member}" has no readable ${PULUMI_EXPORT_FILE} in ${ref.dir}, and its outputs are read from the export (${PULUMI_APPLIED_OUTPUTS_ENV}=export)`);
|
|
69
|
+
throw new Error(`member-outputs: Pulumi member "${ref.member}" has no export in the index store and no readable ${PULUMI_EXPORT_FILE} in ${ref.dir}, and its outputs are read from the export (${PULUMI_APPLIED_OUTPUTS_ENV}=export)`);
|
|
70
70
|
}
|
|
71
71
|
return pulumiExportedOutputValues(exported);
|
|
72
72
|
}
|
|
@@ -74,7 +74,7 @@ export function pulumiOutputSource(options = {}) {
|
|
|
74
74
|
},
|
|
75
75
|
async planned(_ctx, ref) {
|
|
76
76
|
const read = await previewPulumiMemberRead({ member: ref.member, dir: ref.dir, ...runners });
|
|
77
|
-
return pulumiMemberPlannedOutputs(ref.member, { ...read, exported:
|
|
77
|
+
return pulumiMemberPlannedOutputs(ref.member, { ...read, exported: await memberExportOf(ref.dir) });
|
|
78
78
|
},
|
|
79
79
|
};
|
|
80
80
|
}
|
|
@@ -12,8 +12,16 @@
|
|
|
12
12
|
* per resource (`plunge drift --resource <urn> --stream` on plunge), as
|
|
13
13
|
* drift counts.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
15
|
+
* - pulumiAdoptCheck, pulumiAdoptExport, pulumiAdoptPreview, pulumiAdopt:
|
|
16
|
+
* `PulumiAdoptOp`'s steps (#4562), the shared bucket check, the stock
|
|
17
|
+
* checkpoint's export, `plunge stack adopt --json` and, after the gate,
|
|
18
|
+
* `plunge stack adopt --json --yes`. See `./pulumi-adopt.ts`.
|
|
19
|
+
*
|
|
20
|
+
* Only `pulumiAdopt` changes anything: it writes plunge's records. See
|
|
21
|
+
* `./pulumi.ts`.
|
|
16
22
|
*/
|
|
17
23
|
export { pulumiPreview, pulumiDrift } from "./pulumi.js";
|
|
24
|
+
export { pulumiAdoptCheck, pulumiAdoptExport, pulumiAdoptPreview, pulumiAdopt } from "./pulumi-adopt.js";
|
|
25
|
+
export type { PulumiAdoptStackArgs, PulumiAdoptCheckArgs, PulumiAdoptCheckResult, PulumiAdoptExportArgs, PulumiAdoptExportResult, PulumiAdoptPreviewArgs, PulumiAdoptPreviewResult, PulumiAdoptArgs, PulumiAdoptResult, } from "./pulumi-adopt.js";
|
|
18
26
|
export type { PulumiMemberArgs, PulumiPreviewArgs, PulumiPreviewResult, PulumiDriftArgs, PulumiDriftResult } from "./pulumi.js";
|
|
19
27
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACtG,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,eAAe,EACf,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -12,6 +12,13 @@
|
|
|
12
12
|
* per resource (`plunge drift --resource <urn> --stream` on plunge), as
|
|
13
13
|
* drift counts.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
15
|
+
* - pulumiAdoptCheck, pulumiAdoptExport, pulumiAdoptPreview, pulumiAdopt:
|
|
16
|
+
* `PulumiAdoptOp`'s steps (#4562), the shared bucket check, the stock
|
|
17
|
+
* checkpoint's export, `plunge stack adopt --json` and, after the gate,
|
|
18
|
+
* `plunge stack adopt --json --yes`. See `./pulumi-adopt.ts`.
|
|
19
|
+
*
|
|
20
|
+
* Only `pulumiAdopt` changes anything: it writes plunge's records. See
|
|
21
|
+
* `./pulumi.ts`.
|
|
16
22
|
*/
|
|
17
23
|
export { pulumiPreview, pulumiDrift } from "./pulumi.js";
|
|
24
|
+
export { pulumiAdoptCheck, pulumiAdoptExport, pulumiAdoptPreview, pulumiAdopt } from "./pulumi-adopt.js";
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { BucketReport, BucketTarget, CheckBucketOptions } from "@intentius/chant/bucket-check";
|
|
2
|
+
import { type PlungeAdoptStatus } from "../../adopt.js";
|
|
3
|
+
import { type PulumiRunner } from "../../run.js";
|
|
4
|
+
/** The fields every adopt activity takes. */
|
|
5
|
+
export interface PulumiAdoptStackArgs {
|
|
6
|
+
/** The member's name. */
|
|
7
|
+
member: string;
|
|
8
|
+
/** The stack's directory, where `Pulumi.yaml` is. Relative paths resolve against `cwd`. */
|
|
9
|
+
dir: string;
|
|
10
|
+
cwd?: string;
|
|
11
|
+
/** The stack to adopt. */
|
|
12
|
+
stack: string;
|
|
13
|
+
}
|
|
14
|
+
export interface PulumiAdoptCheckArgs extends PulumiAdoptStackArgs {
|
|
15
|
+
/** The plunge backend URL (`plunge+s3://...`). Default: `plywood.yml`'s, `PULUMI_BACKEND_URL`, `Pulumi.yaml`'s. */
|
|
16
|
+
backend?: string;
|
|
17
|
+
/** The bucket to check, when the URL does not say enough (azblob), as `@intentius/chant/bucket-check` takes it. */
|
|
18
|
+
bucket?: Record<string, unknown>;
|
|
19
|
+
/** Key prefixes a lifecycle rule must cover. Default: the URL's path. */
|
|
20
|
+
namespaces?: string[];
|
|
21
|
+
/** Settings waived on top of the URL's `allow_insecure` and `PLUNGE_ALLOW_INSECURE`. An unwaivable one stays refused. */
|
|
22
|
+
allowInsecure?: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface PulumiAdoptCheckResult {
|
|
25
|
+
member: string;
|
|
26
|
+
stack: string;
|
|
27
|
+
/** False when there was no bucket to check. */
|
|
28
|
+
checked: boolean;
|
|
29
|
+
/** Why the check did not run. */
|
|
30
|
+
skipped?: string;
|
|
31
|
+
store?: string;
|
|
32
|
+
bucket?: string;
|
|
33
|
+
correct: boolean;
|
|
34
|
+
/** Settings that failed and were waived. */
|
|
35
|
+
waived: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface PulumiAdoptExportArgs extends PulumiAdoptStackArgs {
|
|
38
|
+
/** The plunge backend URL; its stock form is where the export is read. */
|
|
39
|
+
backend?: string;
|
|
40
|
+
/** Where the checkpoint comes from instead: another backend (Pulumi Cloud, `https://api.pulumi.com`), or an export already taken. */
|
|
41
|
+
from?: {
|
|
42
|
+
backend?: string;
|
|
43
|
+
file?: string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export interface PulumiAdoptExportResult {
|
|
47
|
+
member: string;
|
|
48
|
+
stack: string;
|
|
49
|
+
/** The export, a scratch file (mode 600) or `from.file`. */
|
|
50
|
+
file: string;
|
|
51
|
+
sha256: string;
|
|
52
|
+
resources: number;
|
|
53
|
+
pendingOperations: number;
|
|
54
|
+
/** The backend it was read from, or `file`. */
|
|
55
|
+
source: string;
|
|
56
|
+
/** True when plunge adopts this file (`--file`), on the route from another backend or a given file. */
|
|
57
|
+
adoptFromFile: boolean;
|
|
58
|
+
}
|
|
59
|
+
export interface PulumiAdoptPreviewArgs extends PulumiAdoptStackArgs {
|
|
60
|
+
/** `--file`: the export to adopt, from the Export step when `adoptFromFile`. */
|
|
61
|
+
file?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface PulumiAdoptPreviewResult {
|
|
64
|
+
member: string;
|
|
65
|
+
stack: string;
|
|
66
|
+
status: PlungeAdoptStatus;
|
|
67
|
+
/** What the gate binds. */
|
|
68
|
+
planDigest: string;
|
|
69
|
+
checkpointDigest: string | null;
|
|
70
|
+
resources: number;
|
|
71
|
+
/** Resources by fate: marker, record, pending, already-adopted. */
|
|
72
|
+
fates: Record<string, number>;
|
|
73
|
+
/** False when the stack is already adopted from this checkpoint. */
|
|
74
|
+
changed: boolean;
|
|
75
|
+
}
|
|
76
|
+
export interface PulumiAdoptArgs extends PulumiAdoptPreviewArgs {
|
|
77
|
+
/** The approved preview's digest, to report whether the adoption matched it. */
|
|
78
|
+
planDigest?: string;
|
|
79
|
+
}
|
|
80
|
+
export interface PulumiAdoptResult extends PulumiAdoptPreviewResult {
|
|
81
|
+
/** Whether what plunge adopted digests as the approved preview. Absent when no digest was handed in. */
|
|
82
|
+
matchesApproved?: boolean;
|
|
83
|
+
}
|
|
84
|
+
/** Runners and seams, injectable so the tests run no binary and read no bucket. */
|
|
85
|
+
export interface PulumiAdoptDeps {
|
|
86
|
+
run?: PulumiRunner;
|
|
87
|
+
plunge?: PulumiRunner;
|
|
88
|
+
env?: Record<string, string | undefined>;
|
|
89
|
+
tmp?: string;
|
|
90
|
+
checkBucket?: (target: BucketTarget, options: CheckBucketOptions) => Promise<BucketReport>;
|
|
91
|
+
}
|
|
92
|
+
/** The shared bucket check on the stack's backend bucket; throws when a setting fails unwaived. */
|
|
93
|
+
export declare function adoptCheck(a: PulumiAdoptCheckArgs, deps?: PulumiAdoptDeps): Promise<PulumiAdoptCheckResult>;
|
|
94
|
+
/** The stock checkpoint as a scratch file, or the given one. */
|
|
95
|
+
export declare function adoptExport(a: PulumiAdoptExportArgs, deps?: PulumiAdoptDeps): Promise<PulumiAdoptExportResult>;
|
|
96
|
+
/** `plunge stack adopt --json`: the classification, written nowhere. A refusal fails the step. */
|
|
97
|
+
export declare function adoptPreview(a: PulumiAdoptPreviewArgs, deps?: PulumiAdoptDeps): Promise<PulumiAdoptPreviewResult>;
|
|
98
|
+
/** `plunge stack adopt --json --yes`: writes the records. A refusal fails the step; plunge wrote nothing then. */
|
|
99
|
+
export declare function adoptStack(a: PulumiAdoptArgs, deps?: PulumiAdoptDeps): Promise<PulumiAdoptResult>;
|
|
100
|
+
export declare function pulumiAdoptCheck(args: Record<string, unknown>): Promise<PulumiAdoptCheckResult>;
|
|
101
|
+
export declare function pulumiAdoptExport(args: Record<string, unknown>): Promise<PulumiAdoptExportResult>;
|
|
102
|
+
export declare function pulumiAdoptPreview(args: Record<string, unknown>): Promise<PulumiAdoptPreviewResult>;
|
|
103
|
+
export declare function pulumiAdopt(args: Record<string, unknown>): Promise<PulumiAdoptResult>;
|
|
104
|
+
//# sourceMappingURL=pulumi-adopt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pulumi-adopt.d.ts","sourceRoot":"","sources":["../../../src/op/activities/pulumi-adopt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `PulumiAdoptOp`'s activities (#4562): check the bucket, export the stock
|
|
3
|
+
* checkpoint, preview the adoption, adopt. The composite
|
|
4
|
+
* (`../../composites/pulumi-adopt-op.ts`) puts its gate between the preview
|
|
5
|
+
* and the adoption, bound to the preview's `planDigest`.
|
|
6
|
+
*
|
|
7
|
+
* - `pulumiAdoptCheck`: the shared bucket check (#4558, `@intentius/chant/bucket-check`)
|
|
8
|
+
* on the bucket the stack's backend URL names. A failing setting that is
|
|
9
|
+
* not waived (`allow_insecure` on the URL, `PLUNGE_ALLOW_INSECURE`, or the
|
|
10
|
+
* step's `allowInsecure`) refuses the stack by name with its fix, before
|
|
11
|
+
* anything is exported. A `file://` backend has no bucket and is skipped.
|
|
12
|
+
* - `pulumiAdoptExport`: stock `pulumi stack export --stack <s>`, through the
|
|
13
|
+
* read allowlist (#4546), against the stack's stock backend at the same
|
|
14
|
+
* root (the backend URL without `plunge+`) or the step's `from.backend`
|
|
15
|
+
* (Pulumi Cloud, for the `--file` route). The export is kept in a scratch
|
|
16
|
+
* file under the OS temp dir, mode 600, since it holds secret ciphertext:
|
|
17
|
+
* it is the back-out copy, and on the `--file` route the document plunge
|
|
18
|
+
* adopts. `from.file` names an export taken by hand instead, and nothing
|
|
19
|
+
* runs. The result gives the file, its SHA-256 and its counts.
|
|
20
|
+
* - `pulumiAdoptPreview`: `plunge stack adopt --json --stack <s> [--file f]`,
|
|
21
|
+
* which classifies and writes nothing. A refused adoption fails the step,
|
|
22
|
+
* naming each refusal. Its `planDigest` (`../../adopt.ts`'s
|
|
23
|
+
* `pulumiAdoptDigest`) is what the gate binds.
|
|
24
|
+
* - `pulumiAdopt`: `plunge stack adopt --json --yes --stack <s> [--file f]`
|
|
25
|
+
* through `runAdoptPlunge`, the one entry point allowed to write. It
|
|
26
|
+
* reports whether what plunge adopted digests as the approved preview did.
|
|
27
|
+
*
|
|
28
|
+
* None of them calls a cloud API but the bucket check's reads: adoption
|
|
29
|
+
* writes plunge's records only, and the next `plunge up` writes the
|
|
30
|
+
* markers.
|
|
31
|
+
*/
|
|
32
|
+
import { createHash } from "node:crypto";
|
|
33
|
+
import { existsSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
|
34
|
+
import { tmpdir } from "node:os";
|
|
35
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
36
|
+
import { adoptBucketTarget, adoptFates, parsePlungeAdoptView, pulumiAdoptDigest, pulumiStackBackend, stockBackendUrl, } from "../../adopt.js";
|
|
37
|
+
import { pulumiExportResources } from "../../change-set.js";
|
|
38
|
+
import { defaultPlungeRunner, defaultPulumiRunner, plungeAdoptArgs, pulumiRunFailure, runAdoptPlunge, runAllowedPlunge, runAllowedPulumi, } from "../../run.js";
|
|
39
|
+
import { isObject } from "../../values.js";
|
|
40
|
+
function stackDir(a) {
|
|
41
|
+
return isAbsolute(a.dir) ? a.dir : resolve(a.cwd ?? process.cwd(), a.dir);
|
|
42
|
+
}
|
|
43
|
+
function requireStack(a, what) {
|
|
44
|
+
if (typeof a?.dir !== "string" || a.dir === "")
|
|
45
|
+
throw new Error(`${what}: the step needs "dir", the directory holding Pulumi.yaml`);
|
|
46
|
+
if (typeof a.stack !== "string" || a.stack === "" || a.stack.startsWith("-"))
|
|
47
|
+
throw new Error(`${what}: the step needs "stack", the stack to adopt`);
|
|
48
|
+
}
|
|
49
|
+
function refusalText(refusals) {
|
|
50
|
+
return refusals.map((r) => `${r.code}${r.urn ? ` (${r.urn})` : ""}: ${r.reason}`).join("; ");
|
|
51
|
+
}
|
|
52
|
+
/** The shared bucket check on the stack's backend bucket; throws when a setting fails unwaived. */
|
|
53
|
+
export async function adoptCheck(a, deps = {}) {
|
|
54
|
+
requireStack(a, "pulumiAdoptCheck");
|
|
55
|
+
const env = deps.env ?? process.env;
|
|
56
|
+
const dir = stackDir(a);
|
|
57
|
+
const base = { member: a.member, stack: a.stack };
|
|
58
|
+
let target;
|
|
59
|
+
let namespaces;
|
|
60
|
+
let waived;
|
|
61
|
+
if (a.bucket) {
|
|
62
|
+
target = a.bucket;
|
|
63
|
+
namespaces = a.namespaces ?? [];
|
|
64
|
+
waived = [...(env.PLUNGE_ALLOW_INSECURE ?? "").split(",").map((s) => s.trim()).filter(Boolean)];
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
const backend = pulumiStackBackend(dir, { ...(a.backend ? { configured: a.backend } : {}), env });
|
|
68
|
+
if (!backend) {
|
|
69
|
+
throw new Error(`pulumiAdoptCheck: "${a.member}/${a.stack}" names no backend (the step's backend, plywood.yml, PULUMI_BACKEND_URL or Pulumi.yaml), so its bucket cannot be checked before adoption`);
|
|
70
|
+
}
|
|
71
|
+
const found = adoptBucketTarget(backend.url, env);
|
|
72
|
+
if ("skip" in found)
|
|
73
|
+
return { ...base, checked: false, skipped: found.skip, correct: true, waived: [] };
|
|
74
|
+
if ("refuse" in found)
|
|
75
|
+
throw new Error(`pulumiAdoptCheck: refusing to adopt "${a.member}/${a.stack}": ${found.refuse}`);
|
|
76
|
+
target = found.target;
|
|
77
|
+
namespaces = a.namespaces ?? found.namespaces;
|
|
78
|
+
waived = found.waived;
|
|
79
|
+
}
|
|
80
|
+
waived = [...new Set([...waived, ...(a.allowInsecure ?? [])])];
|
|
81
|
+
const check = deps.checkBucket ??
|
|
82
|
+
(async (t, o) => {
|
|
83
|
+
const mod = await import("@intentius/chant/bucket-check");
|
|
84
|
+
return mod.checkBucket(t, o);
|
|
85
|
+
});
|
|
86
|
+
const report = await check(target, { namespaces });
|
|
87
|
+
const failing = report.settings.filter((f) => f.verdict !== "ok");
|
|
88
|
+
const refused = failing.filter((f) => f.unwaivable || !waived.includes(f.setting));
|
|
89
|
+
if (refused.length > 0) {
|
|
90
|
+
const lines = refused.map((f) => `${f.setting} (${f.verdict}): ${f.found}${f.fix ? `; fix: ${f.fix}` : ""}${f.unwaivable ? "; no waiver reaches it" : ""}`);
|
|
91
|
+
throw new Error(`pulumiAdoptCheck: refusing to adopt "${a.member}/${a.stack}": the ${report.store} bucket ${report.bucket} fails the shared check: ${lines.join(" | ")}`);
|
|
92
|
+
}
|
|
93
|
+
return { ...base, checked: true, store: report.store, bucket: report.bucket, correct: report.correct, waived: failing.map((f) => f.setting) };
|
|
94
|
+
}
|
|
95
|
+
/** The stock checkpoint as a scratch file, or the given one. */
|
|
96
|
+
export async function adoptExport(a, deps = {}) {
|
|
97
|
+
requireStack(a, "pulumiAdoptExport");
|
|
98
|
+
const env = deps.env ?? process.env;
|
|
99
|
+
const dir = stackDir(a);
|
|
100
|
+
const base = { member: a.member, stack: a.stack };
|
|
101
|
+
const summarize = (text, file, source, adoptFromFile) => {
|
|
102
|
+
let doc;
|
|
103
|
+
try {
|
|
104
|
+
doc = JSON.parse(text);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
throw new Error(`pulumiAdoptExport: the export of "${a.member}/${a.stack}" from ${source} is not JSON`);
|
|
108
|
+
}
|
|
109
|
+
const deployment = isObject(doc) && isObject(doc.deployment) ? doc.deployment : undefined;
|
|
110
|
+
const pending = deployment && Array.isArray(deployment.pending_operations) ? deployment.pending_operations.length : 0;
|
|
111
|
+
return {
|
|
112
|
+
...base,
|
|
113
|
+
file,
|
|
114
|
+
sha256: createHash("sha256").update(text).digest("hex"),
|
|
115
|
+
resources: pulumiExportResources(doc).length,
|
|
116
|
+
pendingOperations: pending,
|
|
117
|
+
source,
|
|
118
|
+
adoptFromFile,
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
if (a.from?.file) {
|
|
122
|
+
const file = isAbsolute(a.from.file) ? a.from.file : resolve(dir, a.from.file);
|
|
123
|
+
if (!existsSync(file))
|
|
124
|
+
throw new Error(`pulumiAdoptExport: the export ${file} for "${a.member}/${a.stack}" does not exist`);
|
|
125
|
+
return summarize(readFileSync(file, "utf-8"), file, "file", true);
|
|
126
|
+
}
|
|
127
|
+
let source;
|
|
128
|
+
if (a.from?.backend) {
|
|
129
|
+
source = a.from.backend;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
const backend = pulumiStackBackend(dir, { ...(a.backend ? { configured: a.backend } : {}), env });
|
|
133
|
+
source = backend ? stockBackendUrl(backend.url) : undefined;
|
|
134
|
+
}
|
|
135
|
+
const args = ["stack", "export", "--stack", a.stack];
|
|
136
|
+
let stdout;
|
|
137
|
+
try {
|
|
138
|
+
({ stdout } = await runAllowedPulumi(deps.run ?? defaultPulumiRunner, args, dir, source ? { PULUMI_BACKEND_URL: source } : undefined));
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
const f = pulumiRunFailure(err);
|
|
142
|
+
const why = f.missingBinary ? "the pulumi binary was not found on PATH" : (f.stderr?.trim() || f.message).split("\n").slice(-3).join("\n");
|
|
143
|
+
throw new Error(`pulumiAdoptExport: pulumi ${args.join(" ")} for "${a.member}/${a.stack}"${source ? ` against ${source}` : ""} failed: ${why}`);
|
|
144
|
+
}
|
|
145
|
+
const scratch = mkdtempSync(join(deps.tmp ?? tmpdir(), "chant-pulumi-adopt-"));
|
|
146
|
+
const file = join(scratch, `${a.stack.replace(/[^A-Za-z0-9._-]+/g, "_")}.export.json`);
|
|
147
|
+
writeFileSync(file, stdout, { mode: 0o600 });
|
|
148
|
+
return summarize(stdout, file, source ?? "the selected backend", a.from?.backend !== undefined);
|
|
149
|
+
}
|
|
150
|
+
/** The adopt document from a run, its failure's stdout included; throws when there is none. */
|
|
151
|
+
async function adoptView(run, what, command) {
|
|
152
|
+
try {
|
|
153
|
+
const { stdout } = await run();
|
|
154
|
+
const view = parsePlungeAdoptView(stdout);
|
|
155
|
+
if (!view)
|
|
156
|
+
throw new Error(`${what}: ${command} printed no adopt document`);
|
|
157
|
+
return view;
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
const f = pulumiRunFailure(err);
|
|
161
|
+
const view = parsePlungeAdoptView(f.stdout);
|
|
162
|
+
if (view)
|
|
163
|
+
return view;
|
|
164
|
+
if (err instanceof Error && err.message.startsWith(`${what}:`))
|
|
165
|
+
throw err;
|
|
166
|
+
const why = f.missingBinary ? "the plunge binary was not found on PATH" : (f.stderr?.trim() || f.message).split("\n").slice(-3).join("\n");
|
|
167
|
+
throw new Error(`${what}: ${command} failed: ${why}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function summary(a, view) {
|
|
171
|
+
return {
|
|
172
|
+
member: a.member,
|
|
173
|
+
stack: a.stack,
|
|
174
|
+
status: view.status,
|
|
175
|
+
planDigest: pulumiAdoptDigest(view),
|
|
176
|
+
checkpointDigest: view.checkpoint.digest ?? null,
|
|
177
|
+
resources: view.resources.length,
|
|
178
|
+
fates: adoptFates(view),
|
|
179
|
+
changed: view.status !== "already-adopted",
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/** `plunge stack adopt --json`: the classification, written nowhere. A refusal fails the step. */
|
|
183
|
+
export async function adoptPreview(a, deps = {}) {
|
|
184
|
+
requireStack(a, "pulumiAdoptPreview");
|
|
185
|
+
const dir = stackDir(a);
|
|
186
|
+
const args = plungeAdoptArgs({ stack: a.stack, ...(a.file ? { file: a.file } : {}) });
|
|
187
|
+
const view = await adoptView(() => runAllowedPlunge(deps.plunge ?? defaultPlungeRunner, args, dir), "pulumiAdoptPreview", `plunge ${args.join(" ")}`);
|
|
188
|
+
if (view.status === "refused") {
|
|
189
|
+
throw new Error(`pulumiAdoptPreview: plunge refuses to adopt "${a.member}/${a.stack}": ${refusalText(view.refusals)}. Nothing was written.`);
|
|
190
|
+
}
|
|
191
|
+
return summary(a, view);
|
|
192
|
+
}
|
|
193
|
+
/** `plunge stack adopt --json --yes`: writes the records. A refusal fails the step; plunge wrote nothing then. */
|
|
194
|
+
export async function adoptStack(a, deps = {}) {
|
|
195
|
+
requireStack(a, "pulumiAdopt");
|
|
196
|
+
const dir = stackDir(a);
|
|
197
|
+
const args = plungeAdoptArgs({ stack: a.stack, yes: true, ...(a.file ? { file: a.file } : {}) });
|
|
198
|
+
const view = await adoptView(() => runAdoptPlunge(deps.plunge ?? defaultPlungeRunner, args, dir), "pulumiAdopt", `plunge ${args.join(" ")}`);
|
|
199
|
+
if (view.status === "refused") {
|
|
200
|
+
throw new Error(`pulumiAdopt: plunge refused to adopt "${a.member}/${a.stack}": ${refusalText(view.refusals)}. Nothing was written.`);
|
|
201
|
+
}
|
|
202
|
+
const out = summary(a, view);
|
|
203
|
+
return { ...out, ...(a.planDigest ? { matchesApproved: out.planDigest === a.planDigest } : {}) };
|
|
204
|
+
}
|
|
205
|
+
export async function pulumiAdoptCheck(args) {
|
|
206
|
+
return adoptCheck(args);
|
|
207
|
+
}
|
|
208
|
+
export async function pulumiAdoptExport(args) {
|
|
209
|
+
return adoptExport(args);
|
|
210
|
+
}
|
|
211
|
+
export async function pulumiAdoptPreview(args) {
|
|
212
|
+
return adoptPreview(args);
|
|
213
|
+
}
|
|
214
|
+
export async function pulumiAdopt(args) {
|
|
215
|
+
return adoptStack(args);
|
|
216
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pulumi.d.ts","sourceRoot":"","sources":["../../../src/op/activities/pulumi.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pulumi.d.ts","sourceRoot":"","sources":["../../../src/op/activities/pulumi.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAgD,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAElG,4CAA4C;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,4FAA4F;IAC5F,GAAG,EAAE,MAAM,CAAC;IACZ,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mGAAmG;IACnG,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAED,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iFAAiF;IACjF,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,oHAAoH;IACpH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAQD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAyB/F;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmB3F"}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* already allow: `pulumi preview --json` (or `plunge preview --json`) and
|
|
8
8
|
* `pulumi refresh --preview-only --json --target <urn>` (or `plunge drift
|
|
9
9
|
* --resource <urn> --stream`). Neither changes the stack. There is no apply
|
|
10
|
-
* activity
|
|
10
|
+
* activity: a stack applies as a component step through the `pulumi-up`
|
|
11
|
+
* capability (`../../pulumi-up.ts`, #4541), the only caller of `up`.
|
|
11
12
|
*
|
|
12
13
|
* `dir` is the member's directory, where `Pulumi.yaml` is, resolved against
|
|
13
14
|
* `cwd` (default: the process's working directory, the project root on a
|
|
@@ -31,4 +31,77 @@ export declare const pulumiDriftContract: import("@intentius/chant/op").Activity
|
|
|
31
31
|
notObserved: number;
|
|
32
32
|
records: number;
|
|
33
33
|
}>;
|
|
34
|
+
export declare const pulumiAdoptCheckContract: import("@intentius/chant/op").ActivityContract<{
|
|
35
|
+
member: string;
|
|
36
|
+
dir: string;
|
|
37
|
+
cwd?: string | undefined;
|
|
38
|
+
stack: string;
|
|
39
|
+
backend?: string | undefined;
|
|
40
|
+
bucket?: Record<string, unknown> | undefined;
|
|
41
|
+
namespaces?: string[] | undefined;
|
|
42
|
+
allowInsecure?: string[] | undefined;
|
|
43
|
+
}, {
|
|
44
|
+
member: string;
|
|
45
|
+
stack: string;
|
|
46
|
+
checked: boolean;
|
|
47
|
+
skipped?: string | undefined;
|
|
48
|
+
store?: string | undefined;
|
|
49
|
+
bucket?: string | undefined;
|
|
50
|
+
correct: boolean;
|
|
51
|
+
waived: string[];
|
|
52
|
+
}>;
|
|
53
|
+
export declare const pulumiAdoptExportContract: import("@intentius/chant/op").ActivityContract<{
|
|
54
|
+
member: string;
|
|
55
|
+
dir: string;
|
|
56
|
+
cwd?: string | undefined;
|
|
57
|
+
stack: string;
|
|
58
|
+
backend?: string | undefined;
|
|
59
|
+
from?: {
|
|
60
|
+
backend?: string | undefined;
|
|
61
|
+
file?: string | undefined;
|
|
62
|
+
} | undefined;
|
|
63
|
+
}, {
|
|
64
|
+
member: string;
|
|
65
|
+
stack: string;
|
|
66
|
+
file: string;
|
|
67
|
+
sha256: string;
|
|
68
|
+
resources: number;
|
|
69
|
+
pendingOperations: number;
|
|
70
|
+
source: string;
|
|
71
|
+
adoptFromFile: boolean;
|
|
72
|
+
}>;
|
|
73
|
+
export declare const pulumiAdoptPreviewContract: import("@intentius/chant/op").ActivityContract<{
|
|
74
|
+
member: string;
|
|
75
|
+
dir: string;
|
|
76
|
+
cwd?: string | undefined;
|
|
77
|
+
stack: string;
|
|
78
|
+
file?: string | undefined;
|
|
79
|
+
}, {
|
|
80
|
+
member: string;
|
|
81
|
+
stack: string;
|
|
82
|
+
status: "adopted" | "already-adopted" | "refused" | "would-adopt";
|
|
83
|
+
planDigest: string;
|
|
84
|
+
checkpointDigest: string | null;
|
|
85
|
+
resources: number;
|
|
86
|
+
fates: Record<string, number>;
|
|
87
|
+
changed: boolean;
|
|
88
|
+
}>;
|
|
89
|
+
export declare const pulumiAdoptContract: import("@intentius/chant/op").ActivityContract<{
|
|
90
|
+
member: string;
|
|
91
|
+
dir: string;
|
|
92
|
+
cwd?: string | undefined;
|
|
93
|
+
stack: string;
|
|
94
|
+
file?: string | undefined;
|
|
95
|
+
planDigest?: string | undefined;
|
|
96
|
+
}, {
|
|
97
|
+
member: string;
|
|
98
|
+
stack: string;
|
|
99
|
+
status: "adopted" | "already-adopted" | "refused" | "would-adopt";
|
|
100
|
+
planDigest: string;
|
|
101
|
+
checkpointDigest: string | null;
|
|
102
|
+
resources: number;
|
|
103
|
+
fates: Record<string, number>;
|
|
104
|
+
changed: boolean;
|
|
105
|
+
matchesApproved?: boolean | undefined;
|
|
106
|
+
}>;
|
|
34
107
|
//# sourceMappingURL=activity-contracts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity-contracts.d.ts","sourceRoot":"","sources":["../../src/op/activity-contracts.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;EAiBjC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;EAW/B,CAAC"}
|
|
1
|
+
{"version":3,"file":"activity-contracts.d.ts","sourceRoot":"","sources":["../../src/op/activity-contracts.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;EAiBjC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;EAW/B,CAAC;AAqBF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;EAoBpC,CAAC;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;EAkBrC,CAAC;AAEF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;EAKtC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;EAK/B,CAAC"}
|