mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
NSX: Router Public nic to get IP from systemVM Ip range (#8172)
* NSX: Router Public nic to get IP from systemVM Ip range * Fix VR IP address and setSourceNatIp command * NSX: hide systemVM reserved IP range SourceNAT * fix test --------- Co-authored-by: nvazquez <nicovazquez90@gmail.com>
This commit is contained in:
parent
e3a2762235
commit
a36f355877
@ -97,4 +97,6 @@ public interface IpAddress extends ControlledEntity, Identity, InternalIdentity,
|
||||
|
||||
void setRuleState(State ruleState);
|
||||
|
||||
boolean isForSystemVms();
|
||||
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command.user.address;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
@ -106,6 +107,9 @@ public class ListPublicIpAddressesCmd extends BaseListRetrieveOnlyResourceCountC
|
||||
@Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin})
|
||||
private Boolean display;
|
||||
|
||||
@Parameter(name = ApiConstants.FOR_SYSTEM_VMS, type = CommandType.BOOLEAN, description = "true if range is dedicated for system VMs", since = "4.20.0")
|
||||
private Boolean forSystemVMs;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -177,6 +181,10 @@ public class ListPublicIpAddressesCmd extends BaseListRetrieveOnlyResourceCountC
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean getForSystemVMs() {
|
||||
return !Objects.isNull(forSystemVMs) && forSystemVMs;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -167,6 +167,10 @@ public class IPAddressResponse extends BaseResponseWithAnnotations implements Co
|
||||
@Param(description="whether the ip address has Firewall/PortForwarding/LoadBalancing rules defined")
|
||||
private boolean hasRules;
|
||||
|
||||
@SerializedName(ApiConstants.FOR_SYSTEM_VMS)
|
||||
@Param(description="true if range is dedicated for System VMs")
|
||||
private boolean forSystemVms;
|
||||
|
||||
public void setIpAddress(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
@ -316,4 +320,8 @@ public class IPAddressResponse extends BaseResponseWithAnnotations implements Co
|
||||
public void setHasRules(final boolean hasRules) {
|
||||
this.hasRules = hasRules;
|
||||
}
|
||||
|
||||
public void setForSystemVms(boolean forSystemVms) {
|
||||
this.forSystemVms = forSystemVms;
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,4 +269,11 @@ public class PublicIp implements PublicIpAddress {
|
||||
public void setRuleState(State ruleState) {
|
||||
_addr.setRuleState(ruleState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForSystemVms() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.dc.VlanDetailsVO;
|
||||
import com.cloud.dc.dao.VlanDetailsDao;
|
||||
import com.cloud.network.dao.NsxProviderDao;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.annotation.AnnotationService;
|
||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||
@ -347,6 +348,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
private VlanDetailsDao vlanDetailsDao;
|
||||
|
||||
List<NetworkGuru> networkGurus;
|
||||
@Inject
|
||||
private NsxProviderDao nsxProviderDao;
|
||||
|
||||
@Override
|
||||
public List<NetworkGuru> getNetworkGurus() {
|
||||
@ -1082,16 +1085,26 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
if (!isVirtualRouter || !isPublicTraffic || requested.getIPv4Address() == null) {
|
||||
return false;
|
||||
}
|
||||
IPAddressVO ip = _ipAddressDao.findByIp(requested.getIPv4Address());
|
||||
if (ip == null) {
|
||||
long dataCenterId = vm.getVirtualMachine().getDataCenterId();
|
||||
if (nsxProviderDao.findByZoneId(dataCenterId) == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Long vpcId = _ipAddressDao.findByIp(requested.getIPv4Address()).getVpcId();
|
||||
// TODO: Need to fix isolated network
|
||||
List<IPAddressVO> ips = _ipAddressDao.listByAssociatedVpc(vpcId, true);
|
||||
|
||||
if (CollectionUtils.isEmpty(ips)) {
|
||||
return false;
|
||||
}
|
||||
ips = ips.stream().filter(x -> !x.getAddress().addr().equals(requested.getIPv4Address())).collect(Collectors.toList());
|
||||
IPAddressVO ip = ips.get(0);
|
||||
VlanDetailsVO vlanDetail = vlanDetailsDao.findDetail(ip.getVlanId(), ApiConstants.NSX_DETAIL_KEY);
|
||||
if (vlanDetail == null) {
|
||||
return false;
|
||||
}
|
||||
boolean isForNsx = vlanDetail.getValue().equalsIgnoreCase("true");
|
||||
return isForNsx && ip.isSourceNat() && !ip.isForSystemVms();
|
||||
return isForNsx && !ip.isForSystemVms();
|
||||
}
|
||||
|
||||
private void setMtuDetailsInVRNic(final Pair<NetworkVO, VpcVO> networks, Network network, NicVO vo) {
|
||||
|
||||
@ -40,9 +40,12 @@ import org.apache.cloudstack.agent.api.CreateNsxTier1NatRuleCommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.utils.NsxControllerUtils;
|
||||
import org.apache.cloudstack.utils.NsxHelper;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class NsxPublicNetworkGuru extends PublicNetworkGuru {
|
||||
|
||||
@ -106,6 +109,16 @@ public class NsxPublicNetworkGuru extends PublicNetworkGuru {
|
||||
throw new CloudRuntimeException(err);
|
||||
}
|
||||
|
||||
// For NSX, use VR Public IP != Source NAT
|
||||
List<IPAddressVO> ips = _ipAddressDao.listByAssociatedVpc(vpcId, true);
|
||||
if (CollectionUtils.isEmpty(ips)) {
|
||||
String err = String.format("Cannot find a source NAT IP for the VPC %s", vpc.getName());
|
||||
s_logger.error(err);
|
||||
throw new CloudRuntimeException(err);
|
||||
}
|
||||
ips = ips.stream().filter(x -> !x.getAddress().addr().equals(nic.getIPv4Address())).collect(Collectors.toList());
|
||||
// Use Source NAT IP address from the NSX Public Range. Do not Use the VR Public IP address
|
||||
ipAddress = ips.get(0);
|
||||
if (ipAddress.isSourceNat() && !ipAddress.isForSystemVms()) {
|
||||
VlanDetailsVO detail = vlanDetailsDao.findDetail(ipAddress.getVlanId(), ApiConstants.NSX_DETAIL_KEY);
|
||||
if (detail != null && detail.getValue().equalsIgnoreCase("true")) {
|
||||
|
||||
@ -1097,6 +1097,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
ipResponse.setForDisplay(ipAddr.isDisplay());
|
||||
|
||||
ipResponse.setPortable(ipAddr.isPortable());
|
||||
ipResponse.setForSystemVms(ipAddr.isForSystemVms());
|
||||
|
||||
//set tag information
|
||||
List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.PublicIpAddress, ipAddr.getId());
|
||||
|
||||
@ -2584,6 +2584,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
final Boolean staticNat = cmd.isStaticNat();
|
||||
final Boolean forDisplay = cmd.getDisplay();
|
||||
final String state = cmd.getState();
|
||||
final Boolean forSystemVms = cmd.getForSystemVMs();
|
||||
final Map<String, String> tags = cmd.getTags();
|
||||
|
||||
sc.setJoinParameters("vlanSearch", "vlanType", vlanType);
|
||||
@ -2646,6 +2647,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
|
||||
if (IpAddressManagerImpl.getSystemvmpublicipreservationmodestrictness().value() && IpAddress.State.Free.name().equalsIgnoreCase(state)) {
|
||||
sc.setParameters("forsystemvms", false);
|
||||
} else {
|
||||
sc.setParameters("forsystemvms", forSystemVms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -19,9 +19,14 @@ package org.apache.cloudstack.network.router.deployment;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.Vlan;
|
||||
import com.cloud.network.dao.NetworkDetailVO;
|
||||
import com.cloud.network.dao.NetworkDetailsDao;
|
||||
import com.cloud.network.dao.NsxProviderDao;
|
||||
import com.cloud.network.element.NsxProviderVO;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
@ -86,6 +91,7 @@ public class RouterDeploymentDefinition {
|
||||
|
||||
protected NetworkDao networkDao;
|
||||
protected DomainRouterDao routerDao;
|
||||
protected NsxProviderDao nsxProviderDao;
|
||||
protected PhysicalNetworkServiceProviderDao physicalProviderDao;
|
||||
protected NetworkModel networkModel;
|
||||
protected VirtualRouterProviderDao vrProviderDao;
|
||||
@ -383,8 +389,19 @@ public class RouterDeploymentDefinition {
|
||||
|
||||
protected void findSourceNatIP() throws InsufficientAddressCapacityException, ConcurrentOperationException {
|
||||
sourceNatIp = null;
|
||||
DataCenter zone = dest.getDataCenter();
|
||||
Long zoneId = null;
|
||||
if (Objects.nonNull(zone)) {
|
||||
zoneId = zone.getId();
|
||||
}
|
||||
NsxProviderVO nsxProvider = nsxProviderDao.findByZoneId(zoneId);
|
||||
|
||||
if (isPublicNetwork) {
|
||||
sourceNatIp = ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork);
|
||||
if (Objects.isNull(nsxProvider)) {
|
||||
sourceNatIp = ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork);
|
||||
} else {
|
||||
sourceNatIp = ipAddrMgr.assignPublicIpAddress(zoneId, getPodId(), owner, Vlan.VlanType.VirtualNetwork, null, null, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@ import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.network.dao.NetworkDetailsDao;
|
||||
import com.cloud.network.dao.NsxProviderDao;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@ -63,6 +64,8 @@ public class RouterDeploymentDefinitionBuilder {
|
||||
@Inject
|
||||
private DomainRouterDao routerDao;
|
||||
@Inject
|
||||
private NsxProviderDao nsxProviderDao;
|
||||
@Inject
|
||||
private PhysicalNetworkServiceProviderDao physicalProviderDao;
|
||||
@Inject
|
||||
private NetworkModel networkModel;
|
||||
@ -125,6 +128,7 @@ public class RouterDeploymentDefinitionBuilder {
|
||||
|
||||
routerDeploymentDefinition.networkDao = networkDao;
|
||||
routerDeploymentDefinition.routerDao = routerDao;
|
||||
routerDeploymentDefinition.nsxProviderDao = nsxProviderDao;
|
||||
routerDeploymentDefinition.physicalProviderDao = physicalProviderDao;
|
||||
routerDeploymentDefinition.networkModel = networkModel;
|
||||
routerDeploymentDefinition.vrProviderDao = vrProviderDao;
|
||||
|
||||
@ -19,7 +19,12 @@ package org.apache.cloudstack.network.router.deployment;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.Vlan;
|
||||
import com.cloud.network.dao.IPAddressVO;
|
||||
import com.cloud.network.element.NsxProviderVO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.dc.dao.VlanDao;
|
||||
@ -120,8 +125,26 @@ public class VpcRouterDeploymentDefinition extends RouterDeploymentDefinition {
|
||||
@Override
|
||||
protected void findSourceNatIP() throws InsufficientAddressCapacityException, ConcurrentOperationException {
|
||||
sourceNatIp = null;
|
||||
DataCenter zone = dest.getDataCenter();
|
||||
Long zoneId = null;
|
||||
if (Objects.nonNull(zone)) {
|
||||
zoneId = zone.getId();
|
||||
}
|
||||
NsxProviderVO nsxProvider = nsxProviderDao.findByZoneId(zoneId);
|
||||
|
||||
if (isPublicNetwork) {
|
||||
sourceNatIp = vpcMgr.assignSourceNatIpAddressToVpc(owner, vpc);
|
||||
if (Objects.isNull(nsxProvider)) {
|
||||
sourceNatIp = vpcMgr.assignSourceNatIpAddressToVpc(owner, vpc);
|
||||
} else {
|
||||
// NSX deploys VRs with Public NIC != to the source NAT, the source NAT IP is on the NSX Public range
|
||||
sourceNatIp = ipAddrMgr.assignPublicIpAddress(zoneId, getPodId(), owner, Vlan.VlanType.VirtualNetwork, null, null, false, true);
|
||||
if (vpc != null) {
|
||||
IPAddressVO routerPublicIp = ipAddressDao.findByIp(sourceNatIp.getAddress().toString());
|
||||
routerPublicIp.setVpcId(vpc.getId());
|
||||
routerPublicIp.setSourceNat(true);
|
||||
ipAddressDao.persist(routerPublicIp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -252,7 +252,7 @@ public class ManagementServerImplTest {
|
||||
Mockito.verify(sc, Mockito.times(1)).setParameters("display", false);
|
||||
Mockito.verify(sc, Mockito.times(1)).setParameters("sourceNetworkId", 10L);
|
||||
Mockito.verify(sc, Mockito.times(1)).setParameters("state", "Free");
|
||||
Mockito.verify(sc, Mockito.never()).setParameters("forsystemvms", false);
|
||||
Mockito.verify(sc, Mockito.times(1)).setParameters("forsystemvms", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -274,7 +274,7 @@ public class ManagementServerImplTest {
|
||||
Mockito.verify(sc, Mockito.times(1)).setJoinParameters("vlanSearch", "vlanType", VlanType.VirtualNetwork);
|
||||
Mockito.verify(sc, Mockito.times(1)).setParameters("display", false);
|
||||
Mockito.verify(sc, Mockito.times(1)).setParameters("sourceNetworkId", 10L);
|
||||
Mockito.verify(sc, Mockito.never()).setParameters("forsystemvms", false);
|
||||
Mockito.verify(sc, Mockito.times(1)).setParameters("forsystemvms", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -296,7 +296,7 @@ public class ManagementServerImplTest {
|
||||
Mockito.verify(sc, Mockito.times(1)).setJoinParameters("vlanSearch", "vlanType", VlanType.VirtualNetwork);
|
||||
Mockito.verify(sc, Mockito.times(1)).setParameters("display", false);
|
||||
Mockito.verify(sc, Mockito.times(1)).setParameters("sourceNetworkId", 10L);
|
||||
Mockito.verify(sc, Mockito.never()).setParameters("forsystemvms", false);
|
||||
Mockito.verify(sc, Mockito.times(1)).setParameters("forsystemvms", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user