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
2 changes: 1 addition & 1 deletion api/src/main/java/com/cloud/network/Network.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public static Routing fromValue(String type) {
} else if (type.equalsIgnoreCase("Dynamic")) {
return Dynamic;
} else {
throw new InvalidParameterValueException("Unexpected Routing type : " + type);
throw new InvalidParameterValueException("Unexpected Routing mode : " + type);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
private String internetProtocol;

@SerializedName(ApiConstants.IPV6_ROUTING)
@Param(description = "The IPv6 routing type of network offering", since = "4.17.0")
@Param(description = "The IPv6 routing mode of network offering", since = "4.17.0")
private String ipv6Routing;

@SerializedName(ApiConstants.IPV6_ROUTES)
Expand All @@ -320,7 +320,7 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
private String ipv6Dns2;

@SerializedName(ApiConstants.IPV4_ROUTING)
@Param(description = "The IPv4 routing type of network", since = "4.20.0")
@Param(description = "The IPv4 routing mode of network", since = "4.20.0")
private String ipv4Routing;

@SerializedName(ApiConstants.IPV4_ROUTES)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ public class VpcResponse extends BaseResponseWithAnnotations implements Controll
@Param(description = "The IPv4 routing mode of VPC", since = "4.20.0")
private String ipv4Routing;

@SerializedName(ApiConstants.IPV6_ROUTING)
@Param(description = "The IPv6 routing mode of VPC", since = "4.22.1")
private String ipv6Routing;

@SerializedName(ApiConstants.IPV4_ROUTES)
@Param(description = "The routes for the VPC to ease adding route in upstream router", since = "4.20.0")
private Set<Ipv4RouteResponse> ipv4Routes;
Expand Down Expand Up @@ -312,6 +316,10 @@ public void addIpv4Route(Ipv4RouteResponse ipv4Route) {
this.ipv4Routes.add(ipv4Route);
}

public void setIpv6Routing(String ipv6Routing) {
this.ipv6Routing = ipv6Routing;
}

public void setIpv6Routes(Set<Ipv6RouteResponse> ipv6Routes) {
this.ipv6Routes = ipv6Routes;
}
Expand Down
46 changes: 30 additions & 16 deletions server/src/main/java/com/cloud/api/ApiResponseHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -2820,19 +2820,15 @@ public NetworkResponse createNetworkResponse(ResponseView view, Network network)
Ipv4RouteResponse route = new Ipv4RouteResponse(network.getCidr(), ip.getAddress().addr());
response.addIpv4Route(route);
}

if (view == ResponseView.Full) {
List<BgpPeerVO> bgpPeerVOS = bgpPeerDao.listNonRevokeByNetworkId(network.getId());
for (BgpPeerVO bgpPeerVO : bgpPeerVOS) {
BgpPeerResponse bgpPeerResponse = routedIpv4Manager.createBgpPeerResponse(bgpPeerVO);
response.addBgpPeer(bgpPeerResponse);
}
}
}

if (networkOfferingDao.isIpv6Supported(network.getNetworkOfferingId())) {
response.setInternetProtocol(networkOfferingDao.getNetworkOfferingInternetProtocol(network.getNetworkOfferingId(), NetUtils.InternetProtocol.IPv4).toString());
response.setIpv6Routing(Network.Routing.Static.toString());
if (networkOffering != null && networkOffering.getRoutingMode() != null) {
response.setIpv6Routing(networkOffering.getRoutingMode().name());
} else {
response.setIpv6Routing(Network.Routing.Static.toString());
}
response.setIpv6Routes(new LinkedHashSet<>());
if (Network.GuestType.Isolated.equals(networkOffering.getGuestType())) {
List<String> ipv6Addresses = ipv6Service.getPublicIpv6AddressesForNetwork(network);
Expand All @@ -2843,6 +2839,15 @@ public NetworkResponse createNetworkResponse(ResponseView view, Network network)
}
}

