Search in sources :

Example 61 with TransactionStatus

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

the class ConfigurationManagerImpl method editPod.

@Override
@DB
public Pod editPod(final long id, String name, String startIp, String endIp, String gateway, String netmask, String allocationStateStr) {
    // verify parameters
    final HostPodVO pod = _podDao.findById(id);
    if (pod == null) {
        throw new InvalidParameterValueException("Unable to find pod by id " + id);
    }
    final String[] existingPodIpRange = pod.getDescription().split("-");
    String[] leftRangeToAdd = null;
    String[] rightRangeToAdd = null;
    boolean allowToDownsize = false;
    // pod has allocated private IP addresses
    if (podHasAllocatedPrivateIPs(id)) {
        if (netmask != null) {
            final long newCidr = NetUtils.getCidrSize(netmask);
            final long oldCidr = pod.getCidrSize();
            if (newCidr > oldCidr) {
                throw new CloudRuntimeException("The specified pod has allocated private IP addresses, so its IP address range can be extended only");
            }
        }
        if (startIp != null && !startIp.equals(existingPodIpRange[0])) {
            if (NetUtils.ipRangesOverlap(startIp, null, existingPodIpRange[0], existingPodIpRange[1])) {
                throw new CloudRuntimeException("The specified pod has allocated private IP addresses, so its IP address range can be extended only");
            } else {
                leftRangeToAdd = new String[2];
                final long endIpForUpdate = NetUtils.ip2Long(existingPodIpRange[0]) - 1;
                leftRangeToAdd[0] = startIp;
                leftRangeToAdd[1] = NetUtils.long2Ip(endIpForUpdate);
            }
        }
        if (endIp != null && !endIp.equals(existingPodIpRange[1])) {
            if (NetUtils.ipRangesOverlap(endIp, endIp, existingPodIpRange[0], existingPodIpRange[1])) {
                throw new CloudRuntimeException("The specified pod has allocated private IP addresses, so its IP address range can be extended only");
            } else {
                rightRangeToAdd = new String[2];
                final long startIpForUpdate = NetUtils.ip2Long(existingPodIpRange[1]) + 1;
                rightRangeToAdd[0] = NetUtils.long2Ip(startIpForUpdate);
                rightRangeToAdd[1] = endIp;
            }
        }
    } else {
        allowToDownsize = true;
    }
    if (gateway == null) {
        gateway = pod.getGateway();
    }
    if (netmask == null) {
        netmask = NetUtils.getCidrNetmask(pod.getCidrSize());
    }
    final String oldPodName = pod.getName();
    if (name == null) {
        name = oldPodName;
    }
    if (gateway == null) {
        gateway = pod.getGateway();
    }
    if (startIp == null) {
        startIp = existingPodIpRange[0];
    }
    if (endIp == null) {
        endIp = existingPodIpRange[1];
    }
    if (allocationStateStr == null) {
        allocationStateStr = pod.getAllocationState().toString();
    }
    // Verify pod's attributes
    final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
    final boolean checkForDuplicates = !oldPodName.equals(name);
    checkPodAttributes(id, name, pod.getDataCenterId(), gateway, cidr, startIp, endIp, allocationStateStr, checkForDuplicates, false);
    try {
        final String[] existingPodIpRangeFinal = existingPodIpRange;
        final String[] leftRangeToAddFinal = leftRangeToAdd;
        final String[] rightRangeToAddFinal = rightRangeToAdd;
        final boolean allowToDownsizeFinal = allowToDownsize;
        final String allocationStateStrFinal = allocationStateStr;
        final String startIpFinal = startIp;
        final String endIpFinal = endIp;
        final String nameFinal = name;
        final String gatewayFinal = gateway;
        Transaction.execute(new TransactionCallbackNoReturn() {

            @Override
            public void doInTransactionWithoutResult(final TransactionStatus status) {
                final long zoneId = pod.getDataCenterId();
                String startIp = startIpFinal;
                String endIp = endIpFinal;
                if (!allowToDownsizeFinal) {
                    if (leftRangeToAddFinal != null) {
                        _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), leftRangeToAddFinal[0], leftRangeToAddFinal[1]);
                    }
                    if (rightRangeToAddFinal != null) {
                        _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), rightRangeToAddFinal[0], rightRangeToAddFinal[1]);
                    }
                } else {
                    // delete the old range
                    _zoneDao.deletePrivateIpAddressByPod(pod.getId());
                    // add the new one
                    if (startIp == null) {
                        startIp = existingPodIpRangeFinal[0];
                    }
                    if (endIp == null) {
                        endIp = existingPodIpRangeFinal[1];
                    }
                    _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIp);
                }
                pod.setName(nameFinal);
                pod.setDataCenterId(zoneId);
                pod.setGateway(gatewayFinal);
                pod.setCidrAddress(getCidrAddress(cidr));
                pod.setCidrSize(getCidrSize(cidr));
                final String ipRange = startIp + "-" + endIp;
                pod.setDescription(ipRange);
                Grouping.AllocationState allocationState = null;
                if (allocationStateStrFinal != null && !allocationStateStrFinal.isEmpty()) {
                    allocationState = Grouping.AllocationState.valueOf(allocationStateStrFinal);
                    pod.setAllocationState(allocationState);
                }
                _podDao.update(id, pod);
            }
        });
    } catch (final Exception e) {
        s_logger.error("Unable to edit pod due to " + e.getMessage(), e);
        throw new CloudRuntimeException("Failed to edit pod. Please contact Cloud Support.");
    }
    return pod;
}
Also used : InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) AllocationState(com.cloud.org.Grouping.AllocationState) TransactionStatus(com.cloud.utils.db.TransactionStatus) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) HostPodVO(com.cloud.dc.HostPodVO) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) 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) DB(com.cloud.utils.db.DB)

