firebase-tools 13.6.0 → 13.7.0
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/lib/api.js +1 -1
- package/lib/apphosting/config.js +31 -0
- package/lib/apphosting/githubConnections.js +261 -0
- package/lib/{init/features/apphosting → apphosting}/index.js +21 -17
- package/lib/{init/features/apphosting → apphosting}/repo.js +9 -9
- package/lib/apphosting/secrets/dialogs.js +169 -0
- package/lib/apphosting/secrets/index.js +98 -0
- package/lib/commands/apphosting-backends-create.js +4 -2
- package/lib/commands/apphosting-backends-delete.js +1 -1
- package/lib/commands/apphosting-secrets-access.js +24 -0
- package/lib/commands/apphosting-secrets-describe.js +29 -0
- package/lib/commands/apphosting-secrets-grantaccess.js +45 -0
- package/lib/commands/apphosting-secrets-set.js +105 -0
- package/lib/commands/functions-secrets-access.js +2 -2
- package/lib/commands/functions-secrets-describe.js +14 -0
- package/lib/commands/functions-secrets-destroy.js +2 -2
- package/lib/commands/functions-secrets-get.js +3 -17
- package/lib/commands/functions-secrets-prune.js +2 -1
- package/lib/commands/functions-secrets-set.js +2 -2
- package/lib/commands/index.js +6 -0
- package/lib/deploy/functions/checkIam.js +3 -6
- package/lib/deploy/functions/containerCleaner.js +1 -11
- package/lib/deploy/functions/params.js +2 -2
- package/lib/deploy/functions/prepare.js +12 -3
- package/lib/deploy/functions/prompts.js +39 -7
- package/lib/deploy/functions/release/fabricator.js +5 -5
- package/lib/deploy/functions/release/index.js +17 -2
- package/lib/deploy/functions/release/planner.js +11 -3
- package/lib/deploy/functions/runtimes/index.js +6 -43
- package/lib/deploy/functions/runtimes/node/index.js +3 -2
- package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +15 -34
- package/lib/deploy/functions/runtimes/python/index.js +11 -7
- package/lib/deploy/functions/runtimes/supported.js +135 -0
- package/lib/deploy/functions/services/index.js +4 -0
- package/lib/emulator/controller.js +8 -1
- package/lib/emulator/functionsEmulator.js +2 -2
- package/lib/emulator/hub.js +5 -0
- package/lib/experiments.js +12 -0
- package/lib/extensions/emulator/specHelper.js +4 -3
- package/lib/frameworks/next/constants.js +2 -1
- package/lib/frameworks/next/index.js +22 -12
- package/lib/frameworks/next/utils.js +32 -3
- package/lib/functional.js +2 -2
- package/lib/functions/events/v2.js +7 -1
- package/lib/functions/secrets.js +40 -22
- package/lib/gcp/apphosting.js +15 -2
- package/lib/gcp/cloudbuild.js +7 -3
- package/lib/gcp/cloudfunctions.js +5 -5
- package/lib/gcp/cloudfunctionsv2.js +3 -3
- package/lib/gcp/cloudscheduler.js +2 -2
- package/lib/gcp/computeEngine.js +7 -0
- package/lib/gcp/devConnect.js +24 -11
- package/lib/gcp/iam.js +9 -1
- package/lib/gcp/secretManager.js +53 -13
- package/lib/gcp/serviceusage.js +21 -5
- package/lib/init/features/functions/python.js +4 -3
- package/lib/init/features/index.js +1 -1
- package/lib/utils.js +6 -6
- package/package.json +1 -1
- package/schema/firebase-config.json +12 -2
- /package/lib/{init/features/apphosting → apphosting}/constants.js +0 -0
|
@@ -4,6 +4,7 @@ exports.getRuntime = exports.DEFAULT_RUNTIME = exports.getFunctionProperties = e
|
|
|
4
4
|
const yaml = require("js-yaml");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const fs = require("fs-extra");
|
|
7
|
+
const supported = require("../../deploy/functions/runtimes/supported");
|
|
7
8
|
const error_1 = require("../../error");
|
|
8
9
|
const extensionsHelper_1 = require("../extensionsHelper");
|
|
9
10
|
const utils_1 = require("../utils");
|
|
@@ -77,7 +78,7 @@ function getFunctionProperties(resources) {
|
|
|
77
78
|
return resources.map((r) => r.properties);
|
|
78
79
|
}
|
|
79
80
|
exports.getFunctionProperties = getFunctionProperties;
|
|
80
|
-
exports.DEFAULT_RUNTIME = "
|
|
81
|
+
exports.DEFAULT_RUNTIME = supported.latest("nodejs");
|
|
81
82
|
function getRuntime(resources) {
|
|
82
83
|
if (resources.length === 0) {
|
|
83
84
|
return exports.DEFAULT_RUNTIME;
|
|
@@ -88,7 +89,7 @@ function getRuntime(resources) {
|
|
|
88
89
|
if (!runtime) {
|
|
89
90
|
return exports.DEFAULT_RUNTIME;
|
|
90
91
|
}
|
|
91
|
-
if (
|
|
92
|
+
if (!supported.runtimeIsLanguage(runtime, "nodejs")) {
|
|
92
93
|
invalidRuntimes.push(runtime);
|
|
93
94
|
return exports.DEFAULT_RUNTIME;
|
|
94
95
|
}
|
|
@@ -97,6 +98,6 @@ function getRuntime(resources) {
|
|
|
97
98
|
if (invalidRuntimes.length) {
|
|
98
99
|
throw new error_1.FirebaseError(`The following runtimes are not supported by the Emulator Suite: ${invalidRuntimes.join(", ")}. \n Only Node runtimes are supported.`);
|
|
99
100
|
}
|
|
100
|
-
return
|
|
101
|
+
return supported.latest("nodejs", runtimes);
|
|
101
102
|
}
|
|
102
103
|
exports.getRuntime = getRuntime;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WEBPACK_LAYERS = exports.ESBUILD_VERSION = exports.SERVER_REFERENCE_MANIFEST = exports.APP_PATHS_MANIFEST = exports.ROUTES_MANIFEST = exports.PRERENDER_MANIFEST = exports.PAGES_MANIFEST = exports.MIDDLEWARE_MANIFEST = exports.IMAGES_MANIFEST = exports.EXPORT_MARKER = exports.APP_PATH_ROUTES_MANIFEST = void 0;
|
|
3
|
+
exports.WEBPACK_LAYERS = exports.ESBUILD_VERSION = exports.CONFIG_FILES = exports.SERVER_REFERENCE_MANIFEST = exports.APP_PATHS_MANIFEST = exports.ROUTES_MANIFEST = exports.PRERENDER_MANIFEST = exports.PAGES_MANIFEST = exports.MIDDLEWARE_MANIFEST = exports.IMAGES_MANIFEST = exports.EXPORT_MARKER = exports.APP_PATH_ROUTES_MANIFEST = void 0;
|
|
4
4
|
exports.APP_PATH_ROUTES_MANIFEST = "app-path-routes-manifest.json";
|
|
5
5
|
exports.EXPORT_MARKER = "export-marker.json";
|
|
6
6
|
exports.IMAGES_MANIFEST = "images-manifest.json";
|
|
@@ -10,6 +10,7 @@ exports.PRERENDER_MANIFEST = "prerender-manifest.json";
|
|
|
10
10
|
exports.ROUTES_MANIFEST = "routes-manifest.json";
|
|
11
11
|
exports.APP_PATHS_MANIFEST = "app-paths-manifest.json";
|
|
12
12
|
exports.SERVER_REFERENCE_MANIFEST = "server-reference-manifest.json";
|
|
13
|
+
exports.CONFIG_FILES = ["next.config.js", "next.config.mjs"];
|
|
13
14
|
exports.ESBUILD_VERSION = "0.19.2";
|
|
14
15
|
const WEBPACK_LAYERS_NAMES = {
|
|
15
16
|
shared: "shared",
|
|
@@ -7,7 +7,6 @@ const promises_1 = require("fs/promises");
|
|
|
7
7
|
const path_1 = require("path");
|
|
8
8
|
const fs_extra_1 = require("fs-extra");
|
|
9
9
|
const url_1 = require("url");
|
|
10
|
-
const fs_1 = require("fs");
|
|
11
10
|
const semver_1 = require("semver");
|
|
12
11
|
const clc = require("colorette");
|
|
13
12
|
const stream_chain_1 = require("stream-chain");
|
|
@@ -40,7 +39,7 @@ async function discover(dir) {
|
|
|
40
39
|
if (!(await (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "package.json"))))
|
|
41
40
|
return;
|
|
42
41
|
const version = (0, utils_2.getNextVersion)(dir);
|
|
43
|
-
if (!(await (0,
|
|
42
|
+
if (!(await (0, utils_2.whichNextConfigFile)(dir)) && !version)
|
|
44
43
|
return;
|
|
45
44
|
return { mayWantBackend: true, publicDirectory: (0, path_1.join)(dir, PUBLIC_DIR), version };
|
|
46
45
|
}
|
|
@@ -336,7 +335,8 @@ exports.ɵcodegenPublicDirectory = ɵcodegenPublicDirectory;
|
|
|
336
335
|
async function ɵcodegenFunctionsDirectory(sourceDir, destDir, target, context) {
|
|
337
336
|
const { distDir } = await getConfig(sourceDir);
|
|
338
337
|
const packageJson = await (0, utils_1.readJSON)((0, path_1.join)(sourceDir, "package.json"));
|
|
339
|
-
|
|
338
|
+
const configFile = await (0, utils_2.whichNextConfigFile)(sourceDir);
|
|
339
|
+
if (configFile) {
|
|
340
340
|
try {
|
|
341
341
|
const productionDeps = await new Promise((resolve) => {
|
|
342
342
|
const dependencies = [];
|
|
@@ -361,8 +361,14 @@ async function ɵcodegenFunctionsDirectory(sourceDir, destDir, target, context)
|
|
|
361
361
|
});
|
|
362
362
|
const esbuildArgs = productionDeps
|
|
363
363
|
.map((it) => `--external:${it}`)
|
|
364
|
-
.concat("--bundle", "--platform=node", `--target=node${constants_1.NODE_VERSION}`,
|
|
365
|
-
|
|
364
|
+
.concat("--bundle", "--platform=node", `--target=node${constants_1.NODE_VERSION}`, "--log-level=error");
|
|
365
|
+
if (configFile === "next.config.mjs") {
|
|
366
|
+
esbuildArgs.push(...[`--outfile=${(0, path_1.join)(destDir, configFile)}`, "--format=esm"]);
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
esbuildArgs.push(`--outfile=${(0, path_1.join)(destDir, configFile)}`);
|
|
370
|
+
}
|
|
371
|
+
const bundle = (0, cross_spawn_1.sync)("npx", ["--yes", `esbuild@${constants_2.ESBUILD_VERSION}`, configFile, ...esbuildArgs], {
|
|
366
372
|
cwd: sourceDir,
|
|
367
373
|
timeout: BUNDLE_NEXT_CONFIG_TIMEOUT,
|
|
368
374
|
});
|
|
@@ -371,9 +377,9 @@ async function ɵcodegenFunctionsDirectory(sourceDir, destDir, target, context)
|
|
|
371
377
|
}
|
|
372
378
|
}
|
|
373
379
|
catch (e) {
|
|
374
|
-
console.warn(
|
|
380
|
+
console.warn(`Unable to bundle ${configFile} for use in Cloud Functions, proceeding with deploy but problems may be encountered.`);
|
|
375
381
|
console.error(e.message || e);
|
|
376
|
-
(0, fs_extra_1.copy)((0, path_1.join)(sourceDir,
|
|
382
|
+
await (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, configFile), (0, path_1.join)(destDir, configFile));
|
|
377
383
|
}
|
|
378
384
|
}
|
|
379
385
|
if (await (0, fs_extra_1.pathExists)((0, path_1.join)(sourceDir, "public"))) {
|
|
@@ -390,8 +396,11 @@ async function ɵcodegenFunctionsDirectory(sourceDir, destDir, target, context)
|
|
|
390
396
|
dotEnv["VERCEL_URL"] = deploymentDomain;
|
|
391
397
|
}
|
|
392
398
|
}
|
|
393
|
-
|
|
394
|
-
|
|
399
|
+
const [productionDistDirfiles] = await Promise.all([
|
|
400
|
+
(0, utils_2.getProductionDistDirFiles)(sourceDir, distDir),
|
|
401
|
+
(0, fs_extra_1.mkdirp)((0, path_1.join)(destDir, distDir)),
|
|
402
|
+
]);
|
|
403
|
+
await Promise.all(productionDistDirfiles.map((file) => (0, fs_extra_1.copy)(file, file.replace(sourceDir, destDir), { recursive: true })));
|
|
395
404
|
return { packageJson, frameworksEntry: "next.js", dotEnv };
|
|
396
405
|
}
|
|
397
406
|
exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
|
|
@@ -422,7 +431,8 @@ async function getConfig(dir) {
|
|
|
422
431
|
var _a;
|
|
423
432
|
var _b;
|
|
424
433
|
let config = {};
|
|
425
|
-
|
|
434
|
+
const configFile = await (0, utils_2.whichNextConfigFile)(dir);
|
|
435
|
+
if (configFile) {
|
|
426
436
|
const version = (0, utils_2.getNextVersion)(dir);
|
|
427
437
|
if (!version)
|
|
428
438
|
throw new Error("Unable to find the next dep, try NPM installing?");
|
|
@@ -435,10 +445,10 @@ async function getConfig(dir) {
|
|
|
435
445
|
}
|
|
436
446
|
else {
|
|
437
447
|
try {
|
|
438
|
-
config = await (_a = (0, url_1.pathToFileURL)((0, path_1.join)(dir,
|
|
448
|
+
config = await (_a = (0, url_1.pathToFileURL)((0, path_1.join)(dir, configFile)).toString(), Promise.resolve().then(() => require(_a)));
|
|
439
449
|
}
|
|
440
450
|
catch (e) {
|
|
441
|
-
throw new Error(
|
|
451
|
+
throw new Error(`Unable to load ${configFile}.`);
|
|
442
452
|
}
|
|
443
453
|
}
|
|
444
454
|
}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getRoutesWithServerAction = exports.hasStaticAppNotFoundComponent = exports.getNextVersion = exports.getBuildId = exports.getHeadersFromMetaFiles = exports.getNonStaticServerComponents = exports.getNonStaticRoutes = exports.getMiddlewareMatcherRegexes = exports.allDependencyNames = exports.isUsingAppDirectory = exports.isUsingNextImageInAppDirectory = exports.isUsingImageOptimization = exports.isUsingMiddleware = exports.hasUnoptimizedImage = exports.usesNextImage = exports.usesAppDirRouter = exports.getNextjsRewritesToUse = exports.isHeaderSupportedByHosting = exports.isRedirectSupportedByHosting = exports.isRewriteSupportedByHosting = exports.cleanI18n = exports.cleanCustomRouteI18n = exports.cleanEscapedChars = exports.I18N_SOURCE = void 0;
|
|
3
|
+
exports.whichNextConfigFile = exports.getProductionDistDirFiles = exports.getRoutesWithServerAction = exports.hasStaticAppNotFoundComponent = exports.getNextVersion = exports.getBuildId = exports.getHeadersFromMetaFiles = exports.getNonStaticServerComponents = exports.getNonStaticRoutes = exports.getMiddlewareMatcherRegexes = exports.allDependencyNames = exports.isUsingAppDirectory = exports.isUsingNextImageInAppDirectory = exports.isUsingImageOptimization = exports.isUsingMiddleware = exports.hasUnoptimizedImage = exports.usesNextImage = exports.usesAppDirRouter = exports.getNextjsRewritesToUse = exports.isHeaderSupportedByHosting = exports.isRedirectSupportedByHosting = exports.isRewriteSupportedByHosting = exports.cleanI18n = exports.cleanCustomRouteI18n = exports.cleanEscapedChars = exports.I18N_SOURCE = void 0;
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const fs_extra_1 = require("fs-extra");
|
|
6
6
|
const path_1 = require("path");
|
|
7
7
|
const promises_1 = require("fs/promises");
|
|
8
8
|
const glob_1 = require("glob");
|
|
9
|
+
const glob = require("glob");
|
|
9
10
|
const semver_1 = require("semver");
|
|
10
11
|
const utils_1 = require("../utils");
|
|
11
12
|
const constants_1 = require("./constants");
|
|
12
13
|
const fsutils_1 = require("../../fsutils");
|
|
14
|
+
const utils_2 = require("../../utils");
|
|
13
15
|
exports.I18N_SOURCE = /\/:nextInternalLocale(\([^\)]+\))?/;
|
|
14
16
|
function cleanEscapedChars(path) {
|
|
15
17
|
return path.replace(/\\([(){}:+?*])/g, (a, b) => b);
|
|
@@ -101,10 +103,15 @@ async function isUsingImageOptimization(projectDir, distDir) {
|
|
|
101
103
|
}
|
|
102
104
|
exports.isUsingImageOptimization = isUsingImageOptimization;
|
|
103
105
|
async function isUsingNextImageInAppDirectory(projectDir, nextDir) {
|
|
106
|
+
const nextImagePath = ["node_modules", "next", "dist", "client", "image"];
|
|
107
|
+
const nextImageString = utils_2.IS_WINDOWS
|
|
108
|
+
?
|
|
109
|
+
nextImagePath.join(path_1.sep + path_1.sep)
|
|
110
|
+
: (0, path_1.join)(...nextImagePath);
|
|
104
111
|
const files = (0, glob_1.sync)((0, path_1.join)(projectDir, nextDir, "server", "**", "*client-reference-manifest.js"));
|
|
105
112
|
for (const filepath of files) {
|
|
106
|
-
const fileContents = await (0, promises_1.readFile)(filepath);
|
|
107
|
-
if (fileContents.includes(
|
|
113
|
+
const fileContents = await (0, promises_1.readFile)(filepath, "utf-8");
|
|
114
|
+
if (fileContents.includes(nextImageString)) {
|
|
108
115
|
return true;
|
|
109
116
|
}
|
|
110
117
|
}
|
|
@@ -218,3 +225,25 @@ function getRoutesWithServerAction(serverReferenceManifest, appPathRoutesManifes
|
|
|
218
225
|
return Array.from(routesWithServerAction);
|
|
219
226
|
}
|
|
220
227
|
exports.getRoutesWithServerAction = getRoutesWithServerAction;
|
|
228
|
+
async function getProductionDistDirFiles(sourceDir, distDir) {
|
|
229
|
+
const productionDistDirFiles = await new Promise((resolve, reject) => glob("**", {
|
|
230
|
+
ignore: [(0, path_1.join)("cache", "webpack", "*-development", "**"), (0, path_1.join)("cache", "eslint", "**")],
|
|
231
|
+
cwd: (0, path_1.join)(sourceDir, distDir),
|
|
232
|
+
nodir: true,
|
|
233
|
+
absolute: true,
|
|
234
|
+
}, (err, matches) => {
|
|
235
|
+
if (err)
|
|
236
|
+
reject(err);
|
|
237
|
+
resolve(matches);
|
|
238
|
+
}));
|
|
239
|
+
return productionDistDirFiles;
|
|
240
|
+
}
|
|
241
|
+
exports.getProductionDistDirFiles = getProductionDistDirFiles;
|
|
242
|
+
async function whichNextConfigFile(dir) {
|
|
243
|
+
for (const file of constants_1.CONFIG_FILES) {
|
|
244
|
+
if (await (0, fs_extra_1.pathExists)((0, path_1.join)(dir, file)))
|
|
245
|
+
return file;
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
exports.whichNextConfigFile = whichNextConfigFile;
|
package/lib/functional.js
CHANGED
|
@@ -52,8 +52,8 @@ const zipIn = (other) => (elem, ndx) => {
|
|
|
52
52
|
return [elem, other[ndx]];
|
|
53
53
|
};
|
|
54
54
|
exports.zipIn = zipIn;
|
|
55
|
-
function assertExhaustive(val) {
|
|
56
|
-
throw new Error(`Never has a value (${val}).`);
|
|
55
|
+
function assertExhaustive(val, message) {
|
|
56
|
+
throw new Error(message || `Never has a value (${val}).`);
|
|
57
57
|
}
|
|
58
58
|
exports.assertExhaustive = assertExhaustive;
|
|
59
59
|
function partition(arr, predicate) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FIRESTORE_EVENTS = exports.TEST_LAB_EVENT = exports.REMOTE_CONFIG_EVENT = exports.DATABASE_EVENTS = exports.FIREBASE_ALERTS_PUBLISH_EVENT = exports.STORAGE_EVENTS = exports.PUBSUB_PUBLISH_EVENT = void 0;
|
|
3
|
+
exports.FIRESTORE_EVENT_WITH_AUTH_CONTEXT_REGEX = exports.FIRESTORE_EVENT_REGEX = exports.FIRESTORE_EVENTS = exports.TEST_LAB_EVENT = exports.REMOTE_CONFIG_EVENT = exports.DATABASE_EVENTS = exports.FIREBASE_ALERTS_PUBLISH_EVENT = exports.STORAGE_EVENTS = exports.PUBSUB_PUBLISH_EVENT = void 0;
|
|
4
4
|
exports.PUBSUB_PUBLISH_EVENT = "google.cloud.pubsub.topic.v1.messagePublished";
|
|
5
5
|
exports.STORAGE_EVENTS = [
|
|
6
6
|
"google.cloud.storage.object.v1.finalized",
|
|
@@ -22,4 +22,10 @@ exports.FIRESTORE_EVENTS = [
|
|
|
22
22
|
"google.cloud.firestore.document.v1.created",
|
|
23
23
|
"google.cloud.firestore.document.v1.updated",
|
|
24
24
|
"google.cloud.firestore.document.v1.deleted",
|
|
25
|
+
"google.cloud.firestore.document.v1.written.withAuthContext",
|
|
26
|
+
"google.cloud.firestore.document.v1.created.withAuthContext",
|
|
27
|
+
"google.cloud.firestore.document.v1.updated.withAuthContext",
|
|
28
|
+
"google.cloud.firestore.document.v1.deleted.withAuthContext",
|
|
25
29
|
];
|
|
30
|
+
exports.FIRESTORE_EVENT_REGEX = /^google\.cloud\.firestore\.document\.v1\.[^\.]*$/;
|
|
31
|
+
exports.FIRESTORE_EVENT_WITH_AUTH_CONTEXT_REGEX = /^google\.cloud\.firestore\.document\.v1\..*\.withAuthContext$/;
|
package/lib/functions/secrets.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.updateEndpointSecret = exports.pruneAndDestroySecrets = exports.pruneSecrets = exports.versionInUse = exports.inUse = exports.getSecretVersions = exports.of = exports.ensureSecret = exports.ensureValidKey =
|
|
3
|
+
exports.describeSecret = exports.updateEndpointSecret = exports.pruneAndDestroySecrets = exports.pruneSecrets = exports.versionInUse = exports.inUse = exports.getSecretVersions = exports.of = exports.ensureSecret = exports.ensureValidKey = void 0;
|
|
4
4
|
const utils = require("../utils");
|
|
5
5
|
const poller = require("../operation-poller");
|
|
6
6
|
const gcfV1 = require("../gcp/cloudfunctions");
|
|
7
7
|
const gcfV2 = require("../gcp/cloudfunctionsv2");
|
|
8
|
-
const ensureApiEnabled = require("../ensureApiEnabled");
|
|
9
8
|
const api_1 = require("../api");
|
|
10
9
|
const secretManager_1 = require("../gcp/secretManager");
|
|
11
10
|
const error_1 = require("../error");
|
|
@@ -14,8 +13,10 @@ const prompt_1 = require("../prompt");
|
|
|
14
13
|
const env_1 = require("./env");
|
|
15
14
|
const logger_1 = require("../logger");
|
|
16
15
|
const functional_1 = require("../functional");
|
|
16
|
+
const secretManager_2 = require("../gcp/secretManager");
|
|
17
|
+
const secretManager_3 = require("../gcp/secretManager");
|
|
17
18
|
const projectUtils_1 = require("../projectUtils");
|
|
18
|
-
const
|
|
19
|
+
const Table = require("cli-table");
|
|
19
20
|
const gcfV1PollerOptions = {
|
|
20
21
|
apiOrigin: (0, api_1.functionsOrigin)(),
|
|
21
22
|
apiVersion: "v1",
|
|
@@ -28,25 +29,12 @@ const gcfV2PollerOptions = {
|
|
|
28
29
|
masterTimeout: 25 * 60 * 1000,
|
|
29
30
|
maxBackoff: 10000,
|
|
30
31
|
};
|
|
31
|
-
function isFirebaseManaged(secret) {
|
|
32
|
-
return Object.keys(secret.labels || []).includes(FIREBASE_MANAGED);
|
|
33
|
-
}
|
|
34
|
-
exports.isFirebaseManaged = isFirebaseManaged;
|
|
35
|
-
function labels() {
|
|
36
|
-
return { [FIREBASE_MANAGED]: "true" };
|
|
37
|
-
}
|
|
38
|
-
exports.labels = labels;
|
|
39
32
|
function toUpperSnakeCase(key) {
|
|
40
33
|
return key
|
|
41
34
|
.replace(/[.-]/g, "_")
|
|
42
35
|
.replace(/([a-z])([A-Z])/g, "$1_$2")
|
|
43
36
|
.toUpperCase();
|
|
44
37
|
}
|
|
45
|
-
function ensureApi(options) {
|
|
46
|
-
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
47
|
-
return ensureApiEnabled.ensure(projectId, (0, api_1.secretManagerOrigin)(), "secretmanager", true);
|
|
48
|
-
}
|
|
49
|
-
exports.ensureApi = ensureApi;
|
|
50
38
|
async function ensureValidKey(key, options) {
|
|
51
39
|
const transformedKey = toUpperSnakeCase(key);
|
|
52
40
|
if (transformedKey !== key) {
|
|
@@ -76,18 +64,34 @@ exports.ensureValidKey = ensureValidKey;
|
|
|
76
64
|
async function ensureSecret(projectId, name, options) {
|
|
77
65
|
try {
|
|
78
66
|
const secret = await (0, secretManager_1.getSecret)(projectId, name);
|
|
79
|
-
if (
|
|
67
|
+
if ((0, secretManager_1.isAppHostingManaged)(secret)) {
|
|
68
|
+
(0, utils_1.logWarning)("Your secret is managed by Firebase App Hosting. Continuing will disable automatic deletion of old versions.");
|
|
69
|
+
const stopTracking = await (0, prompt_1.promptOnce)({
|
|
70
|
+
name: "doNotTrack",
|
|
71
|
+
type: "confirm",
|
|
72
|
+
default: false,
|
|
73
|
+
message: "Do you wish to continue?",
|
|
74
|
+
}, options);
|
|
75
|
+
if (stopTracking) {
|
|
76
|
+
delete secret.labels[secretManager_2.FIREBASE_MANAGED];
|
|
77
|
+
await (0, secretManager_1.patchSecret)(secret.projectId, secret.name, secret.labels);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
throw new Error("A secret cannot be managed by both Firebase App Hosting and Cloud Functions for Firebase");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else if (!(0, secretManager_2.isFunctionsManaged)(secret)) {
|
|
80
84
|
if (!options.force) {
|
|
81
|
-
(0, utils_1.logWarning)("Your secret is not managed by Firebase. " +
|
|
85
|
+
(0, utils_1.logWarning)("Your secret is not managed by Cloud Functions for Firebase. " +
|
|
82
86
|
"Firebase managed secrets are automatically pruned to reduce your monthly cost for using Secret Manager. ");
|
|
83
87
|
const confirm = await (0, prompt_1.promptOnce)({
|
|
84
88
|
name: "updateLabels",
|
|
85
89
|
type: "confirm",
|
|
86
90
|
default: true,
|
|
87
|
-
message: `Would you like to have your secret ${secret.name} managed by Firebase?`,
|
|
91
|
+
message: `Would you like to have your secret ${secret.name} managed by Cloud Functions for Firebase?`,
|
|
88
92
|
}, options);
|
|
89
93
|
if (confirm) {
|
|
90
|
-
return (0, secretManager_1.patchSecret)(projectId, secret.name, Object.assign(Object.assign({}, secret.labels), labels()));
|
|
94
|
+
return (0, secretManager_1.patchSecret)(projectId, secret.name, Object.assign(Object.assign({}, secret.labels), (0, secretManager_3.labels)()));
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
}
|
|
@@ -98,7 +102,7 @@ async function ensureSecret(projectId, name, options) {
|
|
|
98
102
|
throw err;
|
|
99
103
|
}
|
|
100
104
|
}
|
|
101
|
-
return await (0, secretManager_1.createSecret)(projectId, name, labels());
|
|
105
|
+
return await (0, secretManager_1.createSecret)(projectId, name, (0, secretManager_3.labels)());
|
|
102
106
|
}
|
|
103
107
|
exports.ensureSecret = ensureSecret;
|
|
104
108
|
function of(endpoints) {
|
|
@@ -139,7 +143,7 @@ async function pruneSecrets(projectInfo, endpoints) {
|
|
|
139
143
|
const { projectId, projectNumber } = projectInfo;
|
|
140
144
|
const pruneKey = (name, version) => `${name}@${version}`;
|
|
141
145
|
const prunedSecrets = new Set();
|
|
142
|
-
const haveSecrets = await (0, secretManager_1.listSecrets)(projectId, `labels.${FIREBASE_MANAGED}=true`);
|
|
146
|
+
const haveSecrets = await (0, secretManager_1.listSecrets)(projectId, `labels.${secretManager_2.FIREBASE_MANAGED}=true`);
|
|
143
147
|
for (const secret of haveSecrets) {
|
|
144
148
|
const versions = await (0, secretManager_1.listSecretVersions)(projectId, secret.name, `NOT state: DESTROYED`);
|
|
145
149
|
for (const version of versions) {
|
|
@@ -237,3 +241,17 @@ async function updateEndpointSecret(projectInfo, secretVersion, endpoint) {
|
|
|
237
241
|
}
|
|
238
242
|
}
|
|
239
243
|
exports.updateEndpointSecret = updateEndpointSecret;
|
|
244
|
+
async function describeSecret(key, options) {
|
|
245
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
246
|
+
const versions = await (0, secretManager_1.listSecretVersions)(projectId, key);
|
|
247
|
+
const table = new Table({
|
|
248
|
+
head: ["Version", "State"],
|
|
249
|
+
style: { head: ["yellow"] },
|
|
250
|
+
});
|
|
251
|
+
for (const version of versions) {
|
|
252
|
+
table.push([version.versionId, version.state]);
|
|
253
|
+
}
|
|
254
|
+
logger_1.logger.info(table.toString());
|
|
255
|
+
return { secrets: versions };
|
|
256
|
+
}
|
|
257
|
+
exports.describeSecret = describeSecret;
|
package/lib/gcp/apphosting.js
CHANGED
|
@@ -31,9 +31,22 @@ async function getBackend(projectId, location, backendId) {
|
|
|
31
31
|
}
|
|
32
32
|
exports.getBackend = getBackend;
|
|
33
33
|
async function listBackends(projectId, location) {
|
|
34
|
+
var _a;
|
|
34
35
|
const name = `projects/${projectId}/locations/${location}/backends`;
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
let pageToken;
|
|
37
|
+
const res = {
|
|
38
|
+
backends: [],
|
|
39
|
+
unreachable: [],
|
|
40
|
+
};
|
|
41
|
+
do {
|
|
42
|
+
const queryParams = pageToken ? { pageToken } : {};
|
|
43
|
+
const int = await exports.client.get(name, { queryParams });
|
|
44
|
+
res.backends.push(...(int.body.backends || []));
|
|
45
|
+
(_a = res.unreachable) === null || _a === void 0 ? void 0 : _a.push(...(int.body.unreachable || []));
|
|
46
|
+
pageToken = int.body.nextPageToken;
|
|
47
|
+
} while (pageToken);
|
|
48
|
+
res.unreachable = [...new Set(res.unreachable)];
|
|
49
|
+
return res;
|
|
37
50
|
}
|
|
38
51
|
exports.listBackends = listBackends;
|
|
39
52
|
async function deleteBackend(projectId, location, backendId) {
|
package/lib/gcp/cloudbuild.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getDefaultServiceAgent = exports.getDefaultServiceAccount = exports.deleteRepository = exports.getRepository = exports.createRepository = exports.fetchLinkableRepositories = exports.deleteConnection = exports.listConnections = exports.getConnection = exports.createConnection = void 0;
|
|
4
4
|
const apiv2_1 = require("../apiv2");
|
|
5
5
|
const api_1 = require("../api");
|
|
6
6
|
const PAGE_SIZE_MAX = 100;
|
|
@@ -74,7 +74,11 @@ async function deleteRepository(projectId, location, connectionId, repositoryId)
|
|
|
74
74
|
return res.body;
|
|
75
75
|
}
|
|
76
76
|
exports.deleteRepository = deleteRepository;
|
|
77
|
-
function
|
|
77
|
+
function getDefaultServiceAccount(projectNumber) {
|
|
78
|
+
return `${projectNumber}@cloudbuild.gserviceaccount.com`;
|
|
79
|
+
}
|
|
80
|
+
exports.getDefaultServiceAccount = getDefaultServiceAccount;
|
|
81
|
+
function getDefaultServiceAgent(projectNumber) {
|
|
78
82
|
return `service-${projectNumber}@gcp-sa-cloudbuild.iam.gserviceaccount.com`;
|
|
79
83
|
}
|
|
80
|
-
exports.
|
|
84
|
+
exports.getDefaultServiceAgent = getDefaultServiceAgent;
|
|
@@ -7,7 +7,7 @@ const logger_1 = require("../logger");
|
|
|
7
7
|
const backend = require("../deploy/functions/backend");
|
|
8
8
|
const utils = require("../utils");
|
|
9
9
|
const proto = require("./proto");
|
|
10
|
-
const
|
|
10
|
+
const supported = require("../deploy/functions/runtimes/supported");
|
|
11
11
|
const projectConfig = require("../functions/projectConfig");
|
|
12
12
|
const apiv2_1 = require("../apiv2");
|
|
13
13
|
const api_1 = require("../api");
|
|
@@ -241,8 +241,8 @@ function endpointFromFunction(gcfFunction) {
|
|
|
241
241
|
uri = gcfFunction.httpsTrigger.url;
|
|
242
242
|
securityLevel = gcfFunction.httpsTrigger.securityLevel;
|
|
243
243
|
}
|
|
244
|
-
if (!
|
|
245
|
-
logger_1.logger.debug("
|
|
244
|
+
if (!supported.isRuntime(gcfFunction.runtime)) {
|
|
245
|
+
logger_1.logger.debug("GCF 1st gen function has unsupported runtime:", JSON.stringify(gcfFunction, null, 2));
|
|
246
246
|
}
|
|
247
247
|
const endpoint = Object.assign(Object.assign({ platform: "gcfv1", id,
|
|
248
248
|
project,
|
|
@@ -273,9 +273,9 @@ function functionFromEndpoint(endpoint, sourceUploadUrl) {
|
|
|
273
273
|
if (endpoint.platform !== "gcfv1") {
|
|
274
274
|
throw new error_1.FirebaseError("Trying to create a v1 CloudFunction with v2 API. This should never happen");
|
|
275
275
|
}
|
|
276
|
-
if (!
|
|
276
|
+
if (!supported.isRuntime(endpoint.runtime)) {
|
|
277
277
|
throw new error_1.FirebaseError("Failed internal assertion. Trying to deploy a new function with a deprecated runtime." +
|
|
278
|
-
" This should never happen");
|
|
278
|
+
" This should never happen", { exit: 1 });
|
|
279
279
|
}
|
|
280
280
|
const gcfFunction = {
|
|
281
281
|
name: backend.functionName(endpoint),
|
|
@@ -7,7 +7,7 @@ const api_1 = require("../api");
|
|
|
7
7
|
const logger_1 = require("../logger");
|
|
8
8
|
const v2_1 = require("../functions/events/v2");
|
|
9
9
|
const backend = require("../deploy/functions/backend");
|
|
10
|
-
const
|
|
10
|
+
const supported = require("../deploy/functions/runtimes/supported");
|
|
11
11
|
const proto = require("./proto");
|
|
12
12
|
const utils = require("../utils");
|
|
13
13
|
const projectConfig = require("../functions/projectConfig");
|
|
@@ -175,7 +175,7 @@ function functionFromEndpoint(endpoint) {
|
|
|
175
175
|
if (endpoint.platform !== "gcfv2") {
|
|
176
176
|
throw new error_1.FirebaseError("Trying to create a v2 CloudFunction with v1 API. This should never happen");
|
|
177
177
|
}
|
|
178
|
-
if (!
|
|
178
|
+
if (!supported.isRuntime(endpoint.runtime)) {
|
|
179
179
|
throw new error_1.FirebaseError("Failed internal assertion. Trying to deploy a new function with a deprecated runtime." +
|
|
180
180
|
" This should never happen");
|
|
181
181
|
}
|
|
@@ -337,7 +337,7 @@ function endpointFromFunction(gcfFunction) {
|
|
|
337
337
|
else {
|
|
338
338
|
trigger = { httpsTrigger: {} };
|
|
339
339
|
}
|
|
340
|
-
if (!
|
|
340
|
+
if (!supported.isRuntime(gcfFunction.buildConfig.runtime)) {
|
|
341
341
|
logger_1.logger.debug("GCFv2 function has a deprecated runtime:", JSON.stringify(gcfFunction, null, 2));
|
|
342
342
|
}
|
|
343
343
|
const endpoint = Object.assign(Object.assign({ platform: "gcfv2", id,
|
|
@@ -8,7 +8,7 @@ const api_1 = require("../api");
|
|
|
8
8
|
const apiv2_1 = require("../apiv2");
|
|
9
9
|
const backend = require("../deploy/functions/backend");
|
|
10
10
|
const proto = require("./proto");
|
|
11
|
-
const
|
|
11
|
+
const gce = require("../gcp/computeEngine");
|
|
12
12
|
const functional_1 = require("../functional");
|
|
13
13
|
const VERSION = "v1";
|
|
14
14
|
const DEFAULT_TIME_ZONE_V1 = "America/Los_Angeles";
|
|
@@ -130,7 +130,7 @@ function jobFromEndpoint(endpoint, location, projectNumber) {
|
|
|
130
130
|
uri: endpoint.uri,
|
|
131
131
|
httpMethod: "POST",
|
|
132
132
|
oidcToken: {
|
|
133
|
-
serviceAccountEmail: (_a = endpoint.serviceAccount) !== null && _a !== void 0 ? _a :
|
|
133
|
+
serviceAccountEmail: (_a = endpoint.serviceAccount) !== null && _a !== void 0 ? _a : gce.getDefaultServiceAccount(projectNumber),
|
|
134
134
|
},
|
|
135
135
|
};
|
|
136
136
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefaultServiceAccount = void 0;
|
|
4
|
+
function getDefaultServiceAccount(projectNumber) {
|
|
5
|
+
return `${projectNumber}-compute@developer.gserviceaccount.com`;
|
|
6
|
+
}
|
|
7
|
+
exports.getDefaultServiceAccount = getDefaultServiceAccount;
|
package/lib/gcp/devConnect.js
CHANGED
|
@@ -1,24 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.serviceAgentEmail = exports.getGitRepositoryLink = exports.createGitRepositoryLink = exports.listAllLinkableGitRepositories = exports.listAllConnections = exports.getConnection = exports.createConnection = exports.client = void 0;
|
|
3
|
+
exports.generateP4SA = exports.serviceAgentEmail = exports.getGitRepositoryLink = exports.createGitRepositoryLink = exports.listAllLinkableGitRepositories = exports.listAllConnections = exports.getConnection = exports.deleteConnection = exports.createConnection = exports.client = void 0;
|
|
4
4
|
const apiv2_1 = require("../apiv2");
|
|
5
5
|
const api_1 = require("../api");
|
|
6
|
+
const serviceusage_1 = require("./serviceusage");
|
|
6
7
|
const PAGE_SIZE_MAX = 1000;
|
|
8
|
+
const LOCATION_OVERRIDE = process.env.FIREBASE_DEVELOPERCONNECT_LOCATION_OVERRIDE;
|
|
7
9
|
exports.client = new apiv2_1.Client({
|
|
8
10
|
urlPrefix: (0, api_1.developerConnectOrigin)(),
|
|
9
11
|
auth: true,
|
|
10
12
|
apiVersion: "v1",
|
|
11
13
|
});
|
|
12
|
-
async function createConnection(projectId, location, connectionId, githubConfig) {
|
|
14
|
+
async function createConnection(projectId, location, connectionId, githubConfig = {}) {
|
|
13
15
|
const config = Object.assign(Object.assign({}, githubConfig), { githubApp: "FIREBASE" });
|
|
14
|
-
const res = await exports.client.post(`projects/${projectId}/locations/${location}/connections`, {
|
|
16
|
+
const res = await exports.client.post(`projects/${projectId}/locations/${LOCATION_OVERRIDE !== null && LOCATION_OVERRIDE !== void 0 ? LOCATION_OVERRIDE : location}/connections`, {
|
|
15
17
|
githubConfig: config,
|
|
16
18
|
}, { queryParams: { connectionId } });
|
|
17
19
|
return res.body;
|
|
18
20
|
}
|
|
19
21
|
exports.createConnection = createConnection;
|
|
22
|
+
async function deleteConnection(projectId, location, connectionId) {
|
|
23
|
+
const name = `projects/${projectId}/locations/${LOCATION_OVERRIDE !== null && LOCATION_OVERRIDE !== void 0 ? LOCATION_OVERRIDE : location}/connections/${connectionId}`;
|
|
24
|
+
const res = await exports.client.delete(name, { queryParams: { force: "true" } });
|
|
25
|
+
return res.body;
|
|
26
|
+
}
|
|
27
|
+
exports.deleteConnection = deleteConnection;
|
|
20
28
|
async function getConnection(projectId, location, connectionId) {
|
|
21
|
-
const name = `projects/${projectId}/locations/${location}/connections/${connectionId}`;
|
|
29
|
+
const name = `projects/${projectId}/locations/${LOCATION_OVERRIDE !== null && LOCATION_OVERRIDE !== void 0 ? LOCATION_OVERRIDE : location}/connections/${connectionId}`;
|
|
22
30
|
const res = await exports.client.get(name);
|
|
23
31
|
return res.body;
|
|
24
32
|
}
|
|
@@ -26,7 +34,7 @@ exports.getConnection = getConnection;
|
|
|
26
34
|
async function listAllConnections(projectId, location) {
|
|
27
35
|
const conns = [];
|
|
28
36
|
const getNextPage = async (pageToken = "") => {
|
|
29
|
-
const res = await exports.client.get(`/projects/${projectId}/locations/${location}/connections`, {
|
|
37
|
+
const res = await exports.client.get(`/projects/${projectId}/locations/${LOCATION_OVERRIDE !== null && LOCATION_OVERRIDE !== void 0 ? LOCATION_OVERRIDE : location}/connections`, {
|
|
30
38
|
queryParams: {
|
|
31
39
|
pageSize: PAGE_SIZE_MAX,
|
|
32
40
|
pageToken,
|
|
@@ -44,17 +52,17 @@ async function listAllConnections(projectId, location) {
|
|
|
44
52
|
}
|
|
45
53
|
exports.listAllConnections = listAllConnections;
|
|
46
54
|
async function listAllLinkableGitRepositories(projectId, location, connectionId) {
|
|
47
|
-
const name = `projects/${projectId}/locations/${location}/connections/${connectionId}:
|
|
55
|
+
const name = `projects/${projectId}/locations/${LOCATION_OVERRIDE !== null && LOCATION_OVERRIDE !== void 0 ? LOCATION_OVERRIDE : location}/connections/${connectionId}:fetchLinkableGitRepositories`;
|
|
48
56
|
const repos = [];
|
|
49
57
|
const getNextPage = async (pageToken = "") => {
|
|
50
58
|
const res = await exports.client.get(name, {
|
|
51
59
|
queryParams: {
|
|
52
|
-
PAGE_SIZE_MAX,
|
|
60
|
+
pageSize: PAGE_SIZE_MAX,
|
|
53
61
|
pageToken,
|
|
54
62
|
},
|
|
55
63
|
});
|
|
56
|
-
if (Array.isArray(res.body.
|
|
57
|
-
repos.push(...res.body.
|
|
64
|
+
if (Array.isArray(res.body.linkableGitRepositories)) {
|
|
65
|
+
repos.push(...res.body.linkableGitRepositories);
|
|
58
66
|
}
|
|
59
67
|
if (res.body.nextPageToken) {
|
|
60
68
|
await getNextPage(res.body.nextPageToken);
|
|
@@ -65,12 +73,12 @@ async function listAllLinkableGitRepositories(projectId, location, connectionId)
|
|
|
65
73
|
}
|
|
66
74
|
exports.listAllLinkableGitRepositories = listAllLinkableGitRepositories;
|
|
67
75
|
async function createGitRepositoryLink(projectId, location, connectionId, gitRepositoryLinkId, cloneUri) {
|
|
68
|
-
const res = await exports.client.post(`projects/${projectId}/locations/${location}/connections/${connectionId}/gitRepositoryLinks`, { cloneUri }, { queryParams: { gitRepositoryLinkId } });
|
|
76
|
+
const res = await exports.client.post(`projects/${projectId}/locations/${LOCATION_OVERRIDE !== null && LOCATION_OVERRIDE !== void 0 ? LOCATION_OVERRIDE : location}/connections/${connectionId}/gitRepositoryLinks`, { cloneUri }, { queryParams: { gitRepositoryLinkId } });
|
|
69
77
|
return res.body;
|
|
70
78
|
}
|
|
71
79
|
exports.createGitRepositoryLink = createGitRepositoryLink;
|
|
72
80
|
async function getGitRepositoryLink(projectId, location, connectionId, gitRepositoryLinkId) {
|
|
73
|
-
const name = `projects/${projectId}/locations/${location}/connections/${connectionId}/gitRepositoryLinks/${gitRepositoryLinkId}`;
|
|
81
|
+
const name = `projects/${projectId}/locations/${LOCATION_OVERRIDE !== null && LOCATION_OVERRIDE !== void 0 ? LOCATION_OVERRIDE : location}/connections/${connectionId}/gitRepositoryLinks/${gitRepositoryLinkId}`;
|
|
74
82
|
const res = await exports.client.get(name);
|
|
75
83
|
return res.body;
|
|
76
84
|
}
|
|
@@ -79,3 +87,8 @@ function serviceAgentEmail(projectNumber) {
|
|
|
79
87
|
return `service-${projectNumber}@${(0, api_1.developerConnectP4SAOrigin)()}`;
|
|
80
88
|
}
|
|
81
89
|
exports.serviceAgentEmail = serviceAgentEmail;
|
|
90
|
+
async function generateP4SA(projectNumber) {
|
|
91
|
+
const devConnectOrigin = (0, api_1.developerConnectOrigin)();
|
|
92
|
+
await (0, serviceusage_1.generateServiceIdentityAndPoll)(projectNumber, new URL(devConnectOrigin).hostname, "apphosting");
|
|
93
|
+
}
|
|
94
|
+
exports.generateP4SA = generateP4SA;
|
package/lib/gcp/iam.js
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.testIamPermissions = exports.testResourceIamPermissions = exports.getRole = exports.listServiceAccountKeys = exports.deleteServiceAccount = exports.createServiceAccountKey = exports.getServiceAccount = exports.createServiceAccount = void 0;
|
|
3
|
+
exports.testIamPermissions = exports.testResourceIamPermissions = exports.getRole = exports.listServiceAccountKeys = exports.deleteServiceAccount = exports.createServiceAccountKey = exports.getServiceAccount = exports.createServiceAccount = exports.getDefaultComputeEngineServiceAgent = exports.getDefaultCloudBuildServiceAgent = void 0;
|
|
4
4
|
const api_1 = require("../api");
|
|
5
5
|
const logger_1 = require("../logger");
|
|
6
6
|
const apiv2_1 = require("../apiv2");
|
|
7
7
|
const apiClient = new apiv2_1.Client({ urlPrefix: (0, api_1.iamOrigin)(), apiVersion: "v1" });
|
|
8
|
+
function getDefaultCloudBuildServiceAgent(projectNumber) {
|
|
9
|
+
return `${projectNumber}@cloudbuild.gserviceaccount.com`;
|
|
10
|
+
}
|
|
11
|
+
exports.getDefaultCloudBuildServiceAgent = getDefaultCloudBuildServiceAgent;
|
|
12
|
+
function getDefaultComputeEngineServiceAgent(projectNumber) {
|
|
13
|
+
return `${projectNumber}-compute@developer.gserviceaccount.com`;
|
|
14
|
+
}
|
|
15
|
+
exports.getDefaultComputeEngineServiceAgent = getDefaultComputeEngineServiceAgent;
|
|
8
16
|
async function createServiceAccount(projectId, accountId, description, displayName) {
|
|
9
17
|
const response = await apiClient.post(`/projects/${projectId}/serviceAccounts`, {
|
|
10
18
|
accountId,
|