UNPKG

@puls-atlas/cli

Version:

The Puls Atlas CLI tool for managing Atlas projects

134 lines 5.85 kB
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);