@caelo-cms/provisioning 0.10.68 → 0.10.70
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/admin-domain.d.ts +28 -0
- package/dist/admin-domain.d.ts.map +1 -1
- package/dist/admin-domain.js +65 -0
- package/dist/admin-domain.js.map +1 -1
- package/dist/adopt-existing.d.ts +119 -0
- package/dist/adopt-existing.d.ts.map +1 -0
- package/dist/adopt-existing.js +118 -0
- package/dist/adopt-existing.js.map +1 -0
- package/dist/cli.js +18 -0
- package/dist/cli.js.map +1 -1
- package/dist/default-firewall.d.ts +1 -1
- package/dist/default-firewall.d.ts.map +1 -1
- package/dist/default-firewall.js +2 -1
- package/dist/default-firewall.js.map +1 -1
- package/dist/gcloud-retry.d.ts +21 -0
- package/dist/gcloud-retry.d.ts.map +1 -1
- package/dist/gcloud-retry.js +34 -0
- package/dist/gcloud-retry.js.map +1 -1
- package/dist/ops-backend.d.ts.map +1 -1
- package/dist/ops-backend.js +13 -3
- package/dist/ops-backend.js.map +1 -1
- package/dist/preview-plan.d.ts +7 -0
- package/dist/preview-plan.d.ts.map +1 -1
- package/dist/preview-plan.js +1 -0
- package/dist/preview-plan.js.map +1 -1
- package/dist/stack-contract.d.ts +9 -2
- package/dist/stack-contract.d.ts.map +1 -1
- package/dist/stack-contract.js +4 -2
- package/dist/stack-contract.js.map +1 -1
- package/dist/stack-converge.d.ts +14 -0
- package/dist/stack-converge.d.ts.map +1 -1
- package/dist/stack-converge.js +83 -8
- package/dist/stack-converge.js.map +1 -1
- package/dist/state-command.d.ts.map +1 -1
- package/dist/state-command.js +3 -1
- package/dist/state-command.js.map +1 -1
- package/dist/state-migrate.d.ts +7 -0
- package/dist/state-migrate.d.ts.map +1 -1
- package/dist/state-migrate.js +18 -1
- package/dist/state-migrate.js.map +1 -1
- package/dist/upgrade/app-roll.d.ts +9 -1
- package/dist/upgrade/app-roll.d.ts.map +1 -1
- package/dist/upgrade/app-roll.js +14 -2
- package/dist/upgrade/app-roll.js.map +1 -1
- package/dist/upgrade/upgrade.d.ts.map +1 -1
- package/dist/upgrade/upgrade.js +1 -1
- package/dist/upgrade/upgrade.js.map +1 -1
- package/dist/upgrader-job.d.ts.map +1 -1
- package/dist/upgrader-job.js +4 -1
- package/dist/upgrader-job.js.map +1 -1
- package/dist/wizards/gcp-pulumi.d.ts +19 -4
- package/dist/wizards/gcp-pulumi.d.ts.map +1 -1
- package/dist/wizards/gcp-pulumi.js +62 -7
- package/dist/wizards/gcp-pulumi.js.map +1 -1
- package/dist/wizards/gcp.d.ts.map +1 -1
- package/dist/wizards/gcp.js +14 -5
- package/dist/wizards/gcp.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/fixtures/viu-one-plan-state-migrate.txt +98 -0
- package/src/admin-domain.test.ts +87 -0
- package/src/admin-domain.ts +71 -0
- package/src/adopt-existing.test.ts +397 -0
- package/src/adopt-existing.ts +228 -0
- package/src/cli.ts +22 -0
- package/src/default-firewall.ts +5 -3
- package/src/gcloud-retry.ts +37 -0
- package/src/ops-backend.test.ts +56 -0
- package/src/ops-backend.ts +21 -3
- package/src/preview-plan.ts +8 -0
- package/src/remote-mcp.test.ts +2 -0
- package/src/stack-contract.ts +10 -2
- package/src/stack-converge-secrets.test.ts +137 -1
- package/src/stack-converge.ts +88 -7
- package/src/state-command.ts +6 -1
- package/src/state-migrate.test.ts +38 -0
- package/src/state-migrate.ts +24 -1
- package/src/upgrade/app-roll.ts +29 -0
- package/src/upgrade/upgrade.test.ts +1 -1
- package/src/upgrade/upgrade.ts +1 -0
- package/src/upgrader-job.ts +3 -0
- package/src/wizards/gcp-pulumi.ts +84 -8
- package/src/wizards/gcp.ts +11 -4
package/dist/admin-domain.d.ts
CHANGED
|
@@ -76,5 +76,33 @@ export declare function enableAdminDomain(opts: DomainOpts): Promise<AdminDomain
|
|
|
76
76
|
export declare function enableStagingDomain(opts: DomainOpts & {
|
|
77
77
|
stagingHost: string;
|
|
78
78
|
}): Promise<StagingDomainResult>;
|
|
79
|
+
/** What {@link setAdminStagingHostEnv} did. */
|
|
80
|
+
export type AdminStagingEnvResult = {
|
|
81
|
+
readonly status: "set";
|
|
82
|
+
readonly service: string;
|
|
83
|
+
readonly previous: string | null;
|
|
84
|
+
} | {
|
|
85
|
+
readonly status: "unchanged";
|
|
86
|
+
readonly service: string;
|
|
87
|
+
} | {
|
|
88
|
+
readonly status: "failed";
|
|
89
|
+
readonly error: string;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* #1058 — point the admin's `CAELO_STAGING_HOST` at the host
|
|
93
|
+
* `staging-domain enable` just mapped. The database row
|
|
94
|
+
* (`staging_access.staging_host`) is the admin's truth and is set through
|
|
95
|
+
* `staging_access.provision` (staging-admin.ts), but the env var is what
|
|
96
|
+
* provisioning recorded: left on the old host, the seed would restore the
|
|
97
|
+
* old host on a fresh database, and the converge job refuses every
|
|
98
|
+
* cloud-setup update because install.json and the deployed admin disagree
|
|
99
|
+
* (converge-job-gcp.ts `deployedSiteMismatch`). Same variable the upgrade's
|
|
100
|
+
* env contract sets (stack-contract.ts STAGING_HOST_ENV); updating only it
|
|
101
|
+
* keeps every other var exactly as deployed. A new revision only when the
|
|
102
|
+
* value differs, so a re-run is a no-op.
|
|
103
|
+
*/
|
|
104
|
+
export declare function setAdminStagingHostEnv(opts: Pick<DomainOpts, "projectId" | "region" | "run"> & {
|
|
105
|
+
stagingHost: string;
|
|
106
|
+
}): Promise<AdminStagingEnvResult>;
|
|
79
107
|
export {};
|
|
80
108
|
//# sourceMappingURL=admin-domain.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-domain.d.ts","sourceRoot":"","sources":["../src/admin-domain.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"admin-domain.d.ts","sourceRoot":"","sources":["../src/admin-domain.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAKzE,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,cAAc,EAAE,CAAA;CAAE,GACnF;IAAE,MAAM,EAAE,oBAAoB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,uEAAuE;AACvE,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAepD,UAAU,UAAU;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,kFAAkF;IAClF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAMD,0GAA0G;AAC1G,wBAAsB,WAAW,CAC/B,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,OAAO,GAAG,SAAS,GACxB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA8BvE;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAMpF;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,UAAU,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GACzC,OAAO,CAAC,mBAAmB,CAAC,CAwC9B;AAED,+CAA+C;AAC/C,MAAM,MAAM,qBAAqB,GAC7B;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACtF;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D;;;;;;;;;;;;GAYG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,GAAG,QAAQ,GAAG,KAAK,CAAC,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAC/E,OAAO,CAAC,qBAAqB,CAAC,CA8ChC"}
|
package/dist/admin-domain.js
CHANGED
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
*/
|
|
30
30
|
import { gcloud as defaultGcloud } from "./gcloud.js";
|
|
31
31
|
import { ensureGcloudComponent } from "./gcloud-components.js";
|
|
32
|
+
import { STAGING_HOST_ENV } from "./stack-contract.js";
|
|
33
|
+
import { liveContainerEnv } from "./stack-converge.js";
|
|
32
34
|
function recordsOf(json, hostname) {
|
|
33
35
|
const parsed = JSON.parse(json);
|
|
34
36
|
return (parsed.status?.resourceRecords ?? []).map((r) => ({
|
|
@@ -128,6 +130,69 @@ export async function enableStagingDomain(opts) {
|
|
|
128
130
|
: opts.stagingHost;
|
|
129
131
|
return mapDomain(run, logOf(opts), scope, verifyDomain, opts.stagingHost, found.service);
|
|
130
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* #1058 — point the admin's `CAELO_STAGING_HOST` at the host
|
|
135
|
+
* `staging-domain enable` just mapped. The database row
|
|
136
|
+
* (`staging_access.staging_host`) is the admin's truth and is set through
|
|
137
|
+
* `staging_access.provision` (staging-admin.ts), but the env var is what
|
|
138
|
+
* provisioning recorded: left on the old host, the seed would restore the
|
|
139
|
+
* old host on a fresh database, and the converge job refuses every
|
|
140
|
+
* cloud-setup update because install.json and the deployed admin disagree
|
|
141
|
+
* (converge-job-gcp.ts `deployedSiteMismatch`). Same variable the upgrade's
|
|
142
|
+
* env contract sets (stack-contract.ts STAGING_HOST_ENV); updating only it
|
|
143
|
+
* keeps every other var exactly as deployed. A new revision only when the
|
|
144
|
+
* value differs, so a re-run is a no-op.
|
|
145
|
+
*/
|
|
146
|
+
export async function setAdminStagingHostEnv(opts) {
|
|
147
|
+
const run = opts.run ?? defaultGcloud;
|
|
148
|
+
const scope = [`--region=${opts.region}`, `--project=${opts.projectId}`];
|
|
149
|
+
const found = await findService(run, scope, "admin");
|
|
150
|
+
if (!found.ok)
|
|
151
|
+
return { status: "failed", error: found.error };
|
|
152
|
+
const described = await run([
|
|
153
|
+
"run",
|
|
154
|
+
"services",
|
|
155
|
+
"describe",
|
|
156
|
+
found.service,
|
|
157
|
+
...scope,
|
|
158
|
+
"--format=json",
|
|
159
|
+
]);
|
|
160
|
+
if (!described.ok) {
|
|
161
|
+
return { status: "failed", error: `read the admin's env: ${described.stderr.trim()}` };
|
|
162
|
+
}
|
|
163
|
+
let live;
|
|
164
|
+
try {
|
|
165
|
+
live = liveContainerEnv(described.stdout);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return { status: "failed", error: "read the admin's env: gcloud's answer is not JSON" };
|
|
169
|
+
}
|
|
170
|
+
const current = live.get(STAGING_HOST_ENV);
|
|
171
|
+
if (current?.kind === "secret") {
|
|
172
|
+
return {
|
|
173
|
+
status: "failed",
|
|
174
|
+
error: `the admin reads ${STAGING_HOST_ENV} from secret ${current.secret}, not a plain value; run \`cms-provision upgrade\` to bring its env back to the contract, then re-run`,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (current?.value === opts.stagingHost)
|
|
178
|
+
return { status: "unchanged", service: found.service };
|
|
179
|
+
const update = await run([
|
|
180
|
+
"run",
|
|
181
|
+
"services",
|
|
182
|
+
"update",
|
|
183
|
+
found.service,
|
|
184
|
+
...scope,
|
|
185
|
+
`--update-env-vars=${STAGING_HOST_ENV}=${opts.stagingHost}`,
|
|
186
|
+
"--quiet",
|
|
187
|
+
]);
|
|
188
|
+
if (!update.ok) {
|
|
189
|
+
return {
|
|
190
|
+
status: "failed",
|
|
191
|
+
error: `set ${STAGING_HOST_ENV} on the admin: ${update.stderr.trim()}`,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return { status: "set", service: found.service, previous: current?.value ?? null };
|
|
195
|
+
}
|
|
131
196
|
/** Steps 2–4 of the module doc for `hostname` → `service`. */
|
|
132
197
|
async function mapDomain(run, log, scope, domain, hostname, service) {
|
|
133
198
|
// Fully managed Cloud Run domain mappings exist only on the beta track: the
|
package/dist/admin-domain.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-domain.js","sourceRoot":"","sources":["../src/admin-domain.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,MAAM,IAAI,aAAa,EAAqB,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"admin-domain.js","sourceRoot":"","sources":["../src/admin-domain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adopt cloud resources the stack declares but its Pulumi state lacks
|
|
3
|
+
* (#1079), before the installer's `pulumi up`.
|
|
4
|
+
*
|
|
5
|
+
* `cms-provision upgrade` converges an install through gcloud and never runs
|
|
6
|
+
* Pulumi (stack-converge.ts), so it creates some resources the stack also
|
|
7
|
+
* declares — the gateway's service account (runtime-secrets.ts), the MCP
|
|
8
|
+
* service account (mcp-iap.ts) — without them entering the state. The next
|
|
9
|
+
* installer run then plans to CREATE them, and `state migrate` refuses an
|
|
10
|
+
* install whose preview plans anything. So, after the preview and before
|
|
11
|
+
* the review:
|
|
12
|
+
*
|
|
13
|
+
* 1. {@link adoptionCandidates}: the planned creates of a kind in
|
|
14
|
+
* {@link ADOPTABLE_KINDS} whose inputs name the cloud resource. Only
|
|
15
|
+
* planned steps are looked at, so nothing the stack does not declare is
|
|
16
|
+
* ever adopted; every other kind is left to Pulumi.
|
|
17
|
+
* 2. {@link existingCandidates}: a gcloud describe per candidate. Exists →
|
|
18
|
+
* adopt; NOT_FOUND → a plain create; anything else stops the run (we
|
|
19
|
+
* can't tell, and guessing either way is wrong).
|
|
20
|
+
* 3. `pulumi import` of the existing ones into the stack, under the
|
|
21
|
+
* stack's explicit GCP provider (wizards/gcp-pulumi.ts). State only: the
|
|
22
|
+
* cloud resources are not touched.
|
|
23
|
+
* 4. A second preview: what the review shows and `up` applies. An adopted
|
|
24
|
+
* resource that is still planned as a create stops the run.
|
|
25
|
+
*
|
|
26
|
+
* Why only service accounts ({@link ADOPTABLE_KINDS}). A kind is adopted
|
|
27
|
+
* when the stack declares it AND the CLI also creates it through gcloud, and
|
|
28
|
+
* its name is unique in the project. Checked per kind against both stacks:
|
|
29
|
+
*
|
|
30
|
+
* - Secret Manager secrets: the stack declares only `postgres-password` and
|
|
31
|
+
* `secret-kek`, which the CLI never creates; the secrets the CLI makes
|
|
32
|
+
* (stack-contract.ts CLI_GENERATED_SECRETS) the stack only references by
|
|
33
|
+
* id. Adopting a secret without its value resource would also make `up`
|
|
34
|
+
* add a version with a freshly generated value — a new KEK.
|
|
35
|
+
* - Buckets, Cloud Run jobs, custom roles: the stack's buckets are made by
|
|
36
|
+
* Pulumi alone; the CLI's own (ops, audit results, the upgrader, converge,
|
|
37
|
+
* audit and operator-access jobs, their custom roles) are not declared.
|
|
38
|
+
* - The admin's Cloud Run domain mapping: owned by `admin-domain enable`
|
|
39
|
+
* (admin-domain.ts), the stack's copy stays off; Pulumi, running as the
|
|
40
|
+
* provisioner, could not manage it.
|
|
41
|
+
* - IAM member resources (`*IamMember`, `IAMMember`): non-authoritative.
|
|
42
|
+
* Their create is a read-modify-write that merges the member into the
|
|
43
|
+
* policy and succeeds when it is there already, so a planned create of
|
|
44
|
+
* one is an adoption already.
|
|
45
|
+
* - Cloud SQL users: the CLI's are IAM users named after service accounts,
|
|
46
|
+
* the stack's are the built-in `admin_role` / `public_role`.
|
|
47
|
+
*/
|
|
48
|
+
import type { GcloudRunner } from "./gcloud-retry.js";
|
|
49
|
+
import type { PlannedStep } from "./preview-plan.js";
|
|
50
|
+
/** The cloud identity of a resource a planned create would make. */
|
|
51
|
+
export interface AdoptionTarget {
|
|
52
|
+
/** How the operator knows it, e.g. the service account's email. */
|
|
53
|
+
readonly display: string;
|
|
54
|
+
/** gcloud args that succeed exactly when it exists. */
|
|
55
|
+
readonly describeArgs: readonly string[];
|
|
56
|
+
/** The id `pulumi import` takes for the kind. */
|
|
57
|
+
readonly importId: string;
|
|
58
|
+
}
|
|
59
|
+
/** A resource kind the installer adopts when it exists already. */
|
|
60
|
+
export interface AdoptableKind {
|
|
61
|
+
/** What it is, for messages (`service account`). */
|
|
62
|
+
readonly label: string;
|
|
63
|
+
/**
|
|
64
|
+
* The resource a create with these inputs would make, or null when the
|
|
65
|
+
* inputs don't pin it down (then the create is left to Pulumi).
|
|
66
|
+
*/
|
|
67
|
+
target(inputs: Readonly<Record<string, unknown>>, projectId: string): AdoptionTarget | null;
|
|
68
|
+
}
|
|
69
|
+
/** Kinds adopted before `up`, by Pulumi type token. See the file comment for the rest. */
|
|
70
|
+
export declare const ADOPTABLE_KINDS: Readonly<Record<string, AdoptableKind>>;
|
|
71
|
+
/** A planned create the installer may adopt instead. */
|
|
72
|
+
export interface AdoptionCandidate extends AdoptionTarget {
|
|
73
|
+
readonly step: PlannedStep;
|
|
74
|
+
readonly label: string;
|
|
75
|
+
}
|
|
76
|
+
/** Thrown when adoption cannot finish; nothing was applied. */
|
|
77
|
+
export declare class AdoptionError extends Error {
|
|
78
|
+
readonly name = "AdoptionError";
|
|
79
|
+
}
|
|
80
|
+
/** The planned creates of an adoptable kind, with what each would create. */
|
|
81
|
+
export declare function adoptionCandidates(steps: readonly PlannedStep[], projectId: string): AdoptionCandidate[];
|
|
82
|
+
/**
|
|
83
|
+
* The candidates that exist in the project.
|
|
84
|
+
*
|
|
85
|
+
* @throws AdoptionError when a describe fails for another reason than NOT_FOUND
|
|
86
|
+
*/
|
|
87
|
+
export declare function existingCandidates(candidates: readonly AdoptionCandidate[], run: GcloudRunner): Promise<AdoptionCandidate[]>;
|
|
88
|
+
/** What adoption needs from Pulumi and gcloud; fakes in tests. */
|
|
89
|
+
export interface AdoptionDeps {
|
|
90
|
+
readonly projectId: string;
|
|
91
|
+
readonly gcloud: GcloudRunner;
|
|
92
|
+
/** A fresh preview of the stack. */
|
|
93
|
+
preview(): Promise<readonly PlannedStep[]>;
|
|
94
|
+
/** `pulumi import` the candidates into the stack (state only). */
|
|
95
|
+
importResources(candidates: readonly AdoptionCandidate[]): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
/** The plan to review after adoption, and what was adopted into it. */
|
|
98
|
+
export interface AdoptionResult {
|
|
99
|
+
readonly adopted: readonly AdoptionCandidate[];
|
|
100
|
+
readonly steps: readonly PlannedStep[];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The line of a failed Pulumi call that says what went wrong. The
|
|
104
|
+
* Automation API's error starts with `code: 255` and carries the CLI's
|
|
105
|
+
* stderr below; its first `error:` line is the reason.
|
|
106
|
+
*/
|
|
107
|
+
export declare function pulumiErrorReason(e: unknown): string;
|
|
108
|
+
/**
|
|
109
|
+
* Adopt the planned creates of `steps` that exist in the project already,
|
|
110
|
+
* and return the plan after it. With nothing to adopt, `steps` comes back
|
|
111
|
+
* unchanged and nothing else runs.
|
|
112
|
+
*
|
|
113
|
+
* @throws AdoptionError when a probe or the import fails, or a re-plan still
|
|
114
|
+
* creates an adopted resource; `up` must not run then
|
|
115
|
+
*/
|
|
116
|
+
export declare function adoptExistingResources(steps: readonly PlannedStep[], deps: AdoptionDeps): Promise<AdoptionResult>;
|
|
117
|
+
/** The adopted resources as lines for the review, or none. */
|
|
118
|
+
export declare function formatAdopted(adopted: readonly AdoptionCandidate[]): string[];
|
|
119
|
+
//# sourceMappingURL=adopt-existing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopt-existing.d.ts","sourceRoot":"","sources":["../src/adopt-existing.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,oEAAoE;AACpE,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,uDAAuD;IACvD,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,mEAAmE;AACnE,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAAC;CAC7F;AAED,0FAA0F;AAC1F,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CA6BnE,CAAC;AAEF,wDAAwD;AACxD,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,+DAA+D;AAC/D,qBAAa,aAAc,SAAQ,KAAK;IACtC,SAAkB,IAAI,mBAAmB;CAC1C;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,SAAS,EAAE,MAAM,GAChB,iBAAiB,EAAE,CAUrB;AAID;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAY9B;AAED,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,oCAAoC;IACpC,OAAO,IAAI,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAAC;IAC3C,kEAAkE;IAClE,eAAe,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E;AAED,uEAAuE;AACvE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAMpD;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,cAAc,CAAC,CAqBzB;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,GAAG,MAAM,EAAE,CAM7E"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
/** Kinds adopted before `up`, by Pulumi type token. See the file comment for the rest. */
|
|
3
|
+
export const ADOPTABLE_KINDS = {
|
|
4
|
+
"gcp:serviceaccount/account:Account": {
|
|
5
|
+
label: "service account",
|
|
6
|
+
target(inputs, projectId) {
|
|
7
|
+
// GCP's account-id format; also keeps out the engine's placeholder
|
|
8
|
+
// for a value only known after apply.
|
|
9
|
+
const accountId = inputs.accountId;
|
|
10
|
+
if (typeof accountId !== "string" || !/^[a-z][a-z0-9-]{4,28}[a-z0-9]$/.test(accountId)) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
// Unset means the provider's project, which is the install's
|
|
14
|
+
// (assertStackProject). Another project is never adopted.
|
|
15
|
+
const project = inputs.project ?? projectId;
|
|
16
|
+
if (project !== projectId)
|
|
17
|
+
return null;
|
|
18
|
+
const email = `${accountId}@${projectId}.iam.gserviceaccount.com`;
|
|
19
|
+
return {
|
|
20
|
+
display: email,
|
|
21
|
+
describeArgs: [
|
|
22
|
+
"iam",
|
|
23
|
+
"service-accounts",
|
|
24
|
+
"describe",
|
|
25
|
+
email,
|
|
26
|
+
`--project=${projectId}`,
|
|
27
|
+
"--format=value(email)",
|
|
28
|
+
],
|
|
29
|
+
importId: `projects/${projectId}/serviceAccounts/${email}`,
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
/** Thrown when adoption cannot finish; nothing was applied. */
|
|
35
|
+
export class AdoptionError extends Error {
|
|
36
|
+
name = "AdoptionError";
|
|
37
|
+
}
|
|
38
|
+
/** The planned creates of an adoptable kind, with what each would create. */
|
|
39
|
+
export function adoptionCandidates(steps, projectId) {
|
|
40
|
+
const out = [];
|
|
41
|
+
for (const step of steps) {
|
|
42
|
+
if (step.op !== "create")
|
|
43
|
+
continue;
|
|
44
|
+
const kind = ADOPTABLE_KINDS[step.type];
|
|
45
|
+
if (!kind || !step.inputs)
|
|
46
|
+
continue;
|
|
47
|
+
const target = kind.target(step.inputs, projectId);
|
|
48
|
+
if (target)
|
|
49
|
+
out.push({ ...target, step, label: kind.label });
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
const NOT_FOUND = /NOT_FOUND|not found|does not exist/i;
|
|
54
|
+
/**
|
|
55
|
+
* The candidates that exist in the project.
|
|
56
|
+
*
|
|
57
|
+
* @throws AdoptionError when a describe fails for another reason than NOT_FOUND
|
|
58
|
+
*/
|
|
59
|
+
export async function existingCandidates(candidates, run) {
|
|
60
|
+
const existing = [];
|
|
61
|
+
for (const c of candidates) {
|
|
62
|
+
const r = await run([...c.describeArgs]);
|
|
63
|
+
if (r.ok)
|
|
64
|
+
existing.push(c);
|
|
65
|
+
else if (!NOT_FOUND.test(r.stderr)) {
|
|
66
|
+
throw new AdoptionError(`could not tell whether the ${c.label} ${c.display} exists (gcloud: ${r.stderr.trim()}). Nothing was imported or applied. Check that gcloud is signed in as the Owner (gcloud auth login) and re-run the installer.`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return existing;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The line of a failed Pulumi call that says what went wrong. The
|
|
73
|
+
* Automation API's error starts with `code: 255` and carries the CLI's
|
|
74
|
+
* stderr below; its first `error:` line is the reason.
|
|
75
|
+
*/
|
|
76
|
+
export function pulumiErrorReason(e) {
|
|
77
|
+
const lines = (e instanceof Error ? e.message : String(e))
|
|
78
|
+
.split("\n")
|
|
79
|
+
.map((l) => l.trim().replace(/^stderr:\s*/, ""))
|
|
80
|
+
.filter((l) => l !== "");
|
|
81
|
+
return lines.find((l) => /^error:/i.test(l)) ?? lines[0] ?? "no output";
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Adopt the planned creates of `steps` that exist in the project already,
|
|
85
|
+
* and return the plan after it. With nothing to adopt, `steps` comes back
|
|
86
|
+
* unchanged and nothing else runs.
|
|
87
|
+
*
|
|
88
|
+
* @throws AdoptionError when a probe or the import fails, or a re-plan still
|
|
89
|
+
* creates an adopted resource; `up` must not run then
|
|
90
|
+
*/
|
|
91
|
+
export async function adoptExistingResources(steps, deps) {
|
|
92
|
+
const existing = await existingCandidates(adoptionCandidates(steps, deps.projectId), deps.gcloud);
|
|
93
|
+
if (existing.length === 0)
|
|
94
|
+
return { adopted: [], steps };
|
|
95
|
+
const names = existing.map((c) => `${c.label} ${c.display}`).join(", ");
|
|
96
|
+
try {
|
|
97
|
+
await deps.importResources(existing);
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
throw new AdoptionError(`could not adopt ${names} (already in the project) into the stack: pulumi import says "${pulumiErrorReason(e)}". Nothing was applied. Re-run the installer: what was adopted stays adopted. If it fails the same way, report it with this message.`);
|
|
101
|
+
}
|
|
102
|
+
const after = await deps.preview();
|
|
103
|
+
const stillCreated = after.filter((s) => s.op === "create" && existing.some((c) => c.step.urn === s.urn));
|
|
104
|
+
if (stillCreated.length > 0) {
|
|
105
|
+
throw new AdoptionError(`imported ${names}, but the next preview still creates ${stillCreated.map((s) => s.name).join(", ")}. Nothing was applied. Report this with the message; re-running the installer does not fix it.`);
|
|
106
|
+
}
|
|
107
|
+
return { adopted: existing, steps: after };
|
|
108
|
+
}
|
|
109
|
+
/** The adopted resources as lines for the review, or none. */
|
|
110
|
+
export function formatAdopted(adopted) {
|
|
111
|
+
if (adopted.length === 0)
|
|
112
|
+
return [];
|
|
113
|
+
return [
|
|
114
|
+
`Adopted (${adopted.length}) — already in the project, now in the stack instead of created again:`,
|
|
115
|
+
...adopted.map((c) => ` ${c.label} ${c.display} (${c.step.name})`),
|
|
116
|
+
];
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=adopt-existing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopt-existing.js","sourceRoot":"","sources":["../src/adopt-existing.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -1253,6 +1253,24 @@ async function domainMappingCommand(kind) {
|
|
|
1253
1253
|
// Prints the staging basic-auth password ON PURPOSE (#678): the operator
|
|
1254
1254
|
// asked for it to be shown once; it is never written to disk or logs.
|
|
1255
1255
|
console.log(describeStagingApply(applied.value).join("\n"));
|
|
1256
|
+
// #1058 — and the admin's CAELO_STAGING_HOST, so the provisioned value
|
|
1257
|
+
// agrees with install.json and the stored host (the converge job
|
|
1258
|
+
// refuses an install whose records and admin disagree). After the
|
|
1259
|
+
// provision call: the update starts a new admin revision.
|
|
1260
|
+
const { setAdminStagingHostEnv } = await import("./admin-domain.js");
|
|
1261
|
+
const env = await setAdminStagingHostEnv({
|
|
1262
|
+
projectId: meta.projectId,
|
|
1263
|
+
region: meta.region,
|
|
1264
|
+
stagingHost: r.hostname,
|
|
1265
|
+
});
|
|
1266
|
+
if (env.status === "failed") {
|
|
1267
|
+
console.error(`${command}: ${r.hostname} is mapped and stored in the admin, but its CAELO_STAGING_HOST could not be updated: ${env.error}\n` +
|
|
1268
|
+
`Run \`${retry}\` again once that is fixed (it is idempotent).`);
|
|
1269
|
+
process.exit(5);
|
|
1270
|
+
}
|
|
1271
|
+
if (env.status === "set") {
|
|
1272
|
+
console.log(`The admin (${env.service}) now runs with CAELO_STAGING_HOST=${r.hostname}${env.previous ? ` (was ${env.previous})` : ""}.`);
|
|
1273
|
+
}
|
|
1256
1274
|
}
|
|
1257
1275
|
if (r.records.length === 0) {
|
|
1258
1276
|
console.log(`Google has not published the DNS records yet; run \`cms-provision ${command} enable\` again in a minute.`);
|