Search in sources :

Example 96 with TransactionStatus

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

the class RemoteAccessVpnManagerImpl method createRemoteAccessVpn.

@Override
@DB
public RemoteAccessVpn createRemoteAccessVpn(final long publicIpId, String ipRange, boolean openFirewall, final Boolean forDisplay) throws NetworkRuleConflictException {
    CallContext ctx = CallContext.current();
    final Account caller = ctx.getCallingAccount();
    Long networkId = null;
    // make sure ip address exists
    final PublicIpAddress ipAddr = _networkMgr.getPublicIpAddress(publicIpId);
    if (ipAddr == null) {
        throw new InvalidParameterValueException("Unable to create remote access vpn, invalid public IP address id" + publicIpId);
    }
    _accountMgr.checkAccess(caller, null, true, ipAddr);
    if (!ipAddr.readyToUse()) {
        throw new InvalidParameterValueException("The Ip address is not ready to be used yet: " + ipAddr.getAddress());
    }
    IPAddressVO ipAddress = _ipAddressDao.findById(publicIpId);
    networkId = ipAddress.getAssociatedWithNetworkId();
    if (networkId != null) {
        _networkMgr.checkIpForService(ipAddress, Service.Vpn, null);
    }
    final Long vpcId = ipAddress.getVpcId();
    /* IP Address used for VPC must be the source NAT IP of whole VPC */
    if (vpcId != null && ipAddress.isSourceNat()) {
        assert networkId == null;
        // No firewall setting for VPC, it would be open internally
        openFirewall = false;
    }
    final boolean openFirewallFinal = openFirewall;
    if (networkId == null && vpcId == null) {
        throw new InvalidParameterValueException("Unable to create remote access vpn for the ipAddress: " + ipAddr.getAddress().addr() + " as ip is not associated with any network or VPC");
    }
    RemoteAccessVpnVO vpnVO = _remoteAccessVpnDao.findByPublicIpAddress(publicIpId);
    if (vpnVO != null) {
        //if vpn is in Added state, return it to the api
        if (vpnVO.getState() == RemoteAccessVpn.State.Added) {
            return vpnVO;
        }
        throw new InvalidParameterValueException("A Remote Access VPN already exists for this public Ip address");
    }
    if (ipRange == null) {
        ipRange = RemoteAccessVpnClientIpRange.valueIn(ipAddr.getAccountId());
    }
    final String[] range = ipRange.split("-");
    if (range.length != 2) {
        throw new InvalidParameterValueException("Invalid ip range");
    }
    if (!NetUtils.isValidIp(range[0]) || !NetUtils.isValidIp(range[1])) {
        throw new InvalidParameterValueException("Invalid ip in range specification " + ipRange);
    }
    if (!NetUtils.validIpRange(range[0], range[1])) {
        throw new InvalidParameterValueException("Invalid ip range " + ipRange);
    }
    Pair<String, Integer> cidr = null;
    // TODO: assumes one virtual network / domr per account per zone
    if (networkId != null) {
        vpnVO = _remoteAccessVpnDao.findByAccountAndNetwork(ipAddr.getAccountId(), networkId);
        if (vpnVO != null) {
            //if vpn is in Added state, return it to the api
            if (vpnVO.getState() == RemoteAccessVpn.State.Added) {
                return vpnVO;
            }
            throw new InvalidParameterValueException("A Remote Access VPN already exists for this account");
        }
        //Verify that vpn service is enabled for the network
        Network network = _networkMgr.getNetwork(networkId);
        if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.Vpn)) {
            throw new InvalidParameterValueException("Vpn service is not supported in network id=" + ipAddr.getAssociatedWithNetworkId());
        }
        cidr = NetUtils.getCidr(network.getCidr());
    } else {
        // Don't need to check VPC because there is only one IP(source NAT IP) available for VPN
        Vpc vpc = _vpcDao.findById(vpcId);
        cidr = NetUtils.getCidr(vpc.getCidr());
    }
    // FIXME: This check won't work for the case where the guest ip range
    // changes depending on the vlan allocated.
    String[] guestIpRange = NetUtils.getIpRangeFromCidr(cidr.first(), cidr.second());
    if (NetUtils.ipRangesOverlap(range[0], range[1], guestIpRange[0], guestIpRange[1])) {
        throw new InvalidParameterValueException("Invalid ip range: " + ipRange + " overlaps with guest ip range " + guestIpRange[0] + "-" + guestIpRange[1]);
    }
    // TODO: check sufficient range
    // TODO: check overlap with private and public ip ranges in datacenter
    long startIp = NetUtils.ip2Long(range[0]);
    final String newIpRange = NetUtils.long2Ip(++startIp) + "-" + range[1];
    final String sharedSecret = PasswordGenerator.generatePresharedKey(_pskLength);
    return Transaction.execute(new TransactionCallbackWithException<RemoteAccessVpn, NetworkRuleConflictException>() {

        @Override
        public RemoteAccessVpn doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
            if (vpcId == null) {
                _rulesMgr.reservePorts(ipAddr, NetUtils.UDP_PROTO, Purpose.Vpn, openFirewallFinal, caller, NetUtils.VPN_PORT, NetUtils.VPN_L2TP_PORT, NetUtils.VPN_NATT_PORT);
            }
            RemoteAccessVpnVO vpnVO = new RemoteAccessVpnVO(ipAddr.getAccountId(), ipAddr.getDomainId(), ipAddr.getAssociatedWithNetworkId(), publicIpId, vpcId, range[0], newIpRange, sharedSecret);
            if (forDisplay != null) {
                vpnVO.setDisplay(forDisplay);
            }
            return _remoteAccessVpnDao.persist(vpnVO);
        }
    });
}
Also used : Account(com.cloud.user.Account) RemoteAccessVpnVO(com.cloud.network.dao.RemoteAccessVpnVO) Vpc(com.cloud.network.vpc.Vpc) TransactionStatus(com.cloud.utils.db.TransactionStatus) CallContext(org.apache.cloudstack.context.CallContext) NetworkRuleConflictException(com.cloud.exception.NetworkRuleConflictException) PublicIpAddress(com.cloud.network.PublicIpAddress) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) Network(com.cloud.network.Network) IPAddressVO(com.cloud.network.dao.IPAddressVO) RemoteAccessVpn(com.cloud.network.RemoteAccessVpn) DB(com.cloud.utils.db.DB)

