Search in sources :

Example 46 with TransactionCallbackNoReturn

use of com.cloud.utils.db.TransactionCallbackNoReturn in project cloudstack by apache.

the class NetworkServiceImpl method updateGuestNetwork.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_UPDATE, eventDescription = "updating network", async = true)
public Network updateGuestNetwork(final long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix, final Long networkOfferingId, Boolean changeCidr, String guestVmCidr, Boolean displayNetwork, String customId, boolean updateInSequence, boolean forced) {
    boolean restartNetwork = false;
    // verify input parameters
    final NetworkVO network = _networksDao.findById(networkId);
    if (network == null) {
        // see NetworkVO.java
        InvalidParameterValueException ex = new InvalidParameterValueException("Specified network id doesn't exist in the system");
        ex.addProxyObject(String.valueOf(networkId), "networkId");
        throw ex;
    }
    //perform below validation if the network is vpc network
    if (network.getVpcId() != null && networkOfferingId != null) {
        Vpc vpc = _entityMgr.findById(Vpc.class, network.getVpcId());
        _vpcMgr.validateNtwkOffForNtwkInVpc(networkId, networkOfferingId, null, null, vpc, null, _accountMgr.getAccount(network.getAccountId()), network.getNetworkACLId());
    }
    // don't allow to update network in Destroy state
    if (network.getState() == Network.State.Destroy) {
        throw new InvalidParameterValueException("Don't allow to update network in state " + Network.State.Destroy);
    }
    // Don't allow to update system network
    NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
    if (offering.isSystemOnly()) {
        throw new InvalidParameterValueException("Can't update system networks");
    }
    // allow to upgrade only Guest networks
    if (network.getTrafficType() != Networks.TrafficType.Guest) {
        throw new InvalidParameterValueException("Can't allow networks which traffic type is not " + TrafficType.Guest);
    }
    _accountMgr.checkAccess(callerAccount, null, true, network);
    if (name != null) {
        network.setName(name);
    }
    if (displayText != null) {
        network.setDisplayText(displayText);
    }
    if (customId != null) {
        network.setUuid(customId);
    }
    // display flag is not null and has changed
    if (displayNetwork != null && displayNetwork != network.getDisplayNetwork()) {
        // Update resource count if it needs to be updated
        NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
        if (_networkMgr.resourceCountNeedsUpdate(networkOffering, network.getAclType())) {
            _resourceLimitMgr.changeResourceCount(network.getAccountId(), Resource.ResourceType.network, displayNetwork);
        }
        network.setDisplayNetwork(displayNetwork);
    }
    // network offering and domain suffix can be updated for Isolated networks only in 3.0
    if ((networkOfferingId != null || domainSuffix != null) && network.getGuestType() != GuestType.Isolated) {
        throw new InvalidParameterValueException("NetworkOffering and domain suffix upgrade can be perfomed for Isolated networks only");
    }
    boolean networkOfferingChanged = false;
    final long oldNetworkOfferingId = network.getNetworkOfferingId();
    NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
    NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
    if (networkOfferingId != null) {
        if (networkOffering == null || networkOffering.isSystemOnly()) {
            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering with specified id");
            ex.addProxyObject(networkOfferingId.toString(), "networkOfferingId");
            throw ex;
        }
        // network offering should be in Enabled state
        if (networkOffering.getState() != NetworkOffering.State.Enabled) {
            InvalidParameterValueException ex = new InvalidParameterValueException("Network offering with specified id is not in " + NetworkOffering.State.Enabled + " state, can't upgrade to it");
            ex.addProxyObject(networkOffering.getUuid(), "networkOfferingId");
            throw ex;
        }
        //can't update from vpc to non-vpc network offering
        boolean forVpcNew = _configMgr.isOfferingForVpc(networkOffering);
        boolean vorVpcOriginal = _configMgr.isOfferingForVpc(_entityMgr.findById(NetworkOffering.class, oldNetworkOfferingId));
        if (forVpcNew != vorVpcOriginal) {
            String errMsg = forVpcNew ? "a vpc offering " : "not a vpc offering";
            throw new InvalidParameterValueException("Can't update as the new offering is " + errMsg);
        }
        if (networkOfferingId != oldNetworkOfferingId) {
            Collection<String> newProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(networkOffering, network.getPhysicalNetworkId()).values();
            Collection<String> oldProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(oldNtwkOff, network.getPhysicalNetworkId()).values();
            if (providersConfiguredForExternalNetworking(newProviders) != providersConfiguredForExternalNetworking(oldProviders) && !changeCidr) {
                throw new InvalidParameterValueException("Updating network failed since guest CIDR needs to be changed!");
            }
            if (changeCidr) {
                if (!checkForNonStoppedVmInNetwork(network.getId())) {
                    InvalidParameterValueException ex = new InvalidParameterValueException("All user vm of network of specified id should be stopped before changing CIDR!");
                    ex.addProxyObject(network.getUuid(), "networkId");
                    throw ex;
                }
            }
            // check if the network is upgradable
            if (!canUpgrade(network, oldNetworkOfferingId, networkOfferingId)) {
                throw new InvalidParameterValueException("Can't upgrade from network offering " + oldNtwkOff.getUuid() + " to " + networkOffering.getUuid() + "; check logs for more information");
            }
            restartNetwork = true;
            networkOfferingChanged = true;
            //Setting the new network's isReduntant to the new network offering's RedundantRouter.
            network.setIsReduntant(_networkOfferingDao.findById(networkOfferingId).getRedundantRouter());
        }
    }
    final Map<String, String> newSvcProviders = networkOfferingChanged ? _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), network.getPhysicalNetworkId()) : new HashMap<String, String>();
    // don't allow to modify network domain if the service is not supported
    if (domainSuffix != null) {
        // validate network domain
        if (!NetUtils.verifyDomainName(domainSuffix)) {
            throw new InvalidParameterValueException("Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + "and the hyphen ('-'); can't start or end with \"-\"");
        }
        long offeringId = oldNetworkOfferingId;
        if (networkOfferingId != null) {
            offeringId = networkOfferingId;
        }
        Map<Network.Capability, String> dnsCapabilities = getNetworkOfferingServiceCapabilities(_entityMgr.findById(NetworkOffering.class, offeringId), Service.Dns);
        String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification);
        if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) {
            // TBD: use uuid instead of networkOfferingId. May need to hardcode tablename in call to addProxyObject().
            throw new InvalidParameterValueException("Domain name change is not supported by the network offering id=" + networkOfferingId);
        }
        network.setNetworkDomain(domainSuffix);
        // have to restart the network
        restartNetwork = true;
    }
    //IP reservation checks
    // allow reservation only to Isolated Guest networks
    DataCenter dc = _dcDao.findById(network.getDataCenterId());
    String networkCidr = network.getNetworkCidr();
    if (guestVmCidr != null) {
        if (dc.getNetworkType() == NetworkType.Basic) {
            throw new InvalidParameterValueException("Guest VM CIDR can't be specified for zone with " + NetworkType.Basic + " networking");
        }
        if (network.getGuestType() != GuestType.Isolated) {
            throw new InvalidParameterValueException("Can only allow IP Reservation in networks with guest type " + GuestType.Isolated);
        }
        if (networkOfferingChanged == true) {
            throw new InvalidParameterValueException("Cannot specify this nework offering change and guestVmCidr at same time. Specify only one.");
        }
        if (!(network.getState() == Network.State.Implemented)) {
            throw new InvalidParameterValueException("The network must be in " + Network.State.Implemented + " state. IP Reservation cannot be applied in " + network.getState() + " state");
        }
        if (!NetUtils.isValidCIDR(guestVmCidr)) {
            throw new InvalidParameterValueException("Invalid format of Guest VM CIDR.");
        }
        if (!NetUtils.validateGuestCidr(guestVmCidr)) {
            throw new InvalidParameterValueException("Invalid format of Guest VM CIDR. Make sure it is RFC1918 compliant. ");
        }
        // But in case networkCidr is a non null value (IP reservation already exists), it implies network cidr is networkCidr
        if (networkCidr != null) {
            if (!NetUtils.isNetworkAWithinNetworkB(guestVmCidr, networkCidr)) {
                throw new InvalidParameterValueException("Invalid value of Guest VM CIDR. For IP Reservation, Guest VM CIDR  should be a subset of network CIDR : " + networkCidr);
            }
        } else {
            if (!NetUtils.isNetworkAWithinNetworkB(guestVmCidr, network.getCidr())) {
                throw new InvalidParameterValueException("Invalid value of Guest VM CIDR. For IP Reservation, Guest VM CIDR  should be a subset of network CIDR :  " + network.getCidr());
            }
        }
        // This check makes sure there are no active IPs existing outside the guestVmCidr in the network
        String[] guestVmCidrPair = guestVmCidr.split("\\/");
        Long size = Long.valueOf(guestVmCidrPair[1]);
        List<NicVO> nicsPresent = _nicDao.listByNetworkId(networkId);
        String[] cidrIpRange = NetUtils.getIpRangeFromCidr(guestVmCidrPair[0], size);
        s_logger.info("The start IP of the specified guest vm cidr is: " + cidrIpRange[0] + " and end IP is: " + cidrIpRange[1]);
        long startIp = NetUtils.ip2Long(cidrIpRange[0]);
        long endIp = NetUtils.ip2Long(cidrIpRange[1]);
        long range = endIp - startIp + 1;
        s_logger.info("The specified guest vm cidr has " + range + " IPs");
        for (NicVO nic : nicsPresent) {
            long nicIp = NetUtils.ip2Long(nic.getIPv4Address());
            //check if nic IP is outside the guest vm cidr
            if (nicIp < startIp || nicIp > endIp) {
                if (!(nic.getState() == Nic.State.Deallocating)) {
                    throw new InvalidParameterValueException("Active IPs like " + nic.getIPv4Address() + " exist outside the Guest VM CIDR. Cannot apply reservation ");
                }
            }
        }
        // the IP ranges exactly matches, in these special cases make sure no Reservation gets applied
        if (network.getNetworkCidr() == null) {
            if (NetUtils.isSameIpRange(guestVmCidr, network.getCidr()) && !guestVmCidr.equals(network.getCidr())) {
                throw new InvalidParameterValueException("The Start IP and End IP of guestvmcidr: " + guestVmCidr + " and CIDR: " + network.getCidr() + " are same, " + "even though both the cidrs appear to be different. As a precaution no IP Reservation will be applied.");
            }
        } else {
            if (NetUtils.isSameIpRange(guestVmCidr, network.getNetworkCidr()) && !guestVmCidr.equals(network.getNetworkCidr())) {
                throw new InvalidParameterValueException("The Start IP and End IP of guestvmcidr: " + guestVmCidr + " and Network CIDR: " + network.getNetworkCidr() + " are same, " + "even though both the cidrs appear to be different. As a precaution IP Reservation will not be affected. If you want to reset IP Reservation, " + "specify guestVmCidr to be: " + network.getNetworkCidr());
            }
        }
        // Populate it with the actual network cidr
        if (network.getNetworkCidr() == null) {
            network.setNetworkCidr(network.getCidr());
        }
        // Condition for IP Reservation reset : guestVmCidr and network CIDR are same
        if (network.getNetworkCidr().equals(guestVmCidr)) {
            s_logger.warn("Guest VM CIDR and Network CIDR both are same, reservation will reset.");
            network.setNetworkCidr(null);
        }
        // Finally update "cidr" with the guestVmCidr
        // which becomes the effective address space for CloudStack guest VMs
        network.setCidr(guestVmCidr);
        _networksDao.update(networkId, network);
        s_logger.info("IP Reservation has been applied. The new CIDR for Guests Vms is " + guestVmCidr);
    }
    ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
    // 1) Shutdown all the elements and cleanup all the rules. Don't allow to shutdown network in intermediate
    // states - Shutdown and Implementing
    int resourceCount = 1;
    if (updateInSequence && restartNetwork && _networkOfferingDao.findById(network.getNetworkOfferingId()).getRedundantRouter() && (networkOfferingId == null || _networkOfferingDao.findById(networkOfferingId).getRedundantRouter()) && network.getVpcId() == null) {
        _networkMgr.canUpdateInSequence(network, forced);
        NetworkDetailVO networkDetail = new NetworkDetailVO(network.getId(), Network.updatingInSequence, "true", true);
        _networkDetailsDao.persist(networkDetail);
        _networkMgr.configureUpdateInSequence(network);
        resourceCount = _networkMgr.getResourceCount(network);
    }
    List<String> servicesNotInNewOffering = null;
    if (networkOfferingId != null)
        servicesNotInNewOffering = _networkMgr.getServicesNotSupportedInNewOffering(network, networkOfferingId);
    if (!forced && servicesNotInNewOffering != null && !servicesNotInNewOffering.isEmpty()) {
        NetworkOfferingVO newOffering = _networkOfferingDao.findById(networkOfferingId);
        throw new CloudRuntimeException("The new offering:" + newOffering.getUniqueName() + " will remove the following services " + servicesNotInNewOffering + "along with all the related configuration currently in use. will not proceed with the network update." + "set forced parameter to true for forcing an update.");
    }
    try {
        if (servicesNotInNewOffering != null && !servicesNotInNewOffering.isEmpty()) {
            _networkMgr.cleanupConfigForServicesInNetwork(servicesNotInNewOffering, network);
        }
    } catch (Throwable e) {
        s_logger.debug("failed to cleanup config related to unused services error:" + e.getMessage());
    }
    boolean validStateToShutdown = (network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup || network.getState() == Network.State.Allocated);
    try {
        do {
            if (restartNetwork) {
                if (validStateToShutdown) {
                    if (!changeCidr) {
                        s_logger.debug("Shutting down elements and resources for network id=" + networkId + " as a part of network update");
                        if (!_networkMgr.shutdownNetworkElementsAndResources(context, true, network)) {
                            s_logger.warn("Failed to shutdown the network elements and resources as a part of network restart: " + network);
                            CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of update to network of specified id");
                            ex.addProxyObject(network.getUuid(), "networkId");
                            throw ex;
                        }
                    } else {
                        // We need to shutdown the network, since we want to re-implement the network.
                        s_logger.debug("Shutting down network id=" + networkId + " as a part of network update");
                        //check if network has reservation
                        if (NetUtils.isNetworkAWithinNetworkB(network.getCidr(), network.getNetworkCidr())) {
                            s_logger.warn("Existing IP reservation will become ineffective for the network with id =  " + networkId + " You need to reapply reservation after network reimplementation.");
                            //set cidr to the newtork cidr
                            network.setCidr(network.getNetworkCidr());
                            //set networkCidr to null to bring network back to no IP reservation state
                            network.setNetworkCidr(null);
                        }
                        if (!_networkMgr.shutdownNetwork(network.getId(), context, true)) {
                            s_logger.warn("Failed to shutdown the network as a part of update to network with specified id");
                            CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network as a part of update of specified network id");
                            ex.addProxyObject(network.getUuid(), "networkId");
                            throw ex;
                        }
                    }
                } else {
                    CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of update to network with specified id; network is in wrong state: " + network.getState());
                    ex.addProxyObject(network.getUuid(), "networkId");
                    throw ex;
                }
            }
            // 2) Only after all the elements and rules are shutdown properly, update the network VO
            // get updated network
            Network.State networkState = _networksDao.findById(networkId).getState();
            boolean validStateToImplement = (networkState == Network.State.Implemented || networkState == Network.State.Setup || networkState == Network.State.Allocated);
            if (restartNetwork && !validStateToImplement) {
                CloudRuntimeException ex = new CloudRuntimeException("Failed to implement the network elements and resources as a part of update to network with specified id; network is in wrong state: " + networkState);
                ex.addProxyObject(network.getUuid(), "networkId");
                throw ex;
            }
            if (networkOfferingId != null) {
                if (networkOfferingChanged) {
                    Transaction.execute(new TransactionCallbackNoReturn() {

                        @Override
                        public void doInTransactionWithoutResult(TransactionStatus status) {
                            network.setNetworkOfferingId(networkOfferingId);
                            _networksDao.update(networkId, network, newSvcProviders);
                            // get all nics using this network
                            // log remove usage events for old offering
                            // log assign usage events for new offering
                            List<NicVO> nics = _nicDao.listByNetworkId(networkId);
                            for (NicVO nic : nics) {
                                long vmId = nic.getInstanceId();
                                VMInstanceVO vm = _vmDao.findById(vmId);
                                if (vm == null) {
                                    s_logger.error("Vm for nic " + nic.getId() + " not found with Vm Id:" + vmId);
                                    continue;
                                }
                                long isDefault = (nic.isDefaultNic()) ? 1 : 0;
                                String nicIdString = Long.toString(nic.getId());
                                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), nicIdString, oldNetworkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay());
                                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), nicIdString, networkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay());
                            }
                        }
                    });
                } else {
                    network.setNetworkOfferingId(networkOfferingId);
                    _networksDao.update(networkId, network, _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), network.getPhysicalNetworkId()));
                }
            } else {
                _networksDao.update(networkId, network);
            }
            // 3) Implement the elements and rules again
            if (restartNetwork) {
                if (network.getState() != Network.State.Allocated) {
                    DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
                    s_logger.debug("Implementing the network " + network + " elements and resources as a part of network update");
                    try {
                        if (!changeCidr) {
                            _networkMgr.implementNetworkElementsAndResources(dest, context, network, _networkOfferingDao.findById(network.getNetworkOfferingId()));
                        } else {
                            _networkMgr.implementNetwork(network.getId(), dest, context);
                        }
                    } catch (Exception ex) {
                        s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network update due to ", ex);
                        CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id) elements and resources as a part of network update");
                        e.addProxyObject(network.getUuid(), "networkId");
                        throw e;
                    }
                }
            }
            // implement the network if its not already
            if (networkOfferingChanged && !oldNtwkOff.getIsPersistent() && networkOffering.getIsPersistent()) {
                if (network.getState() == Network.State.Allocated) {
                    try {
                        DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
                        _networkMgr.implementNetwork(network.getId(), dest, context);
                    } catch (Exception ex) {
                        s_logger.warn("Failed to implement network " + network + " elements and resources as a part o" + "f network update due to ", ex);
                        CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified" + " id) elements and resources as a part of network update");
                        e.addProxyObject(network.getUuid(), "networkId");
                        throw e;
                    }
                }
            }
            resourceCount--;
        } while (updateInSequence && resourceCount > 0);
    } catch (Exception exception) {
        if (updateInSequence)
            _networkMgr.finalizeUpdateInSequence(network, false);
        throw new CloudRuntimeException("failed to update network " + network.getUuid() + " due to " + exception.getMessage());
    } finally {
        if (updateInSequence) {
            if (_networkDetailsDao.findDetail(networkId, Network.updatingInSequence) != null) {
                _networkDetailsDao.removeDetail(networkId, Network.updatingInSequence);
            }
        }
    }
    return getNetwork(network.getId());
}
Also used : Vpc(com.cloud.network.vpc.Vpc) TransactionStatus(com.cloud.utils.db.TransactionStatus) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) ReservationContextImpl(com.cloud.vm.ReservationContextImpl) ReservationContext(com.cloud.vm.ReservationContext) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ArrayList(java.util.ArrayList) List(java.util.List) NicVO(com.cloud.vm.NicVO) NetworkDetailVO(com.cloud.network.dao.NetworkDetailVO) PhysicalNetworkVO(com.cloud.network.dao.PhysicalNetworkVO) NetworkVO(com.cloud.network.dao.NetworkVO) Capability(com.cloud.network.Network.Capability) NetworkOffering(com.cloud.offering.NetworkOffering) VMInstanceVO(com.cloud.vm.VMInstanceVO) InvalidParameterException(java.security.InvalidParameterException) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) InsufficientAddressCapacityException(com.cloud.exception.InsufficientAddressCapacityException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) SQLException(java.sql.SQLException) UnknownHostException(java.net.UnknownHostException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) UnsupportedServiceException(com.cloud.exception.UnsupportedServiceException) ConfigurationException(javax.naming.ConfigurationException) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) DataCenter(com.cloud.dc.DataCenter) DeployDestination(com.cloud.deploy.DeployDestination) NetworkOfferingVO(com.cloud.offerings.NetworkOfferingVO) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 47 with TransactionCallbackNoReturn

