remote access vpn from management server side is done

This commit is contained in:
Alex Huang 2010-12-29 11:36:30 -08:00
parent cc428c14c7
commit a10ce22f99
13 changed files with 245 additions and 181 deletions

View File

@ -28,7 +28,6 @@ import com.cloud.api.ServerApiException;
import com.cloud.api.response.RemoteAccessVpnResponse;
import com.cloud.domain.Domain;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.RemoteAccessVpn;
@ -162,9 +161,6 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd {
} catch (ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
}
}
}

View File

@ -25,6 +25,7 @@ import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.response.SuccessResponse;
import com.cloud.event.EventTypes;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.utils.net.Ip;
@ -70,8 +71,8 @@ public class DeleteRemoteAccessVpnCmd extends BaseAsyncCmd {
}
@Override
public void execute(){
_ravService.destroyRemoteAccessVpn(new Ip(publicIp));
public void execute() throws ResourceUnavailableException {
_ravService.destroyRemoteAccessVpn(new Ip(publicIp), getStartEventId());
}
}

View File

@ -113,11 +113,14 @@ public class RemoveVpnUserCmd extends BaseAsyncCmd {
public void execute(){
Account owner = getValidOwner(accountName, domainId);
boolean result = _ravService.removeVpnUser(owner.getId(), userName);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
if (!result) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to remove vpn user");
}
if (!_ravService.applyVpnUsers(owner.getId())) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to apply vpn user removal");
}
SuccessResponse response = new SuccessResponse(getCommandName());
setResponseObject(response);
}
}

View File

@ -21,9 +21,16 @@ import com.cloud.acl.ControlledEntity;
import com.cloud.utils.net.Ip;
public interface RemoteAccessVpn extends ControlledEntity {
enum State {
Added,
Running,
Removed
}
Ip getServerAddress();
String getIpRange();
String getIpsecPresharedKey();
String getLocalIp();
long getNetworkId();
State getState();
}

View File

