#!/usr/bin/env python3 """ Configuration management for unified email worker """ import os from dataclasses import dataclass from typing import Set @dataclass class Config: """Worker Configuration""" # AWS aws_region: str = os.environ.get('AWS_REGION', 'us-east-2') # Domains to process domains_list: str = os.environ.get('DOMAINS', '') domains_file: str = os.environ.get('DOMAINS_FILE', '/etc/email-worker/domains.txt') # Worker Settings worker_threads: int = int(os.environ.get('WORKER_THREADS', '10')) poll_interval: int = int(os.environ.get('POLL_INTERVAL', '20')) max_messages: int = int(os.environ.get('MAX_MESSAGES', '10')) visibility_timeout: int = int(os.environ.get('VISIBILITY_TIMEOUT', '300')) # SMTP for delivery smtp_host: str = os.environ.get('SMTP_HOST', 'localhost') smtp_port: int = int(os.environ.get('SMTP_PORT', '25')) smtp_use_tls: bool = os.environ.get('SMTP_USE_TLS', 'false').lower() == 'true' smtp_user: str = os.environ.get('SMTP_USER', '') smtp_pass: str = os.environ.get('SMTP_PASS', '') smtp_pool_size: int = int(os.environ.get('SMTP_POOL_SIZE', '5')) # Internal SMTP (bypasses transport_maps) internal_smtp_port: int = int(os.environ.get('INTERNAL_SMTP_PORT', '2525')) # LMTP for local delivery (bypasses Postfix transport_maps) lmtp_enabled: bool = os.environ.get('LMTP_ENABLED', 'false').lower() == 'true' lmtp_host: str = os.environ.get('LMTP_HOST', 'localhost') lmtp_port: int = int(os.environ.get('LMTP_PORT', '24')) # DynamoDB Tables rules_table: str = os.environ.get('DYNAMODB_RULES_TABLE', 'email-rules') messages_table: str = os.environ.get('DYNAMODB_MESSAGES_TABLE', 'ses-outbound-messages') blocked_table: str = os.environ.get('DYNAMODB_BLOCKED_TABLE', 'email-blocked-senders') # Bounce Handling bounce_lookup_retries: int = int(os.environ.get('BOUNCE_LOOKUP_RETRIES', '3')) bounce_lookup_delay: float = float(os.environ.get('BOUNCE_LOOKUP_DELAY', '1.0')) # Monitoring metrics_port: int = int(os.environ.get('METRICS_PORT', '8000')) health_port: int = int(os.environ.get('HEALTH_PORT', '8080')) # Global configuration instance config = Config() # Global set of managed domains (populated at startup) MANAGED_DOMAINS: Set[str] = set() def load_domains() -> list[str]: """Load domains from config and populate MANAGED_DOMAINS global""" global MANAGED_DOMAINS domains = [] if config.domains_list: domains.extend([d.strip() for d in config.domains_list.split(',') if d.strip()]) if os.path.exists(config.domains_file): with open(config.domains_file, 'r') as f: for line in f: domain = line.strip() if domain and not domain.startswith('#'): domains.append(domain) domains = list(set(domains)) MANAGED_DOMAINS = set(d.lower() for d in domains) return domains def is_internal_address(email_address: str) -> bool: """Check if email address belongs to one of our managed domains""" if '@' not in email_address: return False domain = email_address.split('@')[1].lower() return domain in MANAGED_DOMAINS def domain_to_queue_name(domain: str) -> str: """Convert domain to SQS queue name""" return domain.replace('.', '-') + '-queue' def domain_to_bucket_name(domain: str) -> str: """Convert domain to S3 bucket name""" return domain.replace('.', '-') + '-emails'