@caelo-cms/provisioning 0.3.16 → 0.3.18
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 +30 -12
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.18",
|
|
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.18",
|
|
42
42
|
"@clack/prompts": "1.3.0",
|
|
43
43
|
"@pulumi/aws": "^7",
|
|
44
44
|
"@pulumi/awsx": "^3",
|
|
@@ -546,21 +546,27 @@ 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
|
-
//
|
|
552
|
-
// IAP-web-cloud-run resource, then forwards the request to the
|
|
553
|
-
// Cloud Run service (which auto-trusts IAP-forwarded traffic via
|
|
554
|
-
// the native IAP integration on the cloudrunv2.Service spec).
|
|
549
|
+
// v0.3.17 — Native IAP on Cloud Run requires TWO bindings per
|
|
550
|
+
// allowlisted user (testing showed iap-only isn't enough — Cloud
|
|
551
|
+
// Run still rejects with 403 Forbidden after IAP forwards):
|
|
555
552
|
//
|
|
556
|
-
//
|
|
557
|
-
//
|
|
558
|
-
//
|
|
559
|
-
//
|
|
560
|
-
//
|
|
553
|
+
// 1. `roles/iap.httpsResourceAccessor` on the IAP WEB layer —
|
|
554
|
+
// lets the user pass IAP authentication.
|
|
555
|
+
// Resource: `gcp.iap.WebCloudRunServiceIamMember`
|
|
556
|
+
// (matches `gcloud beta iap web add-iam-policy-binding`).
|
|
557
|
+
//
|
|
558
|
+
// 2. `roles/run.invoker` on the Cloud Run service v2 IAM —
|
|
559
|
+
// lets Cloud Run accept the IAP-forwarded request. Without
|
|
560
|
+
// this, Cloud Run's own auth gate rejects with "Your client
|
|
561
|
+
// does not have permission".
|
|
562
|
+
//
|
|
563
|
+
// Both are needed for IAP-protected Cloud Run to actually serve
|
|
564
|
+
// requests to the operator.
|
|
561
565
|
for (const principal of iapAllowlist) {
|
|
566
|
+
const slug = principal.replace(/[^a-z0-9]/gi, "-").slice(0, 40);
|
|
567
|
+
|
|
562
568
|
new gcp.iap.WebCloudRunServiceIamMember(
|
|
563
|
-
`${namePrefix}-admin-iap-${
|
|
569
|
+
`${namePrefix}-admin-iap-${slug}`,
|
|
564
570
|
{
|
|
565
571
|
project,
|
|
566
572
|
location: region,
|
|
@@ -570,6 +576,18 @@ for (const principal of iapAllowlist) {
|
|
|
570
576
|
},
|
|
571
577
|
opts,
|
|
572
578
|
);
|
|
579
|
+
|
|
580
|
+
new gcp.cloudrunv2.ServiceIamMember(
|
|
581
|
+
`${namePrefix}-admin-invoker-${slug}`,
|
|
582
|
+
{
|
|
583
|
+
project,
|
|
584
|
+
location: region,
|
|
585
|
+
name: adminSvc.name,
|
|
586
|
+
role: "roles/run.invoker",
|
|
587
|
+
member: principal,
|
|
588
|
+
},
|
|
589
|
+
opts,
|
|
590
|
+
);
|
|
573
591
|
}
|
|
574
592
|
|
|
575
593
|
// =========================================================================
|