Example 62 with TransactionStatus

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

the class DeploymentPlanningManagerImpl method checkIfHostFitsPlannerUsage.

@DB
private boolean checkIfHostFitsPlannerUsage(final long hostId, final PlannerResourceUsage resourceUsageRequired) {
    // TODO Auto-generated method stub
    // check if this host has been picked up by some other planner
    // exclusively
    // if planner can work with shared host, check if this host has
    // been marked as 'shared'
    // else if planner needs dedicated host,
    PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
    if (reservationEntry != null) {
        final long id = reservationEntry.getId();
        PlannerResourceUsage hostResourceType = reservationEntry.getResourceUsage();
        if (hostResourceType != null) {
            if (hostResourceType == resourceUsageRequired) {
                return true;
            } else {
                s_logger.debug("Cannot use this host for usage: " + resourceUsageRequired + ", since this host has been reserved for planner usage : " + hostResourceType);
                return false;
            }
        } else {
            final PlannerResourceUsage hostResourceTypeFinal = hostResourceType;
            // let us lock the reservation entry before updating.
            return Transaction.execute(new TransactionCallback<Boolean>() {

                @Override
                public Boolean doInTransaction(TransactionStatus status) {
                    final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true);
                    if (lockedEntry == null) {
                        s_logger.error("Unable to lock the host entry for reservation, host: " + hostId);
                        return false;
                    }
                    // check before updating
                    if (lockedEntry.getResourceUsage() == null) {
                        lockedEntry.setResourceUsage(resourceUsageRequired);
                        _plannerHostReserveDao.persist(lockedEntry);
                        return true;
                    } else {
                        // someone updated it earlier. check if we can still use it
                        if (lockedEntry.getResourceUsage() == resourceUsageRequired) {
                            return true;
                        } else {
                            s_logger.debug("Cannot use this host for usage: " + resourceUsageRequired + ", since this host has been reserved for planner usage : " + hostResourceTypeFinal);
                            return false;
                        }
                    }
                }
            });
        }
    }
    return false;
}
Also used : TransactionStatus(com.cloud.utils.db.TransactionStatus) PlannerResourceUsage(com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage) DB(com.cloud.utils.db.DB)

