UNPKG

container-image-scanner

Version:

🚨 EMERGENCY Bitnami Migration Scanner - Critical Timeline Aug 28/Sep 29, 2025. Enterprise scanner for 280+ Bitnami images, 118+ Helm charts with emergency migration automation to AWS alternatives.

222 lines (191 loc) • 8.53 kB
#!/usr/bin/env node const chalk = require('chalk'); class PartnerOpportunityAnalyzer { constructor() { this.partnerMatrix = { 'mongodb': { awsNative: 'Amazon DocumentDB', marketplacePartners: ['MongoDB Atlas'], migrationComplexity: 'MEDIUM', revenueOpportunity: 'HIGH' }, 'redis': { awsNative: 'Amazon ElastiCache for Redis', marketplacePartners: ['Redis Enterprise'], migrationComplexity: 'LOW', revenueOpportunity: 'MEDIUM' }, 'elasticsearch': { awsNative: 'Amazon OpenSearch Service', marketplacePartners: ['Elastic Cloud'], migrationComplexity: 'HIGH', revenueOpportunity: 'HIGH' }, 'kafka': { awsNative: 'Amazon MSK', marketplacePartners: ['Confluent Platform'], migrationComplexity: 'HIGH', revenueOpportunity: 'HIGH' }, 'mysql': { awsNative: 'Amazon RDS for MySQL / Aurora MySQL', marketplacePartners: ['PlanetScale (if available)'], migrationComplexity: 'MEDIUM', revenueOpportunity: 'HIGH' }, 'postgresql': { awsNative: 'Amazon RDS for PostgreSQL / Aurora PostgreSQL', marketplacePartners: ['Neon (if available)', 'Supabase (if available)'], migrationComplexity: 'MEDIUM', revenueOpportunity: 'HIGH' }, 'grafana': { awsNative: 'Amazon Managed Grafana', marketplacePartners: ['Grafana Cloud'], migrationComplexity: 'LOW', revenueOpportunity: 'MEDIUM' }, 'prometheus': { awsNative: 'Amazon Managed Prometheus', marketplacePartners: ['Grafana Cloud (with Prometheus)'], migrationComplexity: 'MEDIUM', revenueOpportunity: 'MEDIUM' } }; } analyzePartnerOpportunity(imageName) { const [name, tag] = imageName.split(':'); const service = name.split('/')[1]?.split(':')[0]; if (!name.includes('bitnami') || !this.partnerMatrix[service]) { return { applicable: false }; } const isVersioned = tag && tag !== 'latest' && /^\d+\.\d+/.test(tag); const partnerInfo = this.partnerMatrix[service]; return { applicable: true, imageName, service, isVersioned, migrationUrgency: isVersioned ? 'HIGH' : 'LOW', awsNative: partnerInfo.awsNative, marketplacePartners: partnerInfo.marketplacePartners, migrationComplexity: partnerInfo.migrationComplexity, revenueOpportunity: partnerInfo.revenueOpportunity, engagementStrategy: this.getEngagementStrategy(service, isVersioned), businessValue: this.calculateBusinessValue(service, isVersioned) }; } getEngagementStrategy(service, isVersioned) { const baseStrategy = { 'mongodb': 'Position MongoDB Atlas for production workloads with enterprise features', 'redis': 'Highlight Redis Enterprise clustering and security features', 'elasticsearch': 'Emphasize Elastic Cloud managed service benefits', 'kafka': 'Focus on Confluent Platform enterprise streaming capabilities', 'mysql': 'Promote Aurora MySQL for performance and availability', 'postgresql': 'Recommend Aurora PostgreSQL for enterprise features' }; const urgencyMultiplier = isVersioned ? ' - URGENT: Versioned image requires immediate migration planning' : ' - Standard timeline: Latest tag transitions automatically'; return baseStrategy[service] + urgencyMultiplier; } calculateBusinessValue(service, isVersioned) { const baseValues = { 'mongodb': { aws: 5000, partner: 3000, migration: 2000 }, 'redis': { aws: 2000, partner: 1500, migration: 500 }, 'elasticsearch': { aws: 4000, partner: 3500, migration: 1500 }, 'kafka': { aws: 6000, partner: 4000, migration: 2500 }, 'mysql': { aws: 3000, partner: 1000, migration: 1000 }, 'postgresql': { aws: 3500, partner: 1200, migration: 1200 } }; const multiplier = isVersioned ? 1.5 : 1.0; // Higher value for urgent migrations const base = baseValues[service] || { aws: 2000, partner: 1000, migration: 500 }; return { awsRevenueOpportunity: Math.round(base.aws * multiplier), partnerRevenueOpportunity: Math.round(base.partner * multiplier), migrationServicesOpportunity: Math.round(base.migration * multiplier), totalOpportunity: Math.round((base.aws + base.partner + base.migration) * multiplier) }; } generatePartnerReport(images) { console.log(chalk.bold.blue('šŸš€ AWS Marketplace & Partner Engagement Opportunities')); console.log(chalk.gray('Bitnami Migration → Partner Revenue Analysis\n')); const opportunities = images .map(img => this.analyzePartnerOpportunity(img)) .filter(opp => opp.applicable); if (opportunities.length === 0) { console.log(chalk.yellow('No Bitnami partner opportunities found in provided images.')); return; } // Group by urgency const urgent = opportunities.filter(opp => opp.migrationUrgency === 'HIGH'); const standard = opportunities.filter(opp => opp.migrationUrgency === 'LOW'); if (urgent.length > 0) { console.log(chalk.red.bold('🚨 HIGH URGENCY - Versioned Images (Immediate Partner Engagement)')); urgent.forEach(opp => this.displayOpportunity(opp)); console.log(''); } if (standard.length > 0) { console.log(chalk.green.bold('šŸ“ˆ STANDARD TIMELINE - Latest Tags (Proactive Engagement)')); standard.forEach(opp => this.displayOpportunity(opp)); console.log(''); } // Summary const totalRevenue = opportunities.reduce((sum, opp) => sum + opp.businessValue.totalOpportunity, 0); console.log(chalk.bold('šŸ’° Revenue Opportunity Summary:')); console.log(` Total Opportunity: ${chalk.green('$' + totalRevenue.toLocaleString())}`); console.log(` High Urgency: ${chalk.red(urgent.length)} opportunities`); console.log(` Standard Timeline: ${chalk.green(standard.length)} opportunities`); console.log(chalk.bold('\nšŸŽÆ Next Steps:')); console.log(' 1. Engage AWS field teams for customer conversations'); console.log(' 2. Activate marketplace partners for joint opportunities'); console.log(' 3. Position AWS managed services as preferred alternatives'); console.log(' 4. Leverage MAP funding for migration projects'); } displayOpportunity(opp) { console.log(chalk.bold(` šŸ“¦ ${opp.imageName}`)); console.log(` Service: ${opp.service}`); console.log(` Migration Complexity: ${this.getComplexityColor(opp.migrationComplexity)}`); console.log(` Revenue Opportunity: ${this.getRevenueColor(opp.revenueOpportunity)}`); console.log(chalk.blue(' šŸ„‡ AWS Managed Services (RECOMMENDED): ') + opp.awsNative); console.log(chalk.magenta(' 🄈 Marketplace Partners (Alternative): ') + opp.marketplacePartners.join(', ')); console.log(chalk.yellow(' Engagement Strategy:')); console.log(chalk.yellow(` ${opp.engagementStrategy}`)); console.log(chalk.green(' Business Value:')); console.log(chalk.green(` AWS Revenue: $${opp.businessValue.awsRevenueOpportunity.toLocaleString()}`)); console.log(chalk.green(` Partner Revenue: $${opp.businessValue.partnerRevenueOpportunity.toLocaleString()}`)); console.log(chalk.green(` Migration Services: $${opp.businessValue.migrationServicesOpportunity.toLocaleString()}`)); console.log(''); } getComplexityColor(complexity) { switch(complexity) { case 'LOW': return chalk.green(complexity); case 'MEDIUM': return chalk.yellow(complexity); case 'HIGH': return chalk.red(complexity); default: return chalk.gray(complexity); } } getRevenueColor(revenue) { switch(revenue) { case 'LOW': return chalk.gray(revenue); case 'MEDIUM': return chalk.yellow(revenue); case 'HIGH': return chalk.green(revenue); default: return chalk.gray(revenue); } } } // Test with sample images if (require.main === module) { const analyzer = new PartnerOpportunityAnalyzer(); const testImages = [ 'bitnami/mongodb:6.0.8', 'bitnami/redis:7.2.4', 'bitnami/elasticsearch:8.8.0', 'bitnami/kafka:3.5.0', 'bitnami/mysql:latest', 'bitnami/postgresql:15.4.0', 'nginx:latest' ]; analyzer.generatePartnerReport(testImages); } module.exports = { PartnerOpportunityAnalyzer };