mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
Fixed RemoteAccessVpn apis
This commit is contained in:
parent
e6cdb1a93b
commit
bd788b1827
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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() + "%");
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user