From 5f627aa70ae9241541dc265f1df614663f2da3e8 Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Fri, 24 Apr 2026 12:32:58 +0530 Subject: [PATCH] changes in this commit: 1. stop and start vm operations wont trigger dns sync 2. ip update for nic will refresh dns records --- .../java/com/cloud/vm/UserVmManagerImpl.java | 12 +++---- .../dns/DnsProviderManagerImpl.java | 35 ++++++++++++------- .../dns/DnsProviderManagerImplTest.java | 33 ++++++++--------- 3 files changed, 45 insertions(+), 35 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index aa09d826bf9..cc61e663cef 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -18,6 +18,7 @@ package com.cloud.vm; import static com.cloud.event.EventTypes.EVENT_NIC_CREATE; import static com.cloud.event.EventTypes.EVENT_NIC_DELETE; +import static com.cloud.event.EventTypes.EVENT_NIC_UPDATE; import static com.cloud.event.EventTypes.EVENT_VM_UPDATE; import static com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality; import static com.cloud.storage.Volume.IOPS_LIMIT; @@ -1582,7 +1583,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir event.put(ApiConstants.INSTANCE_ID, instanceId); event.put(ApiConstants.ACCOUNT_ID, accountId); event.put(ApiConstants.NIC_ID, nicId); - event.put(ApiConstants.EVENT_TYPE, eventType); // NIC_CREATE or NIC_DELETE + event.put(ApiConstants.EVENT_TYPE, eventType); // NIC.CREATE, NIC.DELETE or NIC.UPDATE event.put(ApiConstants.TIME_STAMP, System.currentTimeMillis()); messageBus.publish(_name, Nic.Topics.NIC_LIFECYCLE, PublishScope.GLOBAL, event); @@ -1965,7 +1966,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir logger.debug("Updating IPv4 address of NIC " + nicVO + " to " + ipaddr + "/" + nicVO.getIPv4Netmask() + " with gateway " + nicVO.getIPv4Gateway()); nicVO.setIPv4Address(ipaddr); _nicDao.persist(nicVO); - + publishNicEventMessageBus(vm.getId(), vm.getAccountId(), nicVO.getId(), EVENT_NIC_UPDATE); return vm; } @@ -3506,10 +3507,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (cmd.getConsiderLastHost() != null) { additonalParams.put(VirtualMachineProfile.Param.ConsiderLastHost, cmd.getConsiderLastHost().toString()); } - UserVmVO vm = _vmDao.findById(cmd.getId()); - UserVm userVm = startVirtualMachine(cmd.getId(), cmd.getPodId(), cmd.getClusterId(), cmd.getHostId(), additonalParams, cmd.getDeploymentPlanner()).first(); - publishVmLifecycleMessageBus(userVm, vm.getState(), VirtualMachine.State.Running); - return userVm; + + return startVirtualMachine(cmd.getId(), cmd.getPodId(), cmd.getClusterId(), cmd.getHostId(), additonalParams, cmd.getDeploymentPlanner()).first(); } @Override @@ -5785,7 +5784,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir status = vmEntity.stop(Long.toString(userId)); } if (status) { - publishVmLifecycleMessageBus(vm, vm.getState(), VirtualMachine.State.Stopped); return _vmDao.findById(vmId); } else { return null; diff --git a/server/src/main/java/org/apache/cloudstack/dns/DnsProviderManagerImpl.java b/server/src/main/java/org/apache/cloudstack/dns/DnsProviderManagerImpl.java index c63b7dc9652..50c97032058 100644 --- a/server/src/main/java/org/apache/cloudstack/dns/DnsProviderManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/dns/DnsProviderManagerImpl.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.dns; import static com.cloud.event.EventTypes.EVENT_NIC_CREATE; import static com.cloud.event.EventTypes.EVENT_NIC_DELETE; +import static com.cloud.event.EventTypes.EVENT_NIC_UPDATE; import static com.cloud.event.EventTypes.EVENT_VM_UPDATE; import java.util.ArrayList; @@ -804,15 +805,13 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa long instanceId = (long) event.get(ApiConstants.INSTANCE_ID); switch (newState) { case Running: - handleVmRunningState(instanceId); + handleVmCreateEvent(instanceId); break; - case Stopped: case Destroyed: - handleVmStopAndDestroy(instanceId); + handleVmDestroyEvent(instanceId); break; default: logger.warn("Ignoring lifecycle event for Instance ID: {}, unsupported state={}", instanceId, newState); - break; } } catch (Exception ex) { logger.error("Failed to process Instance lifecycle event", ex); @@ -835,12 +834,19 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa logger.warn("Insufficient data to process NIC lifecycle event: {}", args); return; } - if (EVENT_NIC_CREATE.equals(eventType)) { - handleNicPlug(instanceId, nicId); - } else if (EVENT_NIC_DELETE.equals(eventType)) { - handleNicUnplug(instanceId, nicId); - } else { - logger.warn("Ignoring lifecycle event for NIC with ID: {}, unsupported eventType={}", nicId, eventType); + + switch (eventType) { + case EVENT_NIC_CREATE: + handleNicPlug(instanceId, nicId); + break; + case EVENT_NIC_DELETE: + handleNicUnplug(instanceId, nicId); + break; + case EVENT_NIC_UPDATE: + handleNicRefresh(instanceId, nicId); + break; + default: + logger.warn("Ignoring lifecycle event for NIC with ID: {}, unsupported eventType={}", nicId, eventType); } } catch (Exception ex) { logger.error("Failed to process NIC lifecycle event", ex); @@ -876,7 +882,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa } } - void handleVmRunningState(long instanceId) { + void handleVmCreateEvent(long instanceId) { VirtualMachine instance = vmInstanceDao.findById(instanceId); if (instance == null) { logger.debug("Instance is not found for the given ID: {}", instanceId); @@ -926,7 +932,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa } } - void handleVmStopAndDestroy(long instanceId) { + void handleVmDestroyEvent(long instanceId) { List historicalNics = nicDnsJoinDao.listIncludingRemovedByVmId(instanceId); if (CollectionUtils.isEmpty(historicalNics)) { return; @@ -1109,6 +1115,11 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa } } + private void handleNicRefresh(long instanceId, long nicId) { + handleNicUnplug(instanceId, nicId); + handleNicPlug(instanceId, nicId); + } + String prepareDnsRecordUrl(String hostName, String subDomain, String dnsZoneName) { List parts = new ArrayList<>(); parts.add(hostName); diff --git a/server/src/test/java/org/apache/cloudstack/dns/DnsProviderManagerImplTest.java b/server/src/test/java/org/apache/cloudstack/dns/DnsProviderManagerImplTest.java index 522eba2caf0..662a805cb5f 100644 --- a/server/src/test/java/org/apache/cloudstack/dns/DnsProviderManagerImplTest.java +++ b/server/src/test/java/org/apache/cloudstack/dns/DnsProviderManagerImplTest.java @@ -91,6 +91,7 @@ import com.cloud.user.AccountVO; import com.cloud.utils.db.Transaction; import com.cloud.utils.db.TransactionCallback; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.NicDetailsDao; import com.cloud.vm.dao.VMInstanceDao; @@ -891,11 +892,11 @@ public class DnsProviderManagerImplTest { } @Test - public void testVmLifecycleSubscriberStopped() { + public void testVmLifecycleSubscriberDestroyed() { DnsProviderManagerImpl.VmLifecycleSubscriber subscriber = manager.new VmLifecycleSubscriber(); java.util.Map event = new java.util.HashMap<>(); event.put(org.apache.cloudstack.api.ApiConstants.OLD_STATE, com.cloud.vm.VirtualMachine.State.Running); - event.put(org.apache.cloudstack.api.ApiConstants.NEW_STATE, com.cloud.vm.VirtualMachine.State.Stopped); + event.put(org.apache.cloudstack.api.ApiConstants.NEW_STATE, VirtualMachine.State.Destroyed); event.put(org.apache.cloudstack.api.ApiConstants.INSTANCE_ID, 15L); when(nicDnsJoinDao.listIncludingRemovedByVmId(15L)).thenReturn(null); subscriber.onPublishMessage("sender", "subject", event); @@ -1065,32 +1066,32 @@ public class DnsProviderManagerImplTest { } @Test - public void testHandleVmRunningStateFoundButNoActiveNics() throws DnsProviderException { + public void testHandleVmCreateEventFoundButNoActiveNics() throws DnsProviderException { com.cloud.vm.VMInstanceVO instanceMock = mock(com.cloud.vm.VMInstanceVO.class); when(vmInstanceDao.findById(30L)).thenReturn(instanceMock); when(nicDnsJoinDao.listActiveByVmId(30L)).thenReturn(Collections.emptyList()); - manager.handleVmRunningState(30L); + manager.handleVmCreateEvent(30L); verify(dnsProviderMock, never()).addRecord(any(), any(), any()); verify(dnsProviderMock, never()).deleteRecord(any(), any(), any()); } @Test - public void testHandleVmStopAndDestroyNicWithNullDnsUrlIsSkipped() throws DnsProviderException { + public void testHandleVmDestroyEventNicWithNullDnsUrlIsSkipped() throws DnsProviderException { NicDnsJoinVO nicMock = mock(NicDnsJoinVO.class); when(nicMock.getNicDnsName()).thenReturn(null); when(nicDnsJoinDao.listIncludingRemovedByVmId(31L)) .thenReturn(Collections.singletonList(nicMock)); - manager.handleVmStopAndDestroy(31L); + manager.handleVmDestroyEvent(31L); verify(dnsProviderMock, never()).deleteRecord(any(), any(), any()); } @Test - public void testHandleVmStopAndDestroyWithValidDnsUrlTriggersCleanup() throws Exception { + public void testHandleVmDestroyEventWithValidDnsUrlTriggersCleanup() throws Exception { NicDnsJoinVO nicMock = mock(NicDnsJoinVO.class); when(nicMock.getNicDnsName()).thenReturn("myvm.example.com"); @@ -1118,7 +1119,7 @@ public class DnsProviderManagerImplTest { return null; }); - manager.handleVmStopAndDestroy(32L); + manager.handleVmDestroyEvent(32L); verify(nicDetailsDao).removeDetail(nicMock.getId(), org.apache.cloudstack.api.ApiConstants.NIC_DNS_NAME); verify(dnsProviderMock, times(2)).deleteRecord(eq(serverVO), eq(zoneVO), any(DnsRecord.class)); @@ -1258,7 +1259,7 @@ public class DnsProviderManagerImplTest { } @Test - public void testHandleVmRunningStateNonEmptyNicsAllZonesMissingSkipsSync() throws DnsProviderException { + public void testHandleVmCreateEventNonEmptyNicsAllZonesMissingSkipsSync() throws DnsProviderException { com.cloud.vm.VMInstanceVO instanceMock = mock(com.cloud.vm.VMInstanceVO.class); when(vmInstanceDao.findById(42L)).thenReturn(instanceMock); @@ -1268,7 +1269,7 @@ public class DnsProviderManagerImplTest { when(nicDnsJoinDao.listActiveByVmId(42L)).thenReturn(Collections.singletonList(nicMock)); when(dnsZoneDao.findById(ZONE_ID)).thenReturn(null); // zone null → NIC skipped → empty outer map - manager.handleVmRunningState(42L); + manager.handleVmCreateEvent(42L); verify(dnsZoneDao, times(1)).findById(ZONE_ID); verify(dnsProviderMock, never()).addRecord(any(), any(), any()); @@ -1299,14 +1300,14 @@ public class DnsProviderManagerImplTest { // ─── handleVmRunningState ────────────────────────────────────────────────── @Test - public void testHandleVmRunningStateInstanceNullExitsEarly() throws DnsProviderException { + public void testHandleVmCreateEventInstanceNullExitsEarly() throws DnsProviderException { when(vmInstanceDao.findById(50L)).thenReturn(null); - manager.handleVmRunningState(50L); + manager.handleVmCreateEvent(50L); verify(nicDnsJoinDao, never()).listActiveByVmId(anyLong()); } @Test - public void testHandleVmRunningStateFullSyncNoCollision() throws Exception { + public void testHandleVmCreateEventFullSyncNoCollision() throws Exception { com.cloud.vm.VMInstanceVO instanceMock = mock(com.cloud.vm.VMInstanceVO.class); when(instanceMock.getHostName()).thenReturn("myvm"); when(vmInstanceDao.findById(51L)).thenReturn(instanceMock); @@ -1337,7 +1338,7 @@ public class DnsProviderManagerImplTest { return null; }); - manager.handleVmRunningState(51L); + manager.handleVmCreateEvent(51L); verify(nicDetailsDao).addDetail(anyLong(), eq(org.apache.cloudstack.api.ApiConstants.NIC_DNS_NAME), anyString(), eq(true)); @@ -1346,7 +1347,7 @@ public class DnsProviderManagerImplTest { } @Test - public void testHandleVmRunningStateCollisionSkipsAddDetail() throws Exception { + public void testHandleVmCreateEventCollisionSkipsAddDetail() throws Exception { com.cloud.vm.VMInstanceVO instanceMock = mock(com.cloud.vm.VMInstanceVO.class); when(instanceMock.getHostName()).thenReturn("myvm"); when(vmInstanceDao.findById(52L)).thenReturn(instanceMock); @@ -1381,7 +1382,7 @@ public class DnsProviderManagerImplTest { return null; }); - manager.handleVmRunningState(52L); + manager.handleVmCreateEvent(52L); verify(nicDetailsDao, never()).addDetail(anyLong(), anyString(), anyString(), eq(true)); verify(dnsProviderMock, never()).addRecord(any(), any(), any());