// Add BGP peer information for full view
if (view == ResponseView.Full) {
List<BgpPeerVO> bgpPeerVOS = bgpPeerDao.listNonRevokeByNetworkId(network.getId());
for (BgpPeerVO bgpPeerVO : bgpPeerVOS) {
BgpPeerResponse bgpPeerResponse = routedIpv4Manager.createBgpPeerResponse(bgpPeerVO);
response.addBgpPeer(bgpPeerResponse);
}
}
Comment on lines +2842 to +2849

response.setObjectName("network");
return response;
}
Expand Down Expand Up @@ -3557,7 +3562,6 @@ public VpcResponse createVpcResponse(ResponseView view, Vpc vpc) {
response.setTags(tagResponses);
response.setHasAnnotation(annotationDao.hasAnnotations(vpc.getUuid(), AnnotationService.EntityType.VPC.name(),
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
ipv6Service.updateIpv6RoutesForVpcResponse(vpc, response);
response.setDns1(vpc.getIp4Dns1());
response.setDns2(vpc.getIp4Dns2());
response.setIpv6Dns1(vpc.getIp6Dns1());
Expand All @@ -3578,12 +3582,22 @@ public VpcResponse createVpcResponse(ResponseView view, Vpc vpc) {
response.addIpv4Route(route);
}
}
if (view == ResponseView.Full) {
List<BgpPeerVO> bgpPeerVOS = bgpPeerDao.listNonRevokeByVpcId(vpc.getId());
for (BgpPeerVO bgpPeerVO : bgpPeerVOS) {
BgpPeerResponse bgpPeerResponse = routedIpv4Manager.createBgpPeerResponse(bgpPeerVO);
response.addBgpPeer(bgpPeerResponse);
}
}

// add IPv6 routes
ipv6Service.updateIpv6RoutesForVpcResponse(vpc, response);
if (Objects.nonNull(asNumberVO)) {
response.setIpv6Routing(Network.Routing.Dynamic.name());
} else {
response.setIpv6Routing(Network.Routing.Static.name());
Comment on lines +3589 to +3592
}

// Add BGP peer information for full view
if (view == ResponseView.Full && Objects.nonNull(asNumberVO)) {
List<BgpPeerVO> bgpPeerVOS = bgpPeerDao.listNonRevokeByVpcId(vpc.getId());
for (BgpPeerVO bgpPeerVO : bgpPeerVOS) {
BgpPeerResponse bgpPeerResponse = routedIpv4Manager.createBgpPeerResponse(bgpPeerVO);
response.addBgpPeer(bgpPeerResponse);
}
}

Expand Down
19 changes: 13 additions & 6 deletions server/src/main/java/com/cloud/bgp/BGPServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.cloud.network.element.BgpServiceProvider;
import com.cloud.network.element.NetworkElement;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcOffering;
import com.cloud.network.vpc.VpcOfferingVO;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
Expand Down Expand Up @@ -396,9 +397,12 @@ public boolean applyBgpPeers(Network network, boolean continueOnError) throws Re
if (!routedIpv4Manager.isDynamicRoutedNetwork(network)) {
return true;
}
final String gatewayProviderStr = ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Network.Service.Gateway);
if (gatewayProviderStr != null) {
NetworkElement provider = networkModel.getElementImplementingProvider(gatewayProviderStr);
NetworkOffering networkOffering = networkOfferingDao.findById(network.getNetworkOfferingId());
final String bgpServiceProvider = NetworkOffering.NetworkMode.ROUTED.equals(networkOffering.getNetworkMode()) ?
ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Network.Service.Gateway):
ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Network.Service.SourceNat);
Comment on lines +400 to +403
if (bgpServiceProvider != null) {
NetworkElement provider = networkModel.getElementImplementingProvider(bgpServiceProvider);
if (provider != null && provider instanceof BgpServiceProvider) {
List<? extends BgpPeer> bgpPeers = getBgpPeersForNetwork(network);
LOGGER.debug(String.format("Applying BPG Peers for network [%s]: [%s]", network, bgpPeers));
Expand All @@ -413,9 +417,12 @@ public boolean applyBgpPeers(Vpc vpc, boolean continueOnError) throws ResourceUn
if (!routedIpv4Manager.isDynamicRoutedVpc(vpc)) {
return true;
}
final String gatewayProviderStr = vpcServiceMapDao.getProviderForServiceInVpc(vpc.getId(), Network.Service.Gateway);
if (gatewayProviderStr != null) {
NetworkElement provider = networkModel.getElementImplementingProvider(gatewayProviderStr);
VpcOffering vpcOffering = vpcOfferingDao.findById(vpc.getVpcOfferingId());
final String bgpServiceProvider = NetworkOffering.NetworkMode.ROUTED.equals(vpcOffering.getNetworkMode()) ?
vpcServiceMapDao.getProviderForServiceInVpc(vpc.getId(), Network.Service.Gateway):
vpcServiceMapDao.getProviderForServiceInVpc(vpc.getId(), Network.Service.SourceNat);
if (bgpServiceProvider != null) {
NetworkElement provider = networkModel.getElementImplementingProvider(bgpServiceProvider);
if (provider != null && provider instanceof BgpServiceProvider) {
List<? extends BgpPeer> bgpPeers = getBgpPeersForVpc(vpc);
LOGGER.debug(String.format("Applying BPG Peers for VPC [%s]: [%s]", vpc, bgpPeers));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1467,14 +1467,29 @@ public void createBgpPeersCommands(final List<? extends BgpPeer> bgpPeers, final
} else {
guestNetworks.add(network);
}
Map<Long, NetworkOfferingVO> guestNetworkOfferings = new HashMap<>();
for (Network guestNetwork : guestNetworks) {
final NetworkOfferingVO offering = _networkOfferingDao.findByIdIncludingRemoved(guestNetwork.getNetworkOfferingId());
guestNetworkOfferings.put(guestNetwork.getId(), offering);
}
for (BgpPeer bgpPeer: bgpPeers) {
Map<BgpPeer.Detail, String> bgpPeerDetails = bgpPeerDetailsDao.getBgpPeerDetails(bgpPeer.getId());
for (Network guestNetwork : guestNetworks) {
bgpPeerTOs.add(new BgpPeerTO(bgpPeer.getId(), bgpPeer.getIp4Address(), bgpPeer.getIp6Address(), bgpPeer.getAsNumber(), bgpPeer.getPassword(),
guestNetwork.getId(), asNumberVO.getAsNumber(), guestNetwork.getCidr(), guestNetwork.getIp6Cidr(), bgpPeerDetails));
final NetworkOfferingVO offering = guestNetworkOfferings.get(guestNetwork.getId());
if (NetworkOffering.NetworkMode.ROUTED.equals(offering.getNetworkMode())) {
bgpPeerTOs.add(new BgpPeerTO(bgpPeer.getId(), bgpPeer.getIp4Address(), bgpPeer.getIp6Address(), bgpPeer.getAsNumber(), bgpPeer.getPassword(),
guestNetwork.getId(), asNumberVO.getAsNumber(), guestNetwork.getCidr(), guestNetwork.getIp6Cidr(), bgpPeerDetails));
} else if (guestNetwork.getIp6Cidr() != null && bgpPeer.getIp6Address() != null) {
bgpPeerTOs.add(new BgpPeerTO(bgpPeer.getId(), null, bgpPeer.getIp6Address(), bgpPeer.getAsNumber(), bgpPeer.getPassword(),
guestNetwork.getId(), asNumberVO.getAsNumber(), null, guestNetwork.getIp6Cidr(), bgpPeerDetails));
Comment on lines +1471 to +1484
}
}
}

if (bgpPeerTOs.isEmpty()) {
logger.debug("No BGP peers to configure for the guest network or VPC, skipping.");
return;
Comment on lines +1490 to +1491
}
final SetBgpPeersCommand cmd = new SetBgpPeersCommand(bgpPeerTOs);
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1013,8 +1013,9 @@ public boolean isDynamicRoutedNetwork(Network network) {

@Override
public boolean isDynamicRoutedNetwork(NetworkOffering networkOffering) {
return NetworkOffering.NetworkMode.ROUTED.equals(networkOffering.getNetworkMode())
&& NetworkOffering.RoutingMode.Dynamic.equals(networkOffering.getRoutingMode());
return NetworkOffering.RoutingMode.Dynamic.equals(networkOffering.getRoutingMode()) &&
(NetworkOffering.NetworkMode.ROUTED.equals(networkOffering.getNetworkMode()) ||
NetUtils.InternetProtocol.DualStack.equals(networkOfferingDao.getNetworkOfferingInternetProtocol(networkOffering.getId())));
}

@Override
Expand All @@ -1030,8 +1031,9 @@ public boolean isDynamicRoutedVpc(Vpc vpc) {

@Override
public boolean isDynamicRoutedVpc(VpcOffering vpcOffering) {
return NetworkOffering.NetworkMode.ROUTED.equals(vpcOffering.getNetworkMode())
&& NetworkOffering.RoutingMode.Dynamic.equals(vpcOffering.getRoutingMode());
return NetworkOffering.RoutingMode.Dynamic.equals(vpcOffering.getRoutingMode()) &&
(NetworkOffering.NetworkMode.ROUTED.equals(vpcOffering.getNetworkMode()) ||
NetUtils.InternetProtocol.DualStack.equals(vpcOfferingDao.getVpcOfferingInternetProtocol(vpcOffering.getId())));
Comment on lines +1034 to +1036
}

@Override
Expand Down
28 changes: 26 additions & 2 deletions server/src/test/java/com/cloud/bgp/BGPServiceImplTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@
import com.cloud.network.element.VirtualRouterElement;
import com.cloud.network.element.VpcVirtualRouterElement;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcOfferingVO;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import com.cloud.network.vpc.dao.VpcServiceMapDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import org.apache.cloudstack.network.BgpPeerVO;
Expand All @@ -46,6 +51,7 @@
import java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -76,6 +82,18 @@ public class BGPServiceImplTest {
@Mock
VpcServiceMapDao vpcServiceMapDao;

@Mock
NetworkOfferingDao networkOfferingDao;

@Mock
VpcOfferingDao vpcOfferingDao;

@Mock
NetworkOfferingVO networkOffering;

@Mock
VpcOfferingVO vpcOffering;

@Test
public void testASNumbersOverlap() {
Assert.assertEquals(bGPServiceImplSpy.isASNumbersOverlap(1,2,3,4), false);
Expand All @@ -94,6 +112,8 @@ public void testApplyBgpPeersForIsolatedNetwork() throws ResourceUnavailableExce
when(network.getVpcId()).thenReturn(null);

when(routedIpv4Manager.isDynamicRoutedNetwork(network)).thenReturn(true);
when(networkOfferingDao.findById(anyLong())).thenReturn(networkOffering);
when(networkOffering.getNetworkMode()).thenReturn(NetworkOffering.NetworkMode.ROUTED);
when(ntwkSrvcDao.getProviderForServiceInNetwork(networkId, Network.Service.Gateway)).thenReturn("VirtualRouter");
VirtualRouterElement virtualRouterElement = Mockito.mock(VirtualRouterElement.class);
when(networkModel.getElementImplementingProvider("VirtualRouter")).thenReturn(virtualRouterElement);
Expand Down Expand Up @@ -121,9 +141,11 @@ public void testApplyBgpPeersForVpcTier() throws ResourceUnavailableException {
when(network.getDataCenterId()).thenReturn(zoneId);

when(routedIpv4Manager.isDynamicRoutedNetwork(network)).thenReturn(true);
when(ntwkSrvcDao.getProviderForServiceInNetwork(networkId, Network.Service.Gateway)).thenReturn("VirtualRouter");
when(networkOfferingDao.findById(anyLong())).thenReturn(networkOffering);
when(networkOffering.getNetworkMode()).thenReturn(NetworkOffering.NetworkMode.ROUTED);
when(ntwkSrvcDao.getProviderForServiceInNetwork(networkId, Network.Service.Gateway)).thenReturn("VPCVirtualRouter");
VirtualRouterElement virtualRouterElement = Mockito.mock(VirtualRouterElement.class);
when(networkModel.getElementImplementingProvider("VirtualRouter")).thenReturn(virtualRouterElement);
when(networkModel.getElementImplementingProvider("VPCVirtualRouter")).thenReturn(virtualRouterElement);

when(bgpPeerDao.listNonRevokeByVpcId(vpcId)).thenReturn(new ArrayList<>());

Expand Down Expand Up @@ -153,6 +175,8 @@ public void testApplyBgpPeersForVpcWithBgpPeers() throws ResourceUnavailableExce
when(vpc.getZoneId()).thenReturn(zoneId);

when(routedIpv4Manager.isDynamicRoutedVpc(vpc)).thenReturn(true);
when(vpcOfferingDao.findById(anyLong())).thenReturn(vpcOffering);
when(vpcOffering.getNetworkMode()).thenReturn(NetworkOffering.NetworkMode.ROUTED);
when(vpcServiceMapDao.getProviderForServiceInVpc(vpcId, Network.Service.Gateway)).thenReturn("VPCVirtualRouter");
VpcVirtualRouterElement vpcVirtualRouterElement = Mockito.mock(VpcVirtualRouterElement.class);
when(networkModel.getElementImplementingProvider("VPCVirtualRouter")).thenReturn(vpcVirtualRouterElement);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import java.util.List;
import java.util.Map;

import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
Expand Down Expand Up @@ -226,6 +227,10 @@ public void testCreateBgpPeersCommandsForNetwork() {
when(dcDao.findById(zoneId)).thenReturn(dc);
when(dc.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced);

NetworkOfferingVO offering = Mockito.mock(NetworkOfferingVO.class);
when(networkOfferingDao.findByIdIncludingRemoved(anyLong())).thenReturn(offering);
when(offering.getNetworkMode()).thenReturn(NetworkOffering.NetworkMode.ROUTED);

commandSetupHelper.createBgpPeersCommands(bgpPeers, router, cmds, network);

Assert.assertEquals(1, cmds.size());
Expand Down Expand Up @@ -254,6 +259,7 @@ public void testCreateBgpPeersCommandsForVpc() {
NetworkOfferingVO offering = Mockito.mock(NetworkOfferingVO.class);
when(networkOfferingDao.findByIdIncludingRemoved(networkOfferingId)).thenReturn(offering);
when(offering.getRoutingMode()).thenReturn(NetworkOffering.RoutingMode.Dynamic);
when(offering.getNetworkMode()).thenReturn(NetworkOffering.NetworkMode.ROUTED);
NetworkVO network1 = Mockito.mock(NetworkVO.class);
when(network1.getNetworkOfferingId()).thenReturn(networkOfferingId);
NetworkVO network2 = Mockito.mock(NetworkVO.class);
Expand Down
2 changes: 1 addition & 1 deletion ui/src/config/section/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default {
}, {
name: 'bgp.peers',
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/zone/BgpPeersTab.vue'))),
show: (record, route, user) => { return !record.vpcid && ['Admin'].includes(user.roletype) && record.ip4routing === 'Dynamic' }
show: (record, route, user) => { return !record.vpcid && ['Admin'].includes(user.roletype) && (record.ip4routing === 'Dynamic' || record.ip6routing === 'Dynamic') }
}, {
name: 'routing.firewall',
component: shallowRef(defineAsyncComponent(() => import('@/views/network/RoutingFirewallRulesTab.vue'))),
Expand Down
Loading
Loading