feat: job to delete orphaned custom domains

This commit is contained in:
Vishnu Narayanan
2025-07-29 19:48:40 +05:30
parent 6475a6a593
commit 3700a810c7
3 changed files with 70 additions and 0 deletions
@@ -0,0 +1,39 @@
class Enterprise::CloudflareCleanupJob < ApplicationJob
queue_as :housekeeping
def perform
return unless ChatwootApp.chatwoot_cloud?
Rails.logger.info 'Starting Cloudflare custom hostname cleanup'
result = Cloudflare::ListCustomHostnamesService.new.perform
if result[:errors].present?
Rails.logger.error "Failed to fetch custom hostnames from Cloudflare: #{result[:errors]}"
return
end
cloudflare_hostnames = result[:data] || []
existing_domains = Portal.where.not(custom_domain: [nil, '']).pluck(:custom_domain)
orphaned_hostnames = cloudflare_hostnames.reject do |hostname|
existing_domains.include?(hostname['hostname'])
end
Rails.logger.info "Found #{orphaned_hostnames.size} orphaned custom hostnames to cleanup"
orphaned_hostnames.each do |hostname|
cleanup_result = Cloudflare::DeleteCustomHostnameService.new(
hostname_id: hostname['id']
).perform
if cleanup_result[:errors].present?
Rails.logger.error "Failed to delete hostname #{hostname['hostname']}: #{cleanup_result[:errors]}"
else
Rails.logger.info "Successfully deleted orphaned hostname: #{hostname['hostname']}"
end
end
Rails.logger.info 'Completed Cloudflare custom hostname cleanup'
end
end
@@ -0,0 +1,17 @@
class Cloudflare::DeleteCustomHostnameService < Cloudflare::BaseCloudflareZoneService
pattr_initialize [:hostname_id!]
def perform
return { errors: ['Cloudflare API token or zone ID not found'] } if api_token.blank? || zone_id.blank?
return { errors: ['Hostname ID is required'] } if @hostname_id.blank?
response = HTTParty.delete(
"#{BASE_URI}/zones/#{zone_id}/custom_hostnames/#{@hostname_id}",
headers: headers
)
return { errors: response.parsed_response['errors'] } unless response.success?
{ success: true }
end
end
@@ -0,0 +1,14 @@
class Cloudflare::ListCustomHostnamesService < Cloudflare::BaseCloudflareZoneService
def perform
return { errors: ['Cloudflare API token or zone ID not found'] } if api_token.blank? || zone_id.blank?
response = HTTParty.get(
"#{BASE_URI}/zones/#{zone_id}/custom_hostnames",
headers: headers
)
return { errors: response.parsed_response['errors'] } unless response.success?
{ data: response.parsed_response['result'] }
end
end