fix addDnsRecord and deleteDnsRecord flow for automatic registration and ownership issue for associate/disassociate dnsZoneToNetwork

This commit is contained in:
Manoj Kumar 2026-03-20 13:10:59 +05:30
parent 981bb64b86
commit af7ce8ebdd
No known key found for this signature in database
GPG Key ID: E952B7234D2C6F88
4 changed files with 69 additions and 26 deletions

View File

@ -26,7 +26,6 @@ import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DnsZoneResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
@ -35,6 +34,7 @@ import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network;
import com.cloud.user.Account;
@APICommand(name = "disassociateDnsZoneFromNetwork",
@ -45,9 +45,6 @@ import com.cloud.user.Account;
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class DisassociateDnsZoneFromNetworkCmd extends BaseCmd {
@Parameter(name = ApiConstants.DNS_ZONE_ID, type = CommandType.UUID, entityType = DnsZoneResponse.class, description = "The ID of the DNS zone")
private Long dnsZoneId;
@ACL(accessType = SecurityChecker.AccessType.OperateEntry)
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class,
required = true, description = "The ID of the Network")
@ -70,13 +67,13 @@ public class DisassociateDnsZoneFromNetworkCmd extends BaseCmd {
@Override
public long getEntityOwnerId() {
Network network = _entityMgr.findById(Network.class, networkId);
if (network != null) {
return network.getAccountId();
}
return Account.ACCOUNT_ID_SYSTEM;
}
public Long getDnsZoneId() {
return dnsZoneId;
}
public Long getNetworkId() {
return networkId;
}

View File

@ -75,7 +75,8 @@ public interface DnsProviderManager extends Manager, PluggableService {
boolean disassociateZoneFromNetwork(DisassociateDnsZoneFromNetworkCmd cmd);
String processDnsRecordForInstance(VirtualMachine instance, Network network, Nic nic, boolean isAdd);
void addDnsRecordForVM(VirtualMachine instance, Network network, Nic nic);
void deleteDnsRecordForVM(VirtualMachine instance, Network network, Nic nic);
void checkDnsServerPermission(Account caller, DnsServer dnsServer);

View File

@ -59,6 +59,7 @@ import org.apache.cloudstack.dns.vo.DnsServerVO;
import org.apache.cloudstack.dns.vo.DnsZoneJoinVO;
import org.apache.cloudstack.dns.vo.DnsZoneNetworkMapVO;
import org.apache.cloudstack.dns.vo.DnsZoneVO;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;
import com.cloud.domain.dao.DomainDao;
@ -81,8 +82,10 @@ import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.Nic;
import com.cloud.vm.NicDetailVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.NicDetailsDao;
import com.cloud.vm.dao.UserVmDao;
@Component
@ -110,6 +113,8 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
DnsServerJoinDao dnsServerJoinDao;
@Inject
AccountDao accountDao;
@Inject
NicDetailsDao nicDetailsDao;
private DnsProvider getProviderByType(DnsProviderType type) {
if (type == null) {
@ -649,23 +654,69 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
}
@Override
public String processDnsRecordForInstance(VirtualMachine instance, Network network, Nic nic, boolean isAdd) {
long networkId = network.getId();
DnsZoneNetworkMapVO dnsZoneNetworkMap = dnsZoneNetworkMapDao.findByNetworkId(networkId);
public void addDnsRecordForVM(VirtualMachine instance, Network network, Nic nic) {
DnsZoneNetworkMapVO dnsZoneNetworkMap = dnsZoneNetworkMapDao.findByNetworkId(network.getId());
if (dnsZoneNetworkMap == null) {
logger.warn("No DNS zone is mapped to this network. Please associate a zone first.");
return null;
return;
}
DnsZoneVO dnsZone = dnsZoneDao.findById(dnsZoneNetworkMap.getDnsZoneId());
if (dnsZone == null || dnsZone.getState() != DnsZone.State.Active) {
return null;
logger.warn("DNS zone is not available for DNS record setup");
return;
}
DnsServerVO server = dnsServerDao.findById(dnsZone.getDnsServerId());
if (server == null) {
logger.warn("DNS server is not found to process DNS record for Instance: {}", instance.getInstanceName());
return;
}
// Construct FQDN Prefix (e.g., "instance-id.dnsZoneName" or "instance-id.subdomain.dnsZoneName")
String recordName = String.valueOf(instance.getInstanceName());
if (StringUtils.isNotBlank(dnsZoneNetworkMap.getSubDomain())) {
recordName = String.join(".", recordName, dnsZoneNetworkMap.getSubDomain(), dnsZone.getName());
}
String dnsRecordUrl = processDnsRecordInProvider(recordName, instance, server, dnsZone, nic, true);
if (Strings.isBlank(dnsRecordUrl)) {
logger.error("Failed to add DNS record in provider for Instance: {}", instance.getInstanceName());
return;
}
nicDetailsDao.addDetail(nic.getId(), ApiConstants.NIC_DNS_RECORD, dnsRecordUrl, true);
}
@Override
public void deleteDnsRecordForVM(VirtualMachine instance, Network network, Nic nic) {
String instanceName = instance.getInstanceName();
NicDetailVO nicDetailVO = nicDetailsDao.findDetail(nic.getId(), ApiConstants.NIC_DNS_RECORD);
if (nicDetailVO == null || Strings.isBlank(nicDetailVO.getValue())) {
logger.debug("No DNS record found for Instance: {}", instance.getInstanceName());
return;
}
String dnsRecord = nicDetailVO.getValue();
try {
DnsZoneNetworkMapVO dnsZoneNetworkMap = dnsZoneNetworkMapDao.findByNetworkId(network.getId());
DnsZoneVO dnsZone = null;
DnsServerVO dnsServer = null;
if (dnsZoneNetworkMap != null) {
dnsZone = dnsZoneDao.findById(dnsZoneNetworkMap.getDnsZoneId());
}
if (dnsZone != null) {
dnsServer = dnsServerDao.findById(dnsZone.getDnsServerId());
}
if (dnsServer != null) {
processDnsRecordInProvider(dnsRecord, instance, dnsServer, dnsZone, nic, false);
} else {
logger.warn("Skipping deletion of DNS record: {} from provider for Instance: {}.", dnsRecord, instanceName);
}
} catch (Exception ex) {
logger.error("Failed deleting DNS record: {} for Instance: {}, proceeding with DB cleanup.", dnsRecord, instanceName);
} finally {
nicDetailsDao.removeDetail(nic.getId(), ApiConstants.NIC_DNS_RECORD);
logger.debug("Removed DNS record from DB for Instance: {}, NIC ID: {}", instanceName, nic.getUuid());
}
}
private String processDnsRecordInProvider(String recordName, VirtualMachine instance, DnsServer server, DnsZone dnsZone,
Nic nic, boolean isAdd) {
try {
DnsProvider provider = getProviderByType(server.getProviderType());
@ -695,7 +746,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
logger.error(
"Failed to {} DNS record for Instance {} in zone {}",
isAdd ? "register" : "remove",
instance.getHostName(),
instance.getInstanceName(),
dnsZone.getName(),
ex
);

View File

@ -144,12 +144,12 @@ public class DnsVmLifecycleListener extends ManagerBase implements EventSubscrib
}
private void handleVmEvent(String vmUuid, boolean isAddDnsRecord) {
VMInstanceVO vmInstanceVO = vmInstanceDao.findByUuid(vmUuid);
VMInstanceVO vmInstanceVO = vmInstanceDao.findByUuidIncludingRemoved(vmUuid);
if (vmInstanceVO == null) {
logger.error("Unable to find Instance with ID: {}", vmUuid);
return;
}
List<NicVO> vmNics = nicDao.listByVmId(vmInstanceVO.getId());
List<NicVO> vmNics = nicDao.listByVmIdIncludingRemoved(vmInstanceVO.getId());
for (NicVO nic : vmNics) {
Network network = networkDao.findById(nic.getNetworkId());
if (network == null || !Network.GuestType.Shared.equals(network.getGuestType())) {
@ -160,16 +160,10 @@ public class DnsVmLifecycleListener extends ManagerBase implements EventSubscrib
}
void processEventForDnsRecord(VMInstanceVO vmInstanceVO, Network network, Nic nic, boolean isAddDnsRecord) {
String dnsRecordUrl = providerManager.processDnsRecordForInstance(vmInstanceVO, network, nic, isAddDnsRecord);
if (dnsRecordUrl != null) {
if (isAddDnsRecord) {
nicDetailsDao.addDetail(nic.getId(), ApiConstants.NIC_DNS_RECORD, dnsRecordUrl, true);
} else {
nicDetailsDao.removeDetail(nic.getId(), ApiConstants.NIC_DNS_RECORD);
}
if (isAddDnsRecord) {
providerManager.addDnsRecordForVM(vmInstanceVO, network, nic);
} else {
logger.error("Failure {} DNS record for Instance: {} for Network with ID: {}",
isAddDnsRecord ? "adding" : "removing", vmInstanceVO.getUuid(), network.getUuid());
providerManager.deleteDnsRecordForVM(vmInstanceVO, network, nic);
}
}