diff --git a/src/apphosting/backend.ts b/src/apphosting/backend.ts index 8a5aa579901..285b141eac4 100644 --- a/src/apphosting/backend.ts +++ b/src/apphosting/backend.ts @@ -17,7 +17,7 @@ import { Backend, BackendOutputOnlyFields, API_VERSION } from "../gcp/apphosting import { addServiceAccountToRoles } from "../gcp/resourceManager"; import * as iam from "../gcp/iam"; import { FirebaseError, getErrStatus, getError } from "../error"; -import { promptOnce } from "../prompt"; +import { promptOnce, confirm } from "../prompt"; import { DEFAULT_LOCATION } from "./constants"; import { ensure } from "../ensureApiEnabled"; import * as deploymentTool from "../deploymentTool"; @@ -474,3 +474,51 @@ export async function getBackendForAmbiguousLocation( }); return backendsByLocation.get(location)!; } + +/** + * Fetches a backend from the server. If there are multiple backends with the name, it will fetch the first + * in the list and warn the user that there are other backends with the same name that need to be deleted. If + * the force option is specified nad multiple backends have the same name, it throws an error. + */ +export async function getBackend( + projectId: string, + backendId: string, + force?: boolean, +): Promise { + // TODO: call apphosting.getBackend() once all duplicate named backends have been deleted. + let { unreachable, backends } = await apphosting.listBackends(projectId, "-"); + backends = backends.filter( + (backend) => apphosting.parseBackendName(backend.name).id === backendId, + ); + if (backends.length > 0) { + if (backends.length > 1) { + logWarning( + `You have multiple backends with the same ${backendId} ID. This is no longer supported. ` + + "Please delete and recreate any backends that share an ID with another backend." + ) + if (force) { + throw new FirebaseError( + `Force cannot be used when multiple backends share the same ID`, + ); + }; + const options = {force: force, nonInteractive: false }; + const confirmed = await confirm({ + ...options, + message: `Using backend ${backends[0].name} continue?`, + }); + if (!confirmed) { + throw new FirebaseError("Command aborted."); + } + } + return backends[0]; + } + if (unreachable && unreachable.length !== 0) { + logWarning( + `Backends with the following primary regions are unreachable: ${unreachable}.\n` + + "If your backend is in one of these regions, please try again later." + ); + }; + throw new FirebaseError( + `No backend named ${backendId} found.`, + ); +}