Fixed RemoteAccessVpn apis

This commit is contained in:
alena 2010-12-29 20:55:23 -08:00
parent e6cdb1a93b
commit bd788b1827
16 changed files with 345 additions and 145 deletions

View File

@ -20,6 +20,7 @@ package com.cloud.api.commands;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseAsyncCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
@ -41,6 +42,9 @@ public class DeleteRemoteAccessVpnCmd extends BaseAsyncCmd {
@Parameter(name="publicip", type=CommandType.STRING, required=true, description="public ip address of the vpn server")
private String publicIp;
// unexposed parameter needed for events logging
@Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.LONG, expose=false)
private Long ownerId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -56,8 +60,10 @@ public class DeleteRemoteAccessVpnCmd extends BaseAsyncCmd {
@Override
public long getEntityOwnerId() {
RemoteAccessVpn vpn = _entityMgr.findById(RemoteAccessVpn.class, new Ip(publicIp));
return vpn.getAccountId();
if (ownerId == null) {
ownerId = _entityMgr.findById(RemoteAccessVpn.class, new Ip(publicIp)).getAccountId();
}
return ownerId;
}
@Override

View File

@ -80,10 +80,11 @@ public class ListRemoteAccessVpnsCmd extends BaseListCmd {
List<? extends RemoteAccessVpn> vpns = _ravService.searchForRemoteAccessVpns(this);
ListResponse<RemoteAccessVpnResponse> response = new ListResponse<RemoteAccessVpnResponse>();
List<RemoteAccessVpnResponse> vpnResponses = new ArrayList<RemoteAccessVpnResponse>();
for (RemoteAccessVpn vpn : vpns) {
vpnResponses.add(_responseGenerator.createRemoteAccessVpnResponse(vpn));
if (vpns != null && !vpns.isEmpty()) {
for (RemoteAccessVpn vpn : vpns) {
vpnResponses.add(_responseGenerator.createRemoteAccessVpnResponse(vpn));
}
}
response.setResponses(vpnResponses);
response.setResponseName(getCommandName());
this.setResponseObject(response);

View File

@ -39,6 +39,9 @@ public class RemoteAccessVpnResponse extends BaseResponse {
@SerializedName("domainname") @Param(description="the domain name of the account of the remote access vpn")
private String domainName;
@SerializedName("state") @Param(description="the state of the rule")
private String state;
public String getAccountName() {
return accountName;
}
@ -89,5 +92,11 @@ public class RemoteAccessVpnResponse extends BaseResponse {
return domainName;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}

View File

@ -30,7 +30,7 @@ public class ResourceUnavailableException extends Exception {
}
public ResourceUnavailableException(String msg, Class<?> scope, long resourceId, Throwable cause) {
super(new StringBuilder("Resource [").append(scope).append(":").append(resourceId).append("] is unreachable: ").append(msg).toString(), cause);
super(new StringBuilder("Resource [").append(scope.getSimpleName()).append(":").append(resourceId).append("] is unreachable: ").append(msg).toString(), cause);
_scope = scope;
_id = resourceId;
}

View File

@ -19,7 +19,7 @@
package com.cloud.agent.api.routing;
import java.util.List;
import com.cloud.network.VpnUserVO;
import com.cloud.network.VpnUser;
public class VpnUsersCfgCommand extends NetworkElementCommand {
@ -70,13 +70,13 @@ public class VpnUsersCfgCommand extends NetworkElementCommand {
}
public VpnUsersCfgCommand(List<VpnUserVO> addUsers, List<VpnUserVO> removeUsers) {
public VpnUsersCfgCommand(List<VpnUser> addUsers, List<VpnUser> removeUsers) {
userpwds = new UsernamePassword[addUsers.size() + removeUsers.size()];
int i = 0;
for (VpnUserVO vpnUser: removeUsers) {
for (VpnUser vpnUser: removeUsers) {
userpwds[i++] = new UsernamePassword(vpnUser.getUsername(), vpnUser.getPassword(), false);
}
for (VpnUserVO vpnUser: addUsers) {
for (VpnUser vpnUser: addUsers) {
userpwds[i++] = new UsernamePassword(vpnUser.getUsername(), vpnUser.getPassword(), true);
}
}

View File

@ -53,8 +53,9 @@ public class VpnUserVO implements VpnUser {
public VpnUserVO() { }
public VpnUserVO(long accountId, String userName, String password) {
public VpnUserVO(long accountId, long domainId, String userName, String password) {
this.accountId = accountId;
this.domainId = domainId;
this.username = userName;
this.password = password;
this.state = State.Add;

View File

@ -1288,9 +1288,12 @@ public class ApiResponseHelper implements ResponseGenerator {
if (accountTemp != null) {
vpnResponse.setAccountName(accountTemp.getAccountName());
vpnResponse.setDomainName(ApiDBUtils.findDomainById(accountTemp.getDomainId()).getName());
}
}
vpnResponse.setState(vpn.getState().toString());
vpnResponse.setObjectName("remoteaccessvpn");
return vpnResponse;
}

View File

@ -36,6 +36,8 @@ public interface FirewallRulesDao extends GenericDao<FirewallRuleVO, Long> {
boolean revoke(FirewallRuleVO rule);
boolean releasePorts(Ip ip, String protocol, FirewallRule.Purpose purpose, int[] ports);
List<FirewallRuleVO> listByIpAndPurpose(Ip ip, FirewallRule.Purpose purpose);
// public List<PortForwardingRuleVO> listIPForwarding(String publicIPAddress, boolean forwarding);
// public List<PortForwardingRuleVO> listIPForwarding(String publicIPAddress, String port, boolean forwarding);

View File

@ -80,6 +80,15 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
int results = remove(sc);
return results == ports.length;
}
@Override
public List<FirewallRuleVO> listByIpAndPurpose(Ip ip, FirewallRule.Purpose purpose) {
SearchCriteria<FirewallRuleVO> sc = ReleaseSearch.create();
sc.setParameters("ip", ip);
sc.setParameters("purpose", purpose);
return listBy(sc);
}
@Override
public List<FirewallRuleVO> listByIpAndNotRevoked(Ip ip) {

View File

@ -20,12 +20,14 @@ package com.cloud.network.dao;
import java.util.List;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.RemoteAccessVpnVO;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.net.Ip;
public interface RemoteAccessVpnDao extends GenericDao<RemoteAccessVpnVO, Ip> {
RemoteAccessVpnVO findByPublicIpAddress(String ipAddress);
RemoteAccessVpnVO findByPublicIpAddressAndState(String ipAddress, RemoteAccessVpn.State state);
RemoteAccessVpnVO findByAccountAndNetwork(Long accountId, Long zoneId);
List<RemoteAccessVpnVO> findByAccount(Long accountId);
}

View File

@ -24,6 +24,7 @@ import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.RemoteAccessVpnVO;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
@ -42,6 +43,7 @@ public class RemoteAccessVpnDaoImpl extends GenericDaoBase<RemoteAccessVpnVO, Ip
AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
AllFieldsSearch.and("ipAddress", AllFieldsSearch.entity().getServerAddress(), SearchCriteria.Op.EQ);
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ);
AllFieldsSearch.done();
}
@ -65,5 +67,13 @@ public class RemoteAccessVpnDaoImpl extends GenericDaoBase<RemoteAccessVpnVO, Ip
SearchCriteria<RemoteAccessVpnVO> sc = AllFieldsSearch.create();
sc.setParameters("accountId", accountId);
return listBy(sc);
}
@Override
public RemoteAccessVpnVO findByPublicIpAddressAndState(String ipAddress, RemoteAccessVpn.State state) {
SearchCriteria<RemoteAccessVpnVO> sc = AllFieldsSearch.create();
sc.setParameters("ipAddress", ipAddress);
sc.setParameters("state", state);
return findOneBy(sc);
}
}

View File

@ -39,6 +39,8 @@ import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.NetworkManager;
import com.cloud.network.PublicIpAddress;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.VpnUser;
import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.lb.LoadBalancingRule;
@ -47,6 +49,7 @@ import com.cloud.network.lb.LoadBalancingRulesManager;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRule.Purpose;
import com.cloud.network.vpn.RemoteAccessVpnElement;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.GuestIpType;
import com.cloud.offerings.dao.NetworkOfferingDao;
@ -66,7 +69,7 @@ import com.cloud.vm.dao.UserVmDao;
@Local(value=NetworkElement.class)
public class VirtualRouterElement extends AdapterBase implements NetworkElement {
public class VirtualRouterElement extends AdapterBase implements NetworkElement, RemoteAccessVpnElement {
private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class);
private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
@ -169,6 +172,42 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement
}
return false;
}
@Override
public String[] applyVpnUsers(RemoteAccessVpn vpn, List<? extends VpnUser> users) throws ResourceUnavailableException{
Network network = _networkConfigDao.findById(vpn.getNetworkId());
DataCenter dc = _dataCenterDao.findById(network.getDataCenterId());
if (canHandle(network.getGuestType(),dc)) {
return _routerMgr.applyVpnUsers(network, users);
} else {
s_logger.debug("Element " + this.getName() + " doesn't handle applyVpnUsers command");
return null;
}
}
@Override
public boolean start(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException {
DataCenter dc = _dataCenterDao.findById(network.getDataCenterId());
if (canHandle(network.getGuestType(),dc)) {
return _routerMgr.startRemoteAccessVpn(network, vpn);
} else {
s_logger.debug("Element " + this.getName() + " doesn't handle createVpn command");
return false;
}
}
@Override
public boolean stop(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException {
DataCenter dc = _dataCenterDao.findById(network.getDataCenterId());
if (canHandle(network.getGuestType(),dc)) {
return _routerMgr.deleteRemoteAccessVpn(network, vpn);
} else {
s_logger.debug("Element " + this.getName() + " doesn't handle removeVpn command");
return false;
}
}
@Override
public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException {
@ -224,5 +263,5 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement
return capabilities;
}
}

View File

@ -30,7 +30,9 @@ import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network;
import com.cloud.network.PublicIpAddress;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.RemoteAccessVpnVO;
import com.cloud.network.VpnUser;
import com.cloud.network.VpnUserVO;
import com.cloud.network.rules.FirewallRule;
import com.cloud.user.Account;
@ -97,11 +99,11 @@ public interface VirtualNetworkApplianceManager extends Manager {
VirtualRouter deployDhcp(Network guestNetwork, DeployDestination dest, Account owner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException;
RemoteAccessVpnVO startRemoteAccessVpn(RemoteAccessVpnVO vpnVO) throws ResourceUnavailableException;
boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException;
boolean addRemoveVpnUsers(RemoteAccessVpnVO vpnVO, List<VpnUserVO> addUsers, List<VpnUserVO> removeUsers);
boolean deleteRemoteAccessVpn(RemoteAccessVpnVO vpnVO);
boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException;
VirtualRouter addVirtualMachineIntoNetwork(Network config, NicProfile nic, VirtualMachineProfile<UserVm> vm, DeployDestination dest, ReservationContext context, Boolean startDhcp) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException;
@ -110,4 +112,6 @@ public interface VirtualNetworkApplianceManager extends Manager {
boolean applyLBRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException;
boolean applyPortForwardingRules(Network network, List<? extends FirewallRule> rules) throws AgentUnavailableException;
String[] applyVpnUsers(Network network, List<? extends VpnUser> users) throws ResourceUnavailableException;
}

View File

@ -52,9 +52,11 @@ import com.cloud.agent.api.routing.DhcpEntryCommand;
import com.cloud.agent.api.routing.IPAssocCommand;
import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
import com.cloud.agent.api.routing.SavePasswordCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.agent.api.routing.VpnUsersCfgCommand;
import com.cloud.agent.api.to.IpAddressTO;
import com.cloud.agent.api.to.LoadBalancerTO;
import com.cloud.agent.manager.Commands;
@ -109,9 +111,11 @@ import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.IsolationType;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.PublicIpAddress;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.RemoteAccessVpnVO;
import com.cloud.network.SshKeysDistriMonitor;
import com.cloud.network.VirtualNetworkApplianceService;
import com.cloud.network.VpnUser;
import com.cloud.network.VpnUserVO;
import com.cloud.network.addr.PublicIp;
import com.cloud.network.dao.FirewallRulesDao;
@ -587,20 +591,20 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
* }
*/
private boolean resendVpnServerData(final DomainRouterVO router) {
RemoteAccessVpnVO vpnVO = _remoteAccessVpnDao.findByAccountAndNetwork(router.getAccountId(), router.getDataCenterId());
if (vpnVO != null) {
try {
vpnVO = startRemoteAccessVpn(vpnVO);
} catch (ResourceUnavailableException e) {
s_logger.warn("Unable to resend vpn server information to restarted router: " + router.getInstanceName());
return false;
}
return (vpnVO != null);
}
return true;
}
// private boolean resendVpnServerData(final DomainRouterVO router) {
// RemoteAccessVpnVO vpnVO = _remoteAccessVpnDao.findByAccountAndNetwork(router.getAccountId(), router.getDataCenterId());
//
// if (vpnVO != null) {
// try {
// vpnVO = startRemoteAccessVpn(vpnVO);
// } catch (ResourceUnavailableException e) {
// s_logger.warn("Unable to resend vpn server information to restarted router: " + router.getInstanceName());
// return false;
// }
// return (vpnVO != null);
// }
// return true;
// }
@Override
public boolean stopRouter(final long routerId) {
@ -1559,81 +1563,86 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
}
@Override
public RemoteAccessVpnVO startRemoteAccessVpn(RemoteAccessVpnVO vpnVO) throws ResourceUnavailableException {
return null;
// DomainRouterVO router = getRouter(vpnVO.getAccountId(), vpnVO.getZoneId());
// if (router == null) {
// s_logger.warn("Failed to start remote access VPN: no router found for account and zone");
// return null;
// }
// if (router.getState() != State.Running && router.getState() != State.Starting) {
// s_logger.warn("Failed to start remote access VPN: router not in running state");
// return null;
// }
// List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpnVO.getAccountId());
// VpnUsersCfgCommand addUsersCmd = new VpnUsersCfgCommand(router.getPrivateIpAddress(), vpnUsers, new ArrayList<VpnUserVO>());
// RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(true, router.getPrivateIpAddress(), vpnVO.getServerAddress(),
// vpnVO.getLocalIp(), vpnVO.getIpRange(), vpnVO.getIpsecPresharedKey());
// Commands cmds = new Commands(OnError.Stop);
// cmds.addCommand("users", addUsersCmd);
// cmds.addCommand("startVpn", startVpnCmd);
// try {
// _agentMgr.send(router.getHostId(), cmds);
// } catch (AgentUnavailableException e) {
// s_logger.debug("Failed to start remote access VPN: ", e);
// return null;
// } catch (OperationTimedoutException e) {
// s_logger.debug("Failed to start remote access VPN: ", e);
// return null;
// }
// Answer answer = cmds.getAnswer("users");
// if (!answer.getResult()) {
// s_logger.error("Unable to start vpn: unable add users to vpn in zone " + vpnVO.getZoneId() + " for account " + vpnVO.getAccountId()
// + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails());
// throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + vpnVO.getZoneId() + " for account "
// + vpnVO.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class,
// vpnVO.getZoneId());
// }
// answer = cmds.getAnswer("startVpn");
// if (!answer.getResult()) {
// s_logger.error("Unable to start vpn in zone " + vpnVO.getZoneId() + " for account " + vpnVO.getAccountId() + " on domR: "
// + router.getInstanceName() + " due to " + answer.getDetails());
// throw new ResourceUnavailableException("Unable to start vpn in zone " + vpnVO.getZoneId() + " for account " + vpnVO.getAccountId()
// + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, vpnVO.getZoneId());
// }
// return vpnVO;
public boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException {
DomainRouterVO router = _routerDao.findByNetworkConfiguration(network.getId());
if (router == null) {
s_logger.warn("Failed to start remote access VPN: no router found for account and zone");
throw new ResourceUnavailableException("Unable to apply lb rules", DataCenter.class, network.getDataCenterId());
}
if (router.getState() != State.Running && router.getState() != State.Starting) {
s_logger.warn("Failed to start remote access VPN: router not in running state");
throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId());
}
List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
List<VpnUser> addUsers = new ArrayList<VpnUser>();
List<VpnUser> removeUsers = new ArrayList<VpnUser>();
for (VpnUser user: vpnUsers) {
if (user.getState() == VpnUser.State.Add) {
addUsers.add(user);
} else if (user.getState() == VpnUser.State.Revoke) {
removeUsers.add(user);
}
}
VpnUsersCfgCommand addUsersCmd = new VpnUsersCfgCommand(addUsers, removeUsers);
addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, router.getPrivateIpAddress());
addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(true, vpn.getServerAddress().addr(),
vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey());
startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, router.getPrivateIpAddress());
startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
Commands cmds = new Commands(OnError.Stop);
cmds.addCommand("users", addUsersCmd);
cmds.addCommand("startVpn", startVpnCmd);
//return sendCommandsToRouter(router, cmds);
try {
_agentMgr.send(router.getHostId(), cmds);
} catch (OperationTimedoutException e) {
s_logger.debug("Failed to start remote access VPN: ", e);
throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e);
}
Answer answer = cmds.getAnswer("users");
if (!answer.getResult()) {
s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId()
+ " on domR: " + router.getInstanceName() + " due to " + answer.getDetails());
throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + router.getDataCenterId() + " for account "
+ vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class,
router.getDataCenterId());
}
answer = cmds.getAnswer("startVpn");
if (!answer.getResult()) {
s_logger.error("Unable to start vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
+ router.getInstanceName() + " due to " + answer.getDetails());
throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId()
+ " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterId());
}
return true;
}
@Override
public boolean deleteRemoteAccessVpn(RemoteAccessVpnVO vpnVO) {
return false;
// DomainRouterVO router = getRouter(vpnVO.getAccountId(), vpnVO.getZoneId());
// if (router == null) {
// s_logger.warn("Failed to delete remote access VPN: no router found for account and zone");
// return false;
// }
// if (router.getState() != State.Running) {
// s_logger.warn("Failed to delete remote access VPN: router not in running state");
// return false;
// }
// try {
// Answer answer = _agentMgr.send(
// router.getHostId(),
// new RemoteAccessVpnCfgCommand(false, router.getPrivateIpAddress(), vpnVO.getServerAddress(), vpnVO.getLocalIp(), vpnVO
// .getIpRange(), vpnVO.getIpsecPresharedKey()));
// if (answer != null && answer.getResult()) {
// return true;
// } else {
// s_logger.debug("Failed to delete remote access VPN: " + answer.getDetails());
// return false;
// }
// } catch (AgentUnavailableException e) {
// s_logger.debug("Failed to delete remote access VPN: ", e);
// return false;
// } catch (OperationTimedoutException e) {
// s_logger.debug("Failed to delete remote access VPN: ", e);
// return false;
// }
public boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException{
DomainRouterVO router = getRouter(vpn.getAccountId(), network.getDataCenterId());
if (router == null) {
s_logger.warn("Failed to delete remote access VPN: no router found for account and zone");
throw new ResourceUnavailableException("Unable to apply lb rules", DataCenter.class, network.getDataCenterId());
}
if (router.getState() != State.Running) {
s_logger.warn("Failed to delete remote access VPN: router not in running state");
throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId());
}
Commands cmds = new Commands(OnError.Continue);
RemoteAccessVpnCfgCommand removeVpnCmd = new RemoteAccessVpnCfgCommand(false, vpn.getServerAddress().addr(), vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey());
removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, router.getPrivateIpAddress());
removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
cmds.addCommand(removeVpnCmd);
return sendCommandsToRouter(router, cmds);
}
public DomainRouterVO start(long routerId, User user, Account caller) throws StorageUnavailableException, InsufficientCapacityException,
@ -1743,6 +1752,49 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
// return false;
// }
}
@Override
public String[] applyVpnUsers(Network network, List<? extends VpnUser> users) throws ResourceUnavailableException{
DomainRouterVO router = _routerDao.findByNetworkConfiguration(network.getId());
if (router == null) {
s_logger.warn("Failed to add/remove VPN users: no router found for account and zone");
throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + network.getId(), DataCenter.class, network.getDataCenterId());
}
if (router.getState() != State.Running) {
s_logger.warn("Failed to add/remove VPN users: router not in running state");
throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId());
}
Commands cmds = new Commands(OnError.Continue);
List<VpnUser> addUsers = new ArrayList<VpnUser>();
List<VpnUser> removeUsers = new ArrayList<VpnUser>();
for (VpnUser user: users) {
if (user.getState() == VpnUser.State.Add || user.getState() == VpnUser.State.Active) {
addUsers.add(user);
} else if (user.getState() == VpnUser.State.Revoke) {
removeUsers.add(user);
}
}
VpnUsersCfgCommand cmd = new VpnUsersCfgCommand(addUsers, removeUsers);
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, router.getPrivateIpAddress());
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
cmds.addCommand(cmd);
//Currently we receive just one answer from the agent. In the future we have to parse individual answers and set results accordingly
boolean agentResult = sendCommandsToRouter(router, cmds);;
String[] result = new String[users.size()];
for (int i = 0; i < result.length; i++) {
if (agentResult) {
result[i] = null;
} else {
result[i] = String.valueOf(agentResult);
}
}
return result;
}
@Override
public DomainRouterVO findById(long id) {
@ -1985,4 +2037,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
// TODO Auto-generated method stub
return null;
}
}

