Skip to content

Commit 20e0575

Browse files
committed
Routed: add global setting to enable/disable routed mode
1 parent a506bf1 commit 20e0575

File tree

11 files changed

+68
-20
lines changed

11 files changed

+68
-20
lines changed

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,7 @@ public class ApiConstants {
986986
public static final String ACL_NAME = "aclname";
987987
public static final String NUMBER = "number";
988988
public static final String IS_DYNAMICALLY_SCALABLE = "isdynamicallyscalable";
989+
public static final String ROUTED_MODE_ENABLED = "routedmodeenabled";
989990
public static final String ROUTING = "isrouting";
990991
public static final String ROUTING_MODE = "routingmode";
991992
public static final String MAX_CONNECTIONS = "maxconnections";

api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
157157
@Param(description = "AS Number Range")
158158
private String asnRange;
159159

160+
@SerializedName(ApiConstants.ROUTED_MODE_ENABLED)
161+
@Param(description = "true, if routed network/vpc is enabled", since = "4.20.1")
162+
private boolean routedModeEnabled = false;
163+
164+
160165
public ZoneResponse() {
161166
tags = new LinkedHashSet<ResourceTagResponse>();
162167
}
@@ -412,4 +417,12 @@ public void setAsnRange(String asnRange) {
412417
public String getAsnRange() {
413418
return asnRange;
414419
}
420+
421+
public boolean isRoutedModeEnabled() {
422+
return routedModeEnabled;
423+
}
424+
425+
public void setRoutedModeEnabled(boolean routedModeEnabled) {
426+
this.routedModeEnabled = routedModeEnabled;
427+
}
415428
}

api/src/main/java/org/apache/cloudstack/network/RoutedIpv4Manager.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@
5757

5858
public interface RoutedIpv4Manager extends PluggableService, Configurable {
5959

60+
ConfigKey<Boolean> RoutedNetworkVpcEnabled = new ConfigKey<>(ConfigKey.CATEGORY_NETWORK, Boolean.class,
61+
"routed.network.vpc.enabled",
62+
"true",
63+
"If true, the Routed network and VPC are enabled in the zone.",
64+
true,
65+
ConfigKey.Scope.Zone);
66+
6067
ConfigKey<Integer> RoutedNetworkIPv4MaxCidrSize = new ConfigKey<>(ConfigKey.CATEGORY_NETWORK, Integer.class,
6168
"routed.network.ipv4.max.cidr.size", "30", "The maximum value of the cidr size for isolated networks in ROUTED mode",
6269
true, ConfigKey.Scope.Account);

server/src/main/java/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.apache.cloudstack.api.response.ResourceTagResponse;
3535
import org.apache.cloudstack.api.response.ZoneResponse;
3636
import org.apache.cloudstack.context.CallContext;
37+
import org.apache.cloudstack.network.RoutedIpv4Manager;
3738
import org.apache.commons.collections.CollectionUtils;
3839
import org.apache.commons.lang3.ObjectUtils;
3940
import org.springframework.stereotype.Component;
@@ -141,6 +142,8 @@ public ZoneResponse newDataCenterResponse(ResponseView view, DataCenterJoinVO da
141142
String asRange = asNumberRange.stream().map(range -> range.getStartASNumber() + "-" + range.getEndASNumber()).collect(Collectors.joining(", "));
142143
zoneResponse.setAsnRange(asRange);
143144

145+
zoneResponse.setRoutedModeEnabled(RoutedIpv4Manager.RoutedNetworkVpcEnabled.valueIn(dataCenter.getId()));
146+
144147
zoneResponse.setResourceDetails(ApiDBUtils.getResourceDetails(dataCenter.getId(), ResourceObjectType.Zone));
145148
zoneResponse.setHasAnnotation(annotationDao.hasAnnotations(dataCenter.getUuid(), AnnotationService.EntityType.ZONE.name(),
146149
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));

server/src/main/java/com/cloud/network/NetworkServiceImpl.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,7 +1384,7 @@ private void checkSharedNetworkCidrOverlap(Long zoneId, long physicalNetworkId,
13841384
}
13851385
}
13861386

1387-
void validateNetworkCidrSize(Account caller, Integer cidrSize, String cidr, NetworkOffering networkOffering, long accountId) {
1387+
void validateNetworkCidrSize(Account caller, Integer cidrSize, String cidr, NetworkOffering networkOffering, long accountId, long zoneId) {
13881388
if (!GuestType.Isolated.equals(networkOffering.getGuestType())) {
13891389
if (cidrSize != null) {
13901390
throw new InvalidParameterValueException("network cidr size is only applicable on Isolated networks");
@@ -1394,6 +1394,10 @@ void validateNetworkCidrSize(Account caller, Integer cidrSize, String cidr, Netw
13941394
if (ObjectUtils.allNotNull(cidr, cidrSize)) {
13951395
throw new InvalidParameterValueException("network cidr and cidr size are mutually exclusive");
13961396
}
1397+
if (NetworkOffering.NetworkMode.ROUTED.equals(networkOffering.getNetworkMode())
1398+
&& !routedIpv4Manager.RoutedNetworkVpcEnabled.valueIn(zoneId)) {
1399+
throw new InvalidParameterValueException("Routed network is not enabled in this zone");
1400+
}
13971401
if (NetworkOffering.NetworkMode.ROUTED.equals(networkOffering.getNetworkMode())
13981402
&& routedIpv4Manager.isVirtualRouterGateway(networkOffering)) {
13991403
if (cidr != null) {
@@ -1655,7 +1659,7 @@ public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac
16551659
throw new InvalidParameterValueException("AS number is required for the network but not passed.");
16561660
}
16571661

1658-
validateNetworkCidrSize(caller, networkCidrSize, cidr, ntwkOff, owner.getAccountId());
1662+
validateNetworkCidrSize(caller, networkCidrSize, cidr, ntwkOff, owner.getAccountId(), zone.getId());
16591663

16601664
validateSharedNetworkRouterIPs(gateway, startIP, endIP, netmask, routerIPv4, routerIPv6, startIPv6, endIPv6, ip6Cidr, ntwkOff);
16611665

server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,7 +1162,7 @@ public Vpc createVpc(final long zoneId, final long vpcOffId, final long vpcOwner
11621162
}
11631163

11641164
// Validate VPC cidr/cidrsize
1165-
validateVpcCidrSize(caller, owner.getAccountId(), vpcOff, cidr, cidrSize);
1165+
validateVpcCidrSize(caller, owner.getAccountId(), vpcOff, cidr, cidrSize, zoneId);
11661166

11671167
// Validate BGP peers
11681168
if (CollectionUtils.isNotEmpty(bgpPeerIds)) {
@@ -1247,13 +1247,17 @@ public Vpc createVpc(final long zoneId, final long vpcOffId, final long vpcOwner
12471247
return newVpc;
12481248
}
12491249

1250-
private void validateVpcCidrSize(Account caller, long accountId, VpcOffering vpcOffering, String cidr, Integer cidrSize) {
1250+
private void validateVpcCidrSize(Account caller, long accountId, VpcOffering vpcOffering, String cidr, Integer cidrSize, long zoneId) {
12511251
if (ObjectUtils.allNull(cidr, cidrSize)) {
12521252
throw new InvalidParameterValueException("VPC cidr or cidr size must be specified");
12531253
}
12541254
if (ObjectUtils.allNotNull(cidr, cidrSize)) {
12551255
throw new InvalidParameterValueException("VPC cidr and cidr size are mutually exclusive");
12561256
}
1257+
if (NetworkOffering.NetworkMode.ROUTED.equals(vpcOffering.getNetworkMode())
1258+
&& !routedIpv4Manager.RoutedNetworkVpcEnabled.valueIn(zoneId)) {
1259+
throw new InvalidParameterValueException("Routed VPC is not enabled in this zone");
1260+
}
12571261
if (routedIpv4Manager.isVpcVirtualRouterGateway(vpcOffering)) {
12581262
if (cidr != null) {
12591263
if (!_accountMgr.isRootAdmin(caller.getId())) {

server/src/main/java/com/cloud/server/ManagementServerImpl.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,6 @@
6868
import org.apache.cloudstack.api.command.admin.alert.GenerateAlertCmd;
6969
import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd;
7070
import org.apache.cloudstack.api.command.admin.autoscale.DeleteCounterCmd;
71-
import org.apache.cloudstack.api.command.admin.bgp.CreateASNRangeCmd;
72-
import org.apache.cloudstack.api.command.admin.bgp.DeleteASNRangeCmd;
73-
import org.apache.cloudstack.api.command.admin.bgp.ListASNRangesCmd;
74-
import org.apache.cloudstack.api.command.user.bgp.ListASNumbersCmd;
75-
import org.apache.cloudstack.api.command.admin.bgp.ReleaseASNumberCmd;
7671
import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd;
7772
import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd;
7873
import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd;
@@ -4017,12 +4012,6 @@ public List<Class<?>> getCommands() {
40174012
cmdList.add(RemoveSecondaryStorageSelectorCmd.class);
40184013
cmdList.add(ListAffectedVmsForStorageScopeChangeCmd.class);
40194014

4020-
cmdList.add(CreateASNRangeCmd.class);
4021-
cmdList.add(ListASNRangesCmd.class);
4022-
cmdList.add(DeleteASNRangeCmd.class);
4023-
cmdList.add(ListASNumbersCmd.class);
4024-
cmdList.add(ReleaseASNumberCmd.class);
4025-
40264015
// Out-of-band management APIs for admins
40274016
cmdList.add(EnableOutOfBandManagementForHostCmd.class);
40284017
cmdList.add(DisableOutOfBandManagementForHostCmd.class);

server/src/main/java/org/apache/cloudstack/network/RoutedIpv4ManagerImpl.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@
5757
import com.cloud.utils.exception.CloudRuntimeException;
5858
import com.cloud.utils.net.NetUtils;
5959

60+
import org.apache.cloudstack.api.command.admin.bgp.CreateASNRangeCmd;
61+
import org.apache.cloudstack.api.command.admin.bgp.DeleteASNRangeCmd;
62+
import org.apache.cloudstack.api.command.admin.bgp.ListASNRangesCmd;
63+
import org.apache.cloudstack.api.command.admin.bgp.ReleaseASNumberCmd;
6064
import org.apache.cloudstack.api.command.admin.network.CreateIpv4SubnetForZoneCmd;
6165
import org.apache.cloudstack.api.command.admin.network.CreateIpv4SubnetForGuestNetworkCmd;
6266
import org.apache.cloudstack.api.command.admin.network.DedicateIpv4SubnetForZoneCmd;
@@ -74,6 +78,7 @@
7478
import org.apache.cloudstack.api.command.admin.network.bgp.ListBgpPeersCmd;
7579
import org.apache.cloudstack.api.command.admin.network.bgp.ReleaseDedicatedBgpPeerCmd;
7680
import org.apache.cloudstack.api.command.admin.network.bgp.UpdateBgpPeerCmd;
81+
import org.apache.cloudstack.api.command.user.bgp.ListASNumbersCmd;
7782
import org.apache.cloudstack.api.command.user.network.routing.CreateRoutingFirewallRuleCmd;
7883
import org.apache.cloudstack.api.command.user.network.routing.DeleteRoutingFirewallRuleCmd;
7984
import org.apache.cloudstack.api.command.user.network.routing.ListRoutingFirewallRulesCmd;
@@ -154,6 +159,7 @@ public String getConfigComponentName() {
154159
@Override
155160
public ConfigKey<?>[] getConfigKeys() {
156161
return new ConfigKey[] {
162+
RoutedNetworkVpcEnabled,
157163
RoutedNetworkIPv4MaxCidrSize, RoutedNetworkIPv4MinCidrSize, RoutedIPv4NetworkCidrAutoAllocationEnabled,
158164
RoutedVpcIPv4MaxCidrSize, RoutedVpcIPv4MinCidrSize, UseSystemBgpPeers
159165
};
@@ -162,19 +168,25 @@ public ConfigKey<?>[] getConfigKeys() {
162168
@Override
163169
public List<Class<?>> getCommands() {
164170
final List<Class<?>> cmdList = new ArrayList<Class<?>>();
171+
if (!RoutedNetworkVpcEnabled.value()) {
172+
return cmdList;
173+
}
165174
cmdList.add(CreateIpv4SubnetForZoneCmd.class);
166175
cmdList.add(DeleteIpv4SubnetForZoneCmd.class);
167176
cmdList.add(ListIpv4SubnetsForZoneCmd.class);
168177
cmdList.add(UpdateIpv4SubnetForZoneCmd.class);
169178
cmdList.add(DedicateIpv4SubnetForZoneCmd.class);
170179
cmdList.add(ReleaseDedicatedIpv4SubnetForZoneCmd.class);
180+
171181
cmdList.add(CreateIpv4SubnetForGuestNetworkCmd.class);
172182
cmdList.add(ListIpv4SubnetsForGuestNetworkCmd.class);
173183
cmdList.add(DeleteIpv4SubnetForGuestNetworkCmd.class);
184+
174185
cmdList.add(CreateRoutingFirewallRuleCmd.class);
175186
cmdList.add(ListRoutingFirewallRulesCmd.class);
176187
cmdList.add(UpdateRoutingFirewallRuleCmd.class);
177188
cmdList.add(DeleteRoutingFirewallRuleCmd.class);
189+
178190
cmdList.add(CreateBgpPeerCmd.class);
179191
cmdList.add(DeleteBgpPeerCmd.class);
180192
cmdList.add(ListBgpPeersCmd.class);
@@ -183,6 +195,13 @@ public List<Class<?>> getCommands() {
183195
cmdList.add(ReleaseDedicatedBgpPeerCmd.class);
184196
cmdList.add(ChangeBgpPeersForNetworkCmd.class);
185197
cmdList.add(ChangeBgpPeersForVpcCmd.class);
198+
199+
cmdList.add(CreateASNRangeCmd.class);
200+
cmdList.add(ListASNRangesCmd.class);
201+
cmdList.add(DeleteASNRangeCmd.class);
202+
cmdList.add(ListASNumbersCmd.class);
203+
cmdList.add(ReleaseASNumberCmd.class);
204+
186205
return cmdList;
187206
}
188207

ui/src/config/section/infra/zones.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,16 @@ export default {
7474
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/zone/PhysicalNetworksTab.vue')))
7575
}, {
7676
name: 'ipv4.subnets',
77-
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/zone/Ipv4GuestSubnetsTab.vue')))
77+
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/zone/Ipv4GuestSubnetsTab.vue'))),
78+
show: (record) => { return record.routedmodeenabled && 'listIpv4SubnetsForZone' in store.getters.apis }
7879
}, {
7980
name: 'asnumber',
80-
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/zone/AsNumbersTab.vue')))
81+
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/zone/AsNumbersTab.vue'))),
82+
show: (record) => { return record.routedmodeenabled && 'listASNumbers' in store.getters.apis }
8183
}, {
8284
name: 'bgp.peers',
83-
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/zone/BgpPeersTab.vue')))
85+
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/zone/BgpPeersTab.vue'))),
86+
show: (record) => { return record.routedmodeenabled && 'listBgpPeers' in store.getters.apis }
8487
}, {
8588
name: 'system.vms',
8689
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/zone/SystemVmsTab.vue'))),

ui/src/views/network/CreateIsolatedNetworkForm.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -552,8 +552,9 @@ export default {
552552
this.selectedNetworkOffering = {}
553553
api('listNetworkOfferings', params).then(json => {
554554
this.networkOfferings = json.listnetworkofferingsresponse.networkoffering
555-
if (this.selectedZone.isnsxenabled) {
556-
this.networkOfferings = this.networkOfferings.filter(offering => offering.fornsx)
555+
this.networkOfferings = this.networkOfferings.filter(offering => offering.fornsx === this.selectedZone.isnsxenabled)
556+
if (!this.selectedZone.routedmodeenabled) {
557+
this.networkOfferings = this.networkOfferings.filter(offering => offering.networkmode !== 'ROUTED')
557558
}
558559
}).catch(error => {
559560
this.$notifyError(error)

0 commit comments

Comments
 (0)