Example 63 with TransactionStatus

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

the class ConfigurationManagerImpl method createPortableIpRange.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RANGE_CREATE, eventDescription = "creating portable ip range", async = false)
public PortableIpRange createPortableIpRange(final CreatePortableIpRangeCmd cmd) throws ConcurrentOperationException {
    final Integer regionId = cmd.getRegionId();
    final String startIP = cmd.getStartIp();
    final String endIP = cmd.getEndIp();
    final String gateway = cmd.getGateway();
    final String netmask = cmd.getNetmask();
    String vlanId = cmd.getVlan();
    final RegionVO region = _regionDao.findById(regionId);
    if (region == null) {
        throw new InvalidParameterValueException("Invalid region ID: " + regionId);
    }
    if (!NetUtils.isValidIp(startIP) || !NetUtils.isValidIp(endIP) || !NetUtils.validIpRange(startIP, endIP)) {
        throw new InvalidParameterValueException("Invalid portable ip  range: " + startIP + "-" + endIP);
    }
    if (!NetUtils.sameSubnet(startIP, gateway, netmask)) {
        throw new InvalidParameterValueException("Please ensure that your start IP is in the same subnet as " + "your portable IP range's gateway and as per the IP range's netmask.");
    }
    if (!NetUtils.sameSubnet(endIP, gateway, netmask)) {
        throw new InvalidParameterValueException("Please ensure that your end IP is in the same subnet as " + "your portable IP range's gateway and as per the IP range's netmask.");
    }
    if (checkOverlapPortableIpRange(regionId, startIP, endIP)) {
        throw new InvalidParameterValueException("Ip  range: " + startIP + "-" + endIP + " overlaps with a portable" + " IP range already configured in the region " + regionId);
    }
    if (vlanId == null) {
        vlanId = Vlan.UNTAGGED;
    } else {
        if (!NetUtils.isValidVlan(vlanId)) {
            throw new InvalidParameterValueException("Invalid vlan id " + vlanId);
        }
        final List<DataCenterVO> zones = _zoneDao.listAllZones();
        if (zones != null && !zones.isEmpty()) {
            for (final DataCenterVO zone : zones) {
                // check if there is zone vlan with same id
                if (_vlanDao.findByZoneAndVlanId(zone.getId(), vlanId) != null) {
                    throw new InvalidParameterValueException("Found a VLAN id " + vlanId + " already existing in" + " zone " + zone.getUuid() + " that conflicts with VLAN id of the portable ip range being configured");
                }
                //check if there is a public ip range that overlaps with portable ip range being created
                checkOverlapPublicIpRange(zone.getId(), startIP, endIP);
            }
        }
    }
    final GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
    portableIpLock.lock(5);
    try {
        final String vlanIdFinal = vlanId;
        return Transaction.execute(new TransactionCallback<PortableIpRangeVO>() {

            @Override
            public PortableIpRangeVO doInTransaction(final TransactionStatus status) {
                PortableIpRangeVO portableIpRange = new PortableIpRangeVO(regionId, vlanIdFinal, gateway, netmask, startIP, endIP);
                portableIpRange = _portableIpRangeDao.persist(portableIpRange);
                long startIpLong = NetUtils.ip2Long(startIP);
                final long endIpLong = NetUtils.ip2Long(endIP);
                while (startIpLong <= endIpLong) {
                    final PortableIpVO portableIP = new PortableIpVO(regionId, portableIpRange.getId(), vlanIdFinal, gateway, netmask, NetUtils.long2Ip(startIpLong));
                    _portableIpDao.persist(portableIP);
                    startIpLong++;
                }
                // implicitly enable portable IP service for the region
                region.setPortableipEnabled(true);
                _regionDao.update(region.getId(), region);
                return portableIpRange;
            }
        });
    } finally {
        portableIpLock.unlock();
    }
}
Also used : DataCenterVO(com.cloud.dc.DataCenterVO) GlobalLock(com.cloud.utils.db.GlobalLock) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) RegionVO(org.apache.cloudstack.region.RegionVO) TransactionStatus(com.cloud.utils.db.TransactionStatus) PortableIpRangeVO(org.apache.cloudstack.region.PortableIpRangeVO) PortableIpVO(org.apache.cloudstack.region.PortableIpVO) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 64 with TransactionStatus

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

the class RulesManagerImpl method createStaticNatRule.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating static nat rule", create = true)
public StaticNatRule createStaticNatRule(final StaticNatRule rule, final boolean openFirewall) throws NetworkRuleConflictException {
    final Account caller = CallContext.current().getCallingAccount();
    final Long ipAddrId = rule.getSourceIpAddressId();
    IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
    // Validate ip address
    if (ipAddress == null) {
        throw new InvalidParameterValueException("Unable to create static nat rule; ip id=" + ipAddrId + " doesn't exist in the system");
    } else if (ipAddress.isSourceNat() || !ipAddress.isOneToOneNat() || ipAddress.getAssociatedWithVmId() == null) {
        throw new NetworkRuleConflictException("Can't do static nat on ip address: " + ipAddress.getAddress());
    }
    _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.StaticNat, FirewallRuleType.User, null, rule.getTrafficType());
    final Long networkId = ipAddress.getAssociatedWithNetworkId();
    final Long accountId = ipAddress.getAllocatedToAccountId();
    final Long domainId = ipAddress.getAllocatedInDomainId();
    _networkModel.checkIpForService(ipAddress, Service.StaticNat, null);
    Network network = _networkModel.getNetwork(networkId);
    NetworkOffering off = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
    if (off.getElasticIp()) {
        throw new InvalidParameterValueException("Can't create ip forwarding rules for the network where elasticIP service is enabled");
    }
    //String dstIp = _networkModel.getIpInNetwork(ipAddress.getAssociatedWithVmId(), networkId);
    final String dstIp = ipAddress.getVmIp();
    return Transaction.execute(new TransactionCallbackWithException<StaticNatRule, NetworkRuleConflictException>() {

        @Override
        public StaticNatRule doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
            FirewallRuleVO newRule = new FirewallRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, rule.getPurpose(), null, null, null, null, null);
            newRule = _firewallDao.persist(newRule);
            // create firewallRule for 0.0.0.0/0 cidr
            if (openFirewall) {
                _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null, newRule.getId(), networkId);
            }
            try {
                _firewallMgr.detectRulesConflict(newRule);
                if (!_firewallDao.setStateToAdd(newRule)) {
                    throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
                }
                CallContext.current().setEventDetails("Rule Id: " + newRule.getId());
                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), 0, newRule.getId(), null, FirewallRule.class.getName(), newRule.getUuid());
                StaticNatRule staticNatRule = new StaticNatRuleImpl(newRule, dstIp);
                return staticNatRule;
            } catch (Exception e) {
                if (newRule != null) {
                    // no need to apply the rule as it wasn't programmed on the backend yet
                    _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
                    _firewallMgr.removeRule(newRule);
                }
                if (e instanceof NetworkRuleConflictException) {
                    throw (NetworkRuleConflictException) e;
                }
                throw new CloudRuntimeException("Unable to add static nat rule for the ip id=" + newRule.getSourceIpAddressId(), e);
            }
        }
    });
}
Also used : Account(com.cloud.user.Account) NetworkOffering(com.cloud.offering.NetworkOffering) TransactionStatus(com.cloud.utils.db.TransactionStatus) NetworkRuleConflictException(com.cloud.exception.NetworkRuleConflictException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) NetworkRuleConflictException(com.cloud.exception.NetworkRuleConflictException) InsufficientAddressCapacityException(com.cloud.exception.InsufficientAddressCapacityException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) Network(com.cloud.network.Network) IPAddressVO(com.cloud.network.dao.IPAddressVO) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 65 with TransactionStatus

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