Example 97 with TransactionStatus

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

the class RemoteAccessVpnManagerImpl method applyVpnUsers.

@DB
@Override
public boolean applyVpnUsers(long vpnOwnerId, String userName) throws ResourceUnavailableException {
    Account caller = CallContext.current().getCallingAccount();
    Account owner = _accountDao.findById(vpnOwnerId);
    _accountMgr.checkAccess(caller, null, true, owner);
    s_logger.debug("Applying vpn users for " + owner);
    List<RemoteAccessVpnVO> vpns = _remoteAccessVpnDao.findByAccount(vpnOwnerId);
    RemoteAccessVpnVO vpnTemp = null;
    List<VpnUserVO> users = _vpnUsersDao.listByAccount(vpnOwnerId);
    //If user is in Active state, we still have to resend them therefore their status has to be Add
    for (VpnUserVO user : users) {
        if (user.getState() == State.Active) {
            user.setState(State.Add);
            _vpnUsersDao.update(user.getId(), user);
        }
    }
    boolean success = true;
    Boolean[] finals = new Boolean[users.size()];
    for (RemoteAccessVPNServiceProvider element : _vpnServiceProviders) {
        s_logger.debug("Applying vpn access to " + element.getName());
        for (RemoteAccessVpnVO vpn : vpns) {
            try {
                String[] results = element.applyVpnUsers(vpn, users);
                if (results != null) {
                    int indexUser = -1;
                    for (int i = 0; i < results.length; i++) {
                        indexUser++;
                        if (indexUser == users.size()) {
                            // results on multiple VPC routers are combined in commit 13eb789, reset user index if one VR is done.
                            indexUser = 0;
                        }
                        s_logger.debug("VPN User " + users.get(indexUser) + (results[i] == null ? " is set on " : (" couldn't be set due to " + results[i]) + " on ") + vpn.getUuid());
                        if (results[i] == null) {
                            if (finals[indexUser] == null) {
                                finals[indexUser] = true;
                            }
                        } else {
                            finals[indexUser] = false;
                            success = false;
                            vpnTemp = vpn;
                        }
                    }
                }
            } catch (Exception e) {
                s_logger.warn("Unable to apply vpn users ", e);
                success = false;
                vpnTemp = vpn;
                for (int i = 0; i < finals.length; i++) {
                    finals[i] = false;
                }
            }
        }
    }
    for (int i = 0; i < finals.length; i++) {
        final VpnUserVO user = users.get(i);
        if (finals[i]) {
            if (user.getState() == State.Add) {
                user.setState(State.Active);
                _vpnUsersDao.update(user.getId(), user);
            } else if (user.getState() == State.Revoke) {
                _vpnUsersDao.remove(user.getId());
            }
        } else {
            if (user.getState() == State.Add && (user.getUsername()).equals(userName)) {
                Transaction.execute(new TransactionCallbackNoReturn() {

                    @Override
                    public void doInTransactionWithoutResult(TransactionStatus status) {
                        _vpnUsersDao.remove(user.getId());
                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), 0, user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid());
                    }
                });
            }
            s_logger.warn("Failed to apply vpn for user " + user.getUsername() + ", accountId=" + user.getAccountId());
        }
    }
    if (!success) {
        throw new ResourceUnavailableException("Failed add vpn user due to Resource unavailable ", RemoteAccessVPNServiceProvider.class, vpnTemp.getId());
    }
    return success;
}
Also used : Account(com.cloud.user.Account) RemoteAccessVPNServiceProvider(com.cloud.network.element.RemoteAccessVPNServiceProvider) RemoteAccessVpnVO(com.cloud.network.dao.RemoteAccessVpnVO) VpnUserVO(com.cloud.network.VpnUserVO) TransactionStatus(com.cloud.utils.db.TransactionStatus) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) AccountLimitException(com.cloud.exception.AccountLimitException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) NetworkRuleConflictException(com.cloud.exception.NetworkRuleConflictException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) ConfigurationException(javax.naming.ConfigurationException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) DB(com.cloud.utils.db.DB)

