mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-27 04:58:42 +02:00
check domain before deletion
This commit is contained in:
parent
78be172ee4
commit
40d5828d3e
1 changed files with 41 additions and 28 deletions
|
@ -1076,7 +1076,7 @@ class Domain(TimeStampedModel, DomainHelper):
|
||||||
# addAndRemoveHostsFromDomain removes the hosts from the domain object,
|
# addAndRemoveHostsFromDomain removes the hosts from the domain object,
|
||||||
# but we still need to delete the object themselves
|
# but we still need to delete the object themselves
|
||||||
self._delete_hosts_if_not_used(hostsToDelete=deleted_values)
|
self._delete_hosts_if_not_used(hostsToDelete=deleted_values)
|
||||||
logger.info("Finished _delete_host_if_not_used inside _delete_domain()")
|
logger.info("Finished _delete_hosts_if_not_used inside _delete_domain()")
|
||||||
|
|
||||||
# delete the non-registrant contacts
|
# delete the non-registrant contacts
|
||||||
logger.debug("Deleting non-registrant contacts for %s", self.name)
|
logger.debug("Deleting non-registrant contacts for %s", self.name)
|
||||||
|
@ -1114,36 +1114,49 @@ class Domain(TimeStampedModel, DomainHelper):
|
||||||
e.note = "Error deleting ds data for %s" % self.name
|
e.note = "Error deleting ds data for %s" % self.name
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
# Previous deletions have to complete before we can delete the domain
|
# check if the domain can be deleted
|
||||||
# This is a polling mechanism to ensure that the domain is deleted
|
if not self._domain_can_be_deleted():
|
||||||
try:
|
raise RegistryError(code=ErrorCode.UNKNOWN, note="Domain cannot be deleted.")
|
||||||
logger.info("Attempting to delete domain %s", self.name)
|
|
||||||
delete_request = commands.DeleteDomain(name=self.name)
|
|
||||||
max_attempts = 5 # maximum number of retries
|
|
||||||
wait_interval = 1 # seconds to wait between attempts
|
|
||||||
|
|
||||||
for attempt in range(max_attempts):
|
# delete the domain
|
||||||
try:
|
request = commands.DeleteDomain(name=self.name)
|
||||||
registry.send(delete_request, cleaned=True)
|
try:
|
||||||
logger.info("Domain %s deleted successfully.", self.name)
|
registry.send(request, cleaned=True)
|
||||||
break # exit the loop on success
|
logger.info("Domain %s deleted successfully.", self.name)
|
||||||
except RegistryError as e:
|
|
||||||
error = e
|
|
||||||
logger.warning(
|
|
||||||
"Attempt %d of %d: Domain deletion not possible yet: %s. Retrying in %d seconds.",
|
|
||||||
attempt + 1,
|
|
||||||
max_attempts,
|
|
||||||
e,
|
|
||||||
wait_interval,
|
|
||||||
)
|
|
||||||
time.sleep(wait_interval)
|
|
||||||
else:
|
|
||||||
logger.error("Exceeded maximum attempts to delete domain %s", self.name)
|
|
||||||
raise error
|
|
||||||
except RegistryError as e:
|
except RegistryError as e:
|
||||||
logger.error("Error deleting domain %s after polling: %s", self.name, e)
|
logger.error("Error deleting domain %s: %s", self.name, e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
def _domain_can_be_deleted(self, max_attempts=5, wait_interval=2) -> bool:
|
||||||
|
"""
|
||||||
|
Polls the registry using InfoDomain calls to confirm that the domain can be deleted.
|
||||||
|
Returns True if the domain can be deleted, False otherwise. Includes a retry mechanism
|
||||||
|
using wait_interval and max_attempts, which may be necessary if subdomains and other
|
||||||
|
associated objects were only recently deleted as the registry may not be immediately updated.
|
||||||
|
"""
|
||||||
|
logger.info("Polling registry to confirm deletion pre-conditions for %s", self.name)
|
||||||
|
last_info_error = None
|
||||||
|
for attempt in range(max_attempts):
|
||||||
|
try:
|
||||||
|
info_response = registry.send(commands.InfoDomain(name=self.name), cleaned=True)
|
||||||
|
domain_info = info_response.res_data[0]
|
||||||
|
hosts_associated = getattr(domain_info, "hosts", None)
|
||||||
|
if hosts_associated is None or len(hosts_associated) == 0:
|
||||||
|
logger.info("InfoDomain reports no associated hosts for %s. Proceeding with deletion.", self.name)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.info("Attempt %d: Domain %s still has hosts: %s", attempt + 1, self.name, hosts_associated)
|
||||||
|
except RegistryError as info_e:
|
||||||
|
# If the domain is already gone, we can assume deletion already occurred.
|
||||||
|
if info_e.code == ErrorCode.OBJECT_DOES_NOT_EXIST:
|
||||||
|
logger.info("InfoDomain check indicates domain %s no longer exists.", self.name)
|
||||||
|
raise info_e
|
||||||
|
logger.warning("Attempt %d: Error during InfoDomain check: %s", attempt + 1, info_e)
|
||||||
|
time.sleep(wait_interval)
|
||||||
|
else:
|
||||||
|
logger.error("Exceeded max attempts waiting for domain %s to clear associated objects; last error: %s", self.name, last_info_error)
|
||||||
|
return False
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue