| // 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<? extends Network> 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("Successfully 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<NetworkDetailVO> 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<NicVO> 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<? extends IPAddressVO> 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.getIp4Dns1(), vpc.getIp4Dns2(), |
| vpc.getIp6Dns1(), vpc.getIp6Dns2(), vpc.isDisplay(), vpc.getPublicMtu()); |
| |
| 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("Successfully 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<VpcDetailVO> 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<NetworkACLVO> networkACL = _networkACLDao.listByVpcId(srcVpcId); |
| |
| for (NetworkACLVO aclList : networkACL) { |
| aclList.setVpcId(dstVpcId); |
| _networkACLDao.persist(aclList); |
| } |
| } |
| |
| private void reassignPublicIpsToNewVpc(long srcVpcId, Vpc dstVpc) { |
| List<? extends IPAddressVO> 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<VpcGatewayVO> vpcGateways = _vpcGatewayDao.listByVpcId(srcVpcId); |
| for (VpcGatewayVO vpcGateway : vpcGateways) { |
| vpcGateway.setVpcId(dstVpcId); |
| _vpcGatewayDao.persist(vpcGateway); |
| } |
| } |
| |
| private void copyVpcResourceTagsToNewVpc(long srcVpcId, long dstVpcId){ |
| List<? extends ResourceTag> 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<FirewallRuleVO> 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<FirewallRulesCidrsVO> firewallRulesCidrsVOS = _firewallRulesCidrDao.listByFirewallRuleId(originalFirewallRule.getId()); |
| for (FirewallRulesCidrsVO firewallRulesCidrVO: firewallRulesCidrsVOS) { |
| _firewallRulesCidrDao.persist(new FirewallRulesCidrsVO(ruleVO.getId(), firewallRulesCidrVO.getSourceCidrList())); |
| } |
| |
| //Firewall rules details |
| List<FirewallRuleDetailVO> 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<DomainRouterVO> 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), dest.getHost()); |
| } 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<NicVO> 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 (!VirtualMachine.Type.User.equals(originalNic.getVmType())) { |
| continue; |
| } |
| Transaction.execute((TransactionCallback<Boolean>) |
| (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<? extends IPAddressVO> staticNatIps = _ipAddressDao.listStaticNatPublicIps(networkInOldPhysicalNetwork.getId()); |
| |
| List<String> 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<NicDetailVO> 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); |
| } |
| |
| } |