@puls-atlas/cli
Version:
The Puls Atlas CLI tool for managing Atlas projects
134 lines • 5.85 kB
JavaScript
import * as features from '../../utils/feature.js';
import { logger } from '../../utils/index.js';
import { getSearchProvider, getSearchProviderDisplayName } from './providers/index.js';
import { resolveSearchReleaseTarget } from './release.js';
import { getSearchPromotionStatusViaSearchApi } from './searchApiAdmin.js';
import { createSearchSchemaLifecycleEntries, createSearchSchemaLifecycleGuidanceEntries, createSearchSchemaLifecycleSummaryRows } from './schemaLifecycle.js';
const formatReleaseValue = value => value ? value : 'not set';
const formatRoutingValue = (indexes, key) => {
const normalizedIndexes = Array.isArray(indexes) ? indexes : [];
if (normalizedIndexes.length === 0) {
return 'not set';
}
return normalizedIndexes.map(indexStatus => `${indexStatus.indexName}=${indexStatus[key] ?? 'not set'}`).join(', ');
};
const normalizeProviderPromotionStatus = (providerStatus, releaseTarget) => ({
message: providerStatus?.message ?? 'No provider promotion status details were reported.',
releaseId: providerStatus?.releaseId ?? releaseTarget.releaseId ?? null,
status: providerStatus?.status ?? 'not-supported',
target: providerStatus?.target ?? releaseTarget.target
});
const normalizeRoutingPromotionStatus = routingStatus => ({
indexes: Array.isArray(routingStatus?.indexes) ? routingStatus.indexes : [],
provider: routingStatus?.provider ?? null,
warnings: Array.isArray(routingStatus?.warnings) ? routingStatus.warnings : []
});
export const showSearchPromoteStatus = async (options = {}, dependencies = {}, cwd = process.cwd()) => {
const getSearchPromotionStatusViaSearchApiImpl = dependencies.getSearchPromotionStatusViaSearchApi ?? getSearchPromotionStatusViaSearchApi;
const loadFeatureContextImpl = dependencies.loadFeatureContext ?? features.loadFeatureContext;
const loggerImpl = dependencies.logger ?? logger;
const getSearchProviderImpl = dependencies.getSearchProvider ?? getSearchProvider;
const exit = dependencies.exit ?? (code => process.exit(code));
let spinner;
try {
spinner = loggerImpl.spinner('Loading Atlas search promotion status...');
const context = await loadFeatureContextImpl('search', options, {
cwd
});
const releaseTarget = resolveSearchReleaseTarget(context.config.release);
const provider = getSearchProviderImpl(context.config.provider);
const routingPromotionStatus = normalizeRoutingPromotionStatus(await getSearchPromotionStatusViaSearchApiImpl(context, dependencies));
const providerPromotionStatus = normalizeProviderPromotionStatus(await provider.getPromotionStatus(context, {
releaseTarget,
runCommand: dependencies.runCommand
}), releaseTarget);
spinner.succeed('Atlas search promotion status loaded.');
loggerImpl.summary('Promotion status', [{
label: 'Project',
value: context.projectId
}, context.environment ? {
label: 'Environment',
value: context.environment
} : null, {
label: 'Config',
value: context.configPath
}, {
label: 'Provider',
value: getSearchProviderDisplayName(provider, context.config.provider)
}, {
label: 'Release strategy',
value: releaseTarget.strategy
}, {
label: 'Active release',
value: formatReleaseValue(releaseTarget.active)
}, {
label: 'Candidate release',
value: formatReleaseValue(releaseTarget.candidate)
}, {
label: 'Promotion target',
value: releaseTarget.target
}, {
label: 'Target release id',
value: formatReleaseValue(releaseTarget.releaseId)
}, {
label: 'Routing status',
value: formatRoutingValue(routingPromotionStatus.indexes, 'status')
}, {
label: 'Candidate target',
value: formatRoutingValue(routingPromotionStatus.indexes, 'candidateTarget')
}, {
label: 'Rollback target',
value: formatRoutingValue(routingPromotionStatus.indexes, 'rollbackTarget')
}, {
label: 'Cleanup after',
value: formatRoutingValue(routingPromotionStatus.indexes, 'cleanupAfter')
}, {
label: 'Provider promotion status',
value: providerPromotionStatus.status
}, {
label: 'Provider target release',
value: formatReleaseValue(providerPromotionStatus.releaseId)
}, {
label: 'Provider status details',
value: providerPromotionStatus.message
}]);
const routingLifecycleSummaryRows = createSearchSchemaLifecycleSummaryRows(provider, routingPromotionStatus.indexes, {
includeAffectedIndexNames: true
});
if (routingLifecycleSummaryRows.length > 0) {
loggerImpl.summary('Routing lifecycle', routingLifecycleSummaryRows);
}
const routingLifecycleEntries = createSearchSchemaLifecycleEntries(provider, routingPromotionStatus.indexes);
if (routingLifecycleEntries.length > 0) {
loggerImpl.summary('Routing lifecycle details', routingLifecycleEntries);
}
const guidanceEntries = createSearchSchemaLifecycleGuidanceEntries(routingPromotionStatus.indexes, {
context
});
if (guidanceEntries.length > 0) {
loggerImpl.summary('Operator guidance', guidanceEntries);
}
for (const warning of routingPromotionStatus.warnings) {
loggerImpl.warning(warning);
}
return {
configPath: context.configPath,
providerPromotion: providerPromotionStatus,
release: {
active: releaseTarget.active,
candidate: releaseTarget.candidate,
strategy: releaseTarget.strategy
},
releaseTarget,
routing: routingPromotionStatus,
status: 'loaded'
};
} catch (error) {
if (spinner) {
spinner.fail('Failed to load Atlas search promotion status.');
}
loggerImpl.error(error.message, false);
return exit(1);
}
};
export default async options => showSearchPromoteStatus(options);