mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-05-07 06:15:54 +02:00
Fix CloudFlare DNS Management: Filter main domains only, auto-delete DNS records on domain removal, improve table display
- Filter domain dropdown to show only main domains (exclude sub-domains) - Add automatic CloudFlare DNS record deletion when domains/sub-domains are removed - Improve DNS Records table display to match SSH Logins/Logs table styling - Add loading states and proper table structure with ng-if conditions - Update CSS to match activity-table styling with sticky headers
This commit is contained in:
@@ -839,6 +839,102 @@ class DNS:
|
||||
## There does not exist a zone for this domain.
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def deleteCloudFlareDNSRecords(domainName, adminUserName=None):
|
||||
"""
|
||||
Delete all CloudFlare DNS records for a domain when domain is removed from CyberPanel.
|
||||
This function is called automatically when domains/sub-domains are deleted.
|
||||
"""
|
||||
try:
|
||||
# Check if CloudFlare is configured for this admin user
|
||||
if adminUserName:
|
||||
cfFile = '%s%s' % (DNS.CFPath, adminUserName)
|
||||
else:
|
||||
# Try to find admin user from domain
|
||||
try:
|
||||
from loginSystem.models import Administrator
|
||||
from websiteFunctions.models import Websites, ChildDomains
|
||||
try:
|
||||
website = Websites.objects.get(domain=domainName)
|
||||
adminUserName = website.admin.userName
|
||||
except:
|
||||
try:
|
||||
childDomain = ChildDomains.objects.get(domain=domainName)
|
||||
adminUserName = childDomain.master.admin.userName
|
||||
except:
|
||||
return 0, "Could not find admin user for domain"
|
||||
cfFile = '%s%s' % (DNS.CFPath, adminUserName)
|
||||
except:
|
||||
return 0, "Could not determine admin user"
|
||||
|
||||
if not os.path.exists(cfFile):
|
||||
# CloudFlare not configured for this user, skip deletion
|
||||
return 1, "CloudFlare not configured"
|
||||
|
||||
# Load CloudFlare credentials
|
||||
data = open(cfFile, 'r').readlines()
|
||||
email = data[0].rstrip('\n')
|
||||
token = data[1].rstrip('\n')
|
||||
|
||||
# Initialize CloudFlare API
|
||||
cf = CloudFlare.CloudFlare(email=email, token=token)
|
||||
|
||||
try:
|
||||
# Find the zone for this domain
|
||||
params = {'name': domainName, 'per_page': 50}
|
||||
zones = cf.zones.get(params=params)
|
||||
|
||||
for zone in sorted(zones, key=lambda v: v['name']):
|
||||
if zone['name'] == domainName:
|
||||
zone_id = zone['id']
|
||||
|
||||
# Get all DNS records for this zone
|
||||
try:
|
||||
dns_records = cf.zones.dns_records.get(zone_id)
|
||||
|
||||
# Delete all DNS records
|
||||
deleted_count = 0
|
||||
for record in dns_records:
|
||||
try:
|
||||
cf.zones.dns_records.delete(zone_id, record['id'])
|
||||
deleted_count += 1
|
||||
except Exception as e:
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f'Error deleting CloudFlare DNS record {record["id"]} for {domainName}: {str(e)}')
|
||||
|
||||
if deleted_count > 0:
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f'Deleted {deleted_count} CloudFlare DNS records for {domainName}')
|
||||
return 1, f"Deleted {deleted_count} DNS records"
|
||||
else:
|
||||
return 1, "No DNS records found to delete"
|
||||
|
||||
except CloudFlare.exceptions.CloudFlareAPIError as e:
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f'CloudFlare API error deleting DNS records for {domainName}: {str(e)}')
|
||||
return 0, str(e)
|
||||
except Exception as e:
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f'Error getting CloudFlare DNS records for {domainName}: {str(e)}')
|
||||
return 0, str(e)
|
||||
|
||||
# Zone not found in CloudFlare
|
||||
return 1, "Domain not found in CloudFlare"
|
||||
|
||||
except CloudFlare.exceptions.CloudFlareAPIError as e:
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f'CloudFlare API error for {domainName}: {str(e)}')
|
||||
return 0, str(e)
|
||||
except Exception as e:
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f'Error deleting CloudFlare DNS records for {domainName}: {str(e)}')
|
||||
return 0, str(e)
|
||||
|
||||
except BaseException as msg:
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f'Error in deleteCloudFlareDNSRecords for {domainName}: {str(msg)}')
|
||||
return 0, str(msg)
|
||||
|
||||
@staticmethod
|
||||
def createDNSZone(virtualHostName, admin):
|
||||
try:
|
||||
|
||||
@@ -398,6 +398,12 @@ class vhost:
|
||||
delWebsite = Websites.objects.get(domain=virtualHostName)
|
||||
externalApp = delWebsite.externalApp
|
||||
|
||||
# Get admin user name for CloudFlare cleanup
|
||||
adminUserName = None
|
||||
try:
|
||||
adminUserName = delWebsite.admin.userName
|
||||
except:
|
||||
pass
|
||||
|
||||
##
|
||||
|
||||
@@ -411,6 +417,14 @@ class vhost:
|
||||
numberOfSites = Websites.objects.count() + ChildDomains.objects.count()
|
||||
vhost.deleteCoreConf(items.domain, numberOfSites)
|
||||
|
||||
# Delete CloudFlare DNS records for child domain
|
||||
try:
|
||||
DNS.deleteCloudFlareDNSRecords(items.domain, adminUserName)
|
||||
except Exception as cfError:
|
||||
# Log error but don't fail deletion if CloudFlare deletion fails
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f'CloudFlare DNS deletion failed for child domain {items.domain}: {str(cfError)}')
|
||||
|
||||
### Delete ACME Folder
|
||||
|
||||
if os.path.exists('/root/.acme.sh/%s' % (items.domain)):
|
||||
@@ -455,6 +469,14 @@ class vhost:
|
||||
for items in databases:
|
||||
mysqlUtilities.deleteDatabase(items.dbName, items.dbUser)
|
||||
|
||||
# Delete CloudFlare DNS records for main domain before deletion
|
||||
try:
|
||||
DNS.deleteCloudFlareDNSRecords(virtualHostName, adminUserName)
|
||||
except Exception as cfError:
|
||||
# Log error but don't fail deletion if CloudFlare deletion fails
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f'CloudFlare DNS deletion failed for {virtualHostName}: {str(cfError)}')
|
||||
|
||||
delWebsite.delete()
|
||||
|
||||
## Deleting DNS Zone if there is any.
|
||||
|
||||
@@ -1834,6 +1834,22 @@ local_name %s {
|
||||
vhost.deleteCoreConf(virtualHostName, numberOfWebsites)
|
||||
delWebsite = ChildDomains.objects.get(domain=virtualHostName)
|
||||
|
||||
# Get admin user name before deletion for CloudFlare cleanup
|
||||
adminUserName = None
|
||||
try:
|
||||
adminUserName = delWebsite.master.admin.userName
|
||||
except:
|
||||
pass
|
||||
|
||||
# Delete CloudFlare DNS records for this domain
|
||||
try:
|
||||
from plogical.dnsUtilities import DNS
|
||||
DNS.deleteCloudFlareDNSRecords(virtualHostName, adminUserName)
|
||||
except Exception as cfError:
|
||||
# Log error but don't fail domain deletion if CloudFlare deletion fails
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f'CloudFlare DNS deletion failed for {virtualHostName}: {str(cfError)}')
|
||||
|
||||
if DeleteDocRoot:
|
||||
command = 'rm -rf %s' % (delWebsite.path)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
Reference in New Issue
Block a user