#!/usr/bin/env python3 import sys from typing import Dict, Any, Optional from config import Config from namecheap_api import NamecheapAPI from cloudflare_api import CloudflareAPI class DomainManager: def __init__(self, config: Config): self.config = config self.namecheap = NamecheapAPI(config) self.cloudflare = CloudflareAPI(config) def register_and_setup_domain(self, domain: str, registrant_info: Optional[Dict[str, str]] = None, setup_workers: bool = True, dry_run: bool = False) -> Dict[str, Any]: """ Complete domain registration and setup workflow: 1. Check domain availability 2. Verify pricing and account balance 3. Register domain (with user confirmation) 4. Add domain to Cloudflare 5. Update nameservers in Namecheap 6. Set up basic DNS records """ result = { 'domain': domain, 'steps_completed': [], 'errors': [] } try: # Step 1: Check domain availability print(f"Checking availability for {domain}...") if not self.namecheap.check_domain_availability(domain): result['errors'].append(f"Domain {domain} is not available") return result result['steps_completed'].append('availability_check') print(f"✓ Domain {domain} is available") # Step 2: Check pricing and balance print("Checking pricing and account balance...") try: pricing = self.namecheap.get_domain_pricing(domain) except Exception as e: result['errors'].append(f"Failed to get domain pricing: {str(e)}") return result try: balance = self.namecheap.get_account_balance() except Exception as e: result['errors'].append(f"Failed to get account balance: {str(e)}") return result if balance < pricing['register']: result['errors'].append( f"Insufficient balance. Required: ${pricing['register']:.2f}, " f"Available: ${balance:.2f}" ) return result result['steps_completed'].append('pricing_check') print(f"✓ Pricing: ${pricing['register']:.2f}, Balance: ${balance:.2f}") # Step 3: User confirmation with multiple safeguards print(f"\n" + "="*50) print(f"DOMAIN REGISTRATION CONFIRMATION") print(f"="*50) print(f"Domain: {domain}") print(f"Registration Price: ${pricing['register']:.2f}") print(f"Account Balance: ${balance:.2f}") print(f"Remaining Balance: ${balance - pricing['register']:.2f}") print(f"="*50) # Multiple confirmation steps to prevent accidents print(f"\nWARNING: This will charge ${pricing['register']:.2f} to your account!") first_confirm = input(f"Type 'REGISTER' to proceed with registration of {domain}: ").strip() if first_confirm != 'REGISTER': result['errors'].append("Registration cancelled by user") return result second_confirm = input(f"Are you absolutely sure you want to register {domain} for ${pricing['register']:.2f}? (yes/no): ").lower().strip() if second_confirm != 'yes': result['errors'].append("Registration cancelled by user") return result # Step 4: Register domain if dry_run: print(f"DRY RUN: Would register domain {domain} (skipping actual registration)") result['steps_completed'].append('domain_registration_dry_run') else: print(f"Registering domain {domain}...") if not self.namecheap.register_domain(domain, registrant_info=registrant_info): result['errors'].append(f"Failed to register domain {domain}") return result result['steps_completed'].append('domain_registration') print(f"✓ Domain {domain} registered successfully") # Step 5: Add domain to Cloudflare print(f"Adding {domain} to Cloudflare...") zone_info = self.cloudflare.add_zone(domain) zone_id = zone_info['id'] result['steps_completed'].append('cloudflare_zone_creation') result['zone_id'] = zone_id print(f"✓ Domain added to Cloudflare (Zone ID: {zone_id})") # Step 6: Get Cloudflare nameservers print("Getting Cloudflare nameservers...") nameservers = self.cloudflare.get_zone_nameservers(zone_id) result['nameservers'] = nameservers print(f"✓ Cloudflare nameservers: {', '.join(nameservers)}") # Step 7: Update nameservers in Namecheap print(f"Updating nameservers in Namecheap...") if not self.namecheap.set_dns_servers(domain, nameservers): result['errors'].append("Failed to update nameservers in Namecheap") return result result['steps_completed'].append('nameserver_update') print(f"✓ Nameservers updated in Namecheap") # Step 8: Set up basic DNS records print("Setting up basic DNS records...") dns_records = self.cloudflare.setup_basic_dns_records(zone_id, domain) result['dns_records'] = dns_records result['steps_completed'].append('basic_dns_setup') print(f"✓ Basic DNS records created") # Step 9: Set up worker subdomain if requested if setup_workers: print("Setting up worker subdomain...") worker_record = self.cloudflare.create_worker_subdomain(zone_id, f"app.{domain}") result['worker_record'] = worker_record result['steps_completed'].append('worker_subdomain_setup') print(f"✓ Worker subdomain app.{domain} created") result['success'] = True print(f"\n🎉 Domain {domain} setup completed successfully!") print(f"Zone ID: {zone_id}") print(f"Nameservers: {', '.join(nameservers)}") return result except Exception as e: result['errors'].append(f"Unexpected error: {str(e)}") return result def setup_google_analytics_dns(self, domain: str) -> Dict[str, Any]: """Set up DNS records for Google Analytics""" try: zone_info = self.cloudflare.get_zone_info(domain) if not zone_info: return {'error': f'Domain {domain} not found in Cloudflare'} records = self.cloudflare.setup_google_analytics_dns(zone_info['id'], domain) return {'success': True, 'records': records} except Exception as e: return {'error': str(e)} def main(): if len(sys.argv) < 2: print("Usage: python domain_manager.py [--dry-run]") sys.exit(1) domain = sys.argv[1] dry_run = '--dry-run' in sys.argv # Load configuration config = Config.from_env() # Validate required configuration if not all([ config.namecheap_api_key, config.namecheap_api_user, config.namecheap_username, config.namecheap_client_ip, config.cloudflare_api_token ]): print("Error: Missing required API credentials. Please check your .env file.") sys.exit(1) # Initialize domain manager manager = DomainManager(config) # Register and setup domain if dry_run: print("Running in DRY RUN mode - no actual registration will occur") result = manager.register_and_setup_domain(domain, dry_run=dry_run) if result.get('success'): print(f"\nSuccess! Domain {domain} is ready for use.") else: print(f"\nErrors occurred:") for error in result.get('errors', []): print(f" - {error}") sys.exit(1) if __name__ == "__main__": main()