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);
}
});
}
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;
}
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;
}
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;
}
}
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);
}
}
}
Aggregations