container-image-scanner
Version:
Enterprise Container Image Scanner with AWS Security Best Practices. Scan EKS clusters for Bitnami container image dependencies and generate migration guidance for AWS ECR alternatives.
243 lines (202 loc) ⢠11.6 kB
JavaScript
const chalk = require('chalk');
class ComprehensiveServiceMapper {
constructor() {
// Comprehensive mapping for 280+ Bitnami images
this.serviceMapping = {
// Databases & Data Stores
'mysql': { aws: 'Amazon RDS for MySQL', type: 'Database', specialist: 'Database SA' },
'postgresql': { aws: 'Amazon RDS for PostgreSQL', type: 'Database', specialist: 'Database SA' },
'mongodb': { aws: 'Amazon DocumentDB', type: 'Database', specialist: 'Database SA' },
'redis': { aws: 'Amazon ElastiCache for Redis', type: 'Cache', specialist: 'Database SA' },
'memcached': { aws: 'Amazon ElastiCache for Memcached', type: 'Cache', specialist: 'Database SA' },
'mariadb': { aws: 'Amazon RDS for MariaDB', type: 'Database', specialist: 'Database SA' },
'cassandra': { aws: 'Amazon Keyspaces', type: 'Database', specialist: 'Database SA' },
'influxdb': { aws: 'Amazon Timestream', type: 'Time Series DB', specialist: 'Analytics SA' },
'neo4j': { aws: 'Amazon Neptune', type: 'Graph Database', specialist: 'Database SA' },
'etcd': { aws: 'Amazon EKS (managed etcd)', type: 'Key-Value Store', specialist: 'Container SA' },
// Analytics & Search
'elasticsearch': { aws: 'Amazon OpenSearch Service', type: 'Search', specialist: 'Analytics SA' },
'opensearch': { aws: 'Amazon OpenSearch Service', type: 'Search', specialist: 'Analytics SA' },
'kibana': { aws: 'Amazon OpenSearch Dashboards', type: 'Visualization', specialist: 'Analytics SA' },
'grafana': { aws: 'Amazon Managed Grafana', type: 'Monitoring', specialist: 'Analytics SA' },
'prometheus': { aws: 'Amazon Managed Prometheus', type: 'Monitoring', specialist: 'Analytics SA' },
'solr': { aws: 'Amazon OpenSearch Service', type: 'Search', specialist: 'Analytics SA' },
// Messaging & Streaming
'kafka': { aws: 'Amazon MSK', type: 'Streaming', specialist: 'Integration SA' },
'rabbitmq': { aws: 'Amazon MQ', type: 'Messaging', specialist: 'Integration SA' },
'nats': { aws: 'Amazon MQ', type: 'Messaging', specialist: 'Integration SA' },
'pulsar': { aws: 'Amazon MSK', type: 'Streaming', specialist: 'Integration SA' },
'activemq': { aws: 'Amazon MQ', type: 'Messaging', specialist: 'Integration SA' },
'zookeeper': { aws: 'Amazon MSK (managed Zookeeper)', type: 'Coordination', specialist: 'Integration SA' },
// Big Data & Analytics
'spark': { aws: 'Amazon EMR', type: 'Big Data', specialist: 'Analytics SA' },
'hadoop': { aws: 'Amazon EMR', type: 'Big Data', specialist: 'Analytics SA' },
'airflow': { aws: 'Amazon MWAA', type: 'Workflow', specialist: 'Analytics SA' },
'jupyter': { aws: 'Amazon SageMaker', type: 'ML/Analytics', specialist: 'ML SA' },
'superset': { aws: 'Amazon QuickSight', type: 'BI', specialist: 'Analytics SA' },
'mlflow': { aws: 'Amazon SageMaker', type: 'ML Ops', specialist: 'ML SA' },
// Web Servers & Load Balancers
'nginx': { aws: 'AWS Application Load Balancer', type: 'Load Balancer', specialist: 'Solutions SA' },
'apache': { aws: 'AWS Application Load Balancer', type: 'Web Server', specialist: 'Solutions SA' },
'haproxy': { aws: 'AWS Network Load Balancer', type: 'Load Balancer', specialist: 'Solutions SA' },
'envoy': { aws: 'AWS App Mesh', type: 'Service Mesh', specialist: 'Container SA' },
'traefik': { aws: 'AWS Load Balancer Controller', type: 'Ingress', specialist: 'Container SA' },
// Development & Runtime
'node': { aws: 'AWS Lambda (Node.js)', type: 'Runtime', specialist: 'Solutions SA' },
'python': { aws: 'AWS Lambda (Python)', type: 'Runtime', specialist: 'Solutions SA' },
'java': { aws: 'AWS Lambda (Java)', type: 'Runtime', specialist: 'Solutions SA' },
'go': { aws: 'AWS Lambda (Go)', type: 'Runtime', specialist: 'Solutions SA' },
'dotnet': { aws: 'AWS Lambda (.NET)', type: 'Runtime', specialist: 'Solutions SA' },
'php': { aws: 'AWS Elastic Beanstalk', type: 'Runtime', specialist: 'Solutions SA' },
'ruby': { aws: 'AWS Elastic Beanstalk', type: 'Runtime', specialist: 'Solutions SA' },
// CI/CD & DevOps
'jenkins': { aws: 'AWS CodeBuild + CodePipeline', type: 'CI/CD', specialist: 'DevOps SA' },
'gitlab-runner': { aws: 'AWS CodeBuild', type: 'CI/CD', specialist: 'DevOps SA' },
'sonarqube': { aws: 'Amazon CodeGuru', type: 'Code Quality', specialist: 'DevOps SA' },
'nexus': { aws: 'AWS CodeArtifact', type: 'Artifact Repository', specialist: 'DevOps SA' },
'artifactory': { aws: 'AWS CodeArtifact', type: 'Artifact Repository', specialist: 'DevOps SA' },
'harbor': { aws: 'Amazon ECR', type: 'Container Registry', specialist: 'Container SA' },
'registry': { aws: 'Amazon ECR', type: 'Container Registry', specialist: 'Container SA' },
// Security & Identity
'keycloak': { aws: 'Amazon Cognito', type: 'Identity', specialist: 'Security SA' },
'vault': { aws: 'AWS Secrets Manager', type: 'Secrets', specialist: 'Security SA' },
'consul': { aws: 'AWS Cloud Map', type: 'Service Discovery', specialist: 'Solutions SA' },
'oauth2-proxy': { aws: 'Amazon Cognito', type: 'Authentication', specialist: 'Security SA' },
'cert-manager': { aws: 'AWS Certificate Manager', type: 'Certificates', specialist: 'Security SA' },
// Monitoring & Observability
'jaeger': { aws: 'AWS X-Ray', type: 'Tracing', specialist: 'Solutions SA' },
'zipkin': { aws: 'AWS X-Ray', type: 'Tracing', specialist: 'Solutions SA' },
'fluentd': { aws: 'Amazon CloudWatch', type: 'Logging', specialist: 'Solutions SA' },
'fluent-bit': { aws: 'Amazon CloudWatch', type: 'Logging', specialist: 'Solutions SA' },
'telegraf': { aws: 'Amazon CloudWatch', type: 'Metrics', specialist: 'Solutions SA' },
'node-exporter': { aws: 'Amazon CloudWatch', type: 'Metrics', specialist: 'Solutions SA' },
// Application Servers
'tomcat': { aws: 'AWS Elastic Beanstalk', type: 'App Server', specialist: 'Solutions SA' },
'jetty': { aws: 'AWS Elastic Beanstalk', type: 'App Server', specialist: 'Solutions SA' },
'wildfly': { aws: 'AWS Elastic Beanstalk', type: 'App Server', specialist: 'Solutions SA' },
// Content Management
'wordpress': { aws: 'AWS Lightsail', type: 'CMS', specialist: 'Solutions SA' },
'drupal': { aws: 'AWS Lightsail', type: 'CMS', specialist: 'Solutions SA' },
'joomla': { aws: 'AWS Lightsail', type: 'CMS', specialist: 'Solutions SA' },
// E-commerce
'magento': { aws: 'AWS Lightsail', type: 'E-commerce', specialist: 'Solutions SA' },
'prestashop': { aws: 'AWS Lightsail', type: 'E-commerce', specialist: 'Solutions SA' },
'opencart': { aws: 'AWS Lightsail', type: 'E-commerce', specialist: 'Solutions SA' }
};
}
analyzeImage(imageName) {
const [name, tag] = imageName.split(':');
const service = name.split('/')[1]?.split(':')[0];
if (!name.includes('bitnami')) {
return { applicable: false };
}
const mapping = this.serviceMapping[service];
if (!mapping) {
return {
applicable: true,
imageName,
service,
mapped: false,
recommendation: 'Contact AWS Solutions Architect for custom assessment'
};
}
return {
applicable: true,
imageName,
service,
mapped: true,
type: mapping.type,
awsAlternative: mapping.aws,
specialist: mapping.specialist,
isVersioned: tag && tag !== 'latest' && /^\d+\.\d+/.test(tag)
};
}
generateCoverageReport(images) {
console.log(chalk.bold.blue('š Comprehensive Bitnami Service Coverage Analysis'));
console.log(chalk.gray('280+ Bitnami Images ā AWS Service Mapping\n'));
const analyses = images.map(img => this.analyzeImage(img)).filter(a => a.applicable);
if (analyses.length === 0) {
console.log(chalk.yellow('No Bitnami images provided for analysis.'));
return;
}
const mapped = analyses.filter(a => a.mapped);
const unmapped = analyses.filter(a => !a.mapped);
// Show mapped services
if (mapped.length > 0) {
console.log(chalk.green.bold('ā
MAPPED TO AWS SERVICES'));
// Group by specialist
const bySpecialist = {};
mapped.forEach(analysis => {
if (!bySpecialist[analysis.specialist]) {
bySpecialist[analysis.specialist] = [];
}
bySpecialist[analysis.specialist].push(analysis);
});
Object.entries(bySpecialist).forEach(([specialist, services]) => {
console.log(chalk.bold(`\nšÆ ${specialist}:`));
services.forEach(service => {
console.log(` š¦ ${service.imageName}`);
console.log(` Type: ${service.type}`);
console.log(` AWS Alternative: ${chalk.green(service.awsAlternative)}`);
console.log(` Version: ${service.isVersioned ? chalk.red('Pinned') : chalk.green('Latest')}`);
});
});
}
// Show unmapped services
if (unmapped.length > 0) {
console.log(chalk.yellow.bold('\nā ļø UNMAPPED SERVICES (Need Custom Assessment)'));
unmapped.forEach(analysis => {
console.log(` š¦ ${analysis.imageName}`);
console.log(` Service: ${analysis.service}`);
console.log(` ā ${analysis.recommendation}`);
});
}
// Coverage statistics
console.log(chalk.bold('\nš Coverage Statistics:'));
console.log(` Total Bitnami Images: ${analyses.length}`);
console.log(` Mapped to AWS Services: ${chalk.green(mapped.length)}`);
console.log(` Need Custom Assessment: ${chalk.yellow(unmapped.length)}`);
console.log(` Coverage Rate: ${chalk.blue(Math.round((mapped.length / analyses.length) * 100))}%`);
// Service type breakdown
if (mapped.length > 0) {
const typeBreakdown = {};
mapped.forEach(analysis => {
typeBreakdown[analysis.type] = (typeBreakdown[analysis.type] || 0) + 1;
});
console.log(chalk.bold('\nš·ļø Service Type Breakdown:'));
Object.entries(typeBreakdown)
.sort(([,a], [,b]) => b - a)
.forEach(([type, count]) => {
console.log(` ${type}: ${count}`);
});
}
}
getTotalMappingCount() {
return Object.keys(this.serviceMapping).length;
}
}
// Test with comprehensive image list
if (require.main === module) {
const mapper = new ComprehensiveServiceMapper();
console.log(chalk.bold.blue(`šÆ Comprehensive Service Mapper - ${mapper.getTotalMappingCount()} Services Mapped\n`));
const testImages = [
// Databases
'bitnami/mysql:8.0.35', 'bitnami/postgresql:15.4.0', 'bitnami/mongodb:6.0.8',
'bitnami/redis:7.2.4', 'bitnami/cassandra:4.1.3', 'bitnami/neo4j:5.11.0',
// Analytics
'bitnami/elasticsearch:8.8.0', 'bitnami/grafana:10.0.3', 'bitnami/prometheus:2.45.0',
// Big Data
'bitnami/spark:3.4.1', 'bitnami/airflow:2.7.0', 'bitnami/jupyter:6.5.4',
// Messaging
'bitnami/kafka:3.5.0', 'bitnami/rabbitmq:3.12.2', 'bitnami/pulsar:3.0.0',
// CI/CD
'bitnami/jenkins:2.414.1', 'bitnami/sonarqube:10.1.0', 'bitnami/nexus:3.39.0',
// Security
'bitnami/keycloak:22.0.1', 'bitnami/vault:1.14.0', 'bitnami/consul:1.16.0',
// Unmapped example
'bitnami/custom-app:1.0.0'
];
mapper.generateCoverageReport(testImages);
}
module.exports = { ComprehensiveServiceMapper };