Search in sources :

Example 41 with NetworkRuleConflictException

use of com.cloud.exception.NetworkRuleConflictException in project cloudstack by apache.

the class VpcManagerImpl method createStaticRoute.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_CREATE, eventDescription = "creating static route", create = true)
public StaticRoute createStaticRoute(final long gatewayId, final String cidr) throws NetworkRuleConflictException {
    final Account caller = CallContext.current().getCallingAccount();
    // parameters validation
    final VpcGateway gateway = _vpcGatewayDao.findById(gatewayId);
    if (gateway == null) {
        throw new InvalidParameterValueException("Invalid gateway id is given");
    }
    if (gateway.getState() != VpcGateway.State.Ready) {
        throw new InvalidParameterValueException("Gateway is not in the " + VpcGateway.State.Ready + " state: " + gateway.getState());
    }
    final Vpc vpc = getActiveVpc(gateway.getVpcId());
    if (vpc == null) {
        throw new InvalidParameterValueException("Can't add static route to VPC that is being deleted");
    }
    _accountMgr.checkAccess(caller, null, false, vpc);
    if (!NetUtils.isValidCIDR(cidr)) {
        throw new InvalidParameterValueException("Invalid format for cidr " + cidr);
    }
    // 1) CIDR should be outside of VPC cidr for guest networks
    if (NetUtils.isNetworksOverlap(vpc.getCidr(), cidr)) {
        throw new InvalidParameterValueException("CIDR should be outside of VPC cidr " + vpc.getCidr());
    }
    // 2) CIDR should be outside of link-local cidr
    if (NetUtils.isNetworksOverlap(vpc.getCidr(), NetUtils.getLinkLocalCIDR())) {
        throw new InvalidParameterValueException("CIDR should be outside of link local cidr " + NetUtils.getLinkLocalCIDR());
    }
    // 3) Verify against blacklisted routes
    if (isCidrBlacklisted(cidr, vpc.getZoneId())) {
        throw new InvalidParameterValueException("The static gateway cidr overlaps with one of the blacklisted routes of the zone the VPC belongs to");
    }
    return Transaction.execute(new TransactionCallbackWithException<StaticRouteVO, NetworkRuleConflictException>() {

        @Override
        public StaticRouteVO doInTransaction(final TransactionStatus status) throws NetworkRuleConflictException {
            StaticRouteVO newRoute = new StaticRouteVO(gateway.getId(), cidr, vpc.getId(), vpc.getAccountId(), vpc.getDomainId());
            s_logger.debug("Adding static route " + newRoute);
            newRoute = _staticRouteDao.persist(newRoute);
            detectRoutesConflict(newRoute);
            if (!_staticRouteDao.setStateToAdd(newRoute)) {
                throw new CloudRuntimeException("Unable to update the state to add for " + newRoute);
            }
            CallContext.current().setEventDetails("Static route Id: " + newRoute.getId());
            return newRoute;
        }
    });
}
Also used : Account(com.cloud.user.Account) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) TransactionStatus(com.cloud.utils.db.TransactionStatus) NetworkRuleConflictException(com.cloud.exception.NetworkRuleConflictException) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 42 with NetworkRuleConflictException

use of com.cloud.exception.NetworkRuleConflictException 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 43 with NetworkRuleConflictException

use of com.cloud.exception.NetworkRuleConflictException in project cloudstack by apache.

