Add customer routes and update domain model with project_name
This commit is contained in:
parent
c298116f09
commit
0190a8e0a0
|
|
@ -13,6 +13,7 @@ from app.services.cloudflare_service import CloudflareService
|
||||||
from app.routes.auth import auth_bp
|
from app.routes.auth import auth_bp
|
||||||
from app.routes.admin import admin_bp
|
from app.routes.admin import admin_bp
|
||||||
from app.routes.dns import dns_bp
|
from app.routes.dns import dns_bp
|
||||||
|
from app.routes.customer import customer_bp
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.from_object(Config)
|
app.config.from_object(Config)
|
||||||
|
|
@ -30,6 +31,7 @@ migrate = Migrate(app, db)
|
||||||
app.register_blueprint(auth_bp)
|
app.register_blueprint(auth_bp)
|
||||||
app.register_blueprint(admin_bp)
|
app.register_blueprint(admin_bp)
|
||||||
app.register_blueprint(dns_bp)
|
app.register_blueprint(dns_bp)
|
||||||
|
app.register_blueprint(customer_bp)
|
||||||
|
|
||||||
# Redis
|
# Redis
|
||||||
redis_client = redis.from_url(Config.REDIS_URL)
|
redis_client = redis.from_url(Config.REDIS_URL)
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,10 @@ class Domain(db.Model):
|
||||||
domain_name = db.Column(db.String(255), unique=True, nullable=False, index=True)
|
domain_name = db.Column(db.String(255), unique=True, nullable=False, index=True)
|
||||||
customer_id = db.Column(db.Integer, db.ForeignKey('customers.id'), nullable=False, index=True)
|
customer_id = db.Column(db.Integer, db.ForeignKey('customers.id'), nullable=False, index=True)
|
||||||
|
|
||||||
|
# Project Information
|
||||||
|
project_name = db.Column(db.String(255), nullable=True) # "My WordPress Site"
|
||||||
|
created_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True) # User who created this domain
|
||||||
|
|
||||||
# Cloudflare Configuration
|
# Cloudflare Configuration
|
||||||
use_cloudflare = db.Column(db.Boolean, default=True)
|
use_cloudflare = db.Column(db.Boolean, default=True)
|
||||||
cf_account_type = db.Column(db.String(20), nullable=True) # "own" veya "company"
|
cf_account_type = db.Column(db.String(20), nullable=True) # "own" veya "company"
|
||||||
|
|
@ -119,6 +123,8 @@ class Domain(db.Model):
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"domain_name": self.domain_name,
|
"domain_name": self.domain_name,
|
||||||
"customer_id": self.customer_id,
|
"customer_id": self.customer_id,
|
||||||
|
"project_name": self.project_name,
|
||||||
|
"created_by": self.created_by,
|
||||||
"use_cloudflare": self.use_cloudflare,
|
"use_cloudflare": self.use_cloudflare,
|
||||||
"cf_account_type": self.cf_account_type,
|
"cf_account_type": self.cf_account_type,
|
||||||
"cf_account_id": self.cf_account_id,
|
"cf_account_id": self.cf_account_id,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,328 @@
|
||||||
|
"""
|
||||||
|
Customer Routes - Domain Management
|
||||||
|
Customer-specific endpoints with isolation
|
||||||
|
"""
|
||||||
|
from flask import Blueprint, request, jsonify
|
||||||
|
from app.models.domain import db, Domain, DNSRecord, CloudflareAccount
|
||||||
|
from app.models.user import Customer
|
||||||
|
from app.middleware.auth import token_required
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
customer_bp = Blueprint('customer', __name__, url_prefix='/api/customer')
|
||||||
|
|
||||||
|
|
||||||
|
@customer_bp.route('/domains', methods=['GET'])
|
||||||
|
@token_required
|
||||||
|
def get_domains(current_user):
|
||||||
|
"""Get all domains for the current customer"""
|
||||||
|
try:
|
||||||
|
# Get customer
|
||||||
|
customer = current_user.customer
|
||||||
|
if not customer:
|
||||||
|
return jsonify({'error': 'Customer profile not found'}), 404
|
||||||
|
|
||||||
|
# Get domains with customer isolation
|
||||||
|
domains = Domain.query.filter_by(customer_id=customer.id).all()
|
||||||
|
|
||||||
|
# Add CF account info
|
||||||
|
result = []
|
||||||
|
for domain in domains:
|
||||||
|
domain_dict = domain.to_dict()
|
||||||
|
|
||||||
|
# Add CF account name if using company account
|
||||||
|
if domain.cf_account_type == 'company' and domain.cf_account:
|
||||||
|
domain_dict['cf_account_name'] = domain.cf_account.name
|
||||||
|
else:
|
||||||
|
domain_dict['cf_account_name'] = 'Own Account'
|
||||||
|
|
||||||
|
# Add DNS record count
|
||||||
|
domain_dict['dns_record_count'] = len(domain.dns_records)
|
||||||
|
|
||||||
|
result.append(domain_dict)
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'domains': result,
|
||||||
|
'total': len(result),
|
||||||
|
'limit': customer.max_domains
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@customer_bp.route('/domains/<int:domain_id>', methods=['GET'])
|
||||||
|
@token_required
|
||||||
|
def get_domain(current_user, domain_id):
|
||||||
|
"""Get specific domain details"""
|
||||||
|
try:
|
||||||
|
customer = current_user.customer
|
||||||
|
if not customer:
|
||||||
|
return jsonify({'error': 'Customer profile not found'}), 404
|
||||||
|
|
||||||
|
# Get domain with customer isolation
|
||||||
|
domain = Domain.query.filter_by(
|
||||||
|
id=domain_id,
|
||||||
|
customer_id=customer.id
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if not domain:
|
||||||
|
return jsonify({'error': 'Domain not found'}), 404
|
||||||
|
|
||||||
|
domain_dict = domain.to_dict()
|
||||||
|
|
||||||
|
# Add CF account info
|
||||||
|
if domain.cf_account_type == 'company' and domain.cf_account:
|
||||||
|
domain_dict['cf_account_name'] = domain.cf_account.name
|
||||||
|
|
||||||
|
# Add DNS records
|
||||||
|
domain_dict['dns_records'] = [record.to_dict() for record in domain.dns_records]
|
||||||
|
|
||||||
|
return jsonify(domain_dict), 200
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@customer_bp.route('/domains', methods=['POST'])
|
||||||
|
@token_required
|
||||||
|
def create_domain(current_user):
|
||||||
|
"""Create a new domain"""
|
||||||
|
try:
|
||||||
|
customer = current_user.customer
|
||||||
|
if not customer:
|
||||||
|
return jsonify({'error': 'Customer profile not found'}), 404
|
||||||
|
|
||||||
|
data = request.get_json()
|
||||||
|
|
||||||
|
# Validate required fields
|
||||||
|
if not data.get('domain_name'):
|
||||||
|
return jsonify({'error': 'domain_name is required'}), 400
|
||||||
|
|
||||||
|
domain_name = data['domain_name'].lower().strip()
|
||||||
|
|
||||||
|
# Check domain limit
|
||||||
|
current_count = Domain.query.filter_by(customer_id=customer.id).count()
|
||||||
|
if current_count >= customer.max_domains:
|
||||||
|
return jsonify({
|
||||||
|
'error': f'Domain limit reached. Maximum {customer.max_domains} domains allowed.'
|
||||||
|
}), 403
|
||||||
|
|
||||||
|
# Check if domain already exists
|
||||||
|
existing = Domain.query.filter_by(domain_name=domain_name).first()
|
||||||
|
if existing:
|
||||||
|
return jsonify({'error': 'Domain already exists'}), 409
|
||||||
|
|
||||||
|
# Validate CF account if using company account
|
||||||
|
cf_account_id = data.get('cf_account_id')
|
||||||
|
cf_account_type = data.get('cf_account_type', 'company')
|
||||||
|
|
||||||
|
if cf_account_type == 'company':
|
||||||
|
if not cf_account_id:
|
||||||
|
return jsonify({'error': 'cf_account_id is required for company account'}), 400
|
||||||
|
|
||||||
|
cf_account = CloudflareAccount.query.get(cf_account_id)
|
||||||
|
if not cf_account:
|
||||||
|
return jsonify({'error': 'Cloudflare account not found'}), 404
|
||||||
|
|
||||||
|
if not cf_account.is_active:
|
||||||
|
return jsonify({'error': 'Cloudflare account is not active'}), 400
|
||||||
|
|
||||||
|
# Check CF account capacity
|
||||||
|
if cf_account.current_domain_count >= cf_account.max_domains:
|
||||||
|
return jsonify({
|
||||||
|
'error': f'Cloudflare account is full ({cf_account.max_domains} domains max)'
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
# Create domain
|
||||||
|
domain = Domain(
|
||||||
|
domain_name=domain_name,
|
||||||
|
customer_id=customer.id,
|
||||||
|
created_by=current_user.id,
|
||||||
|
project_name=data.get('project_name'),
|
||||||
|
use_cloudflare=data.get('use_cloudflare', True),
|
||||||
|
cf_account_type=cf_account_type,
|
||||||
|
cf_account_id=cf_account_id if cf_account_type == 'company' else None,
|
||||||
|
cf_zone_id=data.get('cf_zone_id'),
|
||||||
|
cf_proxy_enabled=data.get('cf_proxy_enabled', True),
|
||||||
|
status='pending'
|
||||||
|
)
|
||||||
|
|
||||||
|
# If using own CF account, save encrypted token
|
||||||
|
if cf_account_type == 'own' and data.get('cf_api_token'):
|
||||||
|
domain.set_cf_api_token(data['cf_api_token'])
|
||||||
|
|
||||||
|
db.session.add(domain)
|
||||||
|
|
||||||
|
# Update CF account domain count if using company account
|
||||||
|
if cf_account_type == 'company' and cf_account:
|
||||||
|
cf_account.current_domain_count += 1
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'message': 'Domain created successfully',
|
||||||
|
'domain': domain.to_dict()
|
||||||
|
}), 201
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@customer_bp.route('/domains/<int:domain_id>', methods=['PUT'])
|
||||||
|
@token_required
|
||||||
|
def update_domain(current_user, domain_id):
|
||||||
|
"""Update domain"""
|
||||||
|
try:
|
||||||
|
customer = current_user.customer
|
||||||
|
if not customer:
|
||||||
|
return jsonify({'error': 'Customer profile not found'}), 404
|
||||||
|
|
||||||
|
# Get domain with customer isolation
|
||||||
|
domain = Domain.query.filter_by(
|
||||||
|
id=domain_id,
|
||||||
|
customer_id=customer.id
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if not domain:
|
||||||
|
return jsonify({'error': 'Domain not found'}), 404
|
||||||
|
|
||||||
|
data = request.get_json()
|
||||||
|
|
||||||
|
# Update allowed fields
|
||||||
|
if 'project_name' in data:
|
||||||
|
domain.project_name = data['project_name']
|
||||||
|
|
||||||
|
if 'cf_proxy_enabled' in data:
|
||||||
|
domain.cf_proxy_enabled = data['cf_proxy_enabled']
|
||||||
|
|
||||||
|
if 'status' in data and data['status'] in ['pending', 'active', 'suspended', 'error']:
|
||||||
|
domain.status = data['status']
|
||||||
|
|
||||||
|
domain.updated_at = datetime.utcnow()
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'message': 'Domain updated successfully',
|
||||||
|
'domain': domain.to_dict()
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@customer_bp.route('/domains/<int:domain_id>', methods=['DELETE'])
|
||||||
|
@token_required
|
||||||
|
def delete_domain(current_user, domain_id):
|
||||||
|
"""Delete domain"""
|
||||||
|
try:
|
||||||
|
customer = current_user.customer
|
||||||
|
if not customer:
|
||||||
|
return jsonify({'error': 'Customer profile not found'}), 404
|
||||||
|
|
||||||
|
# Get domain with customer isolation
|
||||||
|
domain = Domain.query.filter_by(
|
||||||
|
id=domain_id,
|
||||||
|
customer_id=customer.id
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if not domain:
|
||||||
|
return jsonify({'error': 'Domain not found'}), 404
|
||||||
|
|
||||||
|
# Update CF account count if using company account
|
||||||
|
if domain.cf_account_type == 'company' and domain.cf_account:
|
||||||
|
domain.cf_account.current_domain_count = max(0, domain.cf_account.current_domain_count - 1)
|
||||||
|
|
||||||
|
db.session.delete(domain)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({'message': 'Domain deleted successfully'}), 200
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@customer_bp.route('/domains/<int:domain_id>/dns', methods=['GET'])
|
||||||
|
@token_required
|
||||||
|
def get_domain_dns(current_user, domain_id):
|
||||||
|
"""Get DNS records for a domain"""
|
||||||
|
try:
|
||||||
|
customer = current_user.customer
|
||||||
|
if not customer:
|
||||||
|
return jsonify({'error': 'Customer profile not found'}), 404
|
||||||
|
|
||||||
|
# Get domain with customer isolation
|
||||||
|
domain = Domain.query.filter_by(
|
||||||
|
id=domain_id,
|
||||||
|
customer_id=customer.id
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if not domain:
|
||||||
|
return jsonify({'error': 'Domain not found'}), 404
|
||||||
|
|
||||||
|
records = [record.to_dict() for record in domain.dns_records]
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'domain': domain.domain_name,
|
||||||
|
'records': records,
|
||||||
|
'total': len(records)
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@customer_bp.route('/cloudflare-accounts', methods=['GET'])
|
||||||
|
@token_required
|
||||||
|
def get_cloudflare_accounts(current_user):
|
||||||
|
"""Get available Cloudflare accounts (company accounts only)"""
|
||||||
|
try:
|
||||||
|
# Get active company CF accounts
|
||||||
|
accounts = CloudflareAccount.query.filter_by(is_active=True).all()
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for account in accounts:
|
||||||
|
account_dict = account.to_dict(include_token=False)
|
||||||
|
# Calculate available capacity
|
||||||
|
account_dict['available_capacity'] = account.max_domains - account.current_domain_count
|
||||||
|
account_dict['is_full'] = account.current_domain_count >= account.max_domains
|
||||||
|
result.append(account_dict)
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'accounts': result,
|
||||||
|
'total': len(result)
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@customer_bp.route('/stats', methods=['GET'])
|
||||||
|
@token_required
|
||||||
|
def get_customer_stats(current_user):
|
||||||
|
"""Get customer statistics"""
|
||||||
|
try:
|
||||||
|
customer = current_user.customer
|
||||||
|
if not customer:
|
||||||
|
return jsonify({'error': 'Customer profile not found'}), 404
|
||||||
|
|
||||||
|
# Count domains by status
|
||||||
|
total_domains = Domain.query.filter_by(customer_id=customer.id).count()
|
||||||
|
active_domains = Domain.query.filter_by(customer_id=customer.id, status='active').count()
|
||||||
|
pending_domains = Domain.query.filter_by(customer_id=customer.id, status='pending').count()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'total_domains': total_domains,
|
||||||
|
'active_domains': active_domains,
|
||||||
|
'pending_domains': pending_domains,
|
||||||
|
'max_domains': customer.max_domains,
|
||||||
|
'available_slots': customer.max_domains - total_domains,
|
||||||
|
'subscription_plan': customer.subscription_plan
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -6,6 +6,7 @@ from datetime import datetime
|
||||||
from app.models.domain import db, CloudflareAccount, Domain
|
from app.models.domain import db, CloudflareAccount, Domain
|
||||||
from app.services.cloudflare_service import CloudflareService
|
from app.services.cloudflare_service import CloudflareService
|
||||||
from app.services.nameserver_service import NameserverService
|
from app.services.nameserver_service import NameserverService
|
||||||
|
from app.middleware.auth import token_required
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
dns_bp = Blueprint('dns', __name__, url_prefix='/api/dns')
|
dns_bp = Blueprint('dns', __name__, url_prefix='/api/dns')
|
||||||
|
|
@ -165,3 +166,128 @@ def select_company_account():
|
||||||
"message": f"Hesap seçimi sırasında hata: {str(e)}"
|
"message": f"Hesap seçimi sırasında hata: {str(e)}"
|
||||||
}), 500
|
}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@dns_bp.route('/preview-changes', methods=['POST'])
|
||||||
|
@token_required
|
||||||
|
def preview_changes(current_user):
|
||||||
|
"""DNS değişiklik önizlemesi"""
|
||||||
|
try:
|
||||||
|
customer = current_user.customer
|
||||||
|
if not customer:
|
||||||
|
return jsonify({'error': 'Customer profile not found'}), 404
|
||||||
|
|
||||||
|
data = request.json
|
||||||
|
domain = data.get('domain')
|
||||||
|
zone_id = data.get('zone_id')
|
||||||
|
cf_token = data.get('cf_token')
|
||||||
|
lb_ips = data.get('lb_ips', ['176.96.129.77']) # Default server IP
|
||||||
|
|
||||||
|
if not all([domain, zone_id, cf_token]):
|
||||||
|
return jsonify({"error": "domain, zone_id ve cf_token gerekli"}), 400
|
||||||
|
|
||||||
|
# Load balancer IP seç
|
||||||
|
new_ip = select_lb_ip(domain, lb_ips)
|
||||||
|
|
||||||
|
cf_service = CloudflareService(cf_token)
|
||||||
|
preview = cf_service.generate_dns_preview(domain, zone_id, new_ip)
|
||||||
|
|
||||||
|
return jsonify(preview)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({
|
||||||
|
"status": "error",
|
||||||
|
"message": f"Preview oluşturma hatası: {str(e)}"
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@dns_bp.route('/apply-changes', methods=['POST'])
|
||||||
|
@token_required
|
||||||
|
def apply_changes(current_user):
|
||||||
|
"""DNS değişikliklerini uygula ve domain'i kaydet"""
|
||||||
|
try:
|
||||||
|
customer = current_user.customer
|
||||||
|
if not customer:
|
||||||
|
return jsonify({'error': 'Customer profile not found'}), 404
|
||||||
|
|
||||||
|
data = request.json
|
||||||
|
domain_name = data.get('domain')
|
||||||
|
zone_id = data.get('zone_id')
|
||||||
|
cf_token = data.get('cf_token')
|
||||||
|
preview = data.get('preview')
|
||||||
|
proxy_enabled = data.get('proxy_enabled', True)
|
||||||
|
cf_account_id = data.get('cf_account_id')
|
||||||
|
cf_account_type = data.get('cf_account_type', 'company')
|
||||||
|
project_name = data.get('project_name')
|
||||||
|
|
||||||
|
if not all([domain_name, zone_id, cf_token, preview]):
|
||||||
|
return jsonify({"error": "Eksik parametreler"}), 400
|
||||||
|
|
||||||
|
# Check domain limit
|
||||||
|
current_count = Domain.query.filter_by(customer_id=customer.id).count()
|
||||||
|
if current_count >= customer.max_domains:
|
||||||
|
return jsonify({
|
||||||
|
'error': f'Domain limit reached ({customer.max_domains})'
|
||||||
|
}), 403
|
||||||
|
|
||||||
|
# Check if domain already exists
|
||||||
|
existing = Domain.query.filter_by(domain_name=domain_name).first()
|
||||||
|
if existing:
|
||||||
|
return jsonify({'error': 'Domain already exists'}), 409
|
||||||
|
|
||||||
|
cf_service = CloudflareService(cf_token)
|
||||||
|
|
||||||
|
# DNS değişikliklerini uygula
|
||||||
|
result = cf_service.apply_dns_changes(zone_id, preview, proxy_enabled)
|
||||||
|
|
||||||
|
if result["status"] == "success":
|
||||||
|
# SSL yapılandır
|
||||||
|
ssl_config = cf_service.configure_ssl(zone_id)
|
||||||
|
|
||||||
|
# Domain'i veritabanına kaydet
|
||||||
|
domain_obj = Domain(
|
||||||
|
domain_name=domain_name,
|
||||||
|
customer_id=customer.id,
|
||||||
|
created_by=current_user.id,
|
||||||
|
project_name=project_name,
|
||||||
|
use_cloudflare=True,
|
||||||
|
cf_account_type=cf_account_type,
|
||||||
|
cf_account_id=cf_account_id if cf_account_type == 'company' else None,
|
||||||
|
cf_zone_id=zone_id,
|
||||||
|
cf_proxy_enabled=proxy_enabled,
|
||||||
|
lb_ip=preview.get("new_ip"),
|
||||||
|
status="active",
|
||||||
|
dns_configured=True,
|
||||||
|
ssl_configured=len(ssl_config.get("errors", [])) == 0
|
||||||
|
)
|
||||||
|
|
||||||
|
# If using own CF account, save encrypted token
|
||||||
|
if cf_account_type == 'own':
|
||||||
|
domain_obj.set_cf_api_token(cf_token)
|
||||||
|
|
||||||
|
db.session.add(domain_obj)
|
||||||
|
|
||||||
|
# Update CF account domain count if using company account
|
||||||
|
if cf_account_type == 'company' and cf_account_id:
|
||||||
|
cf_account = CloudflareAccount.query.get(cf_account_id)
|
||||||
|
if cf_account:
|
||||||
|
cf_account.current_domain_count += 1
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"status": "success",
|
||||||
|
"dns_result": result,
|
||||||
|
"ssl_config": ssl_config,
|
||||||
|
"domain_id": domain_obj.id,
|
||||||
|
"domain": domain_obj.to_dict()
|
||||||
|
}), 201
|
||||||
|
|
||||||
|
return jsonify(result), 500
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
return jsonify({
|
||||||
|
"status": "error",
|
||||||
|
"message": f"DNS uygulama hatası: {str(e)}"
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue