UNPKG

@puls-atlas/cli

Version:

The Puls Atlas CLI tool for managing Atlas projects

107 lines 4.54 kB
import { execFileSync as nodeExecFileSync } from 'child_process'; import { SEARCH_RESOURCE_NAMES } from './resourceNames.js'; import { resolveSearchReleaseTarget } from './release.js'; import { resolveSearchCloudRunDeployConfig, resolveSearchRuntimeContract } from './planning.js'; import { createSearchReindexSessionId } from './reindexSession.js'; import { normalizeOptionalString } from '../../utils/value.js'; import { PULS_ATLAS_SEARCH_INDEXES_ENV, PULS_ATLAS_SEARCH_REINDEX_SESSION_ID_ENV, PULS_ATLAS_SEARCH_RELEASE_ID_ENV, PULS_ATLAS_SEARCH_RELEASE_TARGET_ENV } from './runtimeEnv.js'; import { createGcloudRunJobExecuteCommand, getCommandErrorMessage, isGcloudResourceNotFoundError, runGcloudFileCommand } from '../../utils/gcloud.js'; const toEnvironmentVariableMap = environmentVariables => Object.fromEntries(environmentVariables.map(environmentVariable => [environmentVariable.name, environmentVariable.value])); export const resolveSearchBackfillJobDeployment = context => { const cloudRunConfig = resolveSearchCloudRunDeployConfig(context); const runtimeContract = resolveSearchRuntimeContract(context); return { image: cloudRunConfig.jobImage, jobName: SEARCH_RESOURCE_NAMES.backfillJob, projectId: context.projectId, region: cloudRunConfig.region, runtimeEnvironmentVariables: toEnvironmentVariableMap(runtimeContract.requiredEnvironmentVariables) }; }; export const inspectSearchBackfillJob = (context, options = {}) => { const { runCommand = nodeExecFileSync } = options; const deployment = resolveSearchBackfillJobDeployment(context); try { const resolvedJobName = runGcloudFileCommand(['run', 'jobs', 'describe', deployment.jobName, `--project=${deployment.projectId}`, `--region=${deployment.region}`, '--format="value(metadata.name)"'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }, runCommand).trim(); return { exists: resolvedJobName.length > 0, jobName: deployment.jobName, projectId: deployment.projectId, region: deployment.region }; } catch (error) { if (isGcloudResourceNotFoundError(error)) { return { exists: false, jobName: deployment.jobName, projectId: deployment.projectId, region: deployment.region }; } throw new Error(`Failed to inspect Atlas search backfill job ${deployment.jobName} in project ${deployment.projectId}, region ${deployment.region}. ` + `${normalizeOptionalString(getCommandErrorMessage(error)) ?? error.message}`); } }; export const ensureSearchBackfillJobExists = (context, options = {}) => { const inspection = inspectSearchBackfillJob(context, options); if (!inspection.exists) { throw new Error(`Atlas search backfill job ${inspection.jobName} was not found in project ${inspection.projectId}, region ${inspection.region}. ` + 'Run "atlas search apply" to apply the Terraform-managed backfill job workflow before running "atlas search run <backfill|reindex> --indexes <...>".'); } return inspection; }; export const resolveSearchBackfillJobExecution = ({ action, context, indexNames, now = () => new Date() }) => { if (!['backfill', 'reindex'].includes(action)) { throw new Error(`Unsupported Atlas search post-deploy action: ${action}.`); } const deployment = resolveSearchBackfillJobDeployment(context); const releaseTarget = resolveSearchReleaseTarget(context.config?.release); const environmentVariables = { [PULS_ATLAS_SEARCH_INDEXES_ENV]: indexNames.join(',') }; if (releaseTarget.releaseId) { environmentVariables[PULS_ATLAS_SEARCH_RELEASE_ID_ENV] = releaseTarget.releaseId; environmentVariables[PULS_ATLAS_SEARCH_RELEASE_TARGET_ENV] = releaseTarget.target; } if (action === 'reindex') { environmentVariables[PULS_ATLAS_SEARCH_REINDEX_SESSION_ID_ENV] = createSearchReindexSessionId(now); } return { action, environmentVariables, jobName: deployment.jobName, projectId: deployment.projectId, region: deployment.region, releaseTarget }; }; export const createSearchBackfillJobExecutionCommand = ({ action, context, indexNames, now = () => new Date() }) => { const execution = resolveSearchBackfillJobExecution({ action, context, indexNames, now }); return { ...execution, ...createGcloudRunJobExecuteCommand({ environmentVariables: execution.environmentVariables, jobName: execution.jobName, projectId: execution.projectId, region: execution.region }) }; };