Example 98 with TransactionStatus

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

the class VpcManagerImpl method revokeStaticRoutesForVpc.

@DB
protected boolean revokeStaticRoutesForVpc(final long vpcId, final Account caller) throws ResourceUnavailableException {
    // get all static routes for the vpc
    final List<StaticRouteVO> routes = _staticRouteDao.listByVpcId(vpcId);
    s_logger.debug("Found " + routes.size() + " to revoke for the vpc " + vpcId);
    if (!routes.isEmpty()) {
        // mark all of them as revoke
        Transaction.execute(new TransactionCallbackNoReturn() {

            @Override
            public void doInTransactionWithoutResult(final TransactionStatus status) {
                for (final StaticRouteVO route : routes) {
                    markStaticRouteForRevoke(route, caller);
                }
            }
        });
        return applyStaticRoutesForVpc(vpcId);
    }
    return true;
}
Also used : TransactionStatus(com.cloud.utils.db.TransactionStatus) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) DB(com.cloud.utils.db.DB)

Example 99 with TransactionStatus

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

the class VpcManagerImpl method destroyVpc.

@Override
@DB
public boolean destroyVpc(final Vpc vpc, final Account caller, final Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException {
    s_logger.debug("Destroying vpc " + vpc);
    // don't allow to delete vpc if it's in use by existing non system
    // networks (system networks are networks of a private gateway of the
    // VPC,
    // and they will get removed as a part of VPC cleanup
    final int networksCount = _ntwkDao.getNonSystemNetworkCountByVpcId(vpc.getId());
    if (networksCount > 0) {
        throw new InvalidParameterValueException("Can't delete VPC " + vpc + " as its used by " + networksCount + " networks");
    }
    // mark VPC as inactive
    if (vpc.getState() != Vpc.State.Inactive) {
        s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Inactive + " as a part of vpc delete");
        final VpcVO vpcVO = _vpcDao.findById(vpc.getId());
        vpcVO.setState(Vpc.State.Inactive);
        Transaction.execute(new TransactionCallbackNoReturn() {

            @Override
            public void doInTransactionWithoutResult(final TransactionStatus status) {
                _vpcDao.update(vpc.getId(), vpcVO);
                // decrement resource count
                _resourceLimitMgr.decrementResourceCount(vpc.getAccountId(), ResourceType.vpc);
            }
        });
    }
    // shutdown VPC
    if (!shutdownVpc(vpc.getId())) {
        s_logger.warn("Failed to shutdown vpc " + vpc + " as a part of vpc destroy process");
        return false;
    }
    // cleanup vpc resources
    if (!cleanupVpcResources(vpc.getId(), caller, callerUserId)) {
        s_logger.warn("Failed to cleanup resources for vpc " + vpc);
        return false;
    }
    // executed successfully
    if (_vpcDao.remove(vpc.getId())) {
        s_logger.debug("Vpc " + vpc + " is destroyed succesfully");
        return true;
    } else {
        s_logger.warn("Vpc " + vpc + " failed to destroy");
        return false;
    }
}
Also used : InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) TransactionStatus(com.cloud.utils.db.TransactionStatus) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) DB(com.cloud.utils.db.DB)