use of com.cloud.utils.db.TransactionCallbackNoReturn in project cloudstack by apache.

the class NetworkServiceImpl method releaseSecondaryIpFromNic.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_NIC_SECONDARY_IP_UNASSIGN, eventDescription = "Removing secondary ip " + "from nic", async = true)
public boolean releaseSecondaryIpFromNic(long ipAddressId) {
    Account caller = CallContext.current().getCallingAccount();
    boolean success = false;
    // Verify input parameters
    NicSecondaryIpVO secIpVO = _nicSecondaryIpDao.findById(ipAddressId);
    if (secIpVO == null) {
        throw new InvalidParameterValueException("Unable to find secondary ip address by id");
    }
    VirtualMachine vm = _userVmDao.findById(secIpVO.getVmId());
    if (vm == null) {
        throw new InvalidParameterValueException("There is no vm with the given secondary ip");
    }
    // verify permissions
    _accountMgr.checkAccess(caller, null, true, vm);
    Network network = _networksDao.findById(secIpVO.getNetworkId());
    if (network == null) {
        throw new InvalidParameterValueException("Invalid network id is given");
    }
    // Validate network offering
    NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(network.getNetworkOfferingId());
    Long nicId = secIpVO.getNicId();
    s_logger.debug("ip id = " + ipAddressId + " nic id = " + nicId);
    //check is this the last secondary ip for NIC
    List<NicSecondaryIpVO> ipList = _nicSecondaryIpDao.listByNicId(nicId);
    boolean lastIp = false;
    if (ipList.size() == 1) {
        // this is the last secondary ip to nic
        lastIp = true;
    }
    DataCenter dc = _dcDao.findById(network.getDataCenterId());
    if (dc == null) {
        throw new InvalidParameterValueException("Invalid zone Id is given");
    }
    s_logger.debug("Calling secondary ip " + secIpVO.getIp4Address() + " release ");
    if (dc.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Isolated) {
        //check PF or static NAT is configured on this ip address
        String secondaryIp = secIpVO.getIp4Address();
        List<FirewallRuleVO> fwRulesList = _firewallDao.listByNetworkAndPurpose(network.getId(), Purpose.PortForwarding);
        if (fwRulesList.size() != 0) {
            for (FirewallRuleVO rule : fwRulesList) {
                if (_portForwardingDao.findByIdAndIp(rule.getId(), secondaryIp) != null) {
                    s_logger.debug("VM nic IP " + secondaryIp + " is associated with the port forwarding rule");
                    throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is associate with the port forwarding rule");
                }
            }
        }
        //check if the secondary ip associated with any static nat rule
        IPAddressVO publicIpVO = _ipAddressDao.findByIpAndNetworkId(secIpVO.getNetworkId(), secondaryIp);
        if (publicIpVO != null) {
            s_logger.debug("VM nic IP " + secondaryIp + " is associated with the static NAT rule public IP address id " + publicIpVO.getId());
            throw new InvalidParameterValueException("Can' remove the ip " + secondaryIp + "is associate with static NAT rule public IP address id " + publicIpVO.getId());
        }
        if (_loadBalancerDao.isLoadBalancerRulesMappedToVmGuestIp(vm.getId(), secondaryIp, network.getId())) {
            s_logger.debug("VM nic IP " + secondaryIp + " is mapped to load balancing rule");
            throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is mapped to load balancing rule");
        }
    } else if (dc.getNetworkType() == NetworkType.Basic || ntwkOff.getGuestType() == Network.GuestType.Shared) {
        final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(secIpVO.getNetworkId(), secIpVO.getIp4Address());
        if (ip != null) {
            Transaction.execute(new TransactionCallbackNoReturn() {

                @Override
                public void doInTransactionWithoutResult(TransactionStatus status) {
                    _ipAddrMgr.markIpAsUnavailable(ip.getId());
                    _ipAddressDao.unassignIpAddress(ip.getId());
                }
            });
        }
    } else {
        throw new InvalidParameterValueException("Not supported for this network now");
    }
    success = removeNicSecondaryIP(secIpVO, lastIp);
    return success;
}
Also used : Account(com.cloud.user.Account) TransactionStatus(com.cloud.utils.db.TransactionStatus) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) FirewallRuleVO(com.cloud.network.rules.FirewallRuleVO) NicSecondaryIpVO(com.cloud.vm.dao.NicSecondaryIpVO) DataCenter(com.cloud.dc.DataCenter) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) NetworkOfferingVO(com.cloud.offerings.NetworkOfferingVO) IPAddressVO(com.cloud.network.dao.IPAddressVO) VirtualMachine(com.cloud.vm.VirtualMachine) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 48 with TransactionCallbackNoReturn

