Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.cloud.exception;

public class VPNProviderNotFoundException extends ManagementServerException {
public VPNProviderNotFoundException(String message) {
super(message);
}
}
11 changes: 10 additions & 1 deletion api/src/main/java/com/cloud/network/RemoteAccessVpn.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,17 @@ enum State {
Added, Running, Removed
}

long getServerAddressId();
String getProviderName();

Long getServerAddressId();

String getIpRange();

// TODO: DELETE THIS, it is only for ipsec

/**
* @deprecated
*/
String getIpsecPresharedKey();

String getLocalIp();
Expand All @@ -40,6 +47,8 @@ enum State {

State getState();

Integer getPort();

@Override
boolean isDisplay();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.cloud.network.vpn;

import java.util.List;
import java.util.Map;

import org.apache.cloudstack.api.command.user.vpn.ListRemoteAccessVpnsCmd;
import org.apache.cloudstack.api.command.user.vpn.ListVpnUsersCmd;
Expand All @@ -31,11 +32,18 @@
public interface RemoteAccessVpnService {
static final String RemoteAccessVpnClientIpRangeCK = "remote.access.vpn.client.iprange";

RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall, Boolean forDisplay) throws NetworkRuleConflictException;
String GetName();

// TODO: add method to export all available specific fields with
// - name
// - required flags
// - description

RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall, Boolean forDisplay, Integer listenPort, Map<String, String> implementationData) throws NetworkRuleConflictException;

boolean destroyRemoteAccessVpnForIp(long ipId, Account caller, boolean forceCleanup) throws ResourceUnavailableException;

RemoteAccessVpn startRemoteAccessVpn(long vpnServerAddressId, boolean openFirewall) throws ResourceUnavailableException;
RemoteAccessVpn startRemoteAccessVpn(long vpnServerId, boolean openFirewall) throws ResourceUnavailableException;

VpnUser addVpnUser(long vpnOwnerId, String userName, String password);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.vpn;

import com.cloud.exception.VPNProviderNotFoundException;

import java.util.Map;

public interface RemoteAccessVpnServiceManager {
Map<String, RemoteAccessVpnService> GetAvailableProviders();
RemoteAccessVpnService GetProvider(String key) throws VPNProviderNotFoundException;
}
3 changes: 3 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/BaseCmd.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import javax.inject.Inject;

