@catladder/cli
Version:
Panter cli tool for cloud CI/CD and DevOps
161 lines (160 loc) ⢠6.72 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.commandProjectRestoreDb = void 0;
const defineCommand_1 = require("../../core/defineCommand");
const getProjectConfig_1 = require("../../config/getProjectConfig");
const availability_1 = require("../availability");
const startProxy_1 = require("../../gcloud/cloudSql/startProxy");
const parseConnectionString_1 = require("../../gcloud/cloudSql/parseConnectionString");
const copyDb_1 = require("../../gcloud/cloudSql/copyDb");
const pipeline_1 = require("../../../../pipeline/src/index.js");
const componentHasCloudSql = context => {
var _a, _b, _c;
const deployConfig = (_a = context.deploy) === null || _a === void 0 ? void 0 : _a.config;
if ((0, pipeline_1.isOfDeployType)(deployConfig, "google-cloudrun")) {
return !!deployConfig.cloudSql;
}
if ((0, pipeline_1.isOfDeployType)(deployConfig, "kubernetes")) {
return !!((_c = (_b = deployConfig.values) === null || _b === void 0 ? void 0 : _b.cloudsql) === null || _c === void 0 ? void 0 : _c.enabled);
}
return false;
};
exports.commandProjectRestoreDb = (0, defineCommand_1.defineCommand)({
name: "project cloudsql restore-db",
description: "restores a project db from one source to another target",
group: "project",
isAvailable: (0, availability_1.hasCloudSql)(),
inputs: {
source: {
type: "string",
message: "Source instance? š¤ ",
choices: async () => {
const allContexts = await (0, getProjectConfig_1.getAllPipelineContexts)(undefined, {
includeLocal: true
});
const sortByEnv = (a, b) => {
const aLocal = a.startsWith("local:");
const bLocal = b.startsWith("local:");
if (aLocal !== bLocal) return aLocal ? 1 : -1;
return a.localeCompare(b);
};
return allContexts.filter(componentHasCloudSql).map(c => `${c.env}:${c.name}`).sort(sortByEnv);
}
},
target: {
type: "string",
message: "target env? š¤ ",
choices: async () => {
const allContexts = await (0, getProjectConfig_1.getAllPipelineContexts)(undefined, {
includeLocal: true
});
const sortByEnv = (a, b) => {
const aLocal = a.startsWith("local:");
const bLocal = b.startsWith("local:");
if (aLocal !== bLocal) return aLocal ? 1 : -1;
return a.localeCompare(b);
};
return allContexts.filter(componentHasCloudSql).map(c => {
const value = `${c.env}:${c.name}`;
const isProd = c.environment.envType === "prod";
return {
name: isProd ? `ā ļø ${value}` : value,
value
};
}).sort((a, b) => sortByEnv(a.value, b.value));
}
},
confirmInstance: {
type: "string",
message: "confirm: "
}
},
execute: async ctx => {
var _a, _b, _c, _d, _e;
const source = await ctx.get("source");
const [sourceEnv, sourceComponent] = source.split(":");
const sourceContext = await (0, getProjectConfig_1.getPipelineContextByChoice)(sourceEnv, sourceComponent);
const sourceEnvVars = await (0, getProjectConfig_1.getEnvVarsResolved)(ctx, sourceContext.env, sourceContext.name);
let sourceProxy;
let sourceDbName;
let sourceUsername;
let sourcePassword;
let targetUsername;
let targetPassword;
let targetProxy;
let sourcePort;
let targetPort;
let targetDbName;
const closeAll = () => {
sourceProxy === null || sourceProxy === void 0 ? void 0 : sourceProxy.stop();
targetProxy === null || targetProxy === void 0 ? void 0 : targetProxy.stop();
};
if (sourceEnv === "local") {
const parsersResult = (0, parseConnectionString_1.parseConnectionString)(sourceEnvVars.DATABASE_URL.toString());
sourcePort = (_b = (_a = parsersResult.hosts) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.port;
sourceUsername = parsersResult.username;
sourcePassword = parsersResult.password;
sourceDbName = parsersResult.endpoint;
} else {
sourcePort = 54399;
sourceProxy = await (0, startProxy_1.startCloudSqlProxyInBackground)({
instanceName: sourceEnvVars.CLOUD_SQL_INSTANCE_CONNECTION_NAME.toString(),
localPort: sourcePort
});
sourceUsername = sourceEnvVars.DB_USER.toString();
sourcePassword = sourceEnvVars.DB_PASSWORD.toString();
sourceDbName = (_c = sourceEnvVars.DB_NAME) === null || _c === void 0 ? void 0 : _c.toString();
}
const target = await ctx.get("target");
const [targetEnv, targetComponent] = target.split(":");
const targetContext = await (0, getProjectConfig_1.getPipelineContextByChoice)(targetEnv, targetComponent);
const targetEnvVars = await (0, getProjectConfig_1.getEnvVarsResolved)(ctx, targetContext.env, targetContext.name);
if (targetEnv === "local") {
const parsersResult = (0, parseConnectionString_1.parseConnectionString)(targetEnvVars.DATABASE_URL.toString());
targetPort = (_e = (_d = parsersResult.hosts) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.port;
targetUsername = parsersResult.username;
targetPassword = parsersResult.password;
targetDbName = parsersResult.endpoint;
} else {
targetPort = 54499;
targetProxy = await (0, startProxy_1.startCloudSqlProxyInBackground)({
instanceName: targetEnvVars.CLOUD_SQL_INSTANCE_CONNECTION_NAME.toString(),
localPort: targetPort
});
targetUsername = targetEnvVars.DB_USER.toString();
targetPassword = targetEnvVars.DB_PASSWORD.toString();
targetDbName = targetEnvVars.DB_NAME.toString();
}
const shouldContinue = await ctx.confirm(`This will drop ${targetEnv}/${targetDbName} and replace it with ${sourceEnv}/${sourceDbName}. Continue? š¤ `);
if (!shouldContinue) {
ctx.log("abort");
closeAll();
return;
}
if (targetContext.environment.envType === "prod") {
ctx.log(`\nšØ You are overriding a production environment. Please type in ${targetEnvVars.CLOUD_SQL_INSTANCE_CONNECTION_NAME} to continue\n\n`);
const confirmInstance = await ctx.get("confirmInstance");
if (confirmInstance !== targetEnvVars.CLOUD_SQL_INSTANCE_CONNECTION_NAME) {
ctx.log("abort");
closeAll();
return;
}
}
try {
await (0, copyDb_1.spawnCopyDb)({
targetPassword,
targetPort,
targetUsername,
sourceUsername,
sourcePassword,
sourcePort,
sourceDbName,
targetDbName
});
} finally {
closeAll();
}
}
});