use of com.cloud.utils.db.TransactionCallbackNoReturn in project cloudstack by apache.

the class GlobalLoadBalancingRulesServiceImpl method revokeGslbRule.

@DB
private void revokeGslbRule(final long gslbRuleId, Account caller) {
    final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
    if (gslbRule == null) {
        throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
    }
    _accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
    if (gslbRule.getState() == com.cloud.region.ha.GlobalLoadBalancerRule.State.Staged) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Rule Id: " + gslbRuleId + " is still in Staged state so just removing it.");
        }
        _gslbRuleDao.remove(gslbRuleId);
        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, gslbRule.getAccountId(), 0, gslbRule.getId(), gslbRule.getName(), GlobalLoadBalancerRule.class.getName(), gslbRule.getUuid());
        return;
    } else if (gslbRule.getState() == GlobalLoadBalancerRule.State.Add || gslbRule.getState() == GlobalLoadBalancerRule.State.Active) {
        //mark the GSlb rule to be in revoke state
        gslbRule.setState(GlobalLoadBalancerRule.State.Revoke);
        _gslbRuleDao.update(gslbRuleId, gslbRule);
    }
    final List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = Transaction.execute(new TransactionCallback<List<GlobalLoadBalancerLbRuleMapVO>>() {

        @Override
        public List<GlobalLoadBalancerLbRuleMapVO> doInTransaction(TransactionStatus status) {
            List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
            if (gslbLbMapVos != null) {
                //mark all the GSLB-LB mapping to be in revoke state
                for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) {
                    gslbLbMap.setRevoke(true);
                    _gslbLbMapDao.update(gslbLbMap.getId(), gslbLbMap);
                }
            }
            return gslbLbMapVos;
        }
    });
    boolean success = false;
    try {
        if (gslbLbMapVos != null) {
            applyGlobalLoadBalancerRuleConfig(gslbRuleId, true);
        }
        success = true;
    } catch (ResourceUnavailableException e) {
        throw new CloudRuntimeException("Failed to update the gloabal load balancer");
    }
    Transaction.execute(new TransactionCallbackNoReturn() {

        @Override
        public void doInTransactionWithoutResult(TransactionStatus status) {
            //remove all mappings between GSLB rule and load balancer rules
            if (gslbLbMapVos != null) {
                for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) {
                    _gslbLbMapDao.remove(gslbLbMap.getId());
                }
            }
            //remove the GSLB rule itself
            _gslbRuleDao.remove(gslbRuleId);
            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, gslbRule.getAccountId(), 0, gslbRule.getId(), gslbRule.getName(), GlobalLoadBalancerRule.class.getName(), gslbRule.getUuid());
        }
    });
}
Also used : TransactionStatus(com.cloud.utils.db.TransactionStatus) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) GlobalLoadBalancerRule(com.cloud.region.ha.GlobalLoadBalancerRule) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) ArrayList(java.util.ArrayList) List(java.util.List) DB(com.cloud.utils.db.DB)

