UNPKG

skeet

Version:

Full-stack TypeScript Serverless Framework

169 lines (162 loc) 4.69 kB
import { execSyncCmd } from '@/lib/execSyncCmd' import prompt from 'prompt' import percentEncode from '@stdlib/string-percent-encode' import fs from 'fs' import { Logger } from '@/lib/logger' import { execSync } from 'child_process' import { getNetworkConfig, getContainerRegion, API_ENV_PRODUCTION_PATH, API_ENV_BUILD_PATH, genSecret, regionToTimezone, } from '@/lib/getNetworkConfig' import { patchSQL } from './patchSQL' export const runSqlCreate = async ( projectId: string, appName: string, region: string, databaseVersion: string, cpu: string, memory: string ) => { const dbPassPrompt = { properties: { password: { description: 'Enter DB Root Password', hidden: true, replace: '*', }, passwordConfirm: { description: 'Confirm Password', hidden: true, replace: '*', }, }, } prompt.start() prompt.get(dbPassPrompt, async (err, result) => { if (result.password !== result.passwordConfirm) { console.log('password does not match!') } else { const networkName = (await getNetworkConfig(projectId, appName)) .networkName const password = String(result.password) await createSQL( projectId, appName, region, password, databaseVersion, cpu, memory ) const encodedPassword = percentEncode(password) const databaseIp = await getDatabaseIp(projectId, appName) await generateEnvBuild(appName, databaseIp, encodedPassword) await patchSQL(projectId, appName, '', '', networkName) const databasePrivateIp = await getDatabaseIp(projectId, appName, true) await generateEnvProduction( projectId, appName, region, databasePrivateIp, encodedPassword ) } }) } export const generateEnvBuild = async ( appName: string, databaseIp: string, encodedPassword: string ) => { const filePath = API_ENV_BUILD_PATH const databaseUrl = `DATABASE_URL=postgresql://postgres:${encodedPassword}@${databaseIp}:5432/skeet-${appName}-production?schema=public\n` const nodeSetting = 'NO_PEER_DEPENDENCY_CHECK=1\nSKEET_ENV=production' const envFile = databaseUrl + nodeSetting fs.writeFileSync(filePath, envFile, { flag: 'w' }) Logger.success(`successfully exported! - ${filePath}`) } export const generateEnvProduction = async ( projectId: string, appName: string, region: string, databaseIp: string, encodedPassword: string ) => { const filePath = API_ENV_PRODUCTION_PATH const cRegion = await getContainerRegion(region) const secretKey = await genSecret(appName) const secretKeyPW = await genSecret(appName) const secretKeyCrypto = await genSecret(appName) const timeZone = await regionToTimezone(region) const envProduction = [ `SKEET_APP_NAME=${appName}\n`, `SKEET_GCP_PROJECT_ID=${projectId}\n`, `GOOGLE_CLOUD_PROJECT=${projectId}\n`, `SKEET_GCP_REGION=${region}\n`, `SKEET_GCP_TASK_REGION=${region}\n`, `SKEET_GCP_DB_PASSWORD=${encodedPassword}\n`, `SKEET_CONTAINER_REGION=${cRegion}\n`, `SKEET_GCP_DB_PRIVATE_IP=${databaseIp}\n`, `SKEET_JWT_SALT=${secretKey}\n`, `SKEET_BASE_URL=https://${appName}.com\n`, `SKEET_PW_SALT=${secretKeyPW}\n`, `SKEET_CRYPTO_SALT=${secretKeyCrypto}\n`, `TZ=${timeZone}`, ] envProduction.forEach((keyValue) => { fs.writeFileSync(filePath, keyValue, { flag: 'a' }) }) Logger.success(`successfully exported! - ${filePath}`) } export const getDatabaseIp = async ( projectId: string, appName: string, privateIp: boolean = false ) => { try { const ipCol = privateIp === true ? '$6' : '$5' const cmd = `gcloud sql instances list --project=${projectId} | grep ${appName} | awk '{print ${ipCol}}'` const res = execSync(cmd) const databaseIp = String(res).replace(/\r?\n/g, '') return databaseIp } catch (error) { return `error: ${error}` } } export const createSQL = async ( projectId: string, appName: string, region: string = 'europe-west4-b', dbPassword: string = 'postgres', databaseVersion: string = 'POSTGRES_14', cpu: string = '1', memory: string = '4096MB' ) => { const instanceName = (await getNetworkConfig(projectId, appName)).instanceName const shCmd = [ 'gcloud', 'sql', 'instances', 'create', instanceName, '--database-version', databaseVersion, '--cpu', cpu, '--memory', memory, '--region', region, '--project', projectId, '--root-password', dbPassword, '--database-flags', 'cloudsql.iam_authentication=on', ] await execSyncCmd(shCmd) }