mirror of https://github.com/apache/cloudstack.git
Reserve source NAT IP when its not passed for NSX VPC
This commit is contained in:
parent
3615b10e49
commit
d7afd53164
|
|
@ -19,6 +19,7 @@ package com.cloud.network;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.dc.DataCenter;
|
||||
import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
|
||||
|
|
@ -85,6 +86,8 @@ public interface NetworkService {
|
|||
|
||||
IpAddress reserveIpAddress(Account account, Boolean displayIp, Long ipAddressId) throws ResourceAllocationException;
|
||||
|
||||
IpAddress reserveIpAddressWithVlanDetail(Account account, DataCenter zone, Boolean displayIp, String vlanDetailKey) throws ResourceAllocationException;
|
||||
|
||||
boolean releaseReservedIpAddress(long ipAddressId) throws InsufficientAddressCapacityException;
|
||||
|
||||
boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ import java.util.stream.Collectors;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.dc.VlanDetailsVO;
|
||||
import com.cloud.dc.dao.VlanDetailsDao;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
|
|
@ -281,6 +283,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
@Inject
|
||||
VlanDao _vlanDao = null;
|
||||
@Inject
|
||||
private VlanDetailsDao vlanDetailsDao;
|
||||
@Inject
|
||||
IPAddressDao _ipAddressDao = null;
|
||||
@Inject
|
||||
AccountDao _accountDao = null;
|
||||
|
|
@ -1134,6 +1138,58 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
return ipVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpAddress reserveIpAddressWithVlanDetail(Account account, DataCenter zone, Boolean displayIp, String vlanDetailKey) throws ResourceAllocationException {
|
||||
// verify permissions
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
_accountMgr.checkAccess(caller, null, true, account);
|
||||
|
||||
VlanVO vlan = findOneVlanRangeMatchingVlanDetailKey(zone, vlanDetailKey);
|
||||
if (vlan == null) {
|
||||
String msg = String.format("Cannot find any vlan matching the detail key %s on zone %s", vlanDetailKey, zone.getName());
|
||||
s_logger.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
|
||||
List<IPAddressVO> freeIps = _ipAddressDao.listByVlanIdAndState(vlan.getId(), State.Free);
|
||||
if (CollectionUtils.isEmpty(freeIps)) {
|
||||
String msg = String.format("Cannot find any free IP matching on the VLAN range %s on zone %s", vlan.getIpRange(), zone.getName());
|
||||
s_logger.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
|
||||
Collections.shuffle(freeIps);
|
||||
IPAddressVO selectedIp = freeIps.get(0);
|
||||
|
||||
selectedIp.setAllocatedTime(new Date());
|
||||
selectedIp.setAllocatedToAccountId(account.getAccountId());
|
||||
selectedIp.setAllocatedInDomainId(account.getDomainId());
|
||||
selectedIp.setState(State.Reserved);
|
||||
if (displayIp != null) {
|
||||
selectedIp.setDisplay(displayIp);
|
||||
}
|
||||
selectedIp = _ipAddressDao.persist(selectedIp);
|
||||
|
||||
Long ipDedicatedAccountId = getIpDedicatedAccountId(selectedIp.getVlanId());
|
||||
if (ipDedicatedAccountId == null) {
|
||||
_resourceLimitMgr.incrementResourceCount(account.getId(), Resource.ResourceType.public_ip);
|
||||
}
|
||||
|
||||
return selectedIp;
|
||||
}
|
||||
|
||||
private VlanVO findOneVlanRangeMatchingVlanDetailKey(DataCenter zone, String vlanDetailKey) {
|
||||
List<VlanVO> zoneVlans = _vlanDao.listByZone(zone.getId());
|
||||
for (VlanVO zoneVlan : zoneVlans) {
|
||||
VlanDetailsVO detail = vlanDetailsDao.findDetail(zoneVlan.getId(), vlanDetailKey);
|
||||
if (detail != null && detail.getValue().equalsIgnoreCase("true")) {
|
||||
s_logger.debug(String.format("Found the VLAN range %s is set for NSX on zone %s", zoneVlan.getIpRange(), zone.getName()));
|
||||
return zoneVlan;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Long getIpDedicatedAccountId(Long vlanId) {
|
||||
List<AccountVlanMapVO> accountVlanMaps = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanId);
|
||||
if (CollectionUtils.isNotEmpty(accountVlanMaps)) {
|
||||
|
|
|
|||
|
|
@ -1171,11 +1171,23 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
return vpc;
|
||||
}
|
||||
|
||||
private boolean isVpcForNsx(Vpc vpc) {
|
||||
VpcOfferingServiceMapVO mapVO = _vpcOffSvcMapDao.findByServiceProviderAndOfferingId(Service.SourceNat.getName(), Provider.Nsx.getName(), vpc.getVpcOfferingId());
|
||||
if (mapVO != null) {
|
||||
s_logger.debug(String.format("The VPC %s is NSX-based and supports the %s service", vpc.getName(), Service.SourceNat.getName()));
|
||||
}
|
||||
return mapVO != null;
|
||||
}
|
||||
|
||||
private void allocateSourceNatIp(Vpc vpc, String sourceNatIP) {
|
||||
Account account = _accountMgr.getAccount(vpc.getAccountId());
|
||||
DataCenter zone = _dcDao.findById(vpc.getZoneId());
|
||||
// reserve this ip and then
|
||||
try {
|
||||
if (isVpcForNsx(vpc) && org.apache.commons.lang3.StringUtils.isBlank(sourceNatIP)) {
|
||||
s_logger.debug(String.format("Reserving a source NAT IP for NSX VPC %s", vpc.getName()));
|
||||
sourceNatIP = reserveSourceNatIpForNsxVpc(account, zone, vpc);
|
||||
}
|
||||
IpAddress ip = _ipAddrMgr.allocateIp(account, false, CallContext.current().getCallingAccount(), CallContext.current().getCallingUserId(), zone, null, sourceNatIP);
|
||||
this.associateIPToVpc(ip.getId(), vpc.getId());
|
||||
} catch (ResourceAllocationException | ResourceUnavailableException | InsufficientAddressCapacityException e){
|
||||
|
|
@ -1183,6 +1195,11 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
}
|
||||
}
|
||||
|
||||
private String reserveSourceNatIpForNsxVpc(Account account, DataCenter zone, Vpc vpc) throws ResourceAllocationException {
|
||||
IpAddress ipAddress = _ntwkSvc.reserveIpAddressWithVlanDetail(account, zone, true, ApiConstants.NSX_DETAIL_KEY);
|
||||
return ipAddress.getAddress().addr();
|
||||
}
|
||||
|
||||
@DB
|
||||
protected Vpc createVpc(final Boolean displayVpc, final VpcVO vpc) {
|
||||
final String cidr = vpc.getCidr();
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
// under the License.
|
||||
package com.cloud.vpc;
|
||||
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
|
|
@ -176,6 +177,11 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpAddress reserveIpAddressWithVlanDetail(Account account, DataCenter zone, Boolean displayIp, String vlanDetailKey) throws ResourceAllocationException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseReservedIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue