diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index cb1ee021d67b..1db21e783d20 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -280,6 +280,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C private static final ConfigKey AllowEmptyStartEndIpAddress = new ConfigKey<>("Advanced", Boolean.class, "allow.empty.start.end.ipaddress", "true", "Allow creating network without mentioning start and end IP address", true, ConfigKey.Scope.Account); + public static final ConfigKey AllowUsersToMakeNetworksRedundant = new ConfigKey<>("Advanced", Boolean.class, + "allow.users.to.make.networks.redundant", "true", "Allow Users to make Networks Redundant", + true, ConfigKey.Scope.Global); private static final long MIN_VLAN_ID = 0L; private static final long MAX_VLAN_ID = 4095L; // 2^12 - 1 private static final long MIN_GRE_KEY = 0L; @@ -2986,8 +2989,13 @@ public boolean restartNetwork(RestartNetworkCmd cmd) throws ConcurrentOperationE throwInvalidIdException("Cannot restart a VPC tier with cleanup, please restart the whole VPC.", network.getUuid(), "network tier"); } boolean makeRedundant = cmd.getMakeRedundant(); - boolean livePatch = cmd.getLivePatch(); User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId()); + if (makeRedundant && !_accountMgr.isRootAdmin(callerUser.getAccountId()) && !AllowUsersToMakeNetworksRedundant.value() ) { + throw new InvalidParameterValueException("Could not make the network redundant. Please contact administrator."); + AllowUsersToMakeNetworksRedundant.key())); + } + + boolean livePatch = cmd.getLivePatch(); return restartNetwork(network, cleanup, makeRedundant, livePatch, callerUser); } @@ -6266,7 +6274,7 @@ public String getConfigComponentName() { @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {AllowDuplicateNetworkName, AllowEmptyStartEndIpAddress, VRPrivateInterfaceMtu, VRPublicInterfaceMtu, AllowUsersToSpecifyVRMtu}; + return new ConfigKey[] {AllowDuplicateNetworkName, AllowEmptyStartEndIpAddress, AllowUsersToMakeNetworksRedundant, VRPrivateInterfaceMtu, VRPublicInterfaceMtu, AllowUsersToSpecifyVRMtu}; } public boolean isDefaultAcl(Long aclId) { diff --git a/ui/src/config/section/network.js b/ui/src/config/section/network.js index 8c1ffcdf9cd4..baffdf972086 100644 --- a/ui/src/config/section/network.js +++ b/ui/src/config/section/network.js @@ -171,13 +171,16 @@ export default { if (isGroupAction || record.vpcid == null) { fields.push('cleanup') } + if (!record.redundantrouter) { + fields.push('makeredundant') + } fields.push('livepatch') return fields }, show: (record) => record.type !== 'L2', groupAction: true, popup: true, - groupMap: (selection, values) => { return selection.map(x => { return { id: x, cleanup: values.cleanup } }) } + groupMap: (selection, values) => { return selection.map(x => { return { id: x, cleanup: values.cleanup, makeredundant: values.makeredundant } }) } }, { api: 'replaceNetworkACLList',