UNPKG

firebase-tools

Version:
121 lines (120 loc) 6.34 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getUpdateReason = exports.provisionCloudSql = void 0; const cloudSqlAdminClient = require("../gcp/cloudsql/cloudsqladmin"); const utils = require("../utils"); const checkIam_1 = require("./checkIam"); const utils_1 = require("../utils"); const logger_1 = require("../logger"); const GOOGLE_ML_INTEGRATION_ROLE = "roles/aiplatform.user"; const freeTrial_1 = require("./freeTrial"); async function provisionCloudSql(args) { let connectionName = ""; const { projectId, location, instanceId, databaseId, enableGoogleMlIntegration, waitForCreation, silent, dryRun, } = args; try { const existingInstance = await cloudSqlAdminClient.getInstance(projectId, instanceId); silent || utils.logLabeledBullet("dataconnect", `Found existing instance ${instanceId}.`); connectionName = (existingInstance === null || existingInstance === void 0 ? void 0 : existingInstance.connectionName) || ""; const why = getUpdateReason(existingInstance, enableGoogleMlIntegration); if (why) { const cta = dryRun ? `It will be updated on your next deploy.` : `Updating instance. This may take a few minutes...`; silent || utils.logLabeledBullet("dataconnect", `Instance ${instanceId} settings not compatible with Firebase Data Connect. ` + cta + why); if (!dryRun) { await (0, utils_1.promiseWithSpinner)(() => cloudSqlAdminClient.updateInstanceForDataConnect(existingInstance, enableGoogleMlIntegration), "Updating your instance..."); silent || utils.logLabeledBullet("dataconnect", "Instance updated"); } } } catch (err) { if (err.status !== 404) { throw err; } cmekWarning(); const cta = dryRun ? "It will be created on your next deploy" : "Creating it now."; const freeTrialUsed = await (0, freeTrial_1.checkFreeTrialInstanceUsed)(projectId); silent || utils.logLabeledBullet("dataconnect", `CloudSQL instance '${instanceId}' not found.` + cta + freeTrialUsed ? "" : `\nThis instance is provided under the terms of the Data Connect no-cost trial ${(0, freeTrial_1.freeTrialTermsLink)()}` + dryRun ? `\nMonitor the progress at ${cloudSqlAdminClient.instanceConsoleLink(projectId, instanceId)}` : ""); if (!dryRun) { const newInstance = await (0, utils_1.promiseWithSpinner)(() => cloudSqlAdminClient.createInstance({ projectId, location, instanceId, enableGoogleMlIntegration, waitForCreation, freeTrial: !freeTrialUsed, }), "Creating your instance..."); if (newInstance) { silent || utils.logLabeledBullet("dataconnect", "Instance created"); connectionName = (newInstance === null || newInstance === void 0 ? void 0 : newInstance.connectionName) || ""; } else { silent || utils.logLabeledBullet("dataconnect", "Cloud SQL instance creation started - it should be ready shortly. Database and users will be created on your next deploy."); return connectionName; } } } try { await cloudSqlAdminClient.getDatabase(projectId, instanceId, databaseId); silent || utils.logLabeledBullet("dataconnect", `Found existing database ${databaseId}.`); } catch (err) { if (err.status === 404) { if (dryRun) { silent || utils.logLabeledBullet("dataconnect", `Database ${databaseId} not found. It will be created on your next deploy.`); } else { silent || utils.logLabeledBullet("dataconnect", `Database ${databaseId} not found, creating it now...`); await cloudSqlAdminClient.createDatabase(projectId, instanceId, databaseId); silent || utils.logLabeledBullet("dataconnect", `Database ${databaseId} created.`); } } else { logger_1.logger.debug(`Unexpected error from CloudSQL: ${err}`); silent || utils.logLabeledWarning("dataconnect", `Database ${databaseId} is not accessible.`); } } if (enableGoogleMlIntegration && !dryRun) { await (0, checkIam_1.grantRolesToCloudSqlServiceAccount)(projectId, instanceId, [GOOGLE_ML_INTEGRATION_ROLE]); } return connectionName; } exports.provisionCloudSql = provisionCloudSql; function getUpdateReason(instance, requireGoogleMlIntegration) { var _a, _b, _c, _d; let reason = ""; const settings = instance.settings; if (!((_a = settings.ipConfiguration) === null || _a === void 0 ? void 0 : _a.ipv4Enabled)) { reason += "\n - to enable public IP."; } if (requireGoogleMlIntegration) { if (!settings.enableGoogleMlIntegration) { reason += "\n - to enable Google ML integration."; } if (!((_b = settings.databaseFlags) === null || _b === void 0 ? void 0 : _b.some((f) => f.name === "cloudsql.enable_google_ml_integration" && f.value === "on"))) { reason += "\n - to enable Google ML integration database flag."; } } const isIamEnabled = (_d = (_c = settings.databaseFlags) === null || _c === void 0 ? void 0 : _c.some((f) => f.name === "cloudsql.iam_authentication" && f.value === "on")) !== null && _d !== void 0 ? _d : false; if (!isIamEnabled) { reason += "\n - to enable IAM authentication database flag."; } return reason; } exports.getUpdateReason = getUpdateReason; function cmekWarning() { const message = "Cloud SQL instances created via the Firebase CLI do not support customer managed encryption keys.\n" + "If you'd like to use a CMEK to encrypt your data, first create a CMEK encrypted instance (https://cloud.google.com/sql/docs/postgres/configure-cmek#createcmekinstance).\n" + "Then, edit your `dataconnect.yaml` file to use the encrypted instance and redeploy."; utils.logLabeledWarning("dataconnect", message); }