CLOUDSTACK-1828 Source Nat on private gateway feature

This commit is contained in:
Jayapal 2013-05-02 15:24:21 +05:30 committed by Murali Reddy
parent 101d89c3a3
commit 1f1467974f
23 changed files with 136 additions and 41 deletions

View File

@ -138,6 +138,7 @@ public interface NetworkService {
ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException;
/**
*
* @param networkName
* @param displayText
* @param physicalNetworkId
@ -148,13 +149,14 @@ public interface NetworkService {
* @param netmask
* @param networkOwnerId
* @param vpcId TODO
* @param sourceNat
* @return
* @throws InsufficientCapacityException
* @throws ConcurrentOperationException
* @throws ResourceAllocationException
*/
Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan,
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId)
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat)
throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException;
/* Requests an IP address for the guest nic */

View File

@ -44,5 +44,6 @@ public interface PrivateIp {
String getMacAddress();
long getNetworkId();
boolean getSourceNat();
}

View File

@ -77,4 +77,8 @@ public interface VpcGateway extends Identity, ControlledEntity, InternalIdentity
* @return
*/
State getState();
/**
* @return
*/
boolean getSourceNat();
}

View File

@ -163,6 +163,7 @@ public interface VpcService {
/**
* Persists VPC private gateway in the Database.
*
*
* @param vpcId TODO
* @param physicalNetworkId
* @param vlan
@ -170,13 +171,14 @@ public interface VpcService {
* @param gateway
* @param netmask
* @param gatewayOwnerId
* @param isSourceNat
* @return
* @throws InsufficientCapacityException
* @throws ConcurrentOperationException
* @throws ResourceAllocationException
*/
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress,
String gateway, String netmask, long gatewayOwnerId) throws ResourceAllocationException,
String gateway, String netmask, long gatewayOwnerId, Boolean isSourceNat) throws ResourceAllocationException,
ConcurrentOperationException, InsufficientCapacityException;
/**

View File

@ -69,6 +69,11 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
required=true, description="the VPC network belongs to")
private Long vpcId;
@Parameter(name=ApiConstants.SOURCE_NAT_SUPPORTED, type=CommandType.BOOLEAN, required=false,
description="source NAT supported value. Default value false. If 'true' source NAT is enabled on the private gateway" +
" 'false': sourcenat is not supported")
private Boolean isSourceNat;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -97,6 +102,13 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
return vpcId;
}
public Boolean getIsSourceNat () {
if (isSourceNat == null) {
return false;
}
return true;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@ -111,7 +123,7 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
PrivateGateway result = null;
try {
result = _vpcService.createVpcPrivateGateway(getVpcId(), getPhysicalNetworkId(),
getVlan(), getStartIp(), getGateway(), getNetmask(), getEntityOwnerId());
getVlan(), getStartIp(), getGateway(), getNetmask(), getEntityOwnerId(), getIsSourceNat());
} catch (InsufficientCapacityException ex){
s_logger.info(ex);
s_logger.trace(ex);

View File

@ -76,6 +76,10 @@ public class PrivateGatewayResponse extends BaseResponse implements ControlledEn
private String state;
@SerializedName(ApiConstants.SOURCE_NAT_SUPPORTED) @Param(description = "Souce Nat enable status")
private Boolean sourceNat;
@Override
public String getObjectId() {
return this.id;
@ -145,5 +149,11 @@ public class PrivateGatewayResponse extends BaseResponse implements ControlledEn
public void setState(String state) {
this.state = state;
}
public void setSourceNat(Boolean sourceNat) {
this.sourceNat = sourceNat;
}
}

View File

@ -863,13 +863,16 @@ public class VirtualRoutingResource implements Manager {
}
public void assignVpcIpToRouter(final String routerIP, final boolean add, final String pubIP,
final String nicname, final String gateway, final String netmask, final String subnet) throws InternalErrorException {
final String nicname, final String gateway, final String netmask, final String subnet, boolean sourceNat) throws InternalErrorException {
String args = "";
String snatArgs = "";
if (add) {
args += " -A ";
snatArgs += " -A ";
} else {
args += " -D ";
snatArgs += " -D ";
}
args += " -l ";
@ -887,6 +890,16 @@ public class VirtualRoutingResource implements Manager {
if (result != null) {
throw new InternalErrorException("KVM plugin \"vpc_ipassoc\" failed:"+result);
}
if (sourceNat) {
snatArgs += " -l " + pubIP;
snatArgs += " -c " + nicname;
result = routerProxy("vpc_privateGateway.sh", routerIP, snatArgs);
if (result != null) {
throw new InternalErrorException("KVM plugin \"vpc_privateGateway\" failed:"+result);
}
}
}
private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) {

View File

@ -91,7 +91,7 @@ fi
if [ "$Dflag" == "1" ]
then
remove_sat $publicIp
remove_snat $publicIp
unlock_exit $? $lock $locked
fi

View File

@ -1756,7 +1756,7 @@ ServerResource {
String netmask = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask()));
String subnet = NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask());
_virtRouterResource.assignVpcIpToRouter(routerIP, ip.isAdd(), ip.getPublicIp(),
nicName, ip.getVlanGateway(), netmask, subnet);
nicName, ip.getVlanGateway(), netmask, subnet, ip.isSourceNat());
results[i++] = ip.getPublicIp() + " - success";
}

View File

@ -1441,10 +1441,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
String args = "";
String snatArgs = "";
if (ip.isAdd()) {
args += " -A ";
snatArgs += " -A ";
} else {
args += " -D ";
snatArgs += " -D ";
}
args += " -l ";
@ -1468,6 +1472,21 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if (!result.first()) {
throw new InternalErrorException("Unable to assign public IP address");
}
if (ip.isSourceNat()) {
snatArgs += " -l ";
snatArgs += ip.getPublicIp();
snatArgs += " -c ";
snatArgs += "eth" + ethDeviceNum;
Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null,
"/opt/cloud/bin/vpc_privateGateway.sh " + args);
if (!result.first()) {
throw new InternalErrorException("Unable to assign public IP address");
}
}
}
protected void assignPublicIpAddress(VirtualMachineMO vmMo, final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP,

View File

@ -2217,11 +2217,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
String args = "vpc_ipassoc.sh " + routerIp;
String snatArgs = "vpc_privateGateway.sh " + routerIp;
if (ip.isAdd()) {
args += " -A ";
snatArgs += " -A ";
} else {
args += " -D ";
snatArgs+= " -D ";
}
args += " -l ";
@ -2244,6 +2247,17 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
if (result == null || result.isEmpty()) {
throw new InternalErrorException("Xen plugin \"vpc_ipassoc\" failed.");
}
if (ip.isSourceNat()) {
snatArgs += " -l " + ip.getPublicIp();
snatArgs += " -c " + "eth" + correctVif.getDevice(conn);
result = callHostPlugin(conn, "vmops", "routerProxy", "args", snatArgs);
if (result == null || result.isEmpty()) {
throw new InternalErrorException("Xen plugin \"vcp_privateGateway\" failed.");
}
}
} catch (Exception e) {
String msg = "Unable to assign public IP address due to " + e.toString();
s_logger.warn(msg, e);

View File

@ -3120,6 +3120,7 @@ public class ApiResponseHelper implements ResponseGenerator {
populateAccount(response, result.getAccountId());
populateDomain(response, result.getDomainId());
response.setState(result.getState().toString());
response.setSourceNat(result.getSourceNat());
response.setObjectName("privategateway");

View File

@ -3308,8 +3308,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
@Override @DB
public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId,
String vlan, String startIp, String endIp, String gateway, String netmask, long networkOwnerId, Long vpcId)
public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId,
String vlan, String startIp, String endIp, String gateway, String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat)
throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
Account owner = _accountMgr.getAccount(networkOwnerId);
@ -3377,7 +3377,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
Long nextMac = mac + 1;
dc.setMacAddress(nextMac);
privateIp = new PrivateIpVO(startIp, privateNetwork.getId(), nextMac, vpcId);
privateIp = new PrivateIpVO(startIp, privateNetwork.getId(), nextMac, vpcId, sourceNat);
_privateIpDao.persist(privateIp);
_dcDao.update(dc.getId(), dc);

View File

@ -1178,8 +1178,8 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
for (final PrivateIpAddress ipAddr : ipAddrList) {
Network network = _networkModel.getNetwork(ipAddr.getNetworkId());
IpAddressTO ip = new IpAddressTO(Account.ACCOUNT_ID_SYSTEM, ipAddr.getIpAddress(), add, false,
false, ipAddr.getVlanTag(), ipAddr.getGateway(), ipAddr.getNetmask(), ipAddr.getMacAddress(),
IpAddressTO ip = new IpAddressTO(Account.ACCOUNT_ID_SYSTEM, ipAddr.getIpAddress(), add, false,
ipAddr.getSourceNat(), ipAddr.getVlanTag(), ipAddr.getGateway(), ipAddr.getNetmask(), ipAddr.getMacAddress(),
null, false);
ip.setTrafficType(network.getTrafficType());

View File

@ -100,4 +100,9 @@ public class PrivateGatewayProfile implements PrivateGateway {
public State getState() {
return vpcGateway.getState();
}
@Override
public boolean getSourceNat() {
return vpcGateway.getSourceNat();
}
}

View File

@ -25,6 +25,7 @@ public class PrivateIpAddress implements PrivateIp{
String ipAddress;
String macAddress;
long networkId;
boolean sourceNat;
/**
* @param privateIp
@ -42,6 +43,7 @@ public class PrivateIpAddress implements PrivateIp{
this.netmask = netmask;
this.macAddress = macAddress;
this.networkId = privateIp.getNetworkId();
this.sourceNat = privateIp.getSourceNat();
}
@Override
@ -73,4 +75,9 @@ public class PrivateIpAddress implements PrivateIp{
public long getNetworkId() {
return networkId;
}
@Override
public boolean getSourceNat() {
return sourceNat;
}
}

View File

@ -54,15 +54,19 @@ public class PrivateIpVO implements InternalIdentity {
@Column(name="vpc_id")
private Long vpcId;
@Column(name="source_nat")
private boolean sourceNat;
public PrivateIpVO() {
}
}
public PrivateIpVO(String ipAddress, long networkId, long macAddress, long vpcId) {
public PrivateIpVO(String ipAddress, long networkId, long macAddress, long vpcId, boolean sourceNat) {
this.ipAddress = ipAddress;
this.networkId = networkId;
this.macAddress = macAddress;
this.vpcId = vpcId;
this.sourceNat = sourceNat;
}
public void setTakenAt(Date takenDate) {
@ -92,4 +96,8 @@ public class PrivateIpVO implements InternalIdentity {
public Long getVpcId() {
return vpcId;
}
public boolean getSourceNat() {
return sourceNat;
}
}

View File

@ -29,7 +29,6 @@ import javax.persistence.Id;
import javax.persistence.Table;
import com.cloud.utils.db.GenericDao;
import org.apache.cloudstack.api.InternalIdentity;
@Entity
@ -84,7 +83,10 @@ public class VpcGatewayVO implements VpcGateway {
@Column(name="state")
@Enumerated(value=EnumType.STRING)
State state;
@Column(name="source_nat")
boolean sourceNat;
protected VpcGatewayVO(){
this.uuid = UUID.randomUUID().toString();
}
@ -101,9 +103,10 @@ public class VpcGatewayVO implements VpcGateway {
* @param accountId TODO
* @param domainId TODO
* @param account_id
* @param sourceNat
*/
public VpcGatewayVO(String ip4Address, Type type, Long vpcId, long zoneId, Long networkId, String vlanTag,
String gateway, String netmask, long accountId, long domainId) {
String gateway, String netmask, long accountId, long domainId, boolean sourceNat) {
this.ip4Address = ip4Address;
this.type = type;
this.vpcId = vpcId;
@ -116,6 +119,7 @@ public class VpcGatewayVO implements VpcGateway {
this.accountId = accountId;
this.domainId = domainId;
this.state = State.Creating;
this.sourceNat = sourceNat;
}
@Override
@ -193,4 +197,10 @@ public class VpcGatewayVO implements VpcGateway {
public void setState(State state) {
this.state = state;
}
@Override
public boolean getSourceNat() {
return this.sourceNat;
}
}

View File

@ -1285,8 +1285,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "creating vpc private gateway", create=true)
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress,
String gateway, String netmask, long gatewayOwnerId) throws ResourceAllocationException,
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress,
String gateway, String netmask, long gatewayOwnerId, Boolean isSourceNat) throws ResourceAllocationException,
ConcurrentOperationException, InsufficientCapacityException {
//Validate parameters
@ -1312,11 +1312,11 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
//1) create private network
String networkName = "vpc-" + vpc.getName() + "-privateNetwork";
Network privateNtwk = _ntwkSvc.createPrivateNetwork(networkName, networkName, physicalNetworkId,
vlan, ipAddress, null, gateway, netmask, gatewayOwnerId, vpcId);
vlan, ipAddress, null, gateway, netmask, gatewayOwnerId, vpcId, isSourceNat);
//2) create gateway entry
VpcGatewayVO gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(),
privateNtwk.getId(), vlan, gateway, netmask, vpc.getAccountId(), vpc.getDomainId());
privateNtwk.getId(), vlan, gateway, netmask, vpc.getAccountId(), vpc.getDomainId(), isSourceNat);
_vpcGatewayDao.persist(gatewayVO);
s_logger.debug("Created vpc gateway entry " + gatewayVO);

