// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package com.cloud.network; import java.util.List; import javax.inject.Inject; import org.apache.log4j.Logger; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO; import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.resourcedetail.FirewallRuleDetailVO; import org.apache.cloudstack.resourcedetail.VpcDetailVO; import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao; import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao; import com.cloud.configuration.Resource; import com.cloud.dc.DataCenter; import com.cloud.dc.dao.DataCenterDao; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.Host; import com.cloud.host.dao.HostDao; import com.cloud.network.dao.FirewallRulesCidrsDao; import com.cloud.network.dao.FirewallRulesCidrsVO; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDetailVO; import com.cloud.network.dao.NetworkDetailsDao; import com.cloud.network.dao.NetworkDomainDao; import com.cloud.network.dao.NetworkDomainVO; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.RouterNetworkDao; import com.cloud.network.dao.RouterNetworkVO; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.RulesManager; import com.cloud.network.vpc.NetworkACLVO; import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcGatewayVO; import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpc.VpcService; import com.cloud.network.vpc.VpcVO; import com.cloud.network.vpc.dao.NetworkACLDao; import com.cloud.network.vpc.dao.VpcDao; import com.cloud.network.vpc.dao.VpcGatewayDao; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.server.ResourceTag; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountVO; import com.cloud.user.ResourceLimitService; import com.cloud.user.dao.AccountDao; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.Transaction; import com.cloud.utils.db.TransactionCallback; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.Nic; import com.cloud.vm.NicDetailVO; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; import com.cloud.vm.ReservationContextImpl; import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfileImpl; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.NicDetailsDao; import com.cloud.vm.dao.NicIpAliasDao; import com.cloud.vm.dao.NicSecondaryIpDao; import com.cloud.vm.dao.UserVmDao; public class NetworkMigrationManagerImpl implements NetworkMigrationManager { public static final Logger s_logger = Logger.getLogger(NetworkMigrationManagerImpl.class.getName()); @Inject private DataCenterDao _dcDao = null; @Inject private NetworkDetailsDao _networkDetailsDao = null; @Inject private AccountDao _accountDao = null; @Inject private NetworkDomainDao _networkDomainDao = null; @Inject private NetworkOrchestrationService _networkMgr = null; @Inject private ResourceLimitService _resourceLimitMgr = null; @Inject private NetworkDao _networksDao = null; @Inject private NetworkOfferingDao _networkOfferingDao = null; @Inject private NetworkOfferingServiceMapDao _networkOfferingServiceDao = null; @Inject private NicDao _nicDao = null; @Inject private NicSecondaryIpDao _nicSecondaryIpDao = null; @Inject private NicIpAliasDao _nicIpAliasDao = null; @Inject private NicDetailsDao _nicDetailsDao = null; @Inject private FirewallRulesDao _firewallDao = null; @Inject private FirewallRulesCidrsDao _firewallRulesCidrDao = null; @Inject private FirewallRuleDetailsDao _firewallRuleDetailsDao = null; @Inject private EntityManager _entityMgr = null; @Inject private RouterNetworkDao _routerNetworkDao = null; @Inject private DomainRouterDao _routerDao = null; @Inject private NetworkService _networkService = null; @Inject private UserVmDao _vmDao = null; @Inject private NetworkModel _networkModel= null; @Inject private VMNetworkMapDao _vmNetworkMapDao = null; @Inject private HostDao _hostDao = null; @Inject private VirtualMachineManager _itMgr = null; @Inject private IPAddressDao _ipAddressDao = null; @Inject private RulesManager _rulesMgr = null; @Inject private VpcDao _vpcDao = null; @Inject private VpcDetailsDao _vpcDetailsDao = null; @Inject private IpAddressManager _ipAddressManager = null; @Inject private VpcService _vpcService = null; @Inject private NetworkACLDao _networkACLDao = null; @Inject private VpcManager _vpcManager = null; @Inject private VpcGatewayDao _vpcGatewayDao = null; @Inject private ResourceTagDao _resourceTagDao = null; @Override public long makeCopyOfNetwork(Network network, NetworkOffering networkOffering, Long vpcId) { if (s_logger.isDebugEnabled()) { s_logger.debug("Making a copy of network with uuid " + network.getUuid() + " and id " + network.getId() + " for migration."); } long originalNetworkId = network.getId(); NetworkDomainVO domainNetworkMapByNetworkId = _networkDomainDao.getDomainNetworkMapByNetworkId(originalNetworkId); AccountVO networkAccount = _accountDao.findById(network.getAccountId()); boolean subdomainAccess = true; if (domainNetworkMapByNetworkId != null) { subdomainAccess = domainNetworkMapByNetworkId.isSubdomainAccess(); } DataCenterDeployment plan = new DataCenterDeployment(network.getDataCenterId(), null, null, null, null, network.getPhysicalNetworkId()); List networks = _networkMgr.setupNetwork(networkAccount, networkOffering, network, plan, network.getName(), network.getDisplayText(), true, network.getDomainId(), network.getAclType(), subdomainAccess, vpcId, true); _resourceLimitMgr.incrementResourceCount(network.getAccountId(), Resource.ResourceType.network, network.isDisplay()); long networkCopyId; if (networks == null || networks.isEmpty()) { throw new CloudRuntimeException("Fail to create a network"); } else { DataCenter zone = _dcDao.findById(network.getDataCenterId()); String guestNetworkCidr = zone.getGuestNetworkCidr(); if (networks.get(0).getGuestType() == Network.GuestType.Isolated && networks.get(0).getTrafficType() == Networks.TrafficType.Guest) { Network networkCopy = networks.get(0); for (final Network nw : networks) { if (nw.getCidr() != null && nw.getCidr().equals(guestNetworkCidr)) { networkCopy = nw; } } networkCopyId = networkCopy.getId(); } else { // For shared network networkCopyId = networks.get(0).getId(); } } //Update the related network NetworkVO originalNetwork = _networksDao.findById(originalNetworkId); originalNetwork.setRelated(networkCopyId); _networksDao.update(originalNetworkId, originalNetwork); NetworkVO copiedNetwork = _networksDao.findById(networkCopyId); copiedNetwork.setRelated(originalNetworkId); copiedNetwork.setDisplayNetwork(false); copiedNetwork.setBroadcastUri(network.getBroadcastUri()); copiedNetwork.setState(network.getState()); _networksDao.update(networkCopyId, copiedNetwork); copyNetworkDetails(originalNetworkId, networkCopyId); copyFirewallRulesToNewNetwork(network, networkCopyId); assignUserNicsToNewNetwork(originalNetworkId, networkCopyId); assignRouterNicsToNewNetwork(network.getId(), networkCopyId); if (s_logger.isDebugEnabled()) { s_logger.debug("Succesfully created a copy of network " + originalNetwork.getName() + "(" + originalNetwork.getUuid() + ") id is " + originalNetwork.getId() + " for migration. The network copy has uuid " + network.getUuid() + " and id " + network.getId()); } return networkCopyId; } @DB private void copyNetworkDetails(long srcNetworkId, long dstNetworkId) { List networkDetails = _networkDetailsDao.listDetails(srcNetworkId); for (NetworkDetailVO networkDetail : networkDetails) { _networkDetailsDao.persist(new NetworkDetailVO(dstNetworkId, networkDetail.getName(), networkDetail.getValue(), networkDetail.isDisplay())); } } /** * reassigns the nics to the new network from the src network. * @param srcNetworkId * @param dstNetworkId */ private void assignUserNicsToNewNetwork(long srcNetworkId, long dstNetworkId) { List nics = _nicDao.listByNetworkId(srcNetworkId); for (NicVO nic : nics) { if (nic.getVmType() == VirtualMachine.Type.User) { nic.setNetworkId(dstNetworkId); _nicDao.persist(nic); //update the number of active nics in both networks after migration. if (nic.getState() == Nic.State.Reserved) { _networksDao.changeActiveNicsBy(srcNetworkId, -1); _networksDao.changeActiveNicsBy(dstNetworkId, 1); } } } List publicIps = _ipAddressDao.listByAssociatedNetwork(srcNetworkId, null); for (IPAddressVO ipAddress : publicIps) { ipAddress.setAssociatedWithNetworkId(dstNetworkId); _ipAddressDao.persist(ipAddress); } } @Override public Long makeCopyOfVpc(long vpcId, long vpcOfferingId) { VpcVO vpc = _vpcDao.findById(vpcId); if (s_logger.isDebugEnabled()) { s_logger.debug("Making a copy of vpc with uuid " + vpc.getUuid() + " and id " + vpc.getId() + " for migration."); } if (vpc == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Specified vpc id doesn't exist in the system"); ex.addProxyObject(String.valueOf(vpcId), "vpcId"); throw ex; } Vpc copyOfVpc; long copyOfVpcId; try { copyOfVpc = _vpcService.createVpc(vpc.getZoneId(), vpcOfferingId, vpc.getAccountId(), vpc.getName(), vpc.getDisplayText(), vpc.getCidr(), vpc.getNetworkDomain(), vpc.isDisplay()); copyOfVpcId = copyOfVpc.getId(); //on resume of migration the uuid will be swapped already. So the copy will have the value of the original vpcid. _resourceTagDao.persist(new ResourceTagVO(MIGRATION, Long.toString(vpcId), vpc.getAccountId(), vpc.getDomainId(), copyOfVpcId, ResourceTag.ResourceObjectType.Vpc, null, vpc.getUuid())); VpcVO copyVpcVO = _vpcDao.findById(copyOfVpcId); vpc.setDisplay(false); swapUuids(vpc, copyVpcVO); reassignACLRulesToNewVpc(vpcId, copyOfVpcId); reassignPublicIpsToNewVpc(vpcId, copyOfVpc); copyVpcDetails(vpcId, copyOfVpcId); reassignGatewayToNewVpc(vpcId, copyOfVpcId); copyVpcResourceTagsToNewVpc(vpcId, copyOfVpcId); if (s_logger.isDebugEnabled()) { s_logger.debug("Succesfully created a copy of network " + vpc.getName() + "(" + vpc.getUuid() + ") id is " + vpc.getId() + " for migration. The network copy has uuid " + copyVpcVO.getUuid() + " and id " + copyOfVpc.getId()); } } catch (ResourceAllocationException e) { throw new CloudRuntimeException(e.getMessage()); } return copyOfVpcId; } @Override public void startVpc(Vpc vpc) { if (vpc.getState() != Vpc.State.Enabled) { try { _vpcService.startVpc(vpc.getId(), true); } catch (ResourceUnavailableException | InsufficientCapacityException e) { s_logger.error("Vpc can not be started. Aborting migration process"); throw new CloudRuntimeException("Vpc can not be started.", e); } } } private void copyVpcDetails(long srcVpcId, long dstVpcId) { List vpcDetails = _vpcDetailsDao.listDetails(srcVpcId); for (VpcDetailVO vpcDetail : vpcDetails) { _vpcDetailsDao.persist(new VpcDetailVO(dstVpcId, vpcDetail.getName(), vpcDetail.getValue(), vpcDetail.isDisplay())); } } /** * Reassign the ACL rules from the original vpc to the new VPC * @param srcVpcId * @param dstVpcId */ private void reassignACLRulesToNewVpc(long srcVpcId, long dstVpcId){ List networkACL = _networkACLDao.listByVpcId(srcVpcId); for (NetworkACLVO aclList : networkACL) { aclList.setVpcId(dstVpcId); _networkACLDao.persist(aclList); } } private void reassignPublicIpsToNewVpc(long srcVpcId, Vpc dstVpc) { List publicIps = _ipAddressDao.listByAssociatedVpc(srcVpcId, _vpcManager.isSrcNatIpRequired(dstVpc.getVpcOfferingId()) ? null : false); for(IPAddressVO publicIp : publicIps) { publicIp.setVpcId(dstVpc.getId()); _ipAddressDao.persist(publicIp); } } private void reassignGatewayToNewVpc(long srcVpcId, long dstVpcId){ List vpcGateways = _vpcGatewayDao.listByVpcId(srcVpcId); for (VpcGatewayVO vpcGateway : vpcGateways) { vpcGateway.setVpcId(dstVpcId); _vpcGatewayDao.persist(vpcGateway); } } private void copyVpcResourceTagsToNewVpc(long srcVpcId, long dstVpcId){ List resourceTags = _resourceTagDao.listBy(srcVpcId, ResourceTag.ResourceObjectType.Vpc); for (ResourceTag resourceTag : resourceTags) { resourceTag.setResourceId(dstVpcId); _resourceTagDao.persist( new ResourceTagVO( resourceTag.getKey(), resourceTag.getValue(), resourceTag.getAccountId(), resourceTag.getDomainId(), dstVpcId, resourceTag.getResourceType(), resourceTag.getCustomer(), resourceTag.getResourceUuid())); } } private void copyFirewallRulesToNewNetwork(Network srcNetwork, long dstNetworkId) { List firewallRules = _firewallDao.listByNetworkPurposeTrafficType(srcNetwork.getId(), FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Egress); firewallRules.addAll(_firewallDao.listByNetworkPurposeTrafficType(srcNetwork.getId(), FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Ingress)); if (s_logger.isDebugEnabled()) { s_logger.debug("Copying firewall rules from network with id " + srcNetwork.getId() + " to network with id " + dstNetworkId); } //Loop over all the firewall rules in the original network and copy all values to a new firewall rule //Copy all objects that are dependant on the firewall rules for (FirewallRuleVO originalFirewallRule : firewallRules) { FirewallRuleVO ruleVO = new FirewallRuleVO(originalFirewallRule.getXid(), originalFirewallRule.getSourceIpAddressId(), originalFirewallRule.getSourcePortStart(), originalFirewallRule.getSourcePortEnd(), originalFirewallRule.getProtocol(), dstNetworkId, srcNetwork.getAccountId(), srcNetwork.getDomainId(), originalFirewallRule.getPurpose(), originalFirewallRule.getSourceCidrList(), originalFirewallRule.getDestinationCidrList(), originalFirewallRule.getIcmpCode(), originalFirewallRule.getIcmpType(), originalFirewallRule.getRelated(), originalFirewallRule.getTrafficType(), originalFirewallRule.getType()); ruleVO = _firewallDao.persist(ruleVO); //Firewall rule cidrs List firewallRulesCidrsVOS = _firewallRulesCidrDao.listByFirewallRuleId(originalFirewallRule.getId()); for (FirewallRulesCidrsVO firewallRulesCidrVO: firewallRulesCidrsVOS) { _firewallRulesCidrDao.persist(new FirewallRulesCidrsVO(ruleVO.getId(), firewallRulesCidrVO.getSourceCidrList())); } //Firewall rules details List originalFirewallRuleDetails = _firewallRuleDetailsDao.listDetails(originalFirewallRule.getId()); for (FirewallRuleDetailVO originalFirewallRuleDetail : originalFirewallRuleDetails) { _firewallRuleDetailsDao.persist(new FirewallRuleDetailVO(ruleVO.getId(), originalFirewallRuleDetail.getName(), originalFirewallRuleDetail.getValue(), originalFirewallRuleDetail.isDisplay())); } } } private void assignRouterNicsToNewNetwork(long srcNetworkId, long dstNetworkId) { final List routers = _routerDao.listByNetworkAndRole(srcNetworkId, VirtualRouter.Role.VIRTUAL_ROUTER); for (DomainRouterVO domainRouter : routers) { NicVO vrNic = _nicDao.findByNetworkIdAndType(srcNetworkId, VirtualMachine.Type.DomainRouter); vrNic.setNetworkId(dstNetworkId); _nicDao.update(vrNic.getId(), vrNic); RouterNetworkVO routerNetwork = _routerNetworkDao.findByRouterAndNetwork(domainRouter.getId(), srcNetworkId); routerNetwork.setNetworkId(dstNetworkId); _routerNetworkDao.persist(routerNetwork); } } @Override public Network upgradeNetworkToNewNetworkOffering(long networkId, long newPhysicalNetworkId, long networkOfferingId, Long vpcId) { s_logger.debug("upgrading network to network with new offering."); NetworkVO network = _networksDao.findById(networkId); NetworkOffering newOffering = _networkOfferingDao.findByIdIncludingRemoved(networkOfferingId); long gurusImplementing = 0; network.setBroadcastUri(null); AccountVO networkAccount = _accountDao.findById(network.getAccountId()); DataCenterDeployment plan = new DataCenterDeployment(network.getDataCenterId(), null, null, null, null, newPhysicalNetworkId); for (final NetworkGuru guru : _networkMgr.getNetworkGurus()) { final Network designedNetwork = guru.design(newOffering, plan, network, networkAccount); if (designedNetwork == null) { continue; } gurusImplementing++; if (gurusImplementing > 1) { throw new CloudRuntimeException("Failed to migrate network to new physical network. Multiple network guru's for the same network are currently not supported."); } network.setTrafficType(designedNetwork.getTrafficType()); network.setMode(designedNetwork.getMode()); network.setBroadcastDomainType(designedNetwork.getBroadcastDomainType()); network.setBroadcastUri(designedNetwork.getBroadcastUri()); network.setNetworkOfferingId(designedNetwork.getNetworkOfferingId()); network.setState(designedNetwork.getState()); network.setPhysicalNetworkId(designedNetwork.getPhysicalNetworkId()); network.setRedundant(designedNetwork.isRedundant()); network.setGateway(designedNetwork.getGateway()); network.setCidr(designedNetwork.getCidr()); network.setGuruName(guru.getName()); network.setVpcId(vpcId); } _networksDao.update(network.getId(), network, _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), newPhysicalNetworkId)); return network; } @Override public void deleteCopyOfNetwork(long networkCopyId, long originalNetworkId) { NetworkVO networkCopy = _networksDao.findById(networkCopyId); NicVO userNic = _nicDao.findByNetworkIdAndType(networkCopyId, VirtualMachine.Type.User); if (userNic != null) { s_logger.error("Something went wrong while migrating nics from the old network to the new network. Failed to delete copy of network. There are still user nics present in the network."); throw new CloudRuntimeException("Failed to delete copy of network. There are still user nics present in the network."); } NetworkVO originalNetwork = _networksDao.findById(originalNetworkId); swapUuids(originalNetwork, networkCopy); try { if (!_networkService.deleteNetwork(networkCopy.getId(), true)) { throw new CloudRuntimeException("Failed to delete network. Clean up not successful."); } } finally { swapUuids(networkCopy, originalNetwork); } originalNetwork.setRelated(originalNetworkId); _networksDao.persist(originalNetwork); } @Override public void deleteCopyOfVpc(long vpcCopyId, long originalVpcId) { VpcVO copyOfvpc = _vpcDao.findById(vpcCopyId); VpcVO originalVpc = _vpcDao.findById(originalVpcId); //Be sure that when we delete the vpc, it has the uuid with what it was created. swapUuids(copyOfvpc, originalVpc); try { if(!_vpcService.deleteVpc(vpcCopyId)) { throw new CloudRuntimeException("Deletion of VPC failed. Clean up was not successful."); } } catch (ResourceUnavailableException e) { throw new CloudRuntimeException(e.getMessage()); } finally { swapUuids(originalVpc, copyOfvpc); } _resourceTagDao.removeByResourceIdAndKey(originalVpcId, ResourceTag.ResourceObjectType.Vpc, MIGRATION); } private Boolean migrateNicsInDB(NicVO originalNic, Network networkInNewPhysicalNet, DataCenter dc, ReservationContext context) { s_logger.debug("migrating nics in database."); UserVmVO vmVO = _vmDao.findById(originalNic.getInstanceId()); VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmVO, null, null, null, null); NicProfile nicProfile = new NicProfile(originalNic, networkInNewPhysicalNet, null, null, null, _networkModel.isSecurityGroupSupportedInNetwork(networkInNewPhysicalNet), null); try { nicProfile = _networkMgr.allocateNic(nicProfile, networkInNewPhysicalNet, originalNic.isDefaultNic(), nicProfile.getDeviceId(), vmProfile).first(); } catch (InsufficientVirtualNetworkCapacityException | InsufficientAddressCapacityException e) { throw new CloudRuntimeException("Allocation of new nicProfile failed during migration", e); } //Update vm_network_map table if (vmProfile.getType() == VirtualMachine.Type.User) { final VMNetworkMapVO vno = new VMNetworkMapVO(vmVO.getId(), networkInNewPhysicalNet.getId()); _vmNetworkMapDao.persist(vno); } NicVO newNic = _nicDao.findById(nicProfile.getId()); copyNicDetails(originalNic.getId(), newNic.getId()); //Update nic uuid here moveServices(originalNic, newNic); if (originalNic.getState() == Nic.State.Reserved) { final VirtualMachine vm = vmProfile.getVirtualMachine(); final Host host = _hostDao.findById(vm.getHostId()); final DeployDestination dest = new DeployDestination(dc, null, null, host); try { nicProfile = _networkMgr.prepareNic(vmProfile, dest, context, nicProfile.getId(), networkInNewPhysicalNet); _itMgr.replugNic(networkInNewPhysicalNet, _itMgr.toNicTO(nicProfile, host.getHypervisorType()), _itMgr.toVmTO(vmProfile), context, dest); } catch (ResourceUnavailableException | InsufficientCapacityException e) { throw new CloudRuntimeException("Migration of Nic failed", e); } } //Mark the old nic as removed markAsNonDefault(originalNic); _networkMgr.removeNic(vmProfile, originalNic); if (s_logger.isDebugEnabled()) { s_logger.debug("Nic is migrated successfully for vm " + vmVO + " to " + networkInNewPhysicalNet); } return true; } @Override public void assignNicsToNewPhysicalNetwork(Network srcNetwork, Network networkInNewPhysicalNet) { List nics = _nicDao.listByNetworkId(srcNetwork.getId()); final CallContext cctx = CallContext.current(); final ReservationContext context = new ReservationContextImpl(null, null, cctx.getCallingUser(), cctx.getCallingAccount()); final DataCenter dc = _entityMgr.findById(DataCenter.class, networkInNewPhysicalNet.getDataCenterId()); //For each nic in the old network check if the nic belongs to a guest vm and migrate it to the new network. for (NicVO originalNic : nics) { if (originalNic.getVmType() != VirtualMachine.Type.User) { continue; } Transaction.execute((TransactionCallback) (status) -> migrateNicsInDB(originalNic, networkInNewPhysicalNet, dc, context)); } //Now that nics are migrated we can migrate the static nats on those nics reapplyPublicIps(srcNetwork, networkInNewPhysicalNet); } private void reapplyPublicIps(Network networkInOldPhysicalNetwork, Network networkInNewPhysicalNet) { CallContext ctx = CallContext.current(); long callerUserId = ctx.getCallingUserId(); Account caller = ctx.getCallingAccount(); AccountVO networkAccount = _accountDao.findById(networkInNewPhysicalNet.getAccountId()); List staticNatIps = _ipAddressDao.listStaticNatPublicIps(networkInOldPhysicalNetwork.getId()); List providers = _networkOfferingServiceDao.listProvidersForServiceForNetworkOffering(networkInNewPhysicalNet.getNetworkOfferingId(), Network.Service.SourceNat); boolean isSrcNatIpNeeded = providers.stream().anyMatch(provider -> provider.contains(Network.Provider.VirtualRouter.getName())); for (IPAddressVO ipAddress : staticNatIps) { if (!ipAddress.isSourceNat() || isSrcNatIpNeeded) { ipAddress.setAssociatedWithNetworkId(networkInNewPhysicalNet.getId()); _ipAddressDao.persist(ipAddress); } else { _ipAddressManager.disassociatePublicIpAddress(ipAddress.getId(), callerUserId, caller); } } _rulesMgr.applyStaticNatsForNetwork(networkInNewPhysicalNet.getId(), false, networkAccount); } private void copyNicDetails(long originalNicId, long dstNicId) { List nicDetails = _nicDetailsDao.listDetails(originalNicId); for (NicDetailVO nicDetail : nicDetails) { _nicDetailsDao.persist(new NicDetailVO(dstNicId, nicDetail.getName(), nicDetail.getValue(), nicDetail.isDisplay())); } } private void moveServices(NicVO originalNic, NicVO newNic) { _nicIpAliasDao.moveIpAliases(originalNic.getId(), newNic.getId()); _nicSecondaryIpDao.moveSecondaryIps(originalNic.getId(), newNic.getId()); swapUuids(originalNic, newNic); } private void markAsNonDefault(NicVO nic) { nic.setDefaultNic(false); _nicDao.persist(nic); } /** * Swaps the UUID's of the given nics's * @param oldNic * @param newNic */ private void swapUuids(NicVO oldNic, NicVO newNic) { final String realUuid = oldNic.getUuid(); final String dummyUuid = newNic.getUuid(); oldNic.setUuid(dummyUuid.replace("-", "+")); newNic.setUuid(realUuid); _nicDao.persist(oldNic); _nicDao.persist(newNic); oldNic.setUuid(dummyUuid); _nicDao.persist(oldNic); } /** * Swaps the UUID's of the given networks * @param oldNetwork * @param newNetwork */ private void swapUuids(NetworkVO oldNetwork, NetworkVO newNetwork) { String realUuid = oldNetwork.getUuid(); String dummyUuid = newNetwork.getUuid(); oldNetwork.setUuid(dummyUuid.replace("-","+")); newNetwork.setUuid(realUuid); _networksDao.update(oldNetwork.getId(), oldNetwork); _networksDao.update(newNetwork.getId(), newNetwork); oldNetwork.setUuid(dummyUuid); _networksDao.update(oldNetwork.getId(), oldNetwork); } /** * Swaps the UUID's of the given vpcs * @param oldVpc * @param newVpc */ private void swapUuids(VpcVO oldVpc, VpcVO newVpc) { String realUuid = oldVpc.getUuid(); String dummyUuid = newVpc.getUuid(); oldVpc.setUuid(dummyUuid.replace("-","+")); newVpc.setUuid(realUuid); _vpcDao.update(oldVpc.getId(), oldVpc); _vpcDao.update(newVpc.getId(), newVpc); oldVpc.setUuid(dummyUuid); _vpcDao.update(oldVpc.getId(), oldVpc); } }