123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.compareFunctions = exports.missingEndpoint = exports.hasEndpoint = exports.regionalEndpoints = exports.matchingBackend = exports.findEndpoint = exports.someEndpoint = exports.allEndpoints = exports.checkAvailability = exports.existingBackend = exports.scheduleIdForFunction = exports.functionName = exports.isEmptyBackend = exports.merge = exports.of = exports.empty = exports.isBlockingTriggered = exports.isTaskQueueTriggered = exports.isScheduleTriggered = exports.isEventTriggered = exports.isCallableTriggered = exports.isHttpsTriggered = exports.AllFunctionsPlatforms = exports.secretVersionName = exports.SCHEDULED_FUNCTION_LABEL = exports.MIN_CPU_FOR_CONCURRENCY = exports.DEFAULT_MEMORY = exports.DEFAULT_CONCURRENCY = exports.memoryToGen2Cpu = exports.memoryToGen1Cpu = exports.memoryOptionDisplayName = exports.isValidMemoryOption = exports.AllIngressSettings = exports.AllVpcEgressSettings = exports.endpointTriggerType = void 0;
- const gcf = require("../../gcp/cloudfunctions");
- const gcfV2 = require("../../gcp/cloudfunctionsv2");
- const run = require("../../gcp/run");
- const utils = require("../../utils");
- const error_1 = require("../../error");
- const functional_1 = require("../../functional");
- function endpointTriggerType(endpoint) {
- if (isScheduleTriggered(endpoint)) {
- return "scheduled";
- }
- else if (isHttpsTriggered(endpoint)) {
- return "https";
- }
- else if (isCallableTriggered(endpoint)) {
- return "callable";
- }
- else if (isEventTriggered(endpoint)) {
- return endpoint.eventTrigger.eventType;
- }
- else if (isTaskQueueTriggered(endpoint)) {
- return "taskQueue";
- }
- else if (isBlockingTriggered(endpoint)) {
- return endpoint.blockingTrigger.eventType;
- }
- else {
- throw new Error("Unexpected trigger type for endpoint " + JSON.stringify(endpoint));
- }
- }
- exports.endpointTriggerType = endpointTriggerType;
- exports.AllVpcEgressSettings = ["PRIVATE_RANGES_ONLY", "ALL_TRAFFIC"];
- exports.AllIngressSettings = [
- "ALLOW_ALL",
- "ALLOW_INTERNAL_ONLY",
- "ALLOW_INTERNAL_AND_GCLB",
- ];
- const allMemoryOptions = [128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768];
- function isValidMemoryOption(mem) {
- return allMemoryOptions.includes(mem);
- }
- exports.isValidMemoryOption = isValidMemoryOption;
- function memoryOptionDisplayName(option) {
- return {
- 128: "128MB",
- 256: "256MB",
- 512: "512MB",
- 1024: "1GB",
- 2048: "2GB",
- 4096: "4GB",
- 8192: "8GB",
- 16384: "16GB",
- 32768: "32GB",
- }[option];
- }
- exports.memoryOptionDisplayName = memoryOptionDisplayName;
- function memoryToGen1Cpu(memory) {
- return {
- 128: 0.0833,
- 256: 0.1666,
- 512: 0.3333,
- 1024: 0.5833,
- 2048: 1,
- 4096: 2,
- 8192: 2,
- 16384: 4,
- 32768: 8,
- }[memory];
- }
- exports.memoryToGen1Cpu = memoryToGen1Cpu;
- function memoryToGen2Cpu(memory) {
- return {
- 128: 1,
- 256: 1,
- 512: 1,
- 1024: 1,
- 2048: 1,
- 4096: 2,
- 8192: 2,
- 16384: 4,
- 32768: 8,
- }[memory];
- }
- exports.memoryToGen2Cpu = memoryToGen2Cpu;
- exports.DEFAULT_CONCURRENCY = 80;
- exports.DEFAULT_MEMORY = 256;
- exports.MIN_CPU_FOR_CONCURRENCY = 1;
- exports.SCHEDULED_FUNCTION_LABEL = Object.freeze({ deployment: "firebase-schedule" });
- function secretVersionName(s) {
- var _a;
- return `projects/${s.projectId}/secrets/${s.secret}/versions/${(_a = s.version) !== null && _a !== void 0 ? _a : "latest"}`;
- }
- exports.secretVersionName = secretVersionName;
- exports.AllFunctionsPlatforms = ["gcfv1", "gcfv2"];
- function isHttpsTriggered(triggered) {
- return {}.hasOwnProperty.call(triggered, "httpsTrigger");
- }
- exports.isHttpsTriggered = isHttpsTriggered;
- function isCallableTriggered(triggered) {
- return {}.hasOwnProperty.call(triggered, "callableTrigger");
- }
- exports.isCallableTriggered = isCallableTriggered;
- function isEventTriggered(triggered) {
- return {}.hasOwnProperty.call(triggered, "eventTrigger");
- }
- exports.isEventTriggered = isEventTriggered;
- function isScheduleTriggered(triggered) {
- return {}.hasOwnProperty.call(triggered, "scheduleTrigger");
- }
- exports.isScheduleTriggered = isScheduleTriggered;
- function isTaskQueueTriggered(triggered) {
- return {}.hasOwnProperty.call(triggered, "taskQueueTrigger");
- }
- exports.isTaskQueueTriggered = isTaskQueueTriggered;
- function isBlockingTriggered(triggered) {
- return {}.hasOwnProperty.call(triggered, "blockingTrigger");
- }
- exports.isBlockingTriggered = isBlockingTriggered;
- function empty() {
- return {
- requiredAPIs: [],
- endpoints: {},
- environmentVariables: {},
- };
- }
- exports.empty = empty;
- function of(...endpoints) {
- const bkend = Object.assign({}, empty());
- for (const endpoint of endpoints) {
- bkend.endpoints[endpoint.region] = bkend.endpoints[endpoint.region] || {};
- if (bkend.endpoints[endpoint.region][endpoint.id]) {
- throw new Error("Trying to create a backend with the same endpiont twice");
- }
- bkend.endpoints[endpoint.region][endpoint.id] = endpoint;
- }
- return bkend;
- }
- exports.of = of;
- function merge(...backends) {
- const merged = of(...(0, functional_1.flattenArray)(backends.map((b) => allEndpoints(b))));
- const apiToReasons = {};
- for (const b of backends) {
- for (const { api, reason } of b.requiredAPIs) {
- const reasons = apiToReasons[api] || new Set();
- if (reason) {
- reasons.add(reason);
- }
- apiToReasons[api] = reasons;
- }
- merged.environmentVariables = Object.assign(Object.assign({}, merged.environmentVariables), b.environmentVariables);
- }
- for (const [api, reasons] of Object.entries(apiToReasons)) {
- merged.requiredAPIs.push({ api, reason: Array.from(reasons).join(" ") });
- }
- return merged;
- }
- exports.merge = merge;
- function isEmptyBackend(backend) {
- return (Object.keys(backend.requiredAPIs).length === 0 && Object.keys(backend.endpoints).length === 0);
- }
- exports.isEmptyBackend = isEmptyBackend;
- function functionName(cloudFunction) {
- return `projects/${cloudFunction.project}/locations/${cloudFunction.region}/functions/${cloudFunction.id}`;
- }
- exports.functionName = functionName;
- function scheduleIdForFunction(cloudFunction) {
- return `firebase-schedule-${cloudFunction.id}-${cloudFunction.region}`;
- }
- exports.scheduleIdForFunction = scheduleIdForFunction;
- async function existingBackend(context, forceRefresh) {
- if (!context.loadedExistingBackend || forceRefresh) {
- await loadExistingBackend(context);
- }
- return context.existingBackend;
- }
- exports.existingBackend = existingBackend;
- async function loadExistingBackend(ctx) {
- var _a;
- ctx.loadedExistingBackend = true;
- ctx.existingBackend = Object.assign({}, empty());
- ctx.unreachableRegions = {
- gcfV1: [],
- gcfV2: [],
- };
- const gcfV1Results = await gcf.listAllFunctions(ctx.projectId);
- for (const apiFunction of gcfV1Results.functions) {
- const endpoint = gcf.endpointFromFunction(apiFunction);
- ctx.existingBackend.endpoints[endpoint.region] =
- ctx.existingBackend.endpoints[endpoint.region] || {};
- ctx.existingBackend.endpoints[endpoint.region][endpoint.id] = endpoint;
- }
- ctx.unreachableRegions.gcfV1 = gcfV1Results.unreachable;
- let gcfV2Results;
- try {
- gcfV2Results = await gcfV2.listAllFunctions(ctx.projectId);
- const runResults = await Promise.all(gcfV2Results.functions.map((fn) => run.getService(fn.serviceConfig.service)));
- for (const [apiFunction, runService] of (0, functional_1.zip)(gcfV2Results.functions, runResults)) {
- const endpoint = gcfV2.endpointFromFunction(apiFunction);
- endpoint.concurrency = runService.spec.template.spec.containerConcurrency || 1;
- endpoint.cpu = +runService.spec.template.spec.containers[0].resources.limits.cpu;
- ctx.existingBackend.endpoints[endpoint.region] =
- ctx.existingBackend.endpoints[endpoint.region] || {};
- ctx.existingBackend.endpoints[endpoint.region][endpoint.id] = endpoint;
- }
- ctx.unreachableRegions.gcfV2 = gcfV2Results.unreachable;
- }
- catch (err) {
- if (err.status === 404 && ((_a = err.message) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes("method not found"))) {
- return;
- }
- throw err;
- }
- }
- async function checkAvailability(context, want) {
- var _a, _b, _c, _d;
- if (!context.loadedExistingBackend) {
- await loadExistingBackend(context);
- }
- const gcfV1Regions = new Set();
- const gcfV2Regions = new Set();
- for (const ep of allEndpoints(want)) {
- if (ep.platform === "gcfv1") {
- gcfV1Regions.add(ep.region);
- }
- else {
- gcfV2Regions.add(ep.region);
- }
- }
- const neededUnreachableV1 = (_a = context.unreachableRegions) === null || _a === void 0 ? void 0 : _a.gcfV1.filter((region) => gcfV1Regions.has(region));
- const neededUnreachableV2 = (_b = context.unreachableRegions) === null || _b === void 0 ? void 0 : _b.gcfV2.filter((region) => gcfV2Regions.has(region));
- if (neededUnreachableV1 === null || neededUnreachableV1 === void 0 ? void 0 : neededUnreachableV1.length) {
- throw new error_1.FirebaseError("The following Cloud Functions regions are currently unreachable:\n\t" +
- neededUnreachableV1.join("\n\t") +
- "\nThis deployment contains functions in those regions. Please try again in a few minutes, or exclude these regions from your deployment.");
- }
- if (neededUnreachableV2 === null || neededUnreachableV2 === void 0 ? void 0 : neededUnreachableV2.length) {
- throw new error_1.FirebaseError("The following Cloud Functions V2 regions are currently unreachable:\n\t" +
- neededUnreachableV2.join("\n\t") +
- "\nThis deployment contains functions in those regions. Please try again in a few minutes, or exclude these regions from your deployment.");
- }
- if ((_c = context.unreachableRegions) === null || _c === void 0 ? void 0 : _c.gcfV1.length) {
- utils.logLabeledWarning("functions", "The following Cloud Functions regions are currently unreachable:\n" +
- context.unreachableRegions.gcfV1.join("\n") +
- "\nCloud Functions in these regions won't be deleted.");
- }
- if ((_d = context.unreachableRegions) === null || _d === void 0 ? void 0 : _d.gcfV2.length) {
- utils.logLabeledWarning("functions", "The following Cloud Functions V2 regions are currently unreachable:\n" +
- context.unreachableRegions.gcfV2.join("\n") +
- "\nCloud Functions in these regions won't be deleted.");
- }
- }
- exports.checkAvailability = checkAvailability;
- function allEndpoints(backend) {
- return Object.values(backend.endpoints).reduce((accum, perRegion) => {
- return [...accum, ...Object.values(perRegion)];
- }, []);
- }
- exports.allEndpoints = allEndpoints;
- function someEndpoint(backend, predicate) {
- for (const endpoints of Object.values(backend.endpoints)) {
- if (Object.values(endpoints).some(predicate)) {
- return true;
- }
- }
- return false;
- }
- exports.someEndpoint = someEndpoint;
- function findEndpoint(backend, predicate) {
- for (const endpoints of Object.values(backend.endpoints)) {
- const endpoint = Object.values(endpoints).find(predicate);
- if (endpoint)
- return endpoint;
- }
- }
- exports.findEndpoint = findEndpoint;
- function matchingBackend(backend, predicate) {
- const filtered = Object.assign(Object.assign({}, backend), { endpoints: {} });
- for (const endpoint of allEndpoints(backend)) {
- if (!predicate(endpoint)) {
- continue;
- }
- filtered.endpoints[endpoint.region] = filtered.endpoints[endpoint.region] || {};
- filtered.endpoints[endpoint.region][endpoint.id] = endpoint;
- }
- return filtered;
- }
- exports.matchingBackend = matchingBackend;
- function regionalEndpoints(backend, region) {
- return backend.endpoints[region] ? Object.values(backend.endpoints[region]) : [];
- }
- exports.regionalEndpoints = regionalEndpoints;
- const hasEndpoint = (backend) => (endpoint) => {
- return (!!backend.endpoints[endpoint.region] && !!backend.endpoints[endpoint.region][endpoint.id]);
- };
- exports.hasEndpoint = hasEndpoint;
- const missingEndpoint = (backend) => (endpoint) => {
- return !(0, exports.hasEndpoint)(backend)(endpoint);
- };
- exports.missingEndpoint = missingEndpoint;
- function compareFunctions(left, right) {
- if (left.platform !== right.platform) {
- return right.platform < left.platform ? -1 : 1;
- }
- if (left.region < right.region) {
- return -1;
- }
- if (left.region > right.region) {
- return 1;
- }
- if (left.id < right.id) {
- return -1;
- }
- if (left.id > right.id) {
- return 1;
- }
- return 0;
- }
- exports.compareFunctions = compareFunctions;
|