View File

@ -43,16 +43,8 @@ import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.*;
import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VirtualMachineProfileImpl;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
@ -604,7 +596,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
*/
@Override
public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan,
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId)
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat)
throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
// TODO Auto-generated method stub
return null;

View File

@ -47,16 +47,8 @@ import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.*;
import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VirtualMachineProfileImpl;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
@ -609,7 +601,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
*/
@Override
public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan,
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId)
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat)
throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
// TODO Auto-generated method stub
return null;

View File

@ -164,7 +164,7 @@ public class MockVpcManagerImpl extends ManagerBase implements VpcManager {
* @see com.cloud.network.vpc.VpcService#createVpcPrivateGateway(long, java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, long)
*/
@Override
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress, String gateway, String netmask, long gatewayOwnerId) throws ResourceAllocationException,
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress, String gateway, String netmask, long gatewayOwnerId, Boolean isSourceNat) throws ResourceAllocationException,
ConcurrentOperationException, InsufficientCapacityException {
// TODO Auto-generated method stub
return null;

View File

@ -1123,3 +1123,6 @@ ALTER TABLE `cloud`.`account_details` MODIFY value varchar(255);
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'midonet.apiserver.address', 'http://localhost:8081', 'Specify the address at which the Midonet API server can be contacted (if using Midonet)');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'midonet.providerrouter.id', 'd7c5e6a3-e2f4-426b-b728-b7ce6a0448e5', 'Specifies the UUID of the Midonet provider router (if using Midonet)');
alter table cloud.vpc_gateways add column source_nat boolean default false;
alter table cloud.private_ip_address add column source_nat boolean default false;