the class RulesManagerImpl method createPortForwardingRule.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating forwarding rule", create = true)
public PortForwardingRule createPortForwardingRule(final PortForwardingRule rule, final Long vmId, Ip vmIp, final boolean openFirewall, final Boolean forDisplay) throws NetworkRuleConflictException {
    CallContext ctx = CallContext.current();
    final Account caller = ctx.getCallingAccount();
    final Long ipAddrId = rule.getSourceIpAddressId();
    IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
    // Validate ip address
    if (ipAddress == null) {
        throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " doesn't exist in the system");
    } else if (ipAddress.isOneToOneNat()) {
        throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " has static nat enabled");
    }
    final Long networkId = rule.getNetworkId();
    Network network = _networkModel.getNetwork(networkId);
    //associate ip address to network (if needed)
    boolean performedIpAssoc = false;
    Nic guestNic;
    if (ipAddress.getAssociatedWithNetworkId() == null) {
        boolean assignToVpcNtwk = network.getVpcId() != null && ipAddress.getVpcId() != null && ipAddress.getVpcId().longValue() == network.getVpcId();
        if (assignToVpcNtwk) {
            _networkModel.checkIpForService(ipAddress, Service.PortForwarding, networkId);
            s_logger.debug("The ip is not associated with the VPC network id=" + networkId + ", so assigning");
            try {
                ipAddress = _ipAddrMgr.associateIPToGuestNetwork(ipAddrId, networkId, false);
                performedIpAssoc = true;
            } catch (Exception ex) {
                throw new CloudRuntimeException("Failed to associate ip to VPC network as " + "a part of port forwarding rule creation");
            }
        }
    } else {
        _networkModel.checkIpForService(ipAddress, Service.PortForwarding, null);
    }
    if (ipAddress.getAssociatedWithNetworkId() == null) {
        throw new InvalidParameterValueException("Ip address " + ipAddress + " is not assigned to the network " + network);
    }
    try {
        _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User, networkId, rule.getTrafficType());
        final Long accountId = ipAddress.getAllocatedToAccountId();
        final Long domainId = ipAddress.getAllocatedInDomainId();
        // start port can't be bigger than end port
        if (rule.getDestinationPortStart() > rule.getDestinationPortEnd()) {
            throw new InvalidParameterValueException("Start port can't be bigger than end port");
        }
        // check that the port ranges are of equal size
        if ((rule.getDestinationPortEnd() - rule.getDestinationPortStart()) != (rule.getSourcePortEnd() - rule.getSourcePortStart())) {
            throw new InvalidParameterValueException("Source port and destination port ranges should be of equal sizes.");
        }
        // validate user VM exists
        UserVm vm = _vmDao.findById(vmId);
        if (vm == null) {
            throw new InvalidParameterValueException("Unable to create port forwarding rule on address " + ipAddress + ", invalid virtual machine id specified (" + vmId + ").");
        } else if (vm.getState() == VirtualMachine.State.Destroyed || vm.getState() == VirtualMachine.State.Expunging) {
            throw new InvalidParameterValueException("Invalid user vm: " + vm.getId());
        }
        // Verify that vm has nic in the network
        Ip dstIp = rule.getDestinationIpAddress();
        guestNic = _networkModel.getNicInNetwork(vmId, networkId);
        if (guestNic == null || guestNic.getIPv4Address() == null) {
            throw new InvalidParameterValueException("Vm doesn't belong to network associated with ipAddress");
        } else {
            dstIp = new Ip(guestNic.getIPv4Address());
        }
        if (vmIp != null) {
            //vm ip is passed so it can be primary or secondary ip addreess.
            if (!dstIp.equals(vmIp)) {
                //the vm ip is secondary ip to the nic.
                // is vmIp is secondary ip or not
                NicSecondaryIp secondaryIp = _nicSecondaryDao.findByIp4AddressAndNicId(vmIp.toString(), guestNic.getId());
                if (secondaryIp == null) {
                    throw new InvalidParameterValueException("IP Address is not in the VM nic's network ");
                }
                dstIp = vmIp;
            }
        }
        //if start port and end port are passed in, and they are not equal to each other, perform the validation
        boolean validatePortRange = false;
        if (rule.getSourcePortStart().intValue() != rule.getSourcePortEnd().intValue() || rule.getDestinationPortStart() != rule.getDestinationPortEnd()) {
            validatePortRange = true;
        }
        if (validatePortRange) {
            //source start port and source dest port should be the same. The same applies to dest ports
            if (rule.getSourcePortStart().intValue() != rule.getDestinationPortStart()) {
                throw new InvalidParameterValueException("Private port start should be equal to public port start");
            }
            if (rule.getSourcePortEnd().intValue() != rule.getDestinationPortEnd()) {
                throw new InvalidParameterValueException("Private port end should be equal to public port end");
            }
        }
        final Ip dstIpFinal = dstIp;
        final IPAddressVO ipAddressFinal = ipAddress;
        return Transaction.execute(new TransactionCallbackWithException<PortForwardingRuleVO, NetworkRuleConflictException>() {

            @Override
            public PortForwardingRuleVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
                PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIpFinal, rule.getDestinationPortStart(), rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId);
                if (forDisplay != null) {
                    newRule.setDisplay(forDisplay);
                }
                newRule = _portForwardingDao.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(), ipAddressFinal.getDataCenterId(), newRule.getId(), null, PortForwardingRule.class.getName(), newRule.getUuid());
                    return newRule;
                } 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);
                        removePFRule(newRule);
                    }
                    if (e instanceof NetworkRuleConflictException) {
                        throw (NetworkRuleConflictException) e;
                    }
                    throw new CloudRuntimeException("Unable to add rule for the ip id=" + ipAddrId, e);
                }
            }
        });
    } finally {
        // release ip address if ipassoc was perfored
        if (performedIpAssoc) {
            //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
            IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
            _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), networkId);
        }
    }
}
Also used : Account(com.cloud.user.Account) Ip(com.cloud.utils.net.Ip) NicSecondaryIp(com.cloud.vm.NicSecondaryIp) NicSecondaryIp(com.cloud.vm.NicSecondaryIp) Nic(com.cloud.vm.Nic) TransactionStatus(com.cloud.utils.db.TransactionStatus) CallContext(org.apache.cloudstack.context.CallContext) 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) UserVm(com.cloud.uservm.UserVm) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) Network(com.cloud.network.Network) IPAddressVO(com.cloud.network.dao.IPAddressVO) IpAddress(com.cloud.network.IpAddress) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 44 with NetworkRuleConflictException