Example 49 with TransactionCallbackNoReturn

use of com.cloud.utils.db.TransactionCallbackNoReturn in project cloudstack by apache.

the class GlobalLoadBalancingRulesServiceImpl method assignToGlobalLoadBalancerRule.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_GLOBAL_LOAD_BALANCER_RULE, eventDescription = "Assigning a load balancer rule to global load balancer rule", async = true)
public boolean assignToGlobalLoadBalancerRule(AssignToGlobalLoadBalancerRuleCmd assignToGslbCmd) {
    CallContext ctx = CallContext.current();
    Account caller = ctx.getCallingAccount();
    final long gslbRuleId = assignToGslbCmd.getGlobalLoadBalancerRuleId();
    final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
    if (gslbRule == null) {
        throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
    }
    _accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
    if (gslbRule.getState() == GlobalLoadBalancerRule.State.Revoke) {
        throw new InvalidParameterValueException("global load balancer rule id: " + gslbRule.getUuid() + " is in revoked state");
    }
    final List<Long> newLbRuleIds = assignToGslbCmd.getLoadBalancerRulesIds();
    if (newLbRuleIds == null || newLbRuleIds.isEmpty()) {
        throw new InvalidParameterValueException("empty list of load balancer rule Ids specified to be assigned" + " global load balancer rule");
    }
    List<Long> oldLbRuleIds = new ArrayList<Long>();
    List<Long> oldZones = new ArrayList<Long>();
    List<Long> newZones = new ArrayList<Long>(oldZones);
    List<Pair<Long, Long>> physcialNetworks = new ArrayList<Pair<Long, Long>>();
    // get the list of load balancer rules id's that are assigned currently to GSLB rule and corresponding zone id's
    List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
    if (gslbLbMapVos != null) {
        for (GlobalLoadBalancerLbRuleMapVO gslbLbMapVo : gslbLbMapVos) {
            LoadBalancerVO loadBalancer = _lbDao.findById(gslbLbMapVo.getLoadBalancerId());
            Network network = _networkDao.findById(loadBalancer.getNetworkId());
            oldZones.add(network.getDataCenterId());
            oldLbRuleIds.add(gslbLbMapVo.getLoadBalancerId());
        }
    }
    /* check each of the load balancer rule id passed in the 'AssignToGlobalLoadBalancerRuleCmd' command is
         *     valid ID
         *     caller has access to the rule
         *     check rule is not revoked
         *     no two rules are in same zone
         *     rule is not already assigned to gslb rule
         */
    for (Long lbRuleId : newLbRuleIds) {
        LoadBalancerVO loadBalancer = _lbDao.findById(lbRuleId);
        if (loadBalancer == null) {
            throw new InvalidParameterValueException("Specified load balancer rule ID does not exist.");
        }
        _accountMgr.checkAccess(caller, null, true, loadBalancer);
        if (gslbRule.getAccountId() != loadBalancer.getAccountId()) {
            throw new InvalidParameterValueException("GSLB rule and load balancer rule does not belong to same account");
        }
        if (loadBalancer.getState() == LoadBalancer.State.Revoke) {
            throw new InvalidParameterValueException("Load balancer ID " + loadBalancer.getUuid() + " is in revoke state");
        }
        if (oldLbRuleIds != null && oldLbRuleIds.contains(loadBalancer.getId())) {
            throw new InvalidParameterValueException("Load balancer ID " + loadBalancer.getUuid() + " is already assigned");
        }
        Network network = _networkDao.findById(loadBalancer.getNetworkId());
        if (oldZones != null && oldZones.contains(network.getDataCenterId()) || newZones != null && newZones.contains(network.getDataCenterId())) {
            throw new InvalidParameterValueException("Load balancer rule specified should be in unique zone");
        }
        newZones.add(network.getDataCenterId());
        physcialNetworks.add(new Pair<Long, Long>(network.getDataCenterId(), network.getPhysicalNetworkId()));
    }
    // for each of the physical network check if GSLB service provider configured
    for (Pair<Long, Long> physicalNetwork : physcialNetworks) {
        if (!checkGslbServiceEnabledInZone(physicalNetwork.first(), physicalNetwork.second())) {
            throw new InvalidParameterValueException("GSLB service is not enabled in the Zone:" + physicalNetwork.first() + " and physical network " + physicalNetwork.second());
        }
    }
    final Map<Long, Long> lbRuleWeightMap = assignToGslbCmd.getLoadBalancerRuleWeightMap();
    Transaction.execute(new TransactionCallbackNoReturn() {

        @Override
        public void doInTransactionWithoutResult(TransactionStatus status) {
            // persist the mapping for the new Lb rule that needs to assigned to a gslb rule
            for (Long lbRuleId : newLbRuleIds) {
                GlobalLoadBalancerLbRuleMapVO newGslbLbMap = new GlobalLoadBalancerLbRuleMapVO();
                newGslbLbMap.setGslbLoadBalancerId(gslbRuleId);
                newGslbLbMap.setLoadBalancerId(lbRuleId);
                if (lbRuleWeightMap != null && lbRuleWeightMap.get(lbRuleId) != null) {
                    newGslbLbMap.setWeight(lbRuleWeightMap.get(lbRuleId));
                }
                _gslbLbMapDao.persist(newGslbLbMap);
            }
            // mark the gslb rule state as add
            if (gslbRule.getState() == GlobalLoadBalancerRule.State.Staged || gslbRule.getState() == GlobalLoadBalancerRule.State.Active) {
                gslbRule.setState(GlobalLoadBalancerRule.State.Add);
                _gslbRuleDao.update(gslbRule.getId(), gslbRule);
            }
        }
    });
    boolean success = false;
    try {
        s_logger.debug("Configuring gslb rule configuration on the gslb service providers in the participating zones");
        // apply the gslb rule on to the back end gslb service providers on zones participating in gslb
        if (!applyGlobalLoadBalancerRuleConfig(gslbRuleId, false)) {
            s_logger.warn("Failed to add load balancer rules " + newLbRuleIds + " to global load balancer rule id " + gslbRuleId);
            CloudRuntimeException ex = new CloudRuntimeException("Failed to add load balancer rules to GSLB rule ");
            throw ex;
        }
        // on success set state to Active
        gslbRule.setState(GlobalLoadBalancerRule.State.Active);
        _gslbRuleDao.update(gslbRule.getId(), gslbRule);
        success = true;
    } catch (ResourceUnavailableException e) {
        throw new CloudRuntimeException("Failed to apply new GSLB configuration while assigning new LB rules to GSLB rule.");
    }
    return success;
}
Also used : Account(com.cloud.user.Account) ArrayList(java.util.ArrayList) LoadBalancerVO(com.cloud.network.dao.LoadBalancerVO) TransactionStatus(com.cloud.utils.db.TransactionStatus) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) CallContext(org.apache.cloudstack.context.CallContext) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) Network(com.cloud.network.Network) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) Pair(com.cloud.utils.Pair) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 50 with TransactionCallbackNoReturn

