Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
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 type of VPC", since = "4.22.1")
Comment thread
weizhouapache marked this conversation as resolved.
Outdated
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
48 changes: 32 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 thread
weizhouapache marked this conversation as resolved.
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,24 @@ 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 (CollectionUtils.isNotEmpty(response.getIpv6Routes())) {
if (Objects.nonNull(asNumberVO)) {
response.setIpv6Routing(Network.Routing.Dynamic.name());
} else {
response.setIpv6Routing(Network.Routing.Static.name());
}
Comment thread
weizhouapache marked this conversation as resolved.
Outdated
}

// Add BGP peer information for full view
if (view == ResponseView.Full) {
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 thread
weizhouapache marked this conversation as resolved.
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 @@ -1470,11 +1470,21 @@ public void createBgpPeersCommands(final List<? extends BgpPeer> bgpPeers, final
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 = _networkOfferingDao.findByIdIncludingRemoved(guestNetwork.getNetworkOfferingId());
if (NetworkOffering.NetworkMode.ROUTED.equals(offering.getNetworkMode())) {
Comment thread
weizhouapache marked this conversation as resolved.
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(), guestNetwork.getCidr(), guestNetwork.getIp6Cidr(), bgpPeerDetails));
Comment thread
weizhouapache marked this conversation as resolved.
Outdated
}
}
}

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);
Comment thread
weizhouapache marked this conversation as resolved.

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
14 changes: 7 additions & 7 deletions ui/src/views/infra/zone/BgpPeersTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
<template>
<a-spin :spinning="componentLoading">
<a-alert
v-if="this.resource.ip4routing"
v-if="this.resource.ip4routing || this.resource.ip6routing"
Comment thread
weizhouapache marked this conversation as resolved.
Outdated
type="info">
<template #message>
<div v-html="$t('message.bgp.peers.null')" />
</template>
</a-alert>
<br>
<a-button
v-if="!this.resource.ip4routing"
v-if="!(this.resource.ip4routing || this.resource.ip6routing)"
Comment thread
weizhouapache marked this conversation as resolved.
Outdated
:disabled="!('createBgpPeer' in $store.getters.apis)"
type="primary"
style="margin-bottom: 20px; width: 100%"
Expand Down Expand Up @@ -56,7 +56,7 @@
<template v-if="column.key === 'project'">
{{ record.project }}
</template>
<template v-if="column.key === 'actions' && !this.resource.ip4routing">
<template v-if="column.key === 'actions' && !(this.resource.ip4routing || this.resource.ip6routing)">
<div
class="actions"
style="text-align: right" >
Expand Down Expand Up @@ -103,7 +103,7 @@
</template>
</a-table>
<a-pagination
v-if="!this.resource.ip4routing"
v-if="!(this.resource.ip4routing || this.resource.ip6routing)"
class="row-element pagination"
size="small"
:current="bgpPeersPage"
Expand Down Expand Up @@ -318,7 +318,7 @@

<br>
<a-button
v-if="this.resource.ip4routing && this.$route.meta.name === 'guestnetwork'"
v-if="(this.resource.ip4routing || this.resource.ip6routing) && this.$route.meta.name === 'guestnetwork'"
type="primary"
style="margin-bottom: 20px; width: 100%"
@click="() => { changeBgpPeersForNetworkModal = true }"
Expand All @@ -327,7 +327,7 @@
{{ $t('label.change.bgp.peers') }}
</a-button>
<a-button
v-if="this.resource.ip4routing && this.$route.meta.name === 'vpc'"
v-if="(this.resource.ip4routing || this.resource.ip6routing) && this.$route.meta.name === 'vpc'"
type="primary"
style="margin-bottom: 20px; width: 100%"
@click="() => { changeBgpPeersForVpcModal = true }"
Expand Down Expand Up @@ -474,7 +474,7 @@ export default {
})
},
fetchData () {
if (this.resource.ip4routing) {
if (this.resource.ip4routing || this.resource.ip6routing) {
this.bgpPeers = this.resource.bgppeers
} else {
this.fetchZoneBgpPeer()
Expand Down
2 changes: 1 addition & 1 deletion ui/src/views/network/VpcTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<a-tab-pane :tab="$t('label.networks')" key="tier">
<VpcTiersTab :resource="resource" :loading="loading" />
</a-tab-pane>
<a-tab-pane :tab="$t('label.bgp.peers')" key="bgppeers" v-if="resource.ip4routing === 'Dynamic'">
<a-tab-pane :tab="$t('label.bgp.peers')" key="bgppeers" v-if="resource.ip4routing === 'Dynamic' || resource.ip6routing === 'Dynamic'">
<BgpPeersTab :resource="resource" />
</a-tab-pane>
<a-tab-pane :tab="$t('label.public.ips')" key="ip" v-if="'listPublicIpAddresses' in $store.getters.apis">
Expand Down
Loading