Skip to content

Commit a6e812b

Browse files
committed
improve cleanup logic for DNS zone and server
1 parent af7ce8e commit a6e812b

File tree

10 files changed

+84
-45
lines changed

10 files changed

+84
-45
lines changed

api/src/main/java/org/apache/cloudstack/api/command/user/dns/AssociateDnsZoneToNetworkCmd.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@
2929
import org.apache.cloudstack.api.response.DnsZoneNetworkMapResponse;
3030
import org.apache.cloudstack.api.response.DnsZoneResponse;
3131
import org.apache.cloudstack.api.response.NetworkResponse;
32-
import org.apache.cloudstack.dns.DnsZone;
3332

3433
import com.cloud.exception.ConcurrentOperationException;
3534
import com.cloud.exception.InsufficientCapacityException;
3635
import com.cloud.exception.NetworkRuleConflictException;
3736
import com.cloud.exception.ResourceAllocationException;
3837
import com.cloud.exception.ResourceUnavailableException;
38+
import com.cloud.network.Network;
3939
import com.cloud.user.Account;
4040

4141
@APICommand(name = "associateDnsZoneToNetwork",
@@ -73,9 +73,9 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
7373

7474
@Override
7575
public long getEntityOwnerId() {
76-
DnsZone zone = _entityMgr.findById(DnsZone.class, dnsZoneId);
77-
if (zone != null) {
78-
return zone.getAccountId();
76+
Network network = _entityMgr.findById(Network.class, networkId);
77+
if (network != null) {
78+
return network.getAccountId();
7979
}
8080
return Account.ACCOUNT_ID_SYSTEM;
8181
}

engine/schema/src/main/java/com/cloud/vm/dao/NicDetailsDao.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@
1616
// under the License.
1717
package com.cloud.vm.dao;
1818

19+
import java.util.List;
20+
1921
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
2022

2123
import com.cloud.utils.db.GenericDao;
2224
import com.cloud.vm.NicDetailVO;
2325

2426
public interface NicDetailsDao extends GenericDao<NicDetailVO, Long>, ResourceDetailsDao<NicDetailVO> {
27+
28+
void removeDetailsForValuesIn(String resourceName, List<String> values);
2529
}

engine/schema/src/main/java/com/cloud/vm/dao/NicDetailsDaoImpl.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,40 @@
1717
package com.cloud.vm.dao;
1818

1919

20+
import java.util.List;
21+
22+
import org.apache.cloudstack.api.ApiConstants;
2023
import org.springframework.stereotype.Component;
2124

2225
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
2326

27+
import com.cloud.utils.db.SearchBuilder;
28+
import com.cloud.utils.db.SearchCriteria;
2429
import com.cloud.vm.NicDetailVO;
2530

2631
@Component
2732
public class NicDetailsDaoImpl extends ResourceDetailsDaoBase<NicDetailVO> implements NicDetailsDao {
33+
private final SearchBuilder<NicDetailVO> NameValuesSearch;
34+
35+
public NicDetailsDaoImpl() {
36+
super();
37+
NameValuesSearch = createSearchBuilder();
38+
NameValuesSearch.and(ApiConstants.NAME, NameValuesSearch.entity().getName(), SearchCriteria.Op.EQ);
39+
NameValuesSearch.and(ApiConstants.VALUE, NameValuesSearch.entity().getValue(), SearchCriteria.Op.IN);
40+
NameValuesSearch.done();
41+
}
42+
2843

2944
@Override
3045
public void addDetail(long resourceId, String key, String value, boolean display) {
3146
super.addDetail(new NicDetailVO(resourceId, key, value, display));
3247
}
48+
49+
@Override
50+
public void removeDetailsForValuesIn(String resourceName, List<String> values) {
51+
SearchCriteria<NicDetailVO> sc = NameValuesSearch.create();
52+
sc.setParameters(ApiConstants.NAME, resourceName);
53+
sc.setParameters(ApiConstants.VALUE, values.toArray());
54+
remove(sc);
55+
}
3356
}

server/src/main/java/org/apache/cloudstack/dns/DnsProviderManagerImpl.java

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.ArrayList;
2121
import java.util.Collections;
2222
import java.util.List;
23+
import java.util.Objects;
2324
import java.util.Set;
2425
import java.util.stream.Collectors;
2526

@@ -59,6 +60,7 @@
5960
import org.apache.cloudstack.dns.vo.DnsZoneJoinVO;
6061
import org.apache.cloudstack.dns.vo.DnsZoneNetworkMapVO;
6162
import org.apache.cloudstack.dns.vo.DnsZoneVO;
63+
import org.apache.commons.collections.CollectionUtils;
6264
import org.apache.logging.log4j.util.Strings;
6365
import 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();

server/src/main/java/org/apache/cloudstack/dns/dao/DnsServerDao.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,5 @@ public interface DnsServerDao extends GenericDao<DnsServerVO, Long> {
3333

3434
List<Long> listDnsServerIdsByAccountId(Long accountId);
3535

36-
Pair<List<DnsServerVO>, Integer> searchDnsServers(Long id, String keyword, String provider, Long accountId, Filter filter);
37-
3836
Pair<List<DnsServerVO>, Integer> searchDnsServer(Long dnsServerId, Long accountId, Set<Long> domainIds, DnsProviderType providerType, String keyword, Filter filter);
3937
}

server/src/main/java/org/apache/cloudstack/dns/dao/DnsServerDaoImpl.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -82,24 +82,6 @@ public List<Long> listDnsServerIdsByAccountId(Long accountId) {
8282
return customSearch(sc, null);
8383
}
8484

85-
@Override
86-
public Pair<List<DnsServerVO>, Integer> searchDnsServers(Long id, String keyword, String provider, Long accountId, Filter filter) {
87-
SearchCriteria<DnsServerVO> sc = AllFieldsSearch.create();
88-
if (id != null) {
89-
sc.setParameters(ApiConstants.ID, id);
90-
}
91-
if (keyword != null) {
92-
sc.setParameters(ApiConstants.NAME, "%" + keyword + "%");
93-
}
94-
if (provider != null) {
95-
sc.setParameters(ApiConstants.PROVIDER_TYPE, provider);
96-
}
97-
if (accountId != null) {
98-
sc.setParameters(ApiConstants.ACCOUNT_ID, accountId);
99-
}
100-
return searchAndCount(sc, filter);
101-
}
102-
10385
@Override
10486
public Pair<List<DnsServerVO>, Integer> searchDnsServer(Long dnsServerId, Long accountId, Set<Long> domainIds, DnsProviderType providerType,
10587
String keyword, Filter filter) {

server/src/main/java/org/apache/cloudstack/dns/dao/DnsZoneDaoImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public DnsZoneDaoImpl() {
4141
super();
4242

4343
DnsServerSearch = createSearchBuilder();
44-
DnsServerSearch.selectFields(DnsServerSearch.entity().getDnsServerId());
44+
DnsServerSearch.selectFields(DnsServerSearch.entity().getId());
4545
DnsServerSearch.and(ApiConstants.DNS_SERVER_ID, DnsServerSearch.entity().getDnsServerId(), SearchCriteria.Op.EQ);
4646
DnsServerSearch.done();
4747

server/src/main/java/org/apache/cloudstack/dns/dao/DnsZoneNetworkMapDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@
2424
public interface DnsZoneNetworkMapDao extends GenericDao<DnsZoneNetworkMapVO, Long> {
2525
void removeNetworkMappingByZoneId(long dnsZoneId);
2626
DnsZoneNetworkMapVO findByNetworkId(long networkId);
27+
28+
DnsZoneNetworkMapVO findByZoneId(long networkId);
2729
}

server/src/main/java/org/apache/cloudstack/dns/dao/DnsZoneNetworkMapDaoImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,11 @@ public DnsZoneNetworkMapVO findByNetworkId(long networkId) {
5454
sc.setParameters(ApiConstants.NETWORK_ID, networkId);
5555
return findOneBy(sc);
5656
}
57+
58+
@Override
59+
public DnsZoneNetworkMapVO findByZoneId(long dnsZoneId) {
60+
SearchCriteria<DnsZoneNetworkMapVO> sc = ZoneNetworkSearch.create();
61+
sc.setParameters(ApiConstants.DNS_ZONE_ID, dnsZoneId);
62+
return findOneBy(sc);
63+
}
5764
}

ui/src/config/section/network.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,7 +1528,7 @@ export default {
15281528
{
15291529
name: 'dnsserver',
15301530
title: 'label.dns.server',
1531-
icon: 'global-outlined',
1531+
icon: 'cloud-server-outlined',
15321532
permission: ['listDnsServers'],
15331533
columns: ['name', 'url', 'provider', 'ispublic', 'port', 'nameservers', 'publicdomainsuffix'],
15341534
details: ['name', 'url', 'provider', 'ispublic', 'port', 'nameservers', 'publicdomainsuffix', 'domain', 'account'],
@@ -1572,7 +1572,7 @@ export default {
15721572
{
15731573
name: 'dnszone',
15741574
title: 'label.dns.zones',
1575-
icon: 'global-outlined',
1575+
icon: 'apartment-outlined',
15761576
permission: ['listDnsZones'],
15771577
columns: ['name', 'state', 'dnsservername', 'account', 'description'],
15781578
details: ['name', 'id', 'state', 'dnsservername', 'dnsserverid', 'account', 'domainpath', 'description'],

0 commit comments

Comments
 (0)