UNPKG

@aws-amplify/cli-internal

Version:
117 lines 5.93 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AmplifyDriftDetector = exports.run = void 0; const amplify_cli_core_1 = require("@aws-amplify/amplify-cli-core"); const amplify_prompts_1 = require("@aws-amplify/amplify-prompts"); const chalk_1 = __importDefault(require("chalk")); const detect_stack_drift_1 = require("./drift/detect-stack-drift"); const detect_local_drift_1 = require("./drift/detect-local-drift"); const detect_template_drift_1 = require("./drift/detect-template-drift"); const services_1 = require("./drift/services"); const spinning_logger_1 = require("./gen2-migration/_common/spinning-logger"); const run = async (context) => { const logger = new spinning_logger_1.SpinningLogger('drift'); const detector = new AmplifyDriftDetector(context, logger); logger.start('Drift detection'); const result = await detector.detect(); logger.succeed('Drift detection'); if (result.report) { amplify_prompts_1.printer.info(result.report); amplify_prompts_1.printer.info(chalk_1.default.yellow('Drift detected')); } else { amplify_prompts_1.printer.info(chalk_1.default.green('No drift detected')); } if (result.code !== 0) { process.exitCode = result.code; } }; exports.run = run; class AmplifyDriftDetector { constructor(context, logger) { this.context = context; this.logger = logger; this.cfnService = new services_1.CloudFormationService(this.logger); this.configService = new services_1.AmplifyConfigService(); } async detect() { this.configService.validateAmplifyProject(); this.logger.debug('Amplify project validated'); this.context.amplify.constructExeInfo(this.context); const stackName = this.configService.getRootStackName(); this.logger.debug(`Root Stack: ${stackName}`); const cfn = await this.cfnService.getClient(this.context); this.logger.debug('CloudFormation client initialized'); if (!(await this.cfnService.validateStackExists(cfn, stackName))) { throw new amplify_cli_core_1.AmplifyError('StackNotFoundError', { message: `Stack ${stackName} does not exist.`, resolution: 'Has the project been deployed? Run "amplify push" to deploy your project.', }); } let phase1Results; let phase2Results; let phase3Results; this.logger.debug('Syncing cloud backend'); const syncSuccess = await this.cfnService.syncCloudBackendFromS3(this.context); try { this.logger.push('CloudFormation drift'); phase1Results = await (0, detect_stack_drift_1.detectStackDriftRecursive)(cfn, stackName, this.logger); this.logger.pop(); this.logger.debug('Phase 1 complete'); if (!syncSuccess) { phase2Results = { changes: [], skipped: true, skipReason: 'S3 backend sync failed - cannot compare templates', }; phase3Results = { skipped: true, skipReason: 'S3 backend sync failed - cannot compare local vs cloud', }; this.logger.warn(chalk_1.default.yellow('Cloud backend sync failed - template drift and local drift will be skipped')); } else { this.logger.debug('S3 sync completed successfully'); this.logger.push('Template changes'); this.logger.debug('Checking for template drift using changesets...'); phase2Results = await (0, detect_template_drift_1.detectTemplateDrift)(stackName, this.logger, cfn); this.logger.pop(); this.logger.debug(`Phase 2 complete: ${phase2Results.changes.length} changes`); this.logger.push('Local changes'); this.logger.debug('Checking local files vs cloud backend...'); phase3Results = await (0, detect_local_drift_1.detectLocalDrift)(this.context); this.logger.pop(); this.logger.debug('Phase 3 complete'); } } catch (error) { this.logger.pop(); throw error; } const driftReport = (0, services_1.createUnifiedCategoryView)(phase1Results, phase2Results, phase3Results); const hasAnyErrors = phase1Results.incomplete || phase2Results.skipped || phase3Results.skipped; if (hasAnyErrors) { this.logger.warn(chalk_1.default.yellow('Drift detection encountered errors, results may be incomplete:')); if (phase1Results.incomplete) { this.logger.warn(chalk_1.default.yellow(`CloudFormation drift check incomplete - ${phase1Results.skippedStacks.length} nested stack(s) skipped`)); for (const skippedStack of phase1Results.skippedStacks) { this.logger.debug(` - ${skippedStack}`); } } if (phase2Results.skipped) { this.logger.warn(chalk_1.default.yellow(`Template drift error: ${phase2Results.skipReason}`)); } if (phase3Results.skipped) { this.logger.warn(chalk_1.default.yellow(`Local drift error: ${phase3Results.skipReason}`)); } this.logger.debug('Exit code 1: Incomplete drift detection - cannot guarantee no drift'); return { code: 1, report: driftReport !== null && driftReport !== void 0 ? driftReport : undefined }; } return { code: driftReport ? 1 : 0, report: driftReport }; } } exports.AmplifyDriftDetector = AmplifyDriftDetector; //# sourceMappingURL=drift.js.map