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
JavaScript
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 };