@puls-atlas/cli
Version:
The Puls Atlas CLI tool for managing Atlas projects
107 lines • 4.54 kB
JavaScript
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
})
};
};