271 lines
8.3 KiB
Python
271 lines
8.3 KiB
Python
"""
|
||
Admin routes - Cloudflare hesap yönetimi
|
||
"""
|
||
from flask import Blueprint, request, jsonify
|
||
from app.models.domain import db, CloudflareAccount
|
||
from app.services.cloudflare_service import CloudflareService
|
||
|
||
admin_bp = Blueprint('admin', __name__, url_prefix='/api/admin')
|
||
|
||
|
||
@admin_bp.route('/cf-accounts', methods=['GET'])
|
||
def list_cf_accounts():
|
||
"""Tüm Cloudflare hesaplarını listele"""
|
||
try:
|
||
accounts = CloudflareAccount.query.filter_by(is_active=True).all()
|
||
|
||
return jsonify({
|
||
"status": "success",
|
||
"accounts": [acc.to_dict(include_token=False) for acc in accounts],
|
||
"count": len(accounts)
|
||
})
|
||
|
||
except Exception as e:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"Hesaplar listelenirken hata: {str(e)}"
|
||
}), 500
|
||
|
||
|
||
@admin_bp.route('/cf-accounts', methods=['POST'])
|
||
def create_cf_account():
|
||
"""Yeni Cloudflare hesabı ekle"""
|
||
try:
|
||
data = request.json
|
||
|
||
# Validasyon
|
||
required_fields = ['name', 'email', 'api_token']
|
||
for field in required_fields:
|
||
if not data.get(field):
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"'{field}' alanı gerekli"
|
||
}), 400
|
||
|
||
# Token'ı doğrula
|
||
cf_service = CloudflareService(data['api_token'])
|
||
|
||
# Basit bir API çağrısı yaparak token'ı test et
|
||
try:
|
||
zones = cf_service.cf.zones.get(params={'per_page': 1})
|
||
# Token geçerli
|
||
except Exception as e:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"Cloudflare API token geçersiz: {str(e)}"
|
||
}), 400
|
||
|
||
# Aynı isimde hesap var mı kontrol et
|
||
existing = CloudflareAccount.query.filter_by(name=data['name']).first()
|
||
if existing:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"'{data['name']}' isimli hesap zaten mevcut"
|
||
}), 400
|
||
|
||
# Yeni hesap oluştur
|
||
account = CloudflareAccount(
|
||
name=data['name'],
|
||
email=data['email'],
|
||
max_domains=data.get('max_domains', 100),
|
||
notes=data.get('notes', ''),
|
||
is_active=True
|
||
)
|
||
|
||
# Token'ı şifrele ve kaydet
|
||
account.set_api_token(data['api_token'])
|
||
|
||
db.session.add(account)
|
||
db.session.commit()
|
||
|
||
return jsonify({
|
||
"status": "success",
|
||
"message": "Cloudflare hesabı başarıyla eklendi",
|
||
"account": account.to_dict(include_token=False)
|
||
}), 201
|
||
|
||
except Exception as e:
|
||
db.session.rollback()
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"Hesap eklenirken hata: {str(e)}"
|
||
}), 500
|
||
|
||
|
||
@admin_bp.route('/cf-accounts/<int:account_id>', methods=['GET'])
|
||
def get_cf_account(account_id):
|
||
"""Belirli bir Cloudflare hesabını getir"""
|
||
try:
|
||
account = CloudflareAccount.query.get(account_id)
|
||
|
||
if not account:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": "Hesap bulunamadı"
|
||
}), 404
|
||
|
||
# include_token parametresi ile token'ı da döndürebiliriz (sadece admin için)
|
||
include_token = request.args.get('include_token', 'false').lower() == 'true'
|
||
|
||
return jsonify({
|
||
"status": "success",
|
||
"account": account.to_dict(include_token=include_token)
|
||
})
|
||
|
||
except Exception as e:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"Hesap getirilirken hata: {str(e)}"
|
||
}), 500
|
||
|
||
|
||
@admin_bp.route('/cf-accounts/<int:account_id>', methods=['PUT'])
|
||
def update_cf_account(account_id):
|
||
"""Cloudflare hesabını güncelle"""
|
||
try:
|
||
account = CloudflareAccount.query.get(account_id)
|
||
|
||
if not account:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": "Hesap bulunamadı"
|
||
}), 404
|
||
|
||
data = request.json
|
||
|
||
# Güncellenebilir alanlar
|
||
if 'name' in data:
|
||
# Aynı isimde başka hesap var mı?
|
||
existing = CloudflareAccount.query.filter(
|
||
CloudflareAccount.name == data['name'],
|
||
CloudflareAccount.id != account_id
|
||
).first()
|
||
if existing:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"'{data['name']}' isimli hesap zaten mevcut"
|
||
}), 400
|
||
account.name = data['name']
|
||
|
||
if 'email' in data:
|
||
account.email = data['email']
|
||
|
||
if 'api_token' in data:
|
||
# Yeni token'ı doğrula
|
||
cf_service = CloudflareService(data['api_token'])
|
||
try:
|
||
zones = cf_service.cf.zones.get(params={'per_page': 1})
|
||
except Exception as e:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"Cloudflare API token geçersiz: {str(e)}"
|
||
}), 400
|
||
|
||
account.set_api_token(data['api_token'])
|
||
|
||
if 'max_domains' in data:
|
||
account.max_domains = data['max_domains']
|
||
|
||
if 'notes' in data:
|
||
account.notes = data['notes']
|
||
|
||
if 'is_active' in data:
|
||
account.is_active = data['is_active']
|
||
|
||
db.session.commit()
|
||
|
||
return jsonify({
|
||
"status": "success",
|
||
"message": "Hesap başarıyla güncellendi",
|
||
"account": account.to_dict(include_token=False)
|
||
})
|
||
|
||
except Exception as e:
|
||
db.session.rollback()
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"Hesap güncellenirken hata: {str(e)}"
|
||
}), 500
|
||
|
||
|
||
@admin_bp.route('/cf-accounts/<int:account_id>', methods=['DELETE'])
|
||
def delete_cf_account(account_id):
|
||
"""Cloudflare hesabını sil (soft delete)"""
|
||
try:
|
||
account = CloudflareAccount.query.get(account_id)
|
||
|
||
if not account:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": "Hesap bulunamadı"
|
||
}), 404
|
||
|
||
# Bu hesabı kullanan domain var mı kontrol et
|
||
if account.current_domain_count > 0:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"Bu hesap {account.current_domain_count} domain tarafından kullanılıyor. Önce domain'leri başka hesaba taşıyın."
|
||
}), 400
|
||
|
||
# Soft delete (is_active = False)
|
||
account.is_active = False
|
||
db.session.commit()
|
||
|
||
return jsonify({
|
||
"status": "success",
|
||
"message": "Hesap başarıyla devre dışı bırakıldı"
|
||
})
|
||
|
||
except Exception as e:
|
||
db.session.rollback()
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"Hesap silinirken hata: {str(e)}"
|
||
}), 500
|
||
|
||
|
||
@admin_bp.route('/cf-accounts/<int:account_id>/test', methods=['POST'])
|
||
def test_cf_account(account_id):
|
||
"""Cloudflare hesabının API bağlantısını test et"""
|
||
try:
|
||
account = CloudflareAccount.query.get(account_id)
|
||
|
||
if not account:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": "Hesap bulunamadı"
|
||
}), 404
|
||
|
||
# API token'ı al
|
||
api_token = account.get_api_token()
|
||
|
||
# Cloudflare API'ye bağlan
|
||
cf_service = CloudflareService(api_token)
|
||
|
||
try:
|
||
# Zone listesini al (test için)
|
||
zones = cf_service.cf.zones.get(params={'per_page': 5})
|
||
|
||
return jsonify({
|
||
"status": "success",
|
||
"message": "✅ Cloudflare API bağlantısı başarılı",
|
||
"zone_count": len(zones),
|
||
"sample_zones": [
|
||
{"name": z["name"], "status": z["status"]}
|
||
for z in zones[:3]
|
||
]
|
||
})
|
||
|
||
except Exception as e:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"❌ Cloudflare API bağlantı hatası: {str(e)}"
|
||
}), 400
|
||
|
||
except Exception as e:
|
||
return jsonify({
|
||
"status": "error",
|
||
"message": f"Test sırasında hata: {str(e)}"
|
||
}), 500
|
||
|