import com.cloud.network.vpn.RemoteAccessVpnServiceManager;
import org.apache.cloudstack.acl.ProjectRoleService;
import org.apache.cloudstack.acl.RoleService;
import org.apache.cloudstack.acl.RoleType;
Expand Down Expand Up @@ -160,6 +161,8 @@ public static enum CommandType {
@Inject
public RemoteAccessVpnService _ravService;
@Inject
public RemoteAccessVpnServiceManager _ravpmService;
@Inject
public ProjectService _projectService;
@Inject
public FirewallService _firewallService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
// under the License.
package org.apache.cloudstack.api.command.user.vpn;

import com.cloud.exception.VPNProviderNotFoundException;
import com.cloud.network.vpn.RemoteAccessVpnService;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.log4j.Logger;

Expand All @@ -38,6 +40,10 @@
import com.cloud.network.IpAddress;
import com.cloud.network.RemoteAccessVpn;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@APICommand(name = "createRemoteAccessVpn", description = "Creates a l2tp/ipsec remote access vpn", responseObject = RemoteAccessVpnResponse.class, entityType = {RemoteAccessVpn.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd {
Expand All @@ -56,7 +62,6 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd {

@Parameter(name = "iprange",
type = CommandType.STRING,
required = false,
description = "the range of ip addresses to allocate to vpn clients. The first ip in the range will be taken by the vpn server")
private String ipRange;

Expand All @@ -79,6 +84,25 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the vpn to the end user or not", since = "4.4", authorized = {RoleType.Admin})
private Boolean display;

@Parameter(name = "listenport",
type = CommandType.INTEGER,
description = "Port on which the VPN server will be listening")
private Integer listenPort;

@Parameter(name = "provider",
type = CommandType.STRING,
description = "Name of the protocol used for the VPN")
private String providerName;

@Parameter(name = "implementationdata",
type = CommandType.MAP,
description = "protocol-specific data for the VPN")
private Map<String, String> implementationData;


private RemoteAccessVpnService vpnProtocol;


/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand All @@ -105,11 +129,19 @@ public void setIpRange(String ipRange) {
}

public Boolean getOpenFirewall() {
if (openFirewall != null) {
return openFirewall;
} else {
return true;
}
return Objects.requireNonNullElse(openFirewall, true);
}

public Integer getListenPort() {
return listenPort;
}

public String getProviderName() {
return providerName;
}

public Map<String, String> getImplementationData() {
return implementationData;
}

/////////////////////////////////////////////////////
Expand Down Expand Up @@ -140,29 +172,43 @@ public String getEventType() {
@Override
public void create() {
try {
RemoteAccessVpn vpn = _ravService.createRemoteAccessVpn(publicIpId, ipRange, getOpenFirewall(), isDisplay());

this.vpnProtocol = _ravpmService.GetProvider(getProviderName());

RemoteAccessVpn vpn = vpnProtocol.createRemoteAccessVpn(publicIpId, ipRange, getOpenFirewall(), isDisplay(), getListenPort(), getImplementationData());
if (vpn != null) {
setEntityId(vpn.getId());
setEntityUuid(vpn.getUuid());

} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create remote access vpn");
}

} catch (NetworkRuleConflictException e) {

s_logger.info("Network rule conflict: " + e.getMessage());
s_logger.trace("Network Rule Conflict: ", e);
throw new ServerApiException(ApiErrorCode.NETWORK_RULE_CONFLICT_ERROR, e.getMessage());
} catch (VPNProviderNotFoundException e) {

s_logger.info(e.getMessage());
s_logger.trace(e);
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
}
}

@Override
public void execute() {
try {
RemoteAccessVpn result = _ravService.startRemoteAccessVpn(publicIpId, getOpenFirewall());

RemoteAccessVpn result = this.vpnProtocol.startRemoteAccessVpn(getEntityId(), getOpenFirewall());
if (result != null) {

RemoteAccessVpnResponse response = _responseGenerator.createRemoteAccessVpnResponse(result);
response.setResponseName(getCommandName());
setResponseObject(response);
} else {

throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create remote access vpn");
}
} catch (ResourceUnavailableException ex) {
Expand Down Expand Up @@ -191,10 +237,7 @@ private IpAddress getIp() {

@Override
public boolean isDisplay() {
if(display == null)
return true;
else
return display;
return Objects.requireNonNullElse(display, true);
}

@Override
Expand Down
5 changes: 5 additions & 0 deletions client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,11 @@
<artifactId>cloud-utils</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-remote-access-vpn-l2tp</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1907,7 +1907,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) {

//do not remove vpn service for vpc networks.
if (services.contains(Service.Vpn.getName()) && network.getVpcId() == null) {
RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByAccountAndNetwork(network.getAccountId(), networkId);
RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByAccountNetworkAndPort(network.getAccountId(), networkId);
try {
_vpnMgr.destroyRemoteAccessVpnForIp(vpn.getServerAddressId(), caller, true);
} catch (ResourceUnavailableException ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
import com.cloud.utils.db.GenericDao;

public interface RemoteAccessVpnDao extends GenericDao<RemoteAccessVpnVO, Long> {
RemoteAccessVpnVO findByPublicIpAddress(long ipAddressId);
RemoteAccessVpnVO findByPublicIpAddressAndPort(long ipAddressId, Integer port);

RemoteAccessVpnVO findByPublicIpAddressAndState(long ipAddressId, RemoteAccessVpn.State state);
RemoteAccessVpnVO findByPublicIpAddressStateAndPort(long ipAddressId, RemoteAccessVpn.State state, Integer port);

RemoteAccessVpnVO findByAccountAndNetwork(Long accountId, Long networkId);
RemoteAccessVpnVO findByAccountNetworkAndPort(Long accountId, Long networkId, Integer port);

RemoteAccessVpnVO findByAccountAndVpc(Long accountId, Long vpcId);
RemoteAccessVpnVO findByAccountVpcAndPort(Long accountId, Long vpcId, Integer port);

List<RemoteAccessVpnVO> findByAccount(Long accountId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,41 +44,45 @@ protected RemoteAccessVpnDaoImpl() {
}

@Override
public RemoteAccessVpnVO findByPublicIpAddress(long ipAddressId) {
public RemoteAccessVpnVO findByPublicIpAddressAndPort(long ipAddressId, Integer port) {
SearchCriteria<RemoteAccessVpnVO> sc = AllFieldsSearch.create();
sc.setParameters("ipAddress", ipAddressId);
sc.setParameters("port", port);
return findOneBy(sc);
}

@Override
public RemoteAccessVpnVO findByAccountAndNetwork(Long accountId, Long networkId) {
public RemoteAccessVpnVO findByAccountNetworkAndPort(Long accountId, Long networkId, Integer port) {
SearchCriteria<RemoteAccessVpnVO> sc = AllFieldsSearch.create();
sc.setParameters("accountId", accountId);
sc.setParameters("networkId", networkId);
sc.setParameters("port", port);
return findOneBy(sc);
}

@Override
public RemoteAccessVpnVO findByAccountAndVpc(Long accountId, Long vpcId) {
public RemoteAccessVpnVO findByAccountVpcAndPort(Long accountId, Long vpcId, Integer port) {
SearchCriteria<RemoteAccessVpnVO> sc = AllFieldsSearch.create();
sc.setParameters("accountId", accountId);
sc.setParameters("vpcId", vpcId);
sc.setParameters("port", port);
return findOneBy(sc);
}

@Override
public List<RemoteAccessVpnVO> findByAccount(Long accountId) {
public RemoteAccessVpnVO findByPublicIpAddressStateAndPort(long ipAddressId, RemoteAccessVpn.State state, Integer port) {
SearchCriteria<RemoteAccessVpnVO> sc = AllFieldsSearch.create();
sc.setParameters("accountId", accountId);
return listBy(sc);
sc.setParameters("ipAddress", ipAddressId);
sc.setParameters("state", state);
sc.setParameters("port", port);
return findOneBy(sc);
}

@Override
public RemoteAccessVpnVO findByPublicIpAddressAndState(long ipAddressId, RemoteAccessVpn.State state) {
public List<RemoteAccessVpnVO> findByAccount(Long accountId) {
SearchCriteria<RemoteAccessVpnVO> sc = AllFieldsSearch.create();
sc.setParameters("ipAddress", ipAddressId);
sc.setParameters("state", state);
return findOneBy(sc);
sc.setParameters("accountId", accountId);
return listBy(sc);
}

@Override
Expand Down
Loading
Loading