2020import java .util .ArrayList ;
2121import java .util .Collections ;
2222import java .util .List ;
23+ import java .util .Objects ;
2324import java .util .Set ;
2425import java .util .stream .Collectors ;
2526
5960import org .apache .cloudstack .dns .vo .DnsZoneJoinVO ;
6061import org .apache .cloudstack .dns .vo .DnsZoneNetworkMapVO ;
6162import org .apache .cloudstack .dns .vo .DnsZoneVO ;
63+ import org .apache .commons .collections .CollectionUtils ;
6264import org .apache .logging .log4j .util .Strings ;
6365import org .springframework .stereotype .Component ;
6466
@@ -280,10 +282,11 @@ public boolean deleteDnsServer(DeleteDnsServerCmd cmd) {
280282 if (cmd .getCleanup ()) {
281283 List <DnsZoneVO > dnsZones = dnsZoneDao .findDnsZonesByServerId (dnsServerId );
282284 for (DnsZoneVO dnsZone : dnsZones ) {
283- long dnsZoneId = dnsZone .getId ();
284- dnsZoneNetworkMapDao .removeNetworkMappingByZoneId (dnsZoneId );
285- // ToDo: delete nic_record_urls from vm_details if present before removing dnsZone
286- dnsZoneDao .remove (dnsZoneId );
285+ try {
286+ deleteDnsZone (dnsZone .getId ());
287+ } catch (Exception ex ) {
288+ logger .error ("Error cleaning up DNS zone: {} during DNS server: {} deletion" , dnsZone .getName (), dnsServer .getName ());
289+ }
287290 }
288291 }
289292 return dnsServerDao .remove (dnsServerId );
@@ -304,22 +307,39 @@ public boolean deleteDnsZone(Long zoneId) {
304307 if (server == null ) {
305308 throw new CloudRuntimeException (String .format ("The DNS server not found for DNS zone: %s" , dnsZoneName ));
306309 }
307- try {
308- DnsProvider provider = getProviderByType (server .getProviderType ());
309- provider .deleteZone (server , dnsZone );
310- logger .debug ("Deleted DNS zone: {} from provider" , dnsZoneName );
311- } catch (DnsNotFoundException ex ) {
312- logger .warn ("DNS zone: {} is not present in the provider, proceeding with cleanup" , dnsZoneName );
313- } catch (Exception ex ) {
314- logger .error ("Failed to delete DNS zone from provider" , ex );
315- throw new CloudRuntimeException (String .format ("Failed to delete DNS zone: %s." , dnsZoneName ));
316- }
317310
318311 boolean dbResult = Transaction .execute ((TransactionCallback <Boolean >) status -> {
319- dnsZoneNetworkMapDao .removeNetworkMappingByZoneId (zoneId );
320- // ToDo: delete nic_record_urls from vm_details if present before removing dnsZone
312+ DnsZoneNetworkMapVO networkMapVO = dnsZoneNetworkMapDao .findByZoneId (zoneId );
313+ if (networkMapVO != null ) {
314+ // Remove DNS records from nic_details if there are any
315+ try {
316+ DnsProvider provider = getProviderByType (server .getProviderType ());
317+ List <DnsRecord > records = provider .listRecords (server , dnsZone );
318+ if (CollectionUtils .isNotEmpty (records )) {
319+ List <String > dnsRecordNames = records .stream ().map (DnsRecord ::getName ).filter (Objects ::nonNull )
320+ .map (name -> name .replaceAll ("\\ .+$" , "" ))
321+ .collect (Collectors .toList ());
322+ nicDetailsDao .removeDetailsForValuesIn (ApiConstants .NIC_DNS_RECORD , dnsRecordNames );
323+ }
324+ } catch (Exception ex ) {
325+ logger .warn ("Failed to fetch DNS records for dnsZone: {}, perform manual cleanup." , dnsZoneName , ex );
326+ }
327+ // Remove DNS zone from provider and cleanup DB
328+ try {
329+ DnsProvider provider = getProviderByType (server .getProviderType ());
330+ provider .deleteZone (server , dnsZone );
331+ logger .debug ("Deleted DNS zone: {} from provider" , dnsZoneName );
332+ } catch (DnsNotFoundException ex ) {
333+ logger .warn ("DNS zone: {} is not present in the provider, proceeding with cleanup" , dnsZoneName );
334+ } catch (Exception ex ) {
335+ logger .error ("Failed to delete DNS zone from provider" , ex );
336+ throw new CloudRuntimeException (String .format ("Failed to delete DNS zone: %s." , dnsZoneName ));
337+ }
338+ dnsZoneNetworkMapDao .removeNetworkMappingByZoneId (zoneId );
339+ }
321340 return dnsZoneDao .remove (zoneId );
322341 });
342+
323343 if (!dbResult ) {
324344 logger .error ("Failed to remove DNS zone {} from DB after provider deletion" , dnsZoneName );
325345 }
@@ -612,7 +632,10 @@ public DnsZoneNetworkMapResponse associateZoneToNetwork(AssociateDnsZoneToNetwor
612632 throw new InvalidParameterValueException ("DNS zone not found." );
613633 }
614634 accountMgr .checkAccess (caller , null , true , dnsZone );
615-
635+ DnsServerVO dnsServer = dnsServerDao .findById (dnsZone .getDnsServerId ());
636+ if (dnsServer == null ) {
637+ throw new CloudRuntimeException ("The underlying DNS server for this DNS zone is missing." );
638+ }
616639 NetworkVO network = networkDao .findById (cmd .getNetworkId ());
617640 if (network == null ) {
618641 throw new InvalidParameterValueException ("Network not found." );
@@ -621,11 +644,11 @@ public DnsZoneNetworkMapResponse associateZoneToNetwork(AssociateDnsZoneToNetwor
621644 throw new CloudRuntimeException (String .format ("Operation is not permitted for network type: %s" , network .getGuestType ()));
622645 }
623646 accountMgr .checkAccess (caller , null , true , network );
624-
625647 DnsZoneNetworkMapVO existing = dnsZoneNetworkMapDao .findByNetworkId (network .getId ());
626648 if (existing != null ) {
627649 throw new InvalidParameterValueException ("Network has existing DNS zone associated to it." );
628650 }
651+
629652 DnsZoneNetworkMapVO mapping = new DnsZoneNetworkMapVO (dnsZone .getId (), network .getId (), cmd .getSubDomain ());
630653 dnsZoneNetworkMapDao .persist (mapping );
631654 DnsZoneNetworkMapResponse response = new DnsZoneNetworkMapResponse ();
0 commit comments