Example 100 with TransactionStatus

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

the class VpcManagerImpl method deleteVpcPrivateGateway.

@Override
@ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_DELETE, eventDescription = "deleting private gateway")
@DB
public boolean deleteVpcPrivateGateway(final long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException {
    final VpcGatewayVO gatewayVO = _vpcGatewayDao.acquireInLockTable(gatewayId);
    if (gatewayVO == null || gatewayVO.getType() != VpcGateway.Type.Private) {
        throw new ConcurrentOperationException("Unable to lock gateway " + gatewayId);
    }
    try {
        Transaction.execute(new TransactionCallbackNoReturn() {

            @Override
            public void doInTransactionWithoutResult(final TransactionStatus status) {
                // don't allow to remove gateway when there are static
                // routes associated with it
                final long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId());
                if (routeCount > 0) {
                    throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount + " static routes applied. Remove the routes first");
                }
                gatewayVO.setState(VpcGateway.State.Deleting);
                _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO);
                s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Deleting);
            }
        });
        // 1) delete the gateway on the backend
        final List<Provider> providersToImplement = getVpcProviders(gatewayVO.getVpcId());
        final PrivateGateway gateway = getVpcPrivateGateway(gatewayId);
        for (final VpcProvider provider : getVpcElements()) {
            if (providersToImplement.contains(provider.getProvider())) {
                if (provider.deletePrivateGateway(gateway)) {
                    s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend");
                } else {
                    s_logger.warn("Private gateway " + gateway + " failed to apply on the backend");
                    gatewayVO.setState(VpcGateway.State.Ready);
                    _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO);
                    s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Ready);
                    return false;
                }
            }
        }
        // 2) Delete private gateway from the DB
        return deletePrivateGatewayFromTheDB(gateway);
    } finally {
        if (gatewayVO != null) {
            _vpcGatewayDao.releaseFromLockTable(gatewayId);
        }
    }
}
Also used : VpcProvider(com.cloud.network.element.VpcProvider) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) TransactionStatus(com.cloud.utils.db.TransactionStatus) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) StaticNatServiceProvider(com.cloud.network.element.StaticNatServiceProvider) VpcProvider(com.cloud.network.element.VpcProvider) Provider(com.cloud.network.Network.Provider) ActionEvent(com.cloud.event.ActionEvent) 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