@ -19,11 +19,16 @@ package com.cloud.network.vpn;
import java.util.List;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.VpnUser;
import com.cloud.utils.component.Adapter;
public interface RemoteAccessVpnElement extends Adapter {
String[] applyVpnUsers(RemoteAccessVpn vpn, List<? extends VpnUser> users);
String[] applyVpnUsers(RemoteAccessVpn vpn, List<? extends VpnUser> users) throws ResourceUnavailableException;
boolean start(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException;
boolean stop(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException;
}

View File

@ -22,7 +22,6 @@ import java.util.List;
import com.cloud.api.commands.ListRemoteAccessVpnsCmd;
import com.cloud.api.commands.ListVpnUsersCmd;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.RemoteAccessVpn;
@ -32,9 +31,8 @@ import com.cloud.utils.net.Ip;
public interface RemoteAccessVpnService {
RemoteAccessVpn createRemoteAccessVpn(Ip vpnServerAddress, String ipRange) throws NetworkRuleConflictException;
void destroyRemoteAccessVpn(Ip vpnServerAddress);
List<? extends RemoteAccessVpn> listRemoteAccessVpns(long vpnOwnerId, Ip publicIp);
RemoteAccessVpn startRemoteAccessVpn(Ip vpnServerAddress) throws ConcurrentOperationException, ResourceUnavailableException;
void destroyRemoteAccessVpn(Ip vpnServerAddress, long startEventId) throws ResourceUnavailableException;
RemoteAccessVpn startRemoteAccessVpn(Ip vpnServerAddress) throws ResourceUnavailableException;
VpnUser addVpnUser(long vpnOwnerId, String userName, String password);
boolean removeVpnUser(long vpnOwnerId, String userName);

View File

@ -51,7 +51,10 @@ public class RemoteAccessVpnVO implements RemoteAccessVpn {
private String ipRange;
@Column(name="ipsec_psk")
private String ipsecPresharedKey;
private String ipsecPresharedKey;
@Column(name="state")
private State state;
public RemoteAccessVpnVO() { }
@ -62,7 +65,17 @@ public class RemoteAccessVpnVO implements RemoteAccessVpn {
this.ipsecPresharedKey = presharedKey;
this.localIp = localIp;
this.domainId = domainId;
this.networkId = networkId;
this.networkId = networkId;
this.state = State.Added;
}
@Override
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
@Override

View File

@ -20,6 +20,7 @@ package com.cloud.network.dao;
import java.util.List;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.net.Ip;
@ -33,6 +34,8 @@ public interface FirewallRulesDao extends GenericDao<FirewallRuleVO, Long> {
boolean setStateToAdd(FirewallRuleVO rule);
boolean revoke(FirewallRuleVO rule);
boolean releasePorts(Ip ip, String protocol, FirewallRule.Purpose purpose, int[] ports);
// public List<PortForwardingRuleVO> listIPForwarding(String publicIPAddress, boolean forwarding);
// public List<PortForwardingRuleVO> listIPForwarding(String publicIPAddress, String port, boolean forwarding);

View File

@ -24,6 +24,7 @@ import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRule.State;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.utils.db.DB;
@ -39,6 +40,7 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
protected final SearchBuilder<FirewallRuleVO> AllFieldsSearch;
protected final SearchBuilder<FirewallRuleVO> IpNotRevokedSearch;
protected final SearchBuilder<FirewallRuleVO> ReleaseSearch;
protected FirewallRulesDaoImpl() {
super();
@ -54,12 +56,29 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
AllFieldsSearch.done();
IpNotRevokedSearch = createSearchBuilder();
IpNotRevokedSearch.and("ip", IpNotRevokedSearch.entity().getSourceIpAddress(), Op.EQ);
IpNotRevokedSearch.and("state", IpNotRevokedSearch.entity().getState(), Op.NEQ);
IpNotRevokedSearch.done();
ReleaseSearch = createSearchBuilder();
ReleaseSearch.and("protocol", ReleaseSearch.entity().getProtocol(), Op.EQ);
ReleaseSearch.and("ip", ReleaseSearch.entity().getSourceIpAddress(), Op.EQ);
ReleaseSearch.and("purpose", ReleaseSearch.entity().getPurpose(), Op.EQ);
ReleaseSearch.and("ports", ReleaseSearch.entity().getSourcePortStart(), Op.IN);
ReleaseSearch.done();
}
@Override
public boolean releasePorts(Ip ip, String protocol, FirewallRule.Purpose purpose, int[] ports) {
SearchCriteria<FirewallRuleVO> sc = ReleaseSearch.create();
sc.setParameters("protocol", protocol);
sc.setParameters("ip", ip);
sc.setParameters("purpose", purpose);
sc.setParameters("ports", ports);
int results = remove(sc);
return results == ports.length;
}
@Override

View File

@ -74,4 +74,5 @@ public interface RulesManager extends RulesService {
boolean revokePortForwardingRule(long vmId);
FirewallRule[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, int... ports) throws NetworkRuleConflictException;
boolean releasePorts(Ip ip, String protocol, FirewallRule.Purpose purpose, int... ports);
}

View File

@ -456,6 +456,11 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
return null;
}
@Override
public boolean releasePorts(Ip ip, String protocol, FirewallRule.Purpose purpose, int... ports) {
return _firewallDao.releasePorts(ip, protocol, purpose, ports);
}
@Override @DB
public FirewallRuleVO[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, int... ports) throws NetworkRuleConflictException {
FirewallRuleVO[] rules = new FirewallRuleVO[ports.length];

View File

@ -26,7 +26,6 @@ import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.api.commands.DeleteRemoteAccessVpnCmd;
import com.cloud.api.commands.ListRemoteAccessVpnsCmd;
import com.cloud.api.commands.ListVpnUsersCmd;
import com.cloud.configuration.Config;
@ -35,8 +34,8 @@ import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.EventTypes;
import com.cloud.event.EventUtils;
import com.cloud.event.EventVO;
import com.cloud.exception.AccountLimitException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceUnavailableException;
@ -73,21 +72,30 @@ import com.cloud.utils.db.Transaction;
import com.cloud.utils.net.Ip;
import com.cloud.utils.net.NetUtils;
@Local(value=RemoteAccessVpnService.class)
@Local(value = RemoteAccessVpnService.class)
public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manager {
private final static Logger s_logger = Logger.getLogger(RemoteAccessVpnManagerImpl.class);
String _name;
@Inject AccountDao _accountDao;
@Inject VpnUserDao _vpnUsersDao;
@Inject RemoteAccessVpnDao _remoteAccessVpnDao;
@Inject IPAddressDao _ipAddressDao;
@Inject VirtualNetworkApplianceManager _routerMgr;
@Inject AccountManager _accountMgr;
@Inject NetworkManager _networkMgr;
@Inject RulesManager _rulesMgr;
@Inject DomainDao _domainDao;
@Inject
AccountDao _accountDao;
@Inject
VpnUserDao _vpnUsersDao;
@Inject
RemoteAccessVpnDao _remoteAccessVpnDao;
@Inject
IPAddressDao _ipAddressDao;
@Inject
VirtualNetworkApplianceManager _routerMgr;
@Inject
AccountManager _accountMgr;
@Inject
NetworkManager _networkMgr;
@Inject
RulesManager _rulesMgr;
@Inject
DomainDao _domainDao;
int _userLimit;
int _pskLength;
String _clientIpRange;
@ -97,19 +105,19 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
public RemoteAccessVpn createRemoteAccessVpn(Ip publicIp, String ipRange) throws NetworkRuleConflictException {
UserContext ctx = UserContext.current();
Account caller = ctx.getCaller();
// make sure ip address exists
PublicIpAddress ipAddr = _networkMgr.getPublicIpAddress(publicIp);
if (ipAddr == null) {
throw new InvalidParameterValueException("Unable to create remote access vpn, invalid public IP address " + publicIp);
}
_accountMgr.checkAccess(caller, ipAddr);
if (!ipAddr.readyToUse() || ipAddr.getAssociatedWithNetworkId() == null) {
throw new InvalidParameterValueException("The Ip address is not ready to be used yet: " + ipAddr.getAddress());
}
RemoteAccessVpnVO vpnVO = _remoteAccessVpnDao.findByPublicIpAddress(publicIp.toString());
if (vpnVO != null) {
throw new InvalidParameterValueException("A Remote Access VPN already exists for this public Ip address");
@ -120,7 +128,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
if (vpnVO != null) {
throw new InvalidParameterValueException("A Remote Access VPN already exists for this account");
}
if (ipRange == null) {
ipRange = _clientIpRange;
}
@ -134,12 +142,12 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
if (!NetUtils.validIpRange(range[0], range[1])) {
throw new InvalidParameterValueException("Invalid ip range " + ipRange);
}
Network network = _networkMgr.getNetwork(ipAddr.getAssociatedWithNetworkId());
Pair<String, Integer> cidr = NetUtils.getCidr(network.getCidr());
//FIXME: This check won't work for the case where the guest ip range changes depending on the vlan allocated.
// 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] + "-"
@ -152,10 +160,11 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
String newIpRange = NetUtils.long2Ip(++startIp) + "-" + range[1];
String sharedSecret = PasswordGenerator.generatePresharedKey(_pskLength);
_rulesMgr.reservePorts(ipAddr, NetUtils.UDP_PROTO, Purpose.Vpn, NetUtils.VPN_PORT, NetUtils.VPN_L2TP_PORT, NetUtils.VPN_NATT_PORT);
vpnVO = new RemoteAccessVpnVO(ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId(), ipAddr.getAssociatedWithNetworkId(), publicIp, range[0], newIpRange, sharedSecret);
vpnVO = new RemoteAccessVpnVO(ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId(), ipAddr.getAssociatedWithNetworkId(),
publicIp, range[0], newIpRange, sharedSecret);
return _remoteAccessVpnDao.persist(vpnVO);
}
private void validateRemoteAccessVpnConfiguration() throws ConfigurationException {
String ipRange = _clientIpRange;
if (ipRange == null) {
@ -170,26 +179,69 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
return;
}
String [] range = ipRange.split("-");
String[] range = ipRange.split("-");
if (range.length != 2) {
throw new ConfigurationException("Remote Access VPN: Invalid ip range " + ipRange);
}
if (!NetUtils.isValidIp(range[0]) || !NetUtils.isValidIp(range[1])){
if (!NetUtils.isValidIp(range[0]) || !NetUtils.isValidIp(range[1])) {
throw new ConfigurationException("Remote Access VPN: Invalid ip in range specification " + ipRange);
}
if (!NetUtils.validIpRange(range[0], range[1])){
if (!NetUtils.validIpRange(range[0], range[1])) {
throw new ConfigurationException("Remote Access VPN: Invalid ip range " + ipRange);
}
}
@Override
public void destroyRemoteAccessVpn(Ip ip) {
}
@Override
public List<? extends RemoteAccessVpn> listRemoteAccessVpns(long vpnOwnerId, Ip publicIp) {
// TODO Auto-generated method stub
return null;
@Override @DB
public void destroyRemoteAccessVpn(Ip ip, long startEventId) throws ResourceUnavailableException {
long userId = UserContext.current().getCallerUserId();
Account caller = UserContext.current().getCaller();
RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findById(ip);
if (vpn == null) {
s_logger.debug("vpn does not exists " + ip);
return;
}
_accountMgr.checkAccess(caller, vpn);
Account owner = _accountDao.findById(vpn.getAccountId());
Network network = _networkMgr.getNetwork(vpn.getNetworkId());
EventUtils.saveStartedEvent(userId, owner.getId(), EventTypes.EVENT_REMOTE_ACCESS_VPN_DESTROY, "Deleting Remote Access VPN for account: "
+ owner.getAccountName() + " in " + ip, startEventId);
vpn.setState(RemoteAccessVpn.State.Removed);
List<? extends RemoteAccessVpnElement> elements = _networkMgr.getRemoteAccessVpnElements();
boolean success = false;
try {
for (RemoteAccessVpnElement element : elements) {
if (element.stop(network, vpn)) {
success = true;
break;
}
}
} finally {
if (!success) {
EventUtils.saveEvent(userId, owner.getId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_REMOTE_ACCESS_VPN_DESTROY,
"Unable to delete Remote Access VPN ", owner.getAccountName());
} else {
Transaction txn = Transaction.currentTxn();
txn.start();
_remoteAccessVpnDao.remove(ip);
if (!_rulesMgr.releasePorts(ip, NetUtils.UDP_PROTO, Purpose.Vpn, NetUtils.VPN_L2TP_PORT, NetUtils.VPN_NATT_PORT, NetUtils.VPN_PORT)) {
s_logger.warn("Unable to release the three vpn ports from the firewall rules");
txn.rollback();
} else {
EventUtils.saveEvent(userId, owner.getId(), EventTypes.EVENT_REMOTE_ACCESS_VPN_DESTROY, "Deleted Remote Access VPN for account: "
+ owner.getAccountName());
}
txn.commit();
}
}
}
@Override
@ -199,7 +251,8 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
Account caller = UserContext.current().getCaller();
if (!username.matches("^[a-zA-Z0-9][a-zA-Z0-9@._-]{2,63}$")) {
throw new InvalidParameterValueException("Username has to be begin with an alphabet have 3-64 characters including alphabets, numbers and the set '@.-_'");
throw new InvalidParameterValueException(
"Username has to be begin with an alphabet have 3-64 characters including alphabets, numbers and the set '@.-_'");
}
if (!password.matches("^[a-zA-Z0-9][a-zA-Z0-9@#+=._-]{2,31}$")) {
throw new InvalidParameterValueException("Password has to be 3-32 characters including alphabets, numbers and the set '@#+=.-_'");
@ -211,23 +264,24 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
throw new InvalidParameterValueException("Unable to add vpn user: Another operation active");
}
_accountMgr.checkAccess(caller, owner);
long userCount = _vpnUsersDao.getVpnUserCount(owner.getId());
if (userCount >= _userLimit) {
throw new AccountLimitException("Cannot add more than " + _userLimit + " remote access vpn users");
}
VpnUser user = _vpnUsersDao.persist(new VpnUserVO(vpnOwnerId, username, password));
EventUtils.saveEvent(callerId, owner.getId(), EventTypes.EVENT_VPN_USER_ADD, "Added a VPN user for account: " + owner.getAccountName() + " username= " + username);
EventUtils.saveEvent(callerId, owner.getId(), EventTypes.EVENT_VPN_USER_ADD, "Added a VPN user for account: " + owner.getAccountName()
+ " username= " + username);
txn.commit();
return user;
}
}
@Override
public boolean removeVpnUser(long vpnOwnerId, String username) {
long callerId = UserContext.current().getCallerUserId();
Account caller = UserContext.current().getCaller();
VpnUserVO user = _vpnUsersDao.findByAccountAndUsername(vpnOwnerId, username);
if (user == null) {
throw new InvalidParameterValueException("Could not find vpn user " + username);
@ -247,99 +301,50 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
_accountMgr.checkAccess(caller, owner);
return _vpnUsersDao.listByAccount(vpnOwnerId);
}
@Override
@DB
public RemoteAccessVpnVO startRemoteAccessVpn(Ip vpnServerAddress) throws ConcurrentOperationException, ResourceUnavailableException {
// long userId = UserContext.current().getCallerUserId();
// Account caller = UserContext.current().getCaller();
//
// RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findById(vpnId);
// if (vpn == null) {
// throw new InvalidParameterValueException("Unable to find your vpn: " + vpnId);
// }
//
// _accountMgr.checkAccess(caller, vpn);
//
//
// Account account = getAccountForApiCommand(cmd.getAccountName(), cmd.getDomainId());
// EventUtils.saveStartedEvent(userId, account.getId(), EventTypes.EVENT_REMOTE_ACCESS_VPN_CREATE, "Creating a Remote Access VPN for account: " + account.getAccountName() + " in zone " + cmd.getZoneId(), cmd.getStartEventId());
// String publicIp = vpn.getServerAddress();
// Long vpnId = vpn.getId();
// Transaction txn = Transaction.currentTxn();
// txn.start();
// boolean locked = false;
// boolean created = false;
// try {
// IPAddressVO ipAddr = _ipAddressDao.acquireInLockTable(publicIp);
// if (ipAddr == null) {
// throw new ConcurrentOperationException("Another operation active, unable to create vpn");
// }
// locked = true;
//
// vpn = _routerMgr.startRemoteAccessVpn(vpn);
// created = (vpn != null);
//
// return vpn;
// } finally {
// if (created) {
// EventUtils.saveEvent(userId, account.getId(), EventTypes.EVENT_REMOTE_ACCESS_VPN_CREATE, "Created a Remote Access VPN for account: " + account.getAccountName() + " in zone " + cmd.getZoneId());
// } else {
// EventUtils.saveEvent(userId, account.getId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_REMOTE_ACCESS_VPN_CREATE, "Unable to create Remote Access VPN ", account.getAccountName() + " in zone " + cmd.getZoneId());
// _remoteAccessVpnDao.remove(vpnId);
// }
// txn.commit();
// if (locked) {
// _ipAddressDao.releaseFromLockTable(publicIp);
// }
// }
return null;
public RemoteAccessVpnVO startRemoteAccessVpn(Ip vpnId) throws ResourceUnavailableException {
long userId = UserContext.current().getCallerUserId();
Account caller = UserContext.current().getCaller();
RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findById(vpnId);
if (vpn == null) {
throw new InvalidParameterValueException("Unable to find your vpn: " + vpnId);
}
_accountMgr.checkAccess(caller, vpn);
Account owner = _accountDao.findById(vpn.getAccountId());
Network network = _networkMgr.getNetwork(vpn.getNetworkId());
EventUtils.saveStartedEvent(userId, owner.getId(), EventTypes.EVENT_REMOTE_ACCESS_VPN_CREATE, "Creating a Remote Access VPN for account: "
+ owner.getAccountName() + " in zone ");
List<? extends RemoteAccessVpnElement> elements = _networkMgr.getRemoteAccessVpnElements();
boolean started = false;
try {
for (RemoteAccessVpnElement element : elements) {
if (element.start(network, vpn)) {
started = true;
break;
}
}
return vpn;
} finally {
if (started) {
EventUtils.saveEvent(userId, owner.getId(), EventTypes.EVENT_REMOTE_ACCESS_VPN_CREATE, "Created a Remote Access VPN for account: "
+ owner.getAccountName());
vpn.setState(RemoteAccessVpn.State.Running);
_remoteAccessVpnDao.update(vpn.getServerAddress(), vpn);
} else {
EventUtils.saveEvent(userId, owner.getId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_REMOTE_ACCESS_VPN_CREATE,
"Unable to create Remote Access VPN ", owner.getAccountName());
}
}
}
@DB
public boolean destroyRemoteAccessVpn(DeleteRemoteAccessVpnCmd cmd) throws ConcurrentOperationException {
// Long userId = UserContext.current().getUserId();
// Account account = getAccountForApiCommand(cmd.getAccountName(), cmd.getDomainId());
// //TODO: assumes one virtual network / domr per account per zone
// RemoteAccessVpnVO vpnVO = _remoteAccessVpnDao.findByAccountAndZone(account.getId(), cmd.getZoneId());
// if (vpnVO == null) {
// throw new InvalidParameterValueException("No VPN found for account " + account.getAccountName() + " in zone " + cmd.getZoneId());
// }
// EventUtils.saveStartedEvent(userId, account.getId(), EventTypes.EVENT_REMOTE_ACCESS_VPN_DESTROY, "Deleting Remote Access VPN for account: " + account.getAccountName() + " in zone " + cmd.getZoneId(), cmd.getStartEventId());
// String publicIp = vpnVO.getVpnServerAddress();
// Long vpnId = vpnVO.getId();
// Transaction txn = Transaction.currentTxn();
// txn.start();
// boolean locked = false;
// boolean deleted = false;
// try {
// IPAddressVO ipAddr = _ipAddressDao.acquireInLockTable(publicIp);
// if (ipAddr == null) {
// throw new ConcurrentOperationException("Another operation active, unable to create vpn");
// }
// locked = true;
//
// deleted = _routerMgr.deleteRemoteAccessVpn(vpnVO);
// return deleted;
// } finally {
// if (deleted) {
// _remoteAccessVpnDao.remove(vpnId);
// _rulesDao.deleteIPForwardingByPublicIpAndPort(publicIp, NetUtils.VPN_PORT);
// _rulesDao.deleteIPForwardingByPublicIpAndPort(publicIp, NetUtils.VPN_NATT_PORT);
// _rulesDao.deleteIPForwardingByPublicIpAndPort(publicIp, NetUtils.VPN_L2TP_PORT);
// EventUtils.saveEvent(userId, account.getId(), EventTypes.EVENT_REMOTE_ACCESS_VPN_DESTROY, "Deleted Remote Access VPN for account: " + account.getAccountName() + " in zone " + cmd.getZoneId());
// } else {
// EventUtils.saveEvent(userId, account.getId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_REMOTE_ACCESS_VPN_DESTROY, "Unable to delete Remote Access VPN ", account.getAccountName() + " in zone " + cmd.getZoneId());
// }
// txn.commit();
// if (locked) {
// _ipAddressDao.releaseFromLockTable(publicIp);
// }
// }
return false; // FIXME
}
@DB @Override
@Override
public boolean applyVpnUsers(long vpnOwnerId) {
Account caller = UserContext.current().getCaller();
Account owner = _accountDao.findById(vpnOwnerId);
@ -347,33 +352,43 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
s_logger.debug("Applying vpn users for " + owner);
List<RemoteAccessVpnVO> vpns = _remoteAccessVpnDao.findByAccount(vpnOwnerId);
List<VpnUserVO> users = _vpnUsersDao.listByAccount(vpnOwnerId);
List<RemoteAccessVpnElement> elements = null;
List<? extends RemoteAccessVpnElement> elements = _networkMgr.getRemoteAccessVpnElements();
boolean success = true;
boolean[] finals = new boolean[users.size()];
for (RemoteAccessVpnElement element : elements) {
s_logger.debug("Applying vpn access to " + element.getName());
for (RemoteAccessVpnVO vpn : vpns) {
String[] results = element.applyVpnUsers(vpn, users);
for (int i = 0; i < results.length; i++) {
s_logger.debug("VPN User " + users.get(i) + (results[i] == null ? " is set on " : (" couldn't be set due to " + results[i]) + " on ") + vpn);
if (results[i] == null) {
if (!finals[i]) {
finals[i] = true;
try {
String[] results = element.applyVpnUsers(vpn, users);
for (int i = 0; i < results.length; i++) {
s_logger.debug("VPN User " + users.get(i)
+ (results[i] == null ? " is set on " : (" couldn't be set due to " + results[i]) + " on ") + vpn);
if (results[i] == null) {
if (!finals[i]) {
finals[i] = true;
}
} else {
finals[i] = false;
success = false;
}
} else {
}
} catch (ResourceUnavailableException e) {
s_logger.warn("Unable to apply vpn users ", e);
success= false;
for (int i = 0; i < finals.length; i++) {
finals[i] = false;
success = false;
}
}
}
}
for (int i = 0; i < finals.length; i++) {
if (finals[i]) {
VpnUserVO user = users.get(i);
@ -385,10 +400,10 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
}
}
}
return success;
}
@Override
public List<VpnUserVO> searchForVpnUsers(ListVpnUsersCmd cmd) {
Account account = UserContext.current().getCaller();
@ -400,7 +415,6 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
Filter searchFilter = new Filter(VpnUserVO.class, "username", true, cmd.getStartIndex(), cmd.getPageSizeVal());
Object id = cmd.getId();
SearchBuilder<VpnUserVO> sb = _vpnUsersDao.createSearchBuilder();
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
@ -408,14 +422,15 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
if ((accountId == null) && (domainId != null)) {
// if accountId isn't specified, we can do a domain match for the admin case
// if accountId isn't specified, we can do a domain match for the
// admin case
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
}
SearchCriteria<VpnUserVO> sc = sb.create();
if (id != null) {
sc.setParameters("id", id);
}
@ -423,7 +438,6 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
if (username != null) {
sc.setParameters("username", username);
}
if (accountId != null) {
sc.setParameters("accountId", accountId);
@ -434,7 +448,6 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
return _vpnUsersDao.search(sc, searchFilter);
}
@Override
public List<RemoteAccessVpnVO> searchForRemoteAccessVpns(ListRemoteAccessVpnsCmd cmd) {
@ -442,7 +455,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
Account caller = UserContext.current().getCaller();
String accountName = cmd.getAccountName();
Long domainId = cmd.getDomainId();
Ip ipAddress = cmd.getPublicIp();
if (ipAddress != null) {
PublicIpAddress publicIp = _networkMgr.getPublicIpAddress(ipAddress);
@ -451,11 +464,12 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
} else {
Long ipAddrAcctId = publicIp.getAllocatedToAccountId();
if (ipAddrAcctId == null) {
throw new InvalidParameterValueException("Unable to list remote access vpns, IP address " + ipAddress + " is not associated with an account.");
throw new InvalidParameterValueException("Unable to list remote access vpns, IP address " + ipAddress
+ " is not associated with an account.");
}
}
_accountMgr.checkAccess(caller, publicIp);
List<RemoteAccessVpnVO> vpns = new ArrayList<RemoteAccessVpnVO>(1);
vpns.add(_remoteAccessVpnDao.findById(ipAddress));
return vpns;
@ -469,9 +483,8 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
Filter searchFilter = new Filter(RemoteAccessVpnVO.class, "serverAddress", true, cmd.getStartIndex(), cmd.getPageSizeVal());
SearchCriteria<RemoteAccessVpnVO> sc = VpnSearch.create();
sc.setParameters("accountId", owner.getId());
DomainVO domain = _domainDao.findById(domainId);
sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
@ -479,21 +492,20 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
return _remoteAccessVpnDao.search(sc, searchFilter);
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_name = name;
ComponentLocator locator = ComponentLocator.getCurrentLocator();
ConfigurationDao configDao = locator.getDao(ConfigurationDao.class);
Map<String, String> configs = configDao.getConfiguration(params);
_userLimit = NumbersUtil.parseInt(configs.get(Config.RemoteAccessVpnUserLimit.key()), 8);
_clientIpRange = configs.get(Config.RemoteAccessVpnClientIpRange.key());
_pskLength = NumbersUtil.parseInt(configs.get(Config.RemoteAccessVpnPskLength.key()), 24);
validateRemoteAccessVpnConfiguration();
VpnSearch = _remoteAccessVpnDao.createSearchBuilder();

View File

@ -1055,6 +1055,7 @@ CREATE TABLE `cloud`.`remote_access_vpn` (
`local_ip` varchar(15) NOT NULL,
`ip_range` varchar(32) NOT NULL,
`ipsec_psk` varchar(256) NOT NULL,
`state` char(32) NOT NULL,
PRIMARY KEY (`vpn_server_addr`),
CONSTRAINT `fk_remote_access_vpn__account_id` FOREIGN KEY `fk_remote_access_vpn__account_id`(`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_remote_access_vpn__domain_id` FOREIGN KEY `fk_remote_access_vpn__domain_id`(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE,