@caelo-cms/provisioning 0.3.17 → 0.3.19
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/install-state.d.ts +7 -0
- package/dist/install-state.d.ts.map +1 -1
- package/dist/install-state.js +28 -1
- package/dist/install-state.js.map +1 -1
- package/dist/wizard.d.ts.map +1 -1
- package/dist/wizard.js +92 -40
- package/dist/wizard.js.map +1 -1
- package/package.json +2 -2
- package/stacks/gcp-firebase/index.ts +44 -11
package/dist/install-state.d.ts
CHANGED
|
@@ -33,6 +33,13 @@ export declare function ensureInstallDir(installId: string): {
|
|
|
33
33
|
secretsDir: string;
|
|
34
34
|
stateDir: string;
|
|
35
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Scan `~/.caelo-*` for every install with a readable `install.json`.
|
|
38
|
+
* Used by the wizard to offer "resume X" before prompting for the
|
|
39
|
+
* domain / owner / project again. Silently skips dirs that fail to
|
|
40
|
+
* parse — partial / orphaned dirs don't block the new-install flow.
|
|
41
|
+
*/
|
|
42
|
+
export declare function listInstalls(): InstallMetadata[];
|
|
36
43
|
export declare function readMetadata(installId: string): InstallMetadata | null;
|
|
37
44
|
export declare function writeMetadata(installId: string, meta: InstallMetadata): void;
|
|
38
45
|
export declare function readProgress(installId: string): ProgressCheckpoint;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-state.d.ts","sourceRoot":"","sources":["../src/install-state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"install-state.d.ts","sourceRoot":"","sources":["../src/install-state.ts"],"names":[],"mappings":"AAgCA,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,KAAK,GAAG,cAAc,GAAG,KAAK,GAAG,OAAO,CAAC;AAEhF,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,iEAAiE;IACjE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAOrF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAeA;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,eAAe,EAAE,CAiBhD;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAItE;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAG5E;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,CAMlE;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB,GAAG,IAAI,CAOrF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAKzF;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAG/E;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMzE;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAIhF"}
|
package/dist/install-state.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* The CLAUDE.md §11.C contract: end-users never reach into this directory
|
|
18
18
|
* by hand. The wizard + lifecycle commands wrap every read + write.
|
|
19
19
|
*/
|
|
20
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
20
|
+
import { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, } from "node:fs";
|
|
21
21
|
import { homedir } from "node:os";
|
|
22
22
|
import { join } from "node:path";
|
|
23
23
|
const ROOT_PREFIX = ".caelo-";
|
|
@@ -57,6 +57,33 @@ export function ensureInstallDir(installId) {
|
|
|
57
57
|
chmodSync(stateDir, 0o700);
|
|
58
58
|
return { root, secretsDir, stateDir };
|
|
59
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Scan `~/.caelo-*` for every install with a readable `install.json`.
|
|
62
|
+
* Used by the wizard to offer "resume X" before prompting for the
|
|
63
|
+
* domain / owner / project again. Silently skips dirs that fail to
|
|
64
|
+
* parse — partial / orphaned dirs don't block the new-install flow.
|
|
65
|
+
*/
|
|
66
|
+
export function listInstalls() {
|
|
67
|
+
const home = homedir();
|
|
68
|
+
let entries;
|
|
69
|
+
try {
|
|
70
|
+
entries = readdirSync(home);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
const out = [];
|
|
76
|
+
for (const entry of entries) {
|
|
77
|
+
if (!entry.startsWith(ROOT_PREFIX))
|
|
78
|
+
continue;
|
|
79
|
+
const installId = entry.slice(ROOT_PREFIX.length);
|
|
80
|
+
const meta = readMetadata(installId);
|
|
81
|
+
if (meta)
|
|
82
|
+
out.push(meta);
|
|
83
|
+
}
|
|
84
|
+
out.sort((a, b) => (a.createdAt < b.createdAt ? 1 : -1));
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
60
87
|
export function readMetadata(installId) {
|
|
61
88
|
const path = join(installRoot(installId), "install.json");
|
|
62
89
|
if (!existsSync(path))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-state.js","sourceRoot":"","sources":["../src/install-state.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"install-state.js","sourceRoot":"","sources":["../src/install-state.ts"],"names":[],"mappings":"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"}
|
package/dist/wizard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAmD,OAAO,EAAQ,MAAM,gBAAgB,CAAC;AAEhG,OAAO,
|
|
1
|
+
{"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAmD,OAAO,EAAQ,MAAM,gBAAgB,CAAC;AAEhG,OAAO,EAKL,KAAK,QAAQ,EAGd,MAAM,oBAAoB,CAAC;AAI5B,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,SAAS,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwGvE;AA8GD,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
package/dist/wizard.js
CHANGED
|
@@ -19,50 +19,72 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import { cancel, confirm, intro, isCancel, outro, select, spinner, text } from "@clack/prompts";
|
|
21
21
|
import { bold, cyan, dim } from "kleur/colors";
|
|
22
|
-
import { deriveInstallId, ensureInstallDir, readMetadata, writeMetadata, } from "./install-state.js";
|
|
22
|
+
import { deriveInstallId, ensureInstallDir, listInstalls, readMetadata, writeMetadata, } from "./install-state.js";
|
|
23
23
|
import { runGcpWizard } from "./wizards/gcp.js";
|
|
24
24
|
import { runGcpFirebaseWizard } from "./wizards/gcp-firebase.js";
|
|
25
25
|
export async function runWizard(opts = {}) {
|
|
26
26
|
intro(bold(cyan("Caelo CMS provisioner")) + dim(" — one-command deploy"));
|
|
27
|
-
// 1.
|
|
28
|
-
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const existing =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
cancel(`Aborted. Run with a different domain or remove ~/.caelo-${installId}/ first.`);
|
|
53
|
-
process.exit(0);
|
|
54
|
-
}
|
|
27
|
+
// 1. Resume-existing-install fast path. Before prompting for anything,
|
|
28
|
+
// scan ~/.caelo-* for installs and offer them as "resume X" options.
|
|
29
|
+
// Picking an existing install carries domain + owner + projectId
|
|
30
|
+
// over and skips re-prompting; "new install" falls through to the
|
|
31
|
+
// fresh-flow below.
|
|
32
|
+
//
|
|
33
|
+
// v0.3.18 — previously the wizard re-asked for provider + domain +
|
|
34
|
+
// owner-email + project EVERY re-run. With this fast path, a
|
|
35
|
+
// re-run is a single Enter to "resume <id>".
|
|
36
|
+
let provider;
|
|
37
|
+
let domain;
|
|
38
|
+
let ownerEmail;
|
|
39
|
+
let projectIdHint;
|
|
40
|
+
let installId;
|
|
41
|
+
const existing = opts.nonInteractive ? [] : listInstalls();
|
|
42
|
+
const resumeChoice = existing.length > 0 && !opts.provider && !opts.domain && !opts.ownerEmail
|
|
43
|
+
? await pickInstallToResume(existing)
|
|
44
|
+
: null;
|
|
45
|
+
if (resumeChoice) {
|
|
46
|
+
provider = resumeChoice.provider;
|
|
47
|
+
domain = resumeChoice.domain;
|
|
48
|
+
ownerEmail = resumeChoice.ownerEmail;
|
|
49
|
+
projectIdHint = resumeChoice.projectId;
|
|
50
|
+
installId = resumeChoice.installId;
|
|
51
|
+
ensureInstallDir(installId);
|
|
55
52
|
}
|
|
56
53
|
else {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
provider = opts.provider ?? (await pickProvider());
|
|
55
|
+
domain = opts.domain ?? (await promptDomain());
|
|
56
|
+
ownerEmail = opts.ownerEmail ?? (await promptOwnerEmail());
|
|
57
|
+
projectIdHint = opts.projectId ?? null;
|
|
58
|
+
installId = deriveInstallId(provider, projectIdHint ?? domain);
|
|
59
|
+
ensureInstallDir(installId);
|
|
60
|
+
// If the user picked "new install" but the derived id collides with
|
|
61
|
+
// an existing one (e.g. retyped the same domain), confirm resume.
|
|
62
|
+
const existingForId = readMetadata(installId);
|
|
63
|
+
if (existingForId && !opts.nonInteractive) {
|
|
64
|
+
const resume = await confirm({
|
|
65
|
+
message: `Existing install '${installId}' detected (created ${dim(existingForId.createdAt)}). Resume?`,
|
|
66
|
+
initialValue: true,
|
|
67
|
+
});
|
|
68
|
+
if (isCancel(resume)) {
|
|
69
|
+
cancel("Cancelled.");
|
|
70
|
+
process.exit(0);
|
|
71
|
+
}
|
|
72
|
+
if (!resume) {
|
|
73
|
+
cancel(`Aborted. Run with a different domain or remove ~/.caelo-${installId}/ first.`);
|
|
74
|
+
process.exit(0);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
writeMetadata(installId, {
|
|
79
|
+
installId,
|
|
80
|
+
provider,
|
|
81
|
+
projectId: projectIdHint,
|
|
82
|
+
domain,
|
|
83
|
+
ownerEmail,
|
|
84
|
+
region: null,
|
|
85
|
+
createdAt: new Date().toISOString(),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
66
88
|
}
|
|
67
89
|
// 4. Delegate to the provider-specific wizard.
|
|
68
90
|
switch (provider) {
|
|
@@ -71,7 +93,7 @@ export async function runWizard(opts = {}) {
|
|
|
71
93
|
installId,
|
|
72
94
|
domain,
|
|
73
95
|
ownerEmail,
|
|
74
|
-
projectId:
|
|
96
|
+
projectId: projectIdHint,
|
|
75
97
|
nonInteractive: opts.nonInteractive ?? false,
|
|
76
98
|
});
|
|
77
99
|
break;
|
|
@@ -80,7 +102,7 @@ export async function runWizard(opts = {}) {
|
|
|
80
102
|
installId,
|
|
81
103
|
domain,
|
|
82
104
|
ownerEmail,
|
|
83
|
-
projectId:
|
|
105
|
+
projectId: projectIdHint,
|
|
84
106
|
nonInteractive: opts.nonInteractive ?? false,
|
|
85
107
|
});
|
|
86
108
|
break;
|
|
@@ -96,6 +118,36 @@ export async function runWizard(opts = {}) {
|
|
|
96
118
|
}
|
|
97
119
|
outro(bold("Done. Welcome to Caelo CMS."));
|
|
98
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Offer the operator the list of existing installs (newest first)
|
|
123
|
+
* plus a "start a new install" option. Returning `null` means the
|
|
124
|
+
* operator picked "new" and the wizard falls through to the fresh-
|
|
125
|
+
* inputs prompts. Returning an install means resume — every input
|
|
126
|
+
* (provider, domain, owner, project) carries over from metadata.
|
|
127
|
+
*/
|
|
128
|
+
async function pickInstallToResume(installs) {
|
|
129
|
+
const first = installs[0];
|
|
130
|
+
const choice = await select({
|
|
131
|
+
message: installs.length === 1 && first
|
|
132
|
+
? `Resume existing install '${first.installId}'?`
|
|
133
|
+
: "Resume an existing install or start a new one?",
|
|
134
|
+
options: [
|
|
135
|
+
...installs.map((m) => ({
|
|
136
|
+
value: m.installId,
|
|
137
|
+
label: `${bold(m.installId)} ${dim(`(${m.provider}, ${m.domain})`)}`,
|
|
138
|
+
hint: `created ${m.createdAt.slice(0, 10)}`,
|
|
139
|
+
})),
|
|
140
|
+
{ value: "__new__", label: "Start a new install", hint: "fresh inputs" },
|
|
141
|
+
],
|
|
142
|
+
});
|
|
143
|
+
if (isCancel(choice)) {
|
|
144
|
+
cancel("Cancelled.");
|
|
145
|
+
process.exit(0);
|
|
146
|
+
}
|
|
147
|
+
if (choice === "__new__")
|
|
148
|
+
return null;
|
|
149
|
+
return installs.find((m) => m.installId === choice) ?? null;
|
|
150
|
+
}
|
|
99
151
|
async function pickProvider() {
|
|
100
152
|
const choice = await select({
|
|
101
153
|
message: "Where do you want to deploy?",
|
package/dist/wizard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAChG,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACL,eAAe,EACf,gBAAgB,EAEhB,YAAY,EACZ,aAAa,GACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAejE,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAsB,EAAE;IACtD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,GAAG,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAE1E,
|
|
1
|
+
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caelo-cms/provisioning",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.19",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"description": "Pulumi-driven provisioning for Caelo CMS — `bunx @caelo-cms/provisioning --provider <self-hosted|gcp|aws|azure>` brings up a TLS-served install with Postgres + storage + secrets manager + the admin + the API gateway.",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"prepublishOnly": "tsc -b --force && tsc --project stacks/gcp/tsconfig.json && tsc --project stacks/gcp-firebase/tsconfig.json"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@caelo-cms/shared": "^0.3.
|
|
41
|
+
"@caelo-cms/shared": "^0.3.19",
|
|
42
42
|
"@clack/prompts": "1.3.0",
|
|
43
43
|
"@pulumi/aws": "^7",
|
|
44
44
|
"@pulumi/awsx": "^3",
|
|
@@ -546,22 +546,55 @@ const adminDomainMapping = provisionAdminDomain
|
|
|
546
546
|
// shipped. If your provider build is older than v8.x, run
|
|
547
547
|
// `gcloud beta run services update <admin-service> --iap` as a
|
|
548
548
|
// post-up step. The stack provisions the IAM bindings either way.
|
|
549
|
-
// v0.3.
|
|
550
|
-
//
|
|
551
|
-
//
|
|
549
|
+
// v0.3.19 — Native IAP on Cloud Run needs THREE bindings to
|
|
550
|
+
// actually serve requests. The first two go per allowlisted user;
|
|
551
|
+
// the third goes on the IAP service identity (one for the whole
|
|
552
|
+
// install).
|
|
552
553
|
//
|
|
553
|
-
// 1. `roles/iap.httpsResourceAccessor` on the IAP WEB layer
|
|
554
|
-
//
|
|
554
|
+
// 1. `roles/iap.httpsResourceAccessor` on the IAP WEB layer
|
|
555
|
+
// (per user) — passes IAP auth.
|
|
555
556
|
// Resource: `gcp.iap.WebCloudRunServiceIamMember`
|
|
556
557
|
// (matches `gcloud beta iap web add-iam-policy-binding`).
|
|
557
558
|
//
|
|
558
|
-
// 2. `roles/run.invoker` on the Cloud Run service v2 IAM
|
|
559
|
-
//
|
|
560
|
-
//
|
|
561
|
-
//
|
|
559
|
+
// 2. `roles/run.invoker` on the Cloud Run service v2 IAM
|
|
560
|
+
// (per user) — kept for "private mode" (user hits the
|
|
561
|
+
// *.run.app URL with an OAuth token directly, bypassing
|
|
562
|
+
// IAP). Not strictly required for IAP-forwarded traffic
|
|
563
|
+
// since IAP forwards as its own SA (#3) — but the user
|
|
564
|
+
// principal is harmless extra.
|
|
562
565
|
//
|
|
563
|
-
//
|
|
564
|
-
//
|
|
566
|
+
// 3. `roles/run.invoker` to the IAP SERVICE IDENTITY
|
|
567
|
+
// (`service-<projectnum>@gcp-sa-iap.iam.gserviceaccount.com`)
|
|
568
|
+
// on the Cloud Run service. THIS is the critical one for
|
|
569
|
+
// IAP-forwarded traffic: when IAP intercepts a request and
|
|
570
|
+
// forwards to Cloud Run, it does so AS the IAP SA, and
|
|
571
|
+
// Cloud Run gates the invocation on `run.invoker` for that
|
|
572
|
+
// principal. Without this, Cloud Run returns 403 "request
|
|
573
|
+
// was not authenticated" even after IAP allowed the user
|
|
574
|
+
// through.
|
|
575
|
+
//
|
|
576
|
+
// The IAP SA is materialized via `gcp.projects.ServiceIdentity`
|
|
577
|
+
// (works for iap.googleapis.com; the v0.3.10 attempt failed only
|
|
578
|
+
// for firebasehosting.googleapis.com).
|
|
579
|
+
|
|
580
|
+
const iapServiceIdentity = new gcp.projects.ServiceIdentity(
|
|
581
|
+
`${namePrefix}-iap-sa`,
|
|
582
|
+
{ project, service: "iap.googleapis.com" },
|
|
583
|
+
opts,
|
|
584
|
+
);
|
|
585
|
+
|
|
586
|
+
new gcp.cloudrunv2.ServiceIamMember(
|
|
587
|
+
`${namePrefix}-admin-iap-sa-invoker`,
|
|
588
|
+
{
|
|
589
|
+
project,
|
|
590
|
+
location: region,
|
|
591
|
+
name: adminSvc.name,
|
|
592
|
+
role: "roles/run.invoker",
|
|
593
|
+
member: pulumi.interpolate`serviceAccount:${iapServiceIdentity.email}`,
|
|
594
|
+
},
|
|
595
|
+
{ ...opts, dependsOn: [iapServiceIdentity] },
|
|
596
|
+
);
|
|
597
|
+
|
|
565
598
|
for (const principal of iapAllowlist) {
|
|
566
599
|
const slug = principal.replace(/[^a-z0-9]/gi, "-").slice(0, 40);
|
|
567
600
|
|