""" DNS routes - Yeni akış ile CF hesap seçimi, NS kontrolü, DNS yönetimi """ from flask import Blueprint, request, jsonify from datetime import datetime from app.models.domain import db, CloudflareAccount, Domain from app.services.cloudflare_service import CloudflareService from app.services.nameserver_service import NameserverService import hashlib dns_bp = Blueprint('dns', __name__, url_prefix='/api/dns') def select_lb_ip(domain: str, lb_ips: list) -> str: """Domain için load balancer IP seç (hash-based)""" hash_value = int(hashlib.md5(domain.encode()).hexdigest(), 16) index = hash_value % len(lb_ips) return lb_ips[index] @dns_bp.route('/check-nameservers', methods=['POST']) def check_nameservers(): """Domain'in nameserver'larını kontrol et""" try: data = request.json domain = data.get('domain') if not domain: return jsonify({"error": "domain gerekli"}), 400 # NS kontrolü yap result = NameserverService.check_cloudflare_nameservers(domain) return jsonify(result) except Exception as e: return jsonify({ "status": "error", "message": f"NS kontrolü sırasında hata: {str(e)}" }), 500 @dns_bp.route('/get-ns-instructions', methods=['POST']) def get_ns_instructions(): """NS yönlendirme talimatlarını al""" try: data = request.json domain = data.get('domain') zone_id = data.get('zone_id') api_token = data.get('api_token') if not all([domain, zone_id, api_token]): return jsonify({"error": "domain, zone_id ve api_token gerekli"}), 400 # Mevcut NS'leri al current_ns = NameserverService.get_current_nameservers(domain) # Cloudflare zone NS'lerini al cf_ns = NameserverService.get_cloudflare_zone_nameservers(zone_id, api_token) if cf_ns["status"] == "error": return jsonify(cf_ns), 400 return jsonify({ "status": "success", "domain": domain, "current_nameservers": current_ns.get("nameservers", []), "cloudflare_nameservers": cf_ns["nameservers"], "instructions": [ "1. Domain sağlayıcınızın (GoDaddy, Namecheap, vb.) kontrol paneline giriş yapın", "2. Domain yönetimi veya DNS ayarları bölümüne gidin", "3. 'Nameservers' veya 'Name Servers' seçeneğini bulun", "4. 'Custom Nameservers' veya 'Use custom nameservers' seçeneğini seçin", f"5. Aşağıdaki Cloudflare nameserver'larını ekleyin:", *[f" - {ns}" for ns in cf_ns["nameservers"]], "6. Değişiklikleri kaydedin", "7. DNS propagation 24-48 saat sürebilir (genellikle 1-2 saat içinde tamamlanır)" ] }) except Exception as e: return jsonify({ "status": "error", "message": f"NS talimatları alınırken hata: {str(e)}" }), 500 @dns_bp.route('/validate-token', methods=['POST']) def validate_cf_token(): """Cloudflare API token doğrula (müşterinin kendi token'ı)""" try: data = request.json domain = data.get('domain') cf_token = data.get('cf_token') if not domain or not cf_token: return jsonify({"error": "domain ve cf_token gerekli"}), 400 cf_service = CloudflareService(cf_token) result = cf_service.validate_token_and_get_zone(domain) return jsonify(result) except Exception as e: return jsonify({ "status": "error", "message": f"Token doğrulama hatası: {str(e)}" }), 500 @dns_bp.route('/select-company-account', methods=['POST']) def select_company_account(): """Şirket CF hesabı seç ve zone oluştur/bul""" try: data = request.json domain = data.get('domain') cf_account_id = data.get('cf_account_id') if not domain or not cf_account_id: return jsonify({"error": "domain ve cf_account_id gerekli"}), 400 # CF hesabını al cf_account = CloudflareAccount.query.get(cf_account_id) if not cf_account or not cf_account.is_active: return jsonify({ "status": "error", "message": "Cloudflare hesabı bulunamadı veya aktif değil" }), 404 # Hesap kapasitesi kontrolü if cf_account.current_domain_count >= cf_account.max_domains: return jsonify({ "status": "error", "message": f"Bu hesap kapasitesi dolmuş ({cf_account.current_domain_count}/{cf_account.max_domains})" }), 400 # API token'ı al api_token = cf_account.get_api_token() # Cloudflare'de zone var mı kontrol et cf_service = CloudflareService(api_token) result = cf_service.validate_token_and_get_zone(domain) if result["status"] == "success": # Zone zaten var return jsonify({ "status": "success", "zone_exists": True, **result }) else: # Zone yok, oluşturulması gerekiyor # TODO: Zone oluşturma fonksiyonu eklenecek return jsonify({ "status": "pending", "zone_exists": False, "message": "Zone bulunamadı. Cloudflare'de zone oluşturulması gerekiyor.", "cf_account": cf_account.to_dict(include_token=False) }) except Exception as e: return jsonify({ "status": "error", "message": f"Hesap seçimi sırasında hata: {str(e)}" }), 500