@caelo-cms/provisioning 0.10.43 → 0.10.46
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/adapter.d.ts +1 -1
- package/dist/adc-impersonation.d.ts +28 -0
- package/dist/adc-impersonation.d.ts.map +1 -0
- package/dist/adc-impersonation.js +126 -0
- package/dist/adc-impersonation.js.map +1 -0
- package/dist/caddy.js +1 -1
- package/dist/checkpoint-secrets.d.ts.map +1 -1
- package/dist/checkpoint-secrets.js +2 -1
- package/dist/checkpoint-secrets.js.map +1 -1
- package/dist/cli.js +208 -43
- package/dist/cli.js.map +1 -1
- package/dist/compose.d.ts +45 -0
- package/dist/compose.d.ts.map +1 -1
- package/dist/compose.js +112 -29
- package/dist/compose.js.map +1 -1
- package/dist/gcloud-retry.d.ts +5 -1
- package/dist/gcloud-retry.d.ts.map +1 -1
- package/dist/gcloud-retry.js.map +1 -1
- package/dist/gcloud.d.ts +2 -1
- package/dist/gcloud.d.ts.map +1 -1
- package/dist/gcloud.js +11 -13
- package/dist/gcloud.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/infra-contract.d.ts +24 -0
- package/dist/infra-contract.d.ts.map +1 -0
- package/dist/infra-contract.js +25 -0
- package/dist/infra-contract.js.map +1 -0
- package/dist/install-state.d.ts +68 -2
- package/dist/install-state.d.ts.map +1 -1
- package/dist/install-state.js +166 -22
- package/dist/install-state.js.map +1 -1
- package/dist/lifecycle.d.ts +6 -0
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +185 -819
- package/dist/lifecycle.js.map +1 -1
- package/dist/mcp-iap.js +1 -1
- package/dist/migration-runner.d.ts +3 -0
- package/dist/migration-runner.d.ts.map +1 -1
- package/dist/migration-runner.js +7 -5
- package/dist/migration-runner.js.map +1 -1
- package/dist/ops-backend.d.ts +46 -0
- package/dist/ops-backend.d.ts.map +1 -0
- package/dist/ops-backend.js +370 -0
- package/dist/ops-backend.js.map +1 -0
- package/dist/provisioner-identity.d.ts +103 -0
- package/dist/provisioner-identity.d.ts.map +1 -0
- package/dist/provisioner-identity.js +323 -0
- package/dist/provisioner-identity.js.map +1 -0
- package/dist/regions.d.ts.map +1 -1
- package/dist/regions.js +2 -1
- package/dist/regions.js.map +1 -1
- package/dist/release-contract.d.ts +37 -0
- package/dist/release-contract.d.ts.map +1 -0
- package/dist/release-contract.js +55 -0
- package/dist/release-contract.js.map +1 -0
- package/dist/release-manifest.d.ts +140 -0
- package/dist/release-manifest.d.ts.map +1 -0
- package/dist/release-manifest.js +319 -0
- package/dist/release-manifest.js.map +1 -0
- package/dist/self-command.d.ts +16 -0
- package/dist/self-command.d.ts.map +1 -0
- package/dist/self-command.js +20 -0
- package/dist/self-command.js.map +1 -0
- package/dist/self-hosted-release.d.ts +81 -0
- package/dist/self-hosted-release.d.ts.map +1 -0
- package/dist/self-hosted-release.js +148 -0
- package/dist/self-hosted-release.js.map +1 -0
- package/dist/self-hosted-upgrade.d.ts +91 -0
- package/dist/self-hosted-upgrade.d.ts.map +1 -0
- package/dist/self-hosted-upgrade.js +355 -0
- package/dist/self-hosted-upgrade.js.map +1 -0
- package/dist/stack-contract.js +2 -2
- package/dist/stack-converge.d.ts.map +1 -1
- package/dist/stack-converge.js +2 -1
- package/dist/stack-converge.js.map +1 -1
- package/dist/staging-admin.js +3 -3
- package/dist/state-backend.d.ts +103 -0
- package/dist/state-backend.d.ts.map +1 -0
- package/dist/state-backend.js +180 -0
- package/dist/state-backend.js.map +1 -0
- package/dist/state-store.d.ts +55 -0
- package/dist/state-store.d.ts.map +1 -0
- package/dist/state-store.js +140 -0
- package/dist/state-store.js.map +1 -0
- package/dist/upgrade/app-roll.d.ts +164 -0
- package/dist/upgrade/app-roll.d.ts.map +1 -0
- package/dist/upgrade/app-roll.js +270 -0
- package/dist/upgrade/app-roll.js.map +1 -0
- package/dist/upgrade/backup.d.ts +48 -0
- package/dist/upgrade/backup.d.ts.map +1 -0
- package/dist/upgrade/backup.js +71 -0
- package/dist/upgrade/backup.js.map +1 -0
- package/dist/upgrade/converge.d.ts +45 -0
- package/dist/upgrade/converge.d.ts.map +1 -0
- package/dist/upgrade/converge.js +287 -0
- package/dist/upgrade/converge.js.map +1 -0
- package/dist/upgrade/gcp-lookup.d.ts +23 -0
- package/dist/upgrade/gcp-lookup.d.ts.map +1 -0
- package/dist/upgrade/gcp-lookup.js +95 -0
- package/dist/upgrade/gcp-lookup.js.map +1 -0
- package/dist/upgrade/health.d.ts +99 -0
- package/dist/upgrade/health.d.ts.map +1 -0
- package/dist/upgrade/health.js +214 -0
- package/dist/upgrade/health.js.map +1 -0
- package/dist/upgrade/release-images.d.ts +125 -0
- package/dist/upgrade/release-images.d.ts.map +1 -0
- package/dist/upgrade/release-images.js +315 -0
- package/dist/upgrade/release-images.js.map +1 -0
- package/dist/upgrade/reporter.d.ts +17 -0
- package/dist/upgrade/reporter.d.ts.map +1 -0
- package/dist/upgrade/reporter.js +28 -0
- package/dist/upgrade/reporter.js.map +1 -0
- package/dist/upgrade/upgrade.d.ts +79 -0
- package/dist/upgrade/upgrade.d.ts.map +1 -0
- package/dist/upgrade/upgrade.js +105 -0
- package/dist/upgrade/upgrade.js.map +1 -0
- package/dist/wizard.d.ts.map +1 -1
- package/dist/wizard.js +7 -3
- package/dist/wizard.js.map +1 -1
- package/dist/wizards/gcp-cost.d.ts.map +1 -1
- package/dist/wizards/gcp-cost.js +7 -1
- package/dist/wizards/gcp-cost.js.map +1 -1
- package/dist/wizards/gcp-pulumi.d.ts +99 -8
- package/dist/wizards/gcp-pulumi.d.ts.map +1 -1
- package/dist/wizards/gcp-pulumi.js +157 -50
- package/dist/wizards/gcp-pulumi.js.map +1 -1
- package/dist/wizards/gcp.d.ts.map +1 -1
- package/dist/wizards/gcp.js +185 -61
- package/dist/wizards/gcp.js.map +1 -1
- package/package.json +4 -3
- package/stacks/aws/README.md +1 -1
- package/stacks/gcp/Pulumi.yaml +1 -1
- package/stacks/gcp/README.md +1 -1
- package/stacks/gcp/index.ts +1 -1
- package/stacks/gcp-firebase/Pulumi.yaml +1 -1
- package/stacks/gcp-firebase/index.ts +2 -2
- package/stacks/self-hosted/README.md +4 -0
- package/stacks/self-hosted/index.ts +10 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../src/upgrade/backup.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,mCAAmC;AACnC,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAC7D,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,MAAM,IAAuB,GACjC,OAAO,CAAC,eAAe,CAAC,CA8C1B;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAExD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAQjF"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
import { gcpNamePrefix } from "../gcp-names.js";
|
|
3
|
+
import { resolveGcpResourceName } from "./gcp-lookup.js";
|
|
4
|
+
/**
|
|
5
|
+
* Take an on-demand backup of the install's Cloud SQL instance and return its
|
|
6
|
+
* id. `gcloud sql backups create` waits for the backup to finish but does not
|
|
7
|
+
* print the id in a stable shape, so the backup carries a unique description
|
|
8
|
+
* and is looked up by it afterwards.
|
|
9
|
+
*
|
|
10
|
+
* @param purpose short reason recorded in the backup's description, e.g. "pre-upgrade to 0.11.0"
|
|
11
|
+
*/
|
|
12
|
+
export async function takeSqlBackup(run, install, purpose, now = () => new Date()) {
|
|
13
|
+
const instance = await resolveGcpResourceName(run, "sql-instance", `${gcpNamePrefix(install.env)}-pg`, install.projectId);
|
|
14
|
+
if (!instance) {
|
|
15
|
+
return {
|
|
16
|
+
ok: false,
|
|
17
|
+
error: `no ${gcpNamePrefix(install.env)}-pg* Cloud SQL instance in project ${install.projectId} (or listing it was denied)`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const description = `caelo-cms ${purpose} ${now().toISOString()}`;
|
|
21
|
+
const project = ["--project", install.projectId];
|
|
22
|
+
const create = await run([
|
|
23
|
+
"sql",
|
|
24
|
+
"backups",
|
|
25
|
+
"create",
|
|
26
|
+
"--instance",
|
|
27
|
+
instance,
|
|
28
|
+
...project,
|
|
29
|
+
"--description",
|
|
30
|
+
description,
|
|
31
|
+
]);
|
|
32
|
+
if (!create.ok) {
|
|
33
|
+
return { ok: false, error: `backup of ${instance} failed: ${create.stderr.trim()}` };
|
|
34
|
+
}
|
|
35
|
+
const list = await run([
|
|
36
|
+
"sql",
|
|
37
|
+
"backups",
|
|
38
|
+
"list",
|
|
39
|
+
"--instance",
|
|
40
|
+
instance,
|
|
41
|
+
...project,
|
|
42
|
+
`--filter=description="${description}"`,
|
|
43
|
+
"--format=value(id)",
|
|
44
|
+
]);
|
|
45
|
+
const backupId = list.ok ? list.stdout.trim().split("\n")[0]?.trim() : "";
|
|
46
|
+
if (!backupId) {
|
|
47
|
+
return {
|
|
48
|
+
ok: false,
|
|
49
|
+
error: `backup of ${instance} was created but its id could not be read (${list.ok ? "no backup carries the description" : list.stderr.trim()}); find it with: gcloud sql backups list --instance=${instance} --project=${install.projectId}`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return { ok: true, backup: { projectId: install.projectId, instance, backupId } };
|
|
53
|
+
}
|
|
54
|
+
/** The command that restores `backup` over its instance (overwrites the current data). */
|
|
55
|
+
export function restoreCommand(backup) {
|
|
56
|
+
return `gcloud sql backups restore ${backup.backupId} --restore-instance=${backup.instance} --project=${backup.projectId}`;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* What to tell the operator when a pre-upgrade backup failed: why nothing
|
|
60
|
+
* happened, and how to get past it.
|
|
61
|
+
*/
|
|
62
|
+
export function backupFailureHelp(install) {
|
|
63
|
+
return [
|
|
64
|
+
"Nothing was changed: no migrations ran and no traffic moved.",
|
|
65
|
+
"Fix the cause and re-run upgrade. Common causes:",
|
|
66
|
+
` - the account lacks Cloud SQL backup rights (roles/cloudsql.editor or owner on ${install.projectId})`,
|
|
67
|
+
" - another backup or maintenance operation is running on the instance (wait, then retry)",
|
|
68
|
+
` - the instance is stopped: gcloud sql instances describe <instance> --project=${install.projectId}`,
|
|
69
|
+
].join("\n");
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.js","sourceRoot":"","sources":["../../src/upgrade/backup.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAcnC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAezD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAiB,EACjB,OAA6D,EAC7D,OAAe,EACf,MAAkB,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE;IAElC,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAC3C,GAAG,EACH,cAAc,EACd,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAClC,OAAO,CAAC,SAAS,CAClB,CAAC;IACF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,MAAM,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,sCAAsC,OAAO,CAAC,SAAS,6BAA6B;SAC5H,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,aAAa,OAAO,IAAI,GAAG,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAClE,MAAM,OAAO,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;QACvB,KAAK;QACL,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,QAAQ;QACR,GAAG,OAAO;QACV,eAAe;QACf,WAAW;KACZ,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,QAAQ,YAAY,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;IACvF,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC;QACrB,KAAK;QACL,SAAS;QACT,MAAM;QACN,YAAY;QACZ,QAAQ;QACR,GAAG,OAAO;QACV,yBAAyB,WAAW,GAAG;QACvC,oBAAoB;KACrB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,aAAa,QAAQ,8CAA8C,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,uDAAuD,QAAQ,cAAc,OAAO,CAAC,SAAS,EAAE;SAC7O,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC;AACpF,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,cAAc,CAAC,MAAiB;IAC9C,OAAO,8BAA8B,MAAM,CAAC,QAAQ,uBAAuB,MAAM,CAAC,QAAQ,cAAc,MAAM,CAAC,SAAS,EAAE,CAAC;AAC7H,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAuC;IACvE,OAAO;QACL,8DAA8D;QAC9D,kDAAkD;QAClD,oFAAoF,OAAO,CAAC,SAAS,GAAG;QACxG,2FAA2F;QAC3F,mFAAmF,OAAO,CAAC,SAAS,EAAE;KACvG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { GcloudRunner, Sleep } from "../gcloud-retry.js";
|
|
2
|
+
import type { InstallMetadata } from "../install-state.js";
|
|
3
|
+
import { type HttpFetch } from "../runtime-secrets.js";
|
|
4
|
+
import type { AppRollHooks, AppRollPlan } from "./app-roll.js";
|
|
5
|
+
import type { UpgradeReporter } from "./reporter.js";
|
|
6
|
+
/**
|
|
7
|
+
* Whether the install must converge before an app-roll to a release that
|
|
8
|
+
* expects infrastructure contract `targetVersion` (infra-contract.ts). An
|
|
9
|
+
* install with no recorded version has never completed a converge under
|
|
10
|
+
* this scheme and always needs one.
|
|
11
|
+
*/
|
|
12
|
+
export declare function needsConverge(install: Pick<InstallMetadata, "infraContractVersion">, targetVersion: number): boolean;
|
|
13
|
+
export interface ConvergeDeps {
|
|
14
|
+
readonly run: GcloudRunner;
|
|
15
|
+
readonly sleep?: Sleep;
|
|
16
|
+
/** Cloud SQL Admin API calls (database role passwords). */
|
|
17
|
+
readonly http?: HttpFetch;
|
|
18
|
+
readonly reporter: UpgradeReporter;
|
|
19
|
+
/**
|
|
20
|
+
* The operator's own identity step, run first: the CLI moves the
|
|
21
|
+
* provisioner SA to keyless impersonation (provisioner-identity.ts), which
|
|
22
|
+
* needs the operator's gcloud account and local install dir. False aborts.
|
|
23
|
+
*/
|
|
24
|
+
readonly provisionerIdentity?: () => Promise<boolean>;
|
|
25
|
+
}
|
|
26
|
+
export interface ConvergeSession {
|
|
27
|
+
/**
|
|
28
|
+
* Before the app-roll: runtime identities + secrets, stack invariants, MCP
|
|
29
|
+
* access. False when a step the install cannot work without failed —
|
|
30
|
+
* nothing app-side changed then.
|
|
31
|
+
*/
|
|
32
|
+
beforeAppRoll(): Promise<boolean>;
|
|
33
|
+
/** The steps the app-roll runs between its own. */
|
|
34
|
+
readonly hooks: AppRollHooks;
|
|
35
|
+
/** After a successful app-roll: retire bindings nothing reads any more. */
|
|
36
|
+
afterAppRoll(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Whether every converge step succeeded — only then may the install's
|
|
39
|
+
* infrastructure contract version be recorded.
|
|
40
|
+
*/
|
|
41
|
+
complete(): boolean;
|
|
42
|
+
}
|
|
43
|
+
/** Start a converge for the install `plan` rolls. */
|
|
44
|
+
export declare function startConverge(plan: AppRollPlan, ownerEmail: string, deps: ConvergeDeps): ConvergeSession;
|
|
45
|
+
//# sourceMappingURL=converge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converge.d.ts","sourceRoot":"","sources":["../../src/upgrade/converge.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAsB,MAAM,eAAe,CAAC;AACnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,sBAAsB,CAAC,EACtD,aAAa,EAAE,MAAM,GACpB,OAAO,CAET;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,2EAA2E;IAC3E,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B;;;OAGG;IACH,QAAQ,IAAI,OAAO,CAAC;CACrB;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,YAAY,GACjB,eAAe,CAmQjB"}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
/**
|
|
3
|
+
* The converge half of an upgrade (epic #696): everything that changes IAM,
|
|
4
|
+
* service accounts, secrets or other cloud resources so the install matches
|
|
5
|
+
* what the release's stacks declare — the gateway's run SA and the
|
|
6
|
+
* CLI-generated runtime secrets, the stack's IAM/CDN/firewall invariants,
|
|
7
|
+
* MCP access through IAP, the gateway's and public_role's database logins,
|
|
8
|
+
* the operator-access sync job, and dropping bindings nothing reads any more.
|
|
9
|
+
*
|
|
10
|
+
* It needs the rights of whoever provisioned the install, so only
|
|
11
|
+
* `cms-provision upgrade` (the operator's own identity) runs it — never the
|
|
12
|
+
* in-cloud upgrader job, which only app-rolls and refuses while
|
|
13
|
+
* {@link needsConverge} says the install is behind.
|
|
14
|
+
*
|
|
15
|
+
* The keyless-provisioner step (#696, provisioner-identity.ts) is converge
|
|
16
|
+
* too; it needs the operator's local install dir, so the CLI injects it as
|
|
17
|
+
* {@link ConvergeDeps.provisionerIdentity}.
|
|
18
|
+
*
|
|
19
|
+
* Some steps must sit between app-roll steps (a role migration 0248 creates
|
|
20
|
+
* gets its password after migrations, before the gateway rolls onto it), so
|
|
21
|
+
* a converge is a {@link ConvergeSession}: a part before the app-roll, the
|
|
22
|
+
* {@link AppRollHooks} the app-roll calls in between, and a part after it.
|
|
23
|
+
*/
|
|
24
|
+
import { ensureGatewayRolePassword, findSqlInstance, planPublicRoleSwitch, } from "../gateway-credentials.js";
|
|
25
|
+
import { ensureMcpIapAccess } from "../mcp-iap.js";
|
|
26
|
+
import { ensureOperatorAccessSync, resolveOperatorAccessTarget } from "../operator-access.js";
|
|
27
|
+
import { ensureGatewayServiceAccount, ensureGeneratedSecrets, plainGeneratedSecretSeed, readSecretReplication, } from "../runtime-secrets.js";
|
|
28
|
+
import { selfCommand } from "../self-command.js";
|
|
29
|
+
import { MCP_ENV_VAR, OPERATOR_ACCESS_JOB_ENV_VAR } from "../stack-contract.js";
|
|
30
|
+
import { ensureStackInvariants, liveEnvHasInlinePassword, removeRetiredIamBindings, } from "../stack-converge.js";
|
|
31
|
+
/**
|
|
32
|
+
* Whether the install must converge before an app-roll to a release that
|
|
33
|
+
* expects infrastructure contract `targetVersion` (infra-contract.ts). An
|
|
34
|
+
* install with no recorded version has never completed a converge under
|
|
35
|
+
* this scheme and always needs one.
|
|
36
|
+
*/
|
|
37
|
+
export function needsConverge(install, targetVersion) {
|
|
38
|
+
return (install.infraContractVersion ?? 0) < targetVersion;
|
|
39
|
+
}
|
|
40
|
+
/** Start a converge for the install `plan` rolls. */
|
|
41
|
+
export function startConverge(plan, ownerEmail, deps) {
|
|
42
|
+
const { install } = plan;
|
|
43
|
+
const { reporter: r, run } = deps;
|
|
44
|
+
const runDeps = { run, ...(deps.sleep ? { sleep: deps.sleep } : {}) };
|
|
45
|
+
const service = (slug) => plan.services.find((s) => s.slug === slug);
|
|
46
|
+
const services = { admin: service("admin").serviceName, gateway: service("gateway").serviceName };
|
|
47
|
+
const target = {
|
|
48
|
+
provider: install.provider,
|
|
49
|
+
projectId: install.projectId,
|
|
50
|
+
region: install.region,
|
|
51
|
+
env: install.env,
|
|
52
|
+
services,
|
|
53
|
+
};
|
|
54
|
+
let incomplete = false;
|
|
55
|
+
// Env vars the rolls must leave as the services have them, because the
|
|
56
|
+
// thing they point at could not be set up.
|
|
57
|
+
const leaveUntouched = [];
|
|
58
|
+
let publicRole = null;
|
|
59
|
+
async function runtimeIdentities() {
|
|
60
|
+
// The gateway's own run SA and the CLI-generated secrets the env
|
|
61
|
+
// contract references. Created once, never overwritten; must exist
|
|
62
|
+
// before the invariants bind them and the rolls reference them.
|
|
63
|
+
const s = r.step("Ensuring the gateway service account + generated runtime secrets...");
|
|
64
|
+
const secretsTarget = { projectId: install.projectId, env: install.env };
|
|
65
|
+
const replication = await readSecretReplication(secretsTarget, runDeps);
|
|
66
|
+
const outcomes = [
|
|
67
|
+
await ensureGatewayServiceAccount(secretsTarget, runDeps),
|
|
68
|
+
...(replication.ok
|
|
69
|
+
? await ensureGeneratedSecrets({
|
|
70
|
+
...secretsTarget,
|
|
71
|
+
region: install.region,
|
|
72
|
+
replication: replication.replication,
|
|
73
|
+
seed: plainGeneratedSecretSeed(service("admin").liveEnv),
|
|
74
|
+
}, runDeps)
|
|
75
|
+
: [{ id: "secret replication", status: "failed", error: replication.error }]),
|
|
76
|
+
];
|
|
77
|
+
const failed = outcomes.filter((o) => o.status === "failed");
|
|
78
|
+
if (failed.length > 0) {
|
|
79
|
+
s.failed("Runtime identities/secrets could not be ensured. Aborting upgrade.");
|
|
80
|
+
for (const o of failed)
|
|
81
|
+
r.error(` FAILED: ${o.id}\n ${o.error ?? ""}`);
|
|
82
|
+
r.warn("No traffic was shifted and no migrations ran. Fix the above and re-run.");
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
s.done("Gateway service account + runtime secrets ok");
|
|
86
|
+
for (const o of outcomes.filter((o) => o.status === "applied")) {
|
|
87
|
+
r.info(` created: ${o.id}${o.detail ? ` (${o.detail})` : ""}`);
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
async function stackInvariants() {
|
|
92
|
+
// IAM bindings + CDN policy added to the stacks after this install was
|
|
93
|
+
// provisioned (stack-contract.ts), and GCP's SSH/RDP-from-anywhere
|
|
94
|
+
// firewall rules removed (default-firewall.ts). Additive + idempotent.
|
|
95
|
+
const s = r.step("Ensuring the IAM bindings + CDN settings the stack declares, removing the default network's pre-populated firewall rules...");
|
|
96
|
+
const report = await ensureStackInvariants(target, runDeps);
|
|
97
|
+
const applied = report.outcomes.filter((o) => o.status === "applied");
|
|
98
|
+
const failed = report.outcomes.filter((o) => o.status === "failed");
|
|
99
|
+
if (report.mustAbort)
|
|
100
|
+
s.failed("Stack invariants could not be ensured. Aborting upgrade.");
|
|
101
|
+
else {
|
|
102
|
+
s.done(`Stack invariants ok (${report.outcomes.length - failed.length}/${report.outcomes.length}, ${applied.length} applied)`);
|
|
103
|
+
}
|
|
104
|
+
for (const o of applied)
|
|
105
|
+
r.info(` applied: ${o.id} (${o.why})`);
|
|
106
|
+
for (const o of failed) {
|
|
107
|
+
const line = ` ${o.onFailure === "abort" ? "FAILED" : "not applied"}: ${o.id} — ${o.why}\n ${o.error ?? ""}`;
|
|
108
|
+
if (o.onFailure === "abort")
|
|
109
|
+
r.error(line);
|
|
110
|
+
else
|
|
111
|
+
r.warn(line);
|
|
112
|
+
}
|
|
113
|
+
if (failed.length > 0)
|
|
114
|
+
incomplete = true;
|
|
115
|
+
if (report.mustAbort) {
|
|
116
|
+
r.warn("No traffic was shifted and no migrations ran. Fix the bindings above and re-run.");
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
async function mcpAccess() {
|
|
122
|
+
// Issue #37 — the MCP service account + its IAP/token-creator bindings.
|
|
123
|
+
// Also what the deep health check signs its IAP credential as. A failure
|
|
124
|
+
// costs MCP access, so it warns and the admin keeps its current value.
|
|
125
|
+
const s = r.step("Ensuring MCP access through IAP...");
|
|
126
|
+
// Signing as the MCP account goes through the IAM Credentials API, which
|
|
127
|
+
// installs from before #678 may not have enabled.
|
|
128
|
+
const api = await run([
|
|
129
|
+
"services",
|
|
130
|
+
"enable",
|
|
131
|
+
"iamcredentials.googleapis.com",
|
|
132
|
+
`--project=${install.projectId}`,
|
|
133
|
+
]);
|
|
134
|
+
const resource = api.ok ? await adminIapResource() : null;
|
|
135
|
+
const mcp = !api.ok
|
|
136
|
+
? {
|
|
137
|
+
ok: false,
|
|
138
|
+
error: `enable the IAM Credentials API (iamcredentials.googleapis.com): ${api.stderr.trim()}`,
|
|
139
|
+
}
|
|
140
|
+
: resource
|
|
141
|
+
? await ensureMcpIapAccess({ projectId: install.projectId, resource, ...runDeps })
|
|
142
|
+
: { ok: false, error: "admin IAP backend service not found" };
|
|
143
|
+
if (mcp.ok) {
|
|
144
|
+
s.done(`MCP access ready (${mcp.serviceAccount}; ${mcp.operators.length} operator(s))`);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
s.warned(`MCP access not configured: ${mcp.error}`);
|
|
148
|
+
r.warn("The upgrade continues; external MCP clients stay blocked by IAP until this succeeds.");
|
|
149
|
+
incomplete = true;
|
|
150
|
+
leaveUntouched.push(MCP_ENV_VAR);
|
|
151
|
+
}
|
|
152
|
+
/** The admin's IAP resource: the service on gcp-firebase, the LB backend on gcp. */
|
|
153
|
+
async function adminIapResource() {
|
|
154
|
+
if (install.provider === "gcp-firebase") {
|
|
155
|
+
return { kind: "cloud-run", service: services.admin, region: install.region };
|
|
156
|
+
}
|
|
157
|
+
const res = await run([
|
|
158
|
+
"compute",
|
|
159
|
+
"backend-services",
|
|
160
|
+
"list",
|
|
161
|
+
"--global",
|
|
162
|
+
`--project=${install.projectId}`,
|
|
163
|
+
`--filter=name~^caelo-${install.env}-admin-backend`,
|
|
164
|
+
"--format=value(name)",
|
|
165
|
+
]);
|
|
166
|
+
const name = res.ok ? res.stdout.trim().split("\n")[0]?.trim() : "";
|
|
167
|
+
return name ? { kind: "backend-services", service: name } : null;
|
|
168
|
+
}
|
|
169
|
+
async function databaseLogins() {
|
|
170
|
+
// #613 — migration 0248 creates gateway_role without a password; it gets
|
|
171
|
+
// its secret's value before the gateway rolls onto it. public_role
|
|
172
|
+
// moves onto its own password right before the gateway's roll.
|
|
173
|
+
const s = r.step("Ensuring the gateway's database login (gateway_role)...");
|
|
174
|
+
const sqlInstance = await findSqlInstance(install, { run });
|
|
175
|
+
if (!sqlInstance) {
|
|
176
|
+
s.failed("Could not find the Cloud SQL instance. Aborting upgrade.");
|
|
177
|
+
r.warn("Migrations ran; no traffic was shifted. Re-run upgrade once the instance is found.");
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
const roleTarget = { projectId: install.projectId, env: install.env, sqlInstance };
|
|
181
|
+
const roleDeps = { ...runDeps, ...(deps.http ? { http: deps.http } : {}) };
|
|
182
|
+
const gatewayRole = await ensureGatewayRolePassword(roleTarget, roleDeps);
|
|
183
|
+
if (gatewayRole.status === "failed") {
|
|
184
|
+
s.failed("gateway_role could not be given its password. Aborting upgrade.");
|
|
185
|
+
r.error(` ${gatewayRole.error ?? ""}`);
|
|
186
|
+
r.warn("Migrations ran (0248 creates gateway_role); no traffic was shifted. Fix the above and re-run upgrade.");
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
s.done("gateway_role ready");
|
|
190
|
+
publicRole = planPublicRoleSwitch(roleTarget, service("gateway").liveEnv, roleDeps);
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
async function operatorAccess() {
|
|
194
|
+
// The job that keeps IAP in step with the user list (operator-access.ts).
|
|
195
|
+
// After migrations: its database user gets the role migration 0239
|
|
196
|
+
// creates. A failure only costs IAP following the user list, so it warns.
|
|
197
|
+
const s = r.step("Ensuring the operator-access sync job...");
|
|
198
|
+
const resolved = await resolveOperatorAccessTarget({
|
|
199
|
+
provider: install.provider,
|
|
200
|
+
projectId: install.projectId,
|
|
201
|
+
region: install.region,
|
|
202
|
+
env: install.env,
|
|
203
|
+
ownerEmail,
|
|
204
|
+
imageRef: service("admin").imageRef,
|
|
205
|
+
}, { run });
|
|
206
|
+
const oa = resolved.ok
|
|
207
|
+
? await ensureOperatorAccessSync(resolved.target, runDeps)
|
|
208
|
+
: { ok: false, done: [], error: resolved.error };
|
|
209
|
+
for (const step of oa.done)
|
|
210
|
+
r.info(` ${step}`);
|
|
211
|
+
if (oa.ok) {
|
|
212
|
+
s.done("Operator-access sync job ready (IAP follows the user list)");
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
s.warned(`Operator-access sync job not set up: ${oa.error}`);
|
|
216
|
+
r.warn("The upgrade continues; user changes will report that Google IAP could not be updated until this succeeds. Re-run upgrade once the cause is fixed.");
|
|
217
|
+
incomplete = true;
|
|
218
|
+
leaveUntouched.push(OPERATOR_ACCESS_JOB_ENV_VAR);
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
async beforeAppRoll() {
|
|
222
|
+
if (deps.provisionerIdentity && !(await deps.provisionerIdentity()))
|
|
223
|
+
return false;
|
|
224
|
+
if (!(await runtimeIdentities()))
|
|
225
|
+
return false;
|
|
226
|
+
if (!(await stackInvariants()))
|
|
227
|
+
return false;
|
|
228
|
+
await mcpAccess();
|
|
229
|
+
return true;
|
|
230
|
+
},
|
|
231
|
+
hooks: {
|
|
232
|
+
async afterMigrations() {
|
|
233
|
+
if (!(await databaseLogins()))
|
|
234
|
+
return { ok: false };
|
|
235
|
+
await operatorAccess();
|
|
236
|
+
return { ok: true, leaveUntouched: [...leaveUntouched] };
|
|
237
|
+
},
|
|
238
|
+
async beforeRoll(slug) {
|
|
239
|
+
if (slug !== "gateway" || !publicRole)
|
|
240
|
+
return { ok: true };
|
|
241
|
+
const moved = await publicRole.beforeGatewayRoll();
|
|
242
|
+
return moved.status === "failed"
|
|
243
|
+
? {
|
|
244
|
+
ok: false,
|
|
245
|
+
error: `public_role could not be moved onto its own password: ${moved.error ?? ""}`,
|
|
246
|
+
}
|
|
247
|
+
: { ok: true };
|
|
248
|
+
},
|
|
249
|
+
async afterRollback(slug) {
|
|
250
|
+
// The prior gateway revision reads public_role's old password.
|
|
251
|
+
if (slug !== "gateway" || !publicRole)
|
|
252
|
+
return;
|
|
253
|
+
const outcome = await publicRole.afterGatewayRollFailed();
|
|
254
|
+
if (outcome.startsWith("could NOT"))
|
|
255
|
+
r.error(` ${outcome}`);
|
|
256
|
+
else
|
|
257
|
+
r.info(` ${outcome}`);
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
async afterAppRoll() {
|
|
261
|
+
// #613 — with both services on their new revisions, drop the bindings
|
|
262
|
+
// nothing reads through any more (above all the gateway SA's access to
|
|
263
|
+
// admin_role's password). Loud on failure.
|
|
264
|
+
const retired = await removeRetiredIamBindings(target, runDeps);
|
|
265
|
+
for (const o of retired) {
|
|
266
|
+
if (o.status === "removed")
|
|
267
|
+
r.info(` removed: ${o.id} (${o.why})`);
|
|
268
|
+
if (o.status === "failed") {
|
|
269
|
+
incomplete = true;
|
|
270
|
+
r.error(` NOT removed: ${o.id} — ${o.why}\n ${o.error ?? ""}\n Re-run upgrade with an account that may change IAM, or remove the binding by hand.`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (publicRole?.moves) {
|
|
274
|
+
// Until this upgrade the gateway held admin_role's password; anyone
|
|
275
|
+
// who ever compromised it could have kept a copy.
|
|
276
|
+
r.warn(`The gateway no longer holds admin_role's password, but it did until now. Rotate it: ${selfCommand("rotate-secret", "postgres-password", "--install", install.domain)}`);
|
|
277
|
+
}
|
|
278
|
+
if (plan.services.some((s) => liveEnvHasInlinePassword(s.liveEnv))) {
|
|
279
|
+
// The services moved their database password to Secret Manager, but
|
|
280
|
+
// every earlier revision still shows it in its env.
|
|
281
|
+
r.warn(`The database password was stored in plain env vars before this upgrade and stays readable in the services' old revisions. Rotate it now: ${selfCommand("rotate-secret", "postgres-password", "--install", install.domain)}`);
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
complete: () => !incomplete,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=converge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converge.js","sourceRoot":"","sources":["../../src/upgrade/converge.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,kBAAkB,EAAoB,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EAEtB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAI9B;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAsD,EACtD,aAAqB;IAErB,OAAO,CAAC,OAAO,CAAC,oBAAoB,IAAI,CAAC,CAAC,GAAG,aAAa,CAAC;AAC7D,CAAC;AAkCD,qDAAqD;AACrD,MAAM,UAAU,aAAa,CAC3B,IAAiB,EACjB,UAAkB,EAClB,IAAkB;IAElB,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAClC,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACtE,MAAM,OAAO,GAAG,CAAC,IAAc,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAa,CAAC;IAC3F,MAAM,QAAQ,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;IAClG,MAAM,MAAM,GAAG;QACb,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,QAAQ;KACT,CAAC;IACF,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,uEAAuE;IACvE,2CAA2C;IAC3C,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,IAAI,UAAU,GAAmD,IAAI,CAAC;IAEtE,KAAK,UAAU,iBAAiB;QAC9B,iEAAiE;QACjE,mEAAmE;QACnE,gEAAgE;QAChE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAC;QACxF,MAAM,aAAa,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;QACzE,MAAM,WAAW,GAAG,MAAM,qBAAqB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG;YACf,MAAM,2BAA2B,CAAC,aAAa,EAAE,OAAO,CAAC;YACzD,GAAG,CAAC,WAAW,CAAC,EAAE;gBAChB,CAAC,CAAC,MAAM,sBAAsB,CAC1B;oBACE,GAAG,aAAa;oBAChB,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,WAAW,EAAE,WAAW,CAAC,WAAW;oBACpC,IAAI,EAAE,wBAAwB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;iBACzD,EACD,OAAO,CACR;gBACH,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,oBAAoB,EAAE,MAAM,EAAE,QAAiB,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC;SACzF,CAAC;QACF,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;QAC7D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,CAAC,CAAC,MAAM,CAAC,oEAAoE,CAAC,CAAC;YAC/E,KAAK,MAAM,CAAC,IAAI,MAAM;gBAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC;YAC3E,CAAC,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;YAClF,OAAO,KAAK,CAAC;QACf,CAAC;QACD,CAAC,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;QACvD,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,EAAE,CAAC;YAC/D,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,UAAU,eAAe;QAC5B,uEAAuE;QACvE,mEAAmE;QACnE,uEAAuE;QACvE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CACd,6HAA6H,CAC9H,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;QACpE,IAAI,MAAM,CAAC,SAAS;YAAE,CAAC,CAAC,MAAM,CAAC,0DAA0D,CAAC,CAAC;aACtF,CAAC;YACJ,CAAC,CAAC,IAAI,CACJ,wBAAwB,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,WAAW,CACvH,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,OAAO;YAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QACjE,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YACjH,IAAI,CAAC,CAAC,SAAS,KAAK,OAAO;gBAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;;gBACtC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,UAAU,GAAG,IAAI,CAAC;QACzC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,CAAC,CAAC,IAAI,CAAC,kFAAkF,CAAC,CAAC;YAC3F,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,UAAU,SAAS;QACtB,wEAAwE;QACxE,yEAAyE;QACzE,uEAAuE;QACvE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QACvD,yEAAyE;QACzE,kDAAkD;QAClD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC;YACpB,UAAU;YACV,QAAQ;YACR,+BAA+B;YAC/B,aAAa,OAAO,CAAC,SAAS,EAAE;SACjC,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1D,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE;YACjB,CAAC,CAAC;gBACE,EAAE,EAAE,KAAc;gBAClB,KAAK,EAAE,mEAAmE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE;aAC9F;YACH,CAAC,CAAC,QAAQ;gBACR,CAAC,CAAC,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;gBAClF,CAAC,CAAC,EAAE,EAAE,EAAE,KAAc,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAC;QAC3E,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,CAAC,CAAC,IAAI,CAAC,qBAAqB,GAAG,CAAC,cAAc,KAAK,GAAG,CAAC,SAAS,CAAC,MAAM,eAAe,CAAC,CAAC;YACxF,OAAO;QACT,CAAC;QACD,CAAC,CAAC,MAAM,CAAC,8BAA8B,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QACpD,CAAC,CAAC,IAAI,CAAC,sFAAsF,CAAC,CAAC;QAC/F,UAAU,GAAG,IAAI,CAAC;QAClB,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAED,oFAAoF;IACpF,KAAK,UAAU,gBAAgB;QAC7B,IAAI,OAAO,CAAC,QAAQ,KAAK,cAAc,EAAE,CAAC;YACxC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;QAChF,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC;YACpB,SAAS;YACT,kBAAkB;YAClB,MAAM;YACN,UAAU;YACV,aAAa,OAAO,CAAC,SAAS,EAAE;YAChC,wBAAwB,OAAO,CAAC,GAAG,gBAAgB;YACnD,sBAAsB;SACvB,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,CAAC;IAED,KAAK,UAAU,cAAc;QAC3B,yEAAyE;QACzE,mEAAmE;QACnE,+DAA+D;QAC/D,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;QAC5E,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,CAAC,CAAC,MAAM,CAAC,0DAA0D,CAAC,CAAC;YACrE,CAAC,CAAC,IAAI,CAAC,oFAAoF,CAAC,CAAC;YAC7F,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,UAAU,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,CAAC;QACnF,MAAM,QAAQ,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAC3E,MAAM,WAAW,GAAG,MAAM,yBAAyB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC1E,IAAI,WAAW,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACpC,CAAC,CAAC,MAAM,CAAC,iEAAiE,CAAC,CAAC;YAC5E,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC;YACxC,CAAC,CAAC,IAAI,CACJ,uGAAuG,CACxG,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;QACD,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC7B,UAAU,GAAG,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,UAAU,cAAc;QAC3B,0EAA0E;QAC1E,mEAAmE;QACnE,0EAA0E;QAC1E,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,MAAM,2BAA2B,CAChD;YACE,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,UAAU;YACV,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ;SACpC,EACD,EAAE,GAAG,EAAE,CACR,CAAC;QACF,MAAM,EAAE,GAAG,QAAQ,CAAC,EAAE;YACpB,CAAC,CAAC,MAAM,wBAAwB,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;YAC1D,CAAC,CAAC,EAAE,EAAE,EAAE,KAAc,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC5D,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,IAAI;YAAE,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAChD,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YACV,CAAC,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QACD,CAAC,CAAC,MAAM,CAAC,wCAAwC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC,IAAI,CACJ,mJAAmJ,CACpJ,CAAC;QACF,UAAU,GAAG,IAAI,CAAC;QAClB,cAAc,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACnD,CAAC;IAED,OAAO;QACL,KAAK,CAAC,aAAa;YACjB,IAAI,IAAI,CAAC,mBAAmB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAAE,OAAO,KAAK,CAAC;YAClF,IAAI,CAAC,CAAC,MAAM,iBAAiB,EAAE,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC/C,IAAI,CAAC,CAAC,MAAM,eAAe,EAAE,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC7C,MAAM,SAAS,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,KAAK,EAAE;YACL,KAAK,CAAC,eAAe;gBACnB,IAAI,CAAC,CAAC,MAAM,cAAc,EAAE,CAAC;oBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;gBACpD,MAAM,cAAc,EAAE,CAAC;gBACvB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,GAAG,cAAc,CAAC,EAAE,CAAC;YAC3D,CAAC;YACD,KAAK,CAAC,UAAU,CAAC,IAAI;gBACnB,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,UAAU;oBAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;gBAC3D,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,iBAAiB,EAAE,CAAC;gBACnD,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;oBAC9B,CAAC,CAAC;wBACE,EAAE,EAAE,KAAK;wBACT,KAAK,EAAE,yDAAyD,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;qBACpF;oBACH,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;YACnB,CAAC;YACD,KAAK,CAAC,aAAa,CAAC,IAAI;gBACtB,+DAA+D;gBAC/D,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,UAAU;oBAAE,OAAO;gBAC9C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,sBAAsB,EAAE,CAAC;gBAC1D,IAAI,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC;oBAAE,CAAC,CAAC,KAAK,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;;oBACxD,CAAC,CAAC,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;YAC9B,CAAC;SACF;QAED,KAAK,CAAC,YAAY;YAChB,sEAAsE;YACtE,uEAAuE;YACvE,2CAA2C;YAC3C,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAChE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;oBAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;gBACpE,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC1B,UAAU,GAAG,IAAI,CAAC;oBAClB,CAAC,CAAC,KAAK,CACL,kBAAkB,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,KAAK,IAAI,EAAE,0FAA0F,CAClJ,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,IAAI,UAAU,EAAE,KAAK,EAAE,CAAC;gBACtB,oEAAoE;gBACpE,kDAAkD;gBAClD,CAAC,CAAC,IAAI,CACJ,uFAAuF,WAAW,CAAC,eAAe,EAAE,mBAAmB,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CACxK,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;gBACnE,oEAAoE;gBACpE,oDAAoD;gBACpD,CAAC,CAAC,IAAI,CACJ,4IAA4I,WAAW,CAAC,eAAe,EAAE,mBAAmB,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAC7N,CAAC;YACJ,CAAC;QACH,CAAC;QAED,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,UAAU;KAC5B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only lookups of a deployed GCP install, plus the one traffic move an
|
|
3
|
+
* app-roll needs to undo itself. Every function takes the {@link GcloudRunner}
|
|
4
|
+
* it runs through, so the upgrade phases can be driven by a fake in tests and
|
|
5
|
+
* by a different identity in the in-cloud upgrader job (epic #696).
|
|
6
|
+
*/
|
|
7
|
+
import type { GcloudRunner } from "../gcloud-retry.js";
|
|
8
|
+
/**
|
|
9
|
+
* Pulumi auto-naming appends a random 7-char suffix to every resource
|
|
10
|
+
* (e.g. `caelo-production-admin-3efcfea`), so lifecycle commands find the
|
|
11
|
+
* deployed name by prefix. Returns the first match, or null when the listing
|
|
12
|
+
* fails or finds nothing.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveGcpResourceName(run: GcloudRunner, kind: "run-service" | "sql-instance", prefix: string, projectId: string, region?: string): Promise<string | null>;
|
|
15
|
+
/** The deployed service as `gcloud run services describe --format=json` returns it. */
|
|
16
|
+
export declare function describeServiceJson(run: GcloudRunner, projectId: string, region: string, serviceName: string): Promise<string | null>;
|
|
17
|
+
/** The revision serving traffic now, so a failed roll can go back to it. */
|
|
18
|
+
export declare function findCurrentRevision(run: GcloudRunner, projectId: string, region: string, serviceName: string): Promise<string | null>;
|
|
19
|
+
/** The service's own `run.app` URL. */
|
|
20
|
+
export declare function findServiceUrl(run: GcloudRunner, projectId: string, region: string, serviceName: string): Promise<string | null>;
|
|
21
|
+
/** Pin all of a service's traffic to `revision`. */
|
|
22
|
+
export declare function pinTraffic(run: GcloudRunner, projectId: string, region: string, serviceName: string, revision: string): Promise<boolean>;
|
|
23
|
+
//# sourceMappingURL=gcp-lookup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcp-lookup.d.ts","sourceRoot":"","sources":["../../src/upgrade/gcp-lookup.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAAG,cAAc,EACpC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiCxB;AAsBD,uFAAuF;AACvF,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB;AAED,4EAA4E;AAC5E,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMxB;AAED,uCAAuC;AACvC,wBAAsB,cAAc,CAClC,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxB;AAED,oDAAoD;AACpD,wBAAsB,UAAU,CAC9B,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAelB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Pulumi auto-naming appends a random 7-char suffix to every resource
|
|
4
|
+
* (e.g. `caelo-production-admin-3efcfea`), so lifecycle commands find the
|
|
5
|
+
* deployed name by prefix. Returns the first match, or null when the listing
|
|
6
|
+
* fails or finds nothing.
|
|
7
|
+
*/
|
|
8
|
+
export async function resolveGcpResourceName(run, kind, prefix, projectId, region) {
|
|
9
|
+
const args = kind === "run-service"
|
|
10
|
+
? [
|
|
11
|
+
"run",
|
|
12
|
+
"services",
|
|
13
|
+
"list",
|
|
14
|
+
"--region",
|
|
15
|
+
requiredRegion(region),
|
|
16
|
+
"--project",
|
|
17
|
+
projectId,
|
|
18
|
+
"--filter",
|
|
19
|
+
`metadata.name~^${prefix}`,
|
|
20
|
+
"--format=value(metadata.name)",
|
|
21
|
+
]
|
|
22
|
+
: [
|
|
23
|
+
"sql",
|
|
24
|
+
"instances",
|
|
25
|
+
"list",
|
|
26
|
+
"--project",
|
|
27
|
+
projectId,
|
|
28
|
+
"--filter",
|
|
29
|
+
`name~^${prefix}`,
|
|
30
|
+
"--format=value(name)",
|
|
31
|
+
];
|
|
32
|
+
const r = await run(args);
|
|
33
|
+
if (!r.ok)
|
|
34
|
+
return null;
|
|
35
|
+
return (r.stdout
|
|
36
|
+
.split("\n")
|
|
37
|
+
.map((s) => s.trim())
|
|
38
|
+
.find((s) => s.length > 0) ?? null);
|
|
39
|
+
}
|
|
40
|
+
/** A Cloud Run lookup is regional; there is no default region to guess. */
|
|
41
|
+
function requiredRegion(region) {
|
|
42
|
+
if (!region)
|
|
43
|
+
throw new Error("a Cloud Run lookup needs the install region (install.json)");
|
|
44
|
+
return region;
|
|
45
|
+
}
|
|
46
|
+
function describeArgs(serviceName, region, projectId, format) {
|
|
47
|
+
return [
|
|
48
|
+
"run",
|
|
49
|
+
"services",
|
|
50
|
+
"describe",
|
|
51
|
+
serviceName,
|
|
52
|
+
"--region",
|
|
53
|
+
region,
|
|
54
|
+
"--project",
|
|
55
|
+
projectId,
|
|
56
|
+
`--format=${format}`,
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
/** The deployed service as `gcloud run services describe --format=json` returns it. */
|
|
60
|
+
export async function describeServiceJson(run, projectId, region, serviceName) {
|
|
61
|
+
const r = await run(describeArgs(serviceName, region, projectId, "json"));
|
|
62
|
+
return r.ok ? r.stdout : null;
|
|
63
|
+
}
|
|
64
|
+
/** The revision serving traffic now, so a failed roll can go back to it. */
|
|
65
|
+
export async function findCurrentRevision(run, projectId, region, serviceName) {
|
|
66
|
+
const r = await run(describeArgs(serviceName, region, projectId, "value(status.traffic[0].revisionName)"));
|
|
67
|
+
if (!r.ok)
|
|
68
|
+
return null;
|
|
69
|
+
return r.stdout.trim().split("\n")[0]?.trim() || null;
|
|
70
|
+
}
|
|
71
|
+
/** The service's own `run.app` URL. */
|
|
72
|
+
export async function findServiceUrl(run, projectId, region, serviceName) {
|
|
73
|
+
const r = await run(describeArgs(serviceName, region, projectId, "value(status.url)"));
|
|
74
|
+
if (!r.ok)
|
|
75
|
+
return null;
|
|
76
|
+
return r.stdout.trim() || null;
|
|
77
|
+
}
|
|
78
|
+
/** Pin all of a service's traffic to `revision`. */
|
|
79
|
+
export async function pinTraffic(run, projectId, region, serviceName, revision) {
|
|
80
|
+
const r = await run([
|
|
81
|
+
"run",
|
|
82
|
+
"services",
|
|
83
|
+
"update-traffic",
|
|
84
|
+
serviceName,
|
|
85
|
+
"--region",
|
|
86
|
+
region,
|
|
87
|
+
"--project",
|
|
88
|
+
projectId,
|
|
89
|
+
"--to-revisions",
|
|
90
|
+
`${revision}=100`,
|
|
91
|
+
"--quiet",
|
|
92
|
+
]);
|
|
93
|
+
return r.ok;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=gcp-lookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcp-lookup.js","sourceRoot":"","sources":["../../src/upgrade/gcp-lookup.ts"],"names":[],"mappings":"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"}
|