Skip to content
Draft
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,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,64 @@
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.
*/
default boolean deleteSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException {
return 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 @@ -1034,6 +1034,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 = "4.23.0.0")
private String localVtiIp;

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

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

Comment on lines +147 to +158

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don’t think this will make the version claimed in the ‘since’ attributes here (i.e. “4.23.0.0”)

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