use of com.cloud.exception.NetworkRuleConflictException in project cloudstack by apache.

the class RulesManagerImpl method reservePorts.

@Override
@DB
public FirewallRuleVO[] reservePorts(final IpAddress ip, final String protocol, final FirewallRule.Purpose purpose, final boolean openFirewall, final Account caller, final int... ports) throws NetworkRuleConflictException {
    final FirewallRuleVO[] rules = new FirewallRuleVO[ports.length];
    Transaction.execute(new TransactionCallbackWithExceptionNoReturn<NetworkRuleConflictException>() {

        @Override
        public void doInTransactionWithoutResult(TransactionStatus status) throws NetworkRuleConflictException {
            for (int i = 0; i < ports.length; i++) {
                rules[i] = new FirewallRuleVO(null, ip.getId(), ports[i], protocol, ip.getAssociatedWithNetworkId(), ip.getAllocatedToAccountId(), ip.getAllocatedInDomainId(), purpose, null, null, null, null);
                rules[i] = _firewallDao.persist(rules[i]);
                if (openFirewall) {
                    _firewallMgr.createRuleForAllCidrs(ip.getId(), caller, ports[i], ports[i], protocol, null, null, rules[i].getId(), ip.getAssociatedWithNetworkId());
                }
            }
        }
    });
    boolean success = false;
    try {
        for (FirewallRuleVO newRule : rules) {
            _firewallMgr.detectRulesConflict(newRule);
        }
        success = true;
        return rules;
    } finally {
        if (!success) {
            Transaction.execute(new TransactionCallbackNoReturn() {

                @Override
                public void doInTransactionWithoutResult(TransactionStatus status) {
                    for (FirewallRuleVO newRule : rules) {
                        _firewallMgr.removeRule(newRule);
                    }
                }
            });
        }
    }
}
Also used : TransactionStatus(com.cloud.utils.db.TransactionStatus) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) NetworkRuleConflictException(com.cloud.exception.NetworkRuleConflictException) DB(com.cloud.utils.db.DB)

Aggregations

NetworkRuleConflictException (com.cloud.exception.NetworkRuleConflictException)44 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)19 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)18 ServerApiException (org.apache.cloudstack.api.ServerApiException)14 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)12 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)12 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)12 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)12 Network (com.cloud.network.Network)10 InsufficientAddressCapacityException (com.cloud.exception.InsufficientAddressCapacityException)9 IPAddressVO (com.cloud.network.dao.IPAddressVO)9 DB (com.cloud.utils.db.DB)8 TransactionStatus (com.cloud.utils.db.TransactionStatus)8 ServerApiException (com.cloud.api.ServerApiException)6 Account (com.cloud.user.Account)6 TransactionCallbackWithException (com.cloud.utils.db.TransactionCallbackWithException)6 SuccessResponse (org.apache.cloudstack.api.response.SuccessResponse)5 ActionEvent (com.cloud.event.ActionEvent)4 IpAddress (com.cloud.network.IpAddress)4 FirewallRule (com.cloud.network.rules.FirewallRule)4