168 lines
5.8 KiB
Python
168 lines
5.8 KiB
Python
|
|
"""
|
|||
|
|
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
|
|||
|
|
|