Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// 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;

public class Site2SiteVpnTunnelInterface {
private final String localIp;
private final String peerIp;
private final int prefixLength;

public Site2SiteVpnTunnelInterface(String localIp, String peerIp, int prefixLength) {
this.localIp = localIp;
this.peerIp = peerIp;
this.prefixLength = prefixLength;
}

public String getLocalIp() {
return localIp;
}

public String getPeerIp() {
return peerIp;
}

public int getPrefixLength() {
return prefixLength;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,66 @@
package com.cloud.network.element;

import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.IpAddress;
import com.cloud.network.Site2SiteCustomerGateway;
import com.cloud.network.Site2SiteVpnConnection;
import com.cloud.network.Site2SiteVpnGateway;
import com.cloud.network.Site2SiteVpnTunnelInterface;
import com.cloud.network.vpc.Vpc;
import com.cloud.utils.component.Adapter;

public interface Site2SiteVpnServiceProvider extends Adapter {
default void validateSite2SiteVpnCustomerGateway(Site2SiteCustomerGateway customerGateway) {
}

boolean startSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException;

boolean stopSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException;

/**
* Permanently removes a provider-side connection. This is distinct from stop: providers
* may disable a tunnel while retaining its profiles for an immediate reconnect, but deletion
* must remove all objects owned by the CloudStack connection.
* The default preserves legacy behavior for pending connections, which have not reached the
* virtual router. Providers that may own resources in that state must override this method.
*/
default boolean deleteSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException {
return conn.getState() == Site2SiteVpnConnection.State.Pending || stopSite2SiteVpn(conn);
}

/**
* Lets the provider supply the public IP the VPN gateway should terminate on, instead of the
* VPC source NAT IP. Providers that terminate VPN on an external gateway (e.g. NSX Tier-1)
* acquire and return a dedicated IP here; requestedIp, when not null, is the IP the caller
* asked for and must be validated by the provider. Returning null means the provider has no
* preference and the manager falls back to the default IP selection.
*/
default IpAddress acquireVpnGatewayIp(Vpc vpc, IpAddress requestedIp) {
return null;
}

/**
* Counterpart of {@link #acquireVpnGatewayIp(Vpc, IpAddress)}: invoked when a VPN gateway is
* deleted so the provider can tear down external VPN resources and release the gateway IP if
* it was acquired by the provider.
*/
default void releaseVpnGatewayIp(Site2SiteVpnGateway gateway) {
}

/**
* Identifies a gateway previously owned by this provider. This is used during teardown when
* an offering has been edited since the gateway was created and the current service map no
* longer advertises the provider.
*/
default boolean ownsVpnGateway(Site2SiteVpnGateway gateway) {
return false;
}

/**
* Returns provider-specific route-based tunnel addressing that the peer must configure.
* Policy-based providers return no tunnel-interface details.
*/
default Site2SiteVpnTunnelInterface getSite2SiteVpnTunnelInterface(Site2SiteVpnConnection connection) {
return null;
}
}
13 changes: 13 additions & 0 deletions api/src/main/java/com/cloud/network/nsx/NsxService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
// under the License.
package com.cloud.network.nsx;

import java.util.List;

import org.apache.cloudstack.framework.config.ConfigKey;

import com.cloud.network.IpAddress;
Expand All @@ -35,4 +37,15 @@ public interface NsxService {
boolean createVpcNetwork(Long zoneId, long accountId, long domainId, Long vpcId, String vpcName, boolean sourceNatEnabled);
boolean updateVpcSourceNatIp(Vpc vpc, IpAddress address);
String getSegmentId(long domainId, long accountId, long zoneId, Long vpcId, long networkId);

NsxVpnGatewayResult createVpnGateway(Vpc vpc, String localEndpointIp);
NsxVpnGatewayResult createVpnGateway(Vpc vpc, String localEndpointIp, boolean reconcileExistingService);
boolean deleteVpnGateway(Vpc vpc);
boolean createVpnConnection(Vpc vpc, long connectionId, String peerAddress, String psk,
String ikePolicy, String espPolicy, Long ikeLifetime, Long espLifetime,
boolean dpdEnabled, String ikeVersion, boolean passive, List<String> peerCidrs,
String vtiLocalIp, String vtiPeerIp, int vtiPrefixLength, String localEndpointIp);
boolean deleteVpnConnection(Vpc vpc, long connectionId);
boolean updateVpnConnectionState(Vpc vpc, long connectionId, boolean enabled);
String getVpnConnectionStatus(Vpc vpc, long connectionId);
}
36 changes: 36 additions & 0 deletions api/src/main/java/com/cloud/network/nsx/NsxVpnGatewayResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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.nsx;

public class NsxVpnGatewayResult {

private final boolean successful;
private final boolean endpointMayBeInUse;

public NsxVpnGatewayResult(boolean successful, boolean endpointMayBeInUse) {
this.successful = successful;
this.endpointMayBeInUse = endpointMayBeInUse;
}

public boolean isSuccessful() {
return successful;
}

public boolean isEndpointMayBeInUse() {
return endpointMayBeInUse;
}
}
3 changes: 3 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,9 @@ public class ApiConstants {
public static final String CUSTOMER = "customer";
public static final String S2S_VPN_GATEWAY_ID = "s2svpngatewayid";
public static final String S2S_CUSTOMER_GATEWAY_ID = "s2scustomergatewayid";
public static final String LOCAL_VTI_IP = "localvtiip";
public static final String PEER_VTI_IP = "peervtiip";
public static final String VTI_PREFIX_LENGTH = "vtiprefixlength";
public static final String IPSEC_PSK = "ipsecpsk";
public static final String GUEST_IP = "guestip";
public static final String REMOVED = "removed";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.cloud.event.EventTypes;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Site2SiteVpnConnection;
import com.cloud.network.Site2SiteVpnGateway;
import com.cloud.user.Account;

@APICommand(name = "deleteVpnConnection", description = "Delete site to site VPN connection", responseObject = SuccessResponse.class, entityType = {Site2SiteVpnConnection.class},
Expand Down Expand Up @@ -73,6 +74,21 @@ public String getEventType() {
return EventTypes.EVENT_S2S_VPN_CONNECTION_DELETE;
}

@Override
public String getSyncObjType() {
return BaseAsyncCmd.vpcSyncObject;
}

@Override
public Long getSyncObjId() {
Site2SiteVpnConnection connection = _entityMgr.findById(Site2SiteVpnConnection.class, id);
if (connection == null) {
return null;
}
Site2SiteVpnGateway gateway = _s2sVpnService.getVpnGateway(connection.getVpnGatewayId());
return gateway == null ? null : gateway.getVpcId();
}

@Override
public void execute() {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ public String getEventType() {
return EventTypes.EVENT_S2S_VPN_GATEWAY_DELETE;
}

@Override
public String getSyncObjType() {
return BaseAsyncCmd.vpcSyncObject;
}

@Override
public Long getSyncObjId() {
Site2SiteVpnGateway gateway = _entityMgr.findById(Site2SiteVpnGateway.class, id);
return gateway == null ? null : gateway.getVpcId();
}

@Override
public void execute() {
boolean result = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.cloud.event.EventTypes;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Site2SiteVpnConnection;
import com.cloud.network.Site2SiteVpnGateway;
import com.cloud.user.Account;

@APICommand(name = "resetVpnConnection", description = "Reset site to site VPN connection", responseObject = Site2SiteVpnConnectionResponse.class, entityType = {Site2SiteVpnConnection.class},
Expand Down Expand Up @@ -91,6 +92,21 @@ public String getEventType() {
return EventTypes.EVENT_S2S_VPN_CONNECTION_RESET;
}

@Override
public String getSyncObjType() {
return BaseAsyncCmd.vpcSyncObject;
}

@Override
public Long getSyncObjId() {
Site2SiteVpnConnection connection = _entityMgr.findById(Site2SiteVpnConnection.class, id);
if (connection == null) {
return null;
}
Site2SiteVpnGateway gateway = _s2sVpnService.getVpnGateway(connection.getVpnGatewayId());
return gateway == null ? null : gateway.getVpcId();
}

@Override
public void execute() {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,18 @@ public class Site2SiteVpnConnectionResponse extends BaseResponse implements Cont
@Param(description = "Which IKE Version to use, one of ike (autoselect), IKEv1, or IKEv2. Defaults to ike")
private String ikeVersion;

@SerializedName(ApiConstants.LOCAL_VTI_IP)
@Param(description = "The provider-side virtual tunnel interface IP address", since = "24.0")
private String localVtiIp;

@SerializedName(ApiConstants.PEER_VTI_IP)
@Param(description = "The peer-side virtual tunnel interface IP address", since = "24.0")
private String peerVtiIp;

@SerializedName(ApiConstants.VTI_PREFIX_LENGTH)
@Param(description = "The virtual tunnel interface network prefix length", since = "24.0")
private Integer vtiPrefixLength;

Comment thread
Dogface2k marked this conversation as resolved.
public void setId(String id) {
this.id = id;
}
Expand Down Expand Up @@ -220,6 +232,30 @@ public void setIkeVersion(String ikeVersion) {
this.ikeVersion = ikeVersion;
}

public String getLocalVtiIp() {
return localVtiIp;
}

public void setLocalVtiIp(String localVtiIp) {
this.localVtiIp = localVtiIp;
}

public String getPeerVtiIp() {
return peerVtiIp;
}

public void setPeerVtiIp(String peerVtiIp) {
this.peerVtiIp = peerVtiIp;
}

public Integer getVtiPrefixLength() {
return vtiPrefixLength;
}

public void setVtiPrefixLength(Integer vtiPrefixLength) {
this.vtiPrefixLength = vtiPrefixLength;
}

@Override
public void setAccountName(String accountName) {
this.accountName = accountName;
Expand Down
Loading
Loading