email-amazon/unified-worker/email-worker/config.py

101 lines
3.5 KiB
Python

#!/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'