View File

@ -38,6 +38,7 @@ import com.cloud.event.EventVO;
import com.cloud.exception.AccountLimitException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network;
import com.cloud.network.NetworkManager;
@ -47,11 +48,13 @@ import com.cloud.network.RemoteAccessVpnVO;
import com.cloud.network.VpnUser;
import com.cloud.network.VpnUser.State;
import com.cloud.network.VpnUserVO;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.RemoteAccessVpnDao;
import com.cloud.network.dao.VpnUserDao;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.rules.FirewallRule.Purpose;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.network.rules.RulesManager;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
@ -76,26 +79,18 @@ import com.cloud.utils.net.NetUtils;
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;
@Inject FirewallRulesDao _rulesDao;
int _userLimit;
int _pskLength;
String _clientIpRange;
@ -119,13 +114,22 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
}
RemoteAccessVpnVO vpnVO = _remoteAccessVpnDao.findByPublicIpAddress(publicIp.toString());
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");
}
// TODO: assumes one virtual network / domr per account per zone
vpnVO = _remoteAccessVpnDao.findByAccountAndNetwork(ipAddr.getAllocatedToAccountId(), ipAddr.getAssociatedWithNetworkId());
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");
}
@ -211,6 +215,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
+ owner.getAccountName() + " in " + ip, startEventId);
vpn.setState(RemoteAccessVpn.State.Removed);
_remoteAccessVpnDao.update(vpn.getServerAddress(), vpn);
List<? extends RemoteAccessVpnElement> elements = _networkMgr.getRemoteAccessVpnElements();
@ -229,17 +234,31 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
} 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();
try {
txn.start();
_remoteAccessVpnDao.remove(ip);
} else {
//Cleanup corresponding ports
List<FirewallRuleVO> ports = _rulesDao.listByIpAndPurpose(ip, Purpose.Vpn);
if (ports != null) {
for (FirewallRuleVO port : ports) {
_rulesDao.remove(port.getId());
s_logger.debug("Successfully removed firewall rule with ip " + port.getSourceIpAddress() + " and port " + port.getSourcePortStart() + " as a part of vpn cleanup");
}
}
EventUtils.saveEvent(userId, owner.getId(), EventTypes.EVENT_REMOTE_ACCESS_VPN_DESTROY, "Deleted Remote Access VPN for account: "
+ owner.getAccountName());
txn.commit();
} catch (Exception ex) {
txn.rollback();
s_logger.warn("Unable to release the three vpn ports from the firewall rules", ex);
}
txn.commit();
//
// 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();
}
}
}
@ -270,7 +289,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
throw new AccountLimitException("Cannot add more than " + _userLimit + " remote access vpn users");
}
VpnUser user = _vpnUsersDao.persist(new VpnUserVO(vpnOwnerId, username, password));
VpnUser user = _vpnUsersDao.persist(new VpnUserVO(vpnOwnerId, owner.getDomainId(), username, password));
EventUtils.saveEvent(callerId, owner.getId(), EventTypes.EVENT_VPN_USER_ADD, "Added a VPN user for account: " + owner.getAccountName()
+ " username= " + username);
txn.commit();
@ -354,7 +373,15 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
List<RemoteAccessVpnVO> vpns = _remoteAccessVpnDao.findByAccount(vpnOwnerId);
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);
}
}
List<? extends RemoteAccessVpnElement> elements = _networkMgr.getRemoteAccessVpnElements();
boolean success = true;
@ -365,17 +392,18 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
for (RemoteAccessVpnVO vpn : vpns) {
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;
if (results != null) {
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 {
finals[i] = false;
success = false;
}
}
} catch (ResourceUnavailableException e) {
@ -390,14 +418,16 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
}
for (int i = 0; i < finals.length; i++) {
if (finals[i]) {
VpnUserVO user = users.get(i);
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 {
s_logger.warn("Failed to apply vpn for user " + user.getUsername() + ", accountId=" + user.getAccountId());
}
}
@ -411,6 +441,31 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
Long domainId = cmd.getDomainId();
Long accountId = null;
String username = cmd.getUsername();
//Verify account information
if (account.getType() == Account.ACCOUNT_TYPE_ADMIN) {
if (domainId != null) {
if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) {
throw new PermissionDeniedException("Invalid domain id (" + domainId + ") given, unable to list virtual machines.");
}
if (accountName != null) {
account = _accountDao.findActiveAccount(accountName, domainId);
if (account == null) {
throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
}
accountId = account.getId();
}
}
if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
DomainVO domain = _domainDao.findById(account.getDomainId());
if (domain != null) {
domainId = domain.getId();
}
}
} else {
accountId = account.getId();
}
Filter searchFilter = new Filter(VpnUserVO.class, "username", true, cmd.getStartIndex(), cmd.getPageSizeVal());
@ -420,6 +475,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("username", sb.entity().getUsername(), SearchCriteria.Op.EQ);
sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
if ((accountId == null) && (domainId != null)) {
// if accountId isn't specified, we can do a domain match for the
@ -430,6 +486,9 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
}
SearchCriteria<VpnUserVO> sc = sb.create();
//list only active users
sc.setParameters("state", State.Active);
if (id != null) {
sc.setParameters("id", id);
@ -489,6 +548,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
SearchCriteria<RemoteAccessVpnVO> sc = VpnSearch.create();
sc.setParameters("accountId", owner.getId());
sc.setParameters("state", RemoteAccessVpn.State.Running);
DomainVO domain = _domainDao.findById(domainId);
sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");

View File

@ -99,7 +99,6 @@ import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeployDestination;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.Event;
import com.cloud.event.EventTypes;
import com.cloud.event.EventUtils;
import com.cloud.event.EventVO;