use of com.cloud.utils.db.TransactionCallbackNoReturn in project cloudstack by apache.

the class UserVmManagerImpl method moveVMToUser.

@DB
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_MOVE, eventDescription = "move VM to another user", async = false)
public UserVm moveVMToUser(final AssignVMCmd cmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
    // VERIFICATIONS and VALIDATIONS
    // VV 1: verify the two users
    Account caller = CallContext.current().getCallingAccount();
    if (!_accountMgr.isRootAdmin(caller.getId()) && !_accountMgr.isDomainAdmin(caller.getId())) {
        // VMs
        throw new InvalidParameterValueException("Only domain admins are allowed to assign VMs and not " + caller.getType());
    }
    // get and check the valid VM
    final UserVmVO vm = _vmDao.findById(cmd.getVmId());
    if (vm == null) {
        throw new InvalidParameterValueException("There is no vm by that id " + cmd.getVmId());
    } else if (vm.getState() == State.Running) {
        // running
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("VM is Running, unable to move the vm " + vm);
        }
        InvalidParameterValueException ex = new InvalidParameterValueException("VM is Running, unable to move the vm with specified vmId");
        ex.addProxyObject(vm.getUuid(), "vmId");
        throw ex;
    }
    final Account oldAccount = _accountService.getActiveAccountById(vm.getAccountId());
    if (oldAccount == null) {
        throw new InvalidParameterValueException("Invalid account for VM " + vm.getAccountId() + " in domain.");
    }
    final Account newAccount = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), cmd.getDomainId(), cmd.getProjectId());
    if (newAccount == null) {
        throw new InvalidParameterValueException("Invalid accountid=" + cmd.getAccountName() + " in domain " + cmd.getDomainId());
    }
    if (newAccount.getState() == Account.State.disabled) {
        throw new InvalidParameterValueException("The new account owner " + cmd.getAccountName() + " is disabled.");
    }
    //check caller has access to both the old and new account
    _accountMgr.checkAccess(caller, null, true, oldAccount);
    _accountMgr.checkAccess(caller, null, true, newAccount);
    // make sure the accounts are not same
    if (oldAccount.getAccountId() == newAccount.getAccountId()) {
        throw new InvalidParameterValueException("The new account is the same as the old account. Account id =" + oldAccount.getAccountId());
    }
    // don't allow to move the vm if there are existing PF/LB/Static Nat
    // rules, or vm is assigned to static Nat ip
    List<PortForwardingRuleVO> pfrules = _portForwardingDao.listByVm(cmd.getVmId());
    if (pfrules != null && pfrules.size() > 0) {
        throw new InvalidParameterValueException("Remove the Port forwarding rules for this VM before assigning to another user.");
    }
    List<FirewallRuleVO> snrules = _rulesDao.listStaticNatByVmId(vm.getId());
    if (snrules != null && snrules.size() > 0) {
        throw new InvalidParameterValueException("Remove the StaticNat rules for this VM before assigning to another user.");
    }
    List<LoadBalancerVMMapVO> maps = _loadBalancerVMMapDao.listByInstanceId(vm.getId());
    if (maps != null && maps.size() > 0) {
        throw new InvalidParameterValueException("Remove the load balancing rules for this VM before assigning to another user.");
    }
    // check for one on one nat
    List<IPAddressVO> ips = _ipAddressDao.findAllByAssociatedVmId(cmd.getVmId());
    for (IPAddressVO ip : ips) {
        if (ip.isOneToOneNat()) {
            throw new InvalidParameterValueException("Remove the one to one nat rule for this VM for ip " + ip.toString());
        }
    }
    DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
    // Get serviceOffering and Volumes for Virtual Machine
    final ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId());
    final List<VolumeVO> volumes = _volsDao.findByInstance(cmd.getVmId());
    //Remove vm from instance group
    removeInstanceFromInstanceGroup(cmd.getVmId());
    // VV 2: check if account/domain is with in resource limits to create a new vm
    resourceLimitCheck(newAccount, vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
    // VV 3: check if volumes and primary storage space are with in resource limits
    _resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.volume, _volsDao.findByInstance(cmd.getVmId()).size());
    Long totalVolumesSize = (long) 0;
    for (VolumeVO volume : volumes) {
        totalVolumesSize += volume.getSize();
    }
    _resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.primary_storage, totalVolumesSize);
    // VV 4: Check if new owner can use the vm template
    VirtualMachineTemplate template = _templateDao.findById(vm.getTemplateId());
    if (!template.isPublicTemplate()) {
        Account templateOwner = _accountMgr.getAccount(template.getAccountId());
        _accountMgr.checkAccess(newAccount, null, true, templateOwner);
    }
    // VV 5: check the new account can create vm in the domain
    DomainVO domain = _domainDao.findById(cmd.getDomainId());
    _accountMgr.checkAccess(newAccount, domain);
    Transaction.execute(new TransactionCallbackNoReturn() {

        @Override
        public void doInTransactionWithoutResult(TransactionStatus status) {
            //generate destroy vm event for usage
            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
            // update resource counts for old account
            resourceCountDecrement(oldAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
            // OWNERSHIP STEP 1: update the vm owner
            vm.setAccountId(newAccount.getAccountId());
            vm.setDomainId(cmd.getDomainId());
            _vmDao.persist(vm);
            // OS 2: update volume
            for (VolumeVO volume : volumes) {
                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
                _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
                _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
                volume.setAccountId(newAccount.getAccountId());
                volume.setDomainId(newAccount.getDomainId());
                _volsDao.persist(volume);
                _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
                _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
                //snapshots: mark these removed in db
                List<SnapshotVO> snapshots = _snapshotDao.listByVolumeIdIncludingRemoved(volume.getId());
                for (SnapshotVO snapshot : snapshots) {
                    _snapshotDao.remove(snapshot.getId());
                }
            }
            //update resource count of new account
            resourceCountIncrement(newAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
            //generate usage events to account for this change
            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
        }
    });
    VirtualMachine vmoi = _itMgr.findById(vm.getId());
    VirtualMachineProfileImpl vmOldProfile = new VirtualMachineProfileImpl(vmoi);
    // OS 3: update the network
    List<Long> networkIdList = cmd.getNetworkIds();
    List<Long> securityGroupIdList = cmd.getSecurityGroupIdList();
    if (zone.getNetworkType() == NetworkType.Basic) {
        if (networkIdList != null && !networkIdList.isEmpty()) {
            throw new InvalidParameterValueException("Can't move vm with network Ids; this is a basic zone VM");
        }
        // cleanup the old security groups
        _securityGroupMgr.removeInstanceFromGroups(cmd.getVmId());
        // cleanup the network for the oldOwner
        _networkMgr.cleanupNics(vmOldProfile);
        _networkMgr.expungeNics(vmOldProfile);
        // security groups will be recreated for the new account, when the
        // VM is started
        List<NetworkVO> networkList = new ArrayList<NetworkVO>();
        // Get default guest network in Basic zone
        Network defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId());
        if (defaultNetwork == null) {
            throw new InvalidParameterValueException("Unable to find a default network to start a vm");
        } else {
            networkList.add(_networkDao.findById(defaultNetwork.getId()));
        }
        boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware);
        if (securityGroupIdList != null && isVmWare) {
            throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
        } else if (!isVmWare && _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkModel.canAddDefaultSecurityGroup()) {
            if (securityGroupIdList == null) {
                securityGroupIdList = new ArrayList<Long>();
            }
            SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(newAccount.getId());
            if (defaultGroup != null) {
                // check if security group id list already contains Default
                // security group, and if not - add it
                boolean defaultGroupPresent = false;
                for (Long securityGroupId : securityGroupIdList) {
                    if (securityGroupId.longValue() == defaultGroup.getId()) {
                        defaultGroupPresent = true;
                        break;
                    }
                }
                if (!defaultGroupPresent) {
                    securityGroupIdList.add(defaultGroup.getId());
                }
            } else {
                // create default security group for the account
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Couldn't find default security group for the account " + newAccount + " so creating a new one");
                }
                defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION, newAccount.getDomainId(), newAccount.getId(), newAccount.getAccountName());
                securityGroupIdList.add(defaultGroup.getId());
            }
        }
        LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
        NicProfile profile = new NicProfile();
        profile.setDefaultNic(true);
        networks.put(networkList.get(0), new ArrayList<NicProfile>(Arrays.asList(profile)));
        VirtualMachine vmi = _itMgr.findById(vm.getId());
        VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
        _networkMgr.allocate(vmProfile, networks);
        _securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList);
        s_logger.debug("AssignVM: Basic zone, adding security groups no " + securityGroupIdList.size() + " to " + vm.getInstanceName());
    } else {
        if (zone.isSecurityGroupEnabled()) {
            // advanced zone with security groups
            // cleanup the old security groups
            _securityGroupMgr.removeInstanceFromGroups(cmd.getVmId());
            Set<NetworkVO> applicableNetworks = new HashSet<NetworkVO>();
            String requestedIPv4ForDefaultNic = null;
            String requestedIPv6ForDefaultNic = null;
            // if networkIdList is null and the first network of vm is shared network, then keep it if possible
            if (networkIdList == null || networkIdList.isEmpty()) {
                NicVO defaultNicOld = _nicDao.findDefaultNicForVM(vm.getId());
                if (defaultNicOld != null) {
                    NetworkVO defaultNetworkOld = _networkDao.findById(defaultNicOld.getNetworkId());
                    if (defaultNetworkOld != null && defaultNetworkOld.getGuestType() == Network.GuestType.Shared && defaultNetworkOld.getAclType() == ACLType.Domain) {
                        try {
                            _networkModel.checkNetworkPermissions(newAccount, defaultNetworkOld);
                            applicableNetworks.add(defaultNetworkOld);
                            requestedIPv4ForDefaultNic = defaultNicOld.getIPv4Address();
                            requestedIPv6ForDefaultNic = defaultNicOld.getIPv6Address();
                            s_logger.debug("AssignVM: use old shared network " + defaultNetworkOld.getName() + " with old ip " + requestedIPv4ForDefaultNic + " on default nic of vm:" + vm.getInstanceName());
                        } catch (PermissionDeniedException e) {
                            s_logger.debug("AssignVM: the shared network on old default nic can not be applied to new account");
                        }
                    }
                }
            }
            // cleanup the network for the oldOwner
            _networkMgr.cleanupNics(vmOldProfile);
            _networkMgr.expungeNics(vmOldProfile);
            if (networkIdList != null && !networkIdList.isEmpty()) {
                // add any additional networks
                for (Long networkId : networkIdList) {
                    NetworkVO network = _networkDao.findById(networkId);
                    if (network == null) {
                        InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find specified network id");
                        ex.addProxyObject(networkId.toString(), "networkId");
                        throw ex;
                    }
                    _networkModel.checkNetworkPermissions(newAccount, network);
                    // don't allow to use system networks
                    NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
                    if (networkOffering.isSystemOnly()) {
                        InvalidParameterValueException ex = new InvalidParameterValueException("Specified Network id is system only and can't be used for vm deployment");
                        ex.addProxyObject(network.getUuid(), "networkId");
                        throw ex;
                    }
                    applicableNetworks.add(network);
                }
            }
            // add the new nics
            LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
            int toggle = 0;
            NetworkVO defaultNetwork = null;
            for (NetworkVO appNet : applicableNetworks) {
                NicProfile defaultNic = new NicProfile();
                if (toggle == 0) {
                    defaultNic.setDefaultNic(true);
                    defaultNic.setRequestedIPv4(requestedIPv4ForDefaultNic);
                    defaultNic.setRequestedIPv6(requestedIPv6ForDefaultNic);
                    defaultNetwork = appNet;
                    toggle++;
                }
                networks.put(appNet, new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
            }
            boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware);
            if (securityGroupIdList != null && isVmWare) {
                throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
            } else if (!isVmWare && (defaultNetwork == null || _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork)) && _networkModel.canAddDefaultSecurityGroup()) {
                if (securityGroupIdList == null) {
                    securityGroupIdList = new ArrayList<Long>();
                }
                SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(newAccount.getId());
                if (defaultGroup != null) {
                    // check if security group id list already contains Default
                    // security group, and if not - add it
                    boolean defaultGroupPresent = false;
                    for (Long securityGroupId : securityGroupIdList) {
                        if (securityGroupId.longValue() == defaultGroup.getId()) {
                            defaultGroupPresent = true;
                            break;
                        }
                    }
                    if (!defaultGroupPresent) {
                        securityGroupIdList.add(defaultGroup.getId());
                    }
                } else {
                    // create default security group for the account
                    if (s_logger.isDebugEnabled()) {
                        s_logger.debug("Couldn't find default security group for the account " + newAccount + " so creating a new one");
                    }
                    defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION, newAccount.getDomainId(), newAccount.getId(), newAccount.getAccountName());
                    securityGroupIdList.add(defaultGroup.getId());
                }
            }
            VirtualMachine vmi = _itMgr.findById(vm.getId());
            VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
            if (applicableNetworks.isEmpty()) {
                throw new InvalidParameterValueException("No network is specified, please specify one when you move the vm. For now, please add a network to VM on NICs tab.");
            } else {
                _networkMgr.allocate(vmProfile, networks);
            }
            _securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList);
            s_logger.debug("AssignVM: Advanced zone, adding security groups no " + securityGroupIdList.size() + " to " + vm.getInstanceName());
        } else {
            if (securityGroupIdList != null && !securityGroupIdList.isEmpty()) {
                throw new InvalidParameterValueException("Can't move vm with security groups; security group feature is not enabled in this zone");
            }
            Set<NetworkVO> applicableNetworks = new HashSet<NetworkVO>();
            // if networkIdList is null and the first network of vm is shared network, then keep it if possible
            if (networkIdList == null || networkIdList.isEmpty()) {
                NicVO defaultNicOld = _nicDao.findDefaultNicForVM(vm.getId());
                if (defaultNicOld != null) {
                    NetworkVO defaultNetworkOld = _networkDao.findById(defaultNicOld.getNetworkId());
                    if (defaultNetworkOld != null && defaultNetworkOld.getGuestType() == Network.GuestType.Shared && defaultNetworkOld.getAclType() == ACLType.Domain) {
                        try {
                            _networkModel.checkNetworkPermissions(newAccount, defaultNetworkOld);
                            applicableNetworks.add(defaultNetworkOld);
                        } catch (PermissionDeniedException e) {
                            s_logger.debug("AssignVM: the shared network on old default nic can not be applied to new account");
                        }
                    }
                }
            }
            // cleanup the network for the oldOwner
            _networkMgr.cleanupNics(vmOldProfile);
            _networkMgr.expungeNics(vmOldProfile);
            if (networkIdList != null && !networkIdList.isEmpty()) {
                // add any additional networks
                for (Long networkId : networkIdList) {
                    NetworkVO network = _networkDao.findById(networkId);
                    if (network == null) {
                        InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find specified network id");
                        ex.addProxyObject(networkId.toString(), "networkId");
                        throw ex;
                    }
                    _networkModel.checkNetworkPermissions(newAccount, network);
                    // don't allow to use system networks
                    NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
                    if (networkOffering.isSystemOnly()) {
                        InvalidParameterValueException ex = new InvalidParameterValueException("Specified Network id is system only and can't be used for vm deployment");
                        ex.addProxyObject(network.getUuid(), "networkId");
                        throw ex;
                    }
                    applicableNetworks.add(network);
                }
            } else if (applicableNetworks.isEmpty()) {
                NetworkVO defaultNetwork = null;
                List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
                if (requiredOfferings.size() < 1) {
                    throw new InvalidParameterValueException("Unable to find network offering with availability=" + Availability.Required + " to automatically create the network as a part of vm creation");
                }
                if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
                    // get Virtual networks
                    List<? extends Network> virtualNetworks = _networkModel.listNetworksForAccount(newAccount.getId(), zone.getId(), Network.GuestType.Isolated);
                    if (virtualNetworks.isEmpty()) {
                        long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType());
                        // Validate physical network
                        PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
                        if (physicalNetwork == null) {
                            throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: " + requiredOfferings.get(0).getTags());
                        }
                        s_logger.debug("Creating network for account " + newAccount + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process");
                        Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network", newAccount.getAccountName() + "-network", null, null, null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null);
                        // if the network offering has persistent set to true, implement the network
                        if (requiredOfferings.get(0).getIsPersistent()) {
                            DeployDestination dest = new DeployDestination(zone, null, null, null);
                            UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
                            Journal journal = new Journal.LogJournal("Implementing " + newNetwork, s_logger);
                            ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, caller);
                            s_logger.debug("Implementing the network for account" + newNetwork + " as a part of" + " network provision for persistent networks");
                            try {
                                Pair<? extends NetworkGuru, ? extends Network> implementedNetwork = _networkMgr.implementNetwork(newNetwork.getId(), dest, context);
                                if (implementedNetwork == null || implementedNetwork.first() == null) {
                                    s_logger.warn("Failed to implement the network " + newNetwork);
                                }
                                newNetwork = implementedNetwork.second();
                            } catch (Exception ex) {
                                s_logger.warn("Failed to implement network " + newNetwork + " elements and" + " resources as a part of network provision for persistent network due to ", ex);
                                CloudRuntimeException e = new CloudRuntimeException("Failed to implement network" + " (with specified id) elements and resources as a part of network provision");
                                e.addProxyObject(newNetwork.getUuid(), "networkId");
                                throw e;
                            }
                        }
                        defaultNetwork = _networkDao.findById(newNetwork.getId());
                    } else if (virtualNetworks.size() > 1) {
                        throw new InvalidParameterValueException("More than 1 default Isolated networks are found " + "for account " + newAccount + "; please specify networkIds");
                    } else {
                        defaultNetwork = _networkDao.findById(virtualNetworks.get(0).getId());
                    }
                } else {
                    throw new InvalidParameterValueException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
                }
                applicableNetworks.add(defaultNetwork);
            }
            // add the new nics
            LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
            int toggle = 0;
            for (NetworkVO appNet : applicableNetworks) {
                NicProfile defaultNic = new NicProfile();
                if (toggle == 0) {
                    defaultNic.setDefaultNic(true);
                    toggle++;
                }
                networks.put(appNet, new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
            }
            VirtualMachine vmi = _itMgr.findById(vm.getId());
            VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
            _networkMgr.allocate(vmProfile, networks);
            s_logger.debug("AssignVM: Advance virtual, adding networks no " + networks.size() + " to " + vm.getInstanceName());
        }
    // END IF NON SEC GRP ENABLED
    }
    // END IF ADVANCED
    s_logger.info("AssignVM: vm " + vm.getInstanceName() + " now belongs to account " + newAccount.getAccountName());
    return vm;
}
Also used : Account(com.cloud.user.Account) ArrayList(java.util.ArrayList) TransactionStatus(com.cloud.utils.db.TransactionStatus) Journal(com.cloud.utils.Journal) ServiceOfferingVO(com.cloud.service.ServiceOfferingVO) FirewallRuleVO(com.cloud.network.rules.FirewallRuleVO) LinkedHashMap(java.util.LinkedHashMap) VolumeVO(com.cloud.storage.VolumeVO) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) PhysicalNetwork(com.cloud.network.PhysicalNetwork) Network(com.cloud.network.Network) PhysicalNetwork(com.cloud.network.PhysicalNetwork) LoadBalancerVMMapVO(com.cloud.network.dao.LoadBalancerVMMapVO) ArrayList(java.util.ArrayList) ExcludeList(com.cloud.deploy.DeploymentPlanner.ExcludeList) List(java.util.List) HashSet(java.util.HashSet) DataCenterVO(com.cloud.dc.DataCenterVO) PortForwardingRuleVO(com.cloud.network.rules.PortForwardingRuleVO) NetworkVO(com.cloud.network.dao.NetworkVO) VirtualMachineTemplate(com.cloud.template.VirtualMachineTemplate) SecurityGroup(com.cloud.network.security.SecurityGroup) DomainVO(com.cloud.domain.DomainVO) DeployDestination(com.cloud.deploy.DeployDestination) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) Pair(com.cloud.utils.Pair) SSHKeyPair(com.cloud.user.SSHKeyPair) NetworkOffering(com.cloud.offering.NetworkOffering) NetworkGuru(com.cloud.network.guru.NetworkGuru) ExecutionException(com.cloud.utils.exception.ExecutionException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) VirtualMachineMigrationException(com.cloud.exception.VirtualMachineMigrationException) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) CloudException(com.cloud.exception.CloudException) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) InsufficientAddressCapacityException(com.cloud.exception.InsufficientAddressCapacityException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) ConfigurationException(javax.naming.ConfigurationException) ManagementServerException(com.cloud.exception.ManagementServerException) VMSnapshotVO(com.cloud.vm.snapshot.VMSnapshotVO) SnapshotVO(com.cloud.storage.SnapshotVO) UserVO(com.cloud.user.UserVO) IPAddressVO(com.cloud.network.dao.IPAddressVO) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Aggregations

TransactionCallbackNoReturn (com.cloud.utils.db.TransactionCallbackNoReturn)93 TransactionStatus (com.cloud.utils.db.TransactionStatus)93 DB (com.cloud.utils.db.DB)73 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)50 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)34 ArrayList (java.util.ArrayList)30 List (java.util.List)21 ActionEvent (com.cloud.event.ActionEvent)20 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)19 Account (com.cloud.user.Account)18 ConfigurationException (javax.naming.ConfigurationException)15 IPAddressVO (com.cloud.network.dao.IPAddressVO)14 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)11 Network (com.cloud.network.Network)10 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)9 HostVO (com.cloud.host.HostVO)9 HashMap (java.util.HashMap)9 InsufficientAddressCapacityException (com.cloud.exception.InsufficientAddressCapacityException)8 DataCenter (com.cloud.dc.DataCenter)7 PermissionDeniedException (com.cloud.exception.PermissionDeniedException)7