hosting-platform/backend/app/routes/admin.py

271 lines
8.3 KiB
Python
Raw Normal View History

"""
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