the class SecurityGroupManagerImpl method scheduleRulesetUpdateToHosts.

@DB
public void scheduleRulesetUpdateToHosts(final List<Long> affectedVms, final boolean updateSeqno, Long delayMs) {
    if (affectedVms.size() == 0) {
        return;
    }
    if (delayMs == null) {
        delayMs = new Long(100l);
    }
    Collections.sort(affectedVms);
    if (s_logger.isTraceEnabled()) {
        s_logger.trace("Security Group Mgr: scheduling ruleset updates for " + affectedVms.size() + " vms");
    }
    boolean locked = _workLock.lock(_globalWorkLockTimeout);
    if (!locked) {
        s_logger.warn("Security Group Mgr: failed to acquire global work lock");
        return;
    }
    if (s_logger.isTraceEnabled()) {
        s_logger.trace("Security Group Mgr: acquired global work lock");
    }
    try {
        Transaction.execute(new TransactionCallbackNoReturn() {

            @Override
            public void doInTransactionWithoutResult(TransactionStatus status) {
                for (Long vmId : affectedVms) {
                    if (s_logger.isTraceEnabled()) {
                        s_logger.trace("Security Group Mgr: scheduling ruleset update for " + vmId);
                    }
                    VmRulesetLogVO log = null;
                    SecurityGroupWorkVO work = null;
                    log = _rulesetLogDao.findByVmId(vmId);
                    if (log == null) {
                        log = new VmRulesetLogVO(vmId);
                        log = _rulesetLogDao.persist(log);
                    }
                    if (log != null && updateSeqno) {
                        log.incrLogsequence();
                        _rulesetLogDao.update(log.getId(), log);
                    }
                    work = _workDao.findByVmIdStep(vmId, Step.Scheduled);
                    if (work == null) {
                        work = new SecurityGroupWorkVO(vmId, null, null, SecurityGroupWork.Step.Scheduled, null);
                        work = _workDao.persist(work);
                        if (s_logger.isTraceEnabled()) {
                            s_logger.trace("Security Group Mgr: created new work item for " + vmId + "; id = " + work.getId());
                        }
                    }
                    work.setLogsequenceNumber(log.getLogsequence());
                    _workDao.update(work.getId(), work);
                }
            }
        });
        for (Long vmId : affectedVms) {
            _executorPool.schedule(new WorkerThread(), delayMs, TimeUnit.MILLISECONDS);
        }
    } finally {
        _workLock.unlock();
        if (s_logger.isTraceEnabled()) {
            s_logger.trace("Security Group Mgr: released global work lock");
        }
    }
}
Also used : TransactionStatus(com.cloud.utils.db.TransactionStatus) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) DB(com.cloud.utils.db.DB)

Aggregations

TransactionStatus (com.cloud.utils.db.TransactionStatus)171 DB (com.cloud.utils.db.DB)139 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)100 TransactionCallbackNoReturn (com.cloud.utils.db.TransactionCallbackNoReturn)93 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)77 ArrayList (java.util.ArrayList)54 Account (com.cloud.user.Account)44 List (java.util.List)44 ActionEvent (com.cloud.event.ActionEvent)40 ConfigurationException (javax.naming.ConfigurationException)40 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)35 IPAddressVO (com.cloud.network.dao.IPAddressVO)26 TransactionCallbackWithException (com.cloud.utils.db.TransactionCallbackWithException)26 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)23 InsufficientAddressCapacityException (com.cloud.exception.InsufficientAddressCapacityException)23 PermissionDeniedException (com.cloud.exception.PermissionDeniedException)22 HashMap (java.util.HashMap)22 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)21 Network (com.cloud.network.Network)20 DataCenterVO (com.cloud.dc.DataCenterVO)17