diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java index 6d346e9a4db..2dfd749ddca 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java @@ -40,7 +40,7 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd { @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network") private String vlan; - @Parameter(name=ApiConstants.BYPASS_VLAN_OVERLAP_CHECK, type=CommandType.BOOLEAN, description="when true bypasses VLAN id/range overlap check during network creation for shared networks") + @Parameter(name=ApiConstants.BYPASS_VLAN_OVERLAP_CHECK, type=CommandType.BOOLEAN, description="when true bypasses VLAN id/range overlap check during network creation for shared and L2 networks") private Boolean bypassVlanOverlapCheck; ///////////////////////////////////////////////////// diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index c4db7dce8a6..f223eb34ac7 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -2281,7 +2281,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } if (! UuidUtils.validateUUID(vlanId)){ // For Isolated and L2 networks, don't allow to create network with vlan that already exists in the zone - if (ntwkOff.getGuestType() == GuestType.Isolated || ntwkOff.getGuestType() == GuestType.L2) { + if (ntwkOff.getGuestType() == GuestType.Isolated || !hasGuestBypassVlanOverlapCheck(bypassVlanOverlapCheck, ntwkOff)) { if (_networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), null).size() > 0) { throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists or overlaps with other network vlans in zone " + zoneId); } else { @@ -2469,7 +2469,16 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra return network; } - /** + /** + * Checks bypass VLAN id/range overlap check during network creation for guest networks + * @param bypassVlanOverlapCheck bypass VLAN id/range overlap check + * @param ntwkOff network offering + */ + private boolean hasGuestBypassVlanOverlapCheck(final boolean bypassVlanOverlapCheck, final NetworkOfferingVO ntwkOff) { + return bypassVlanOverlapCheck && ntwkOff.getGuestType() != GuestType.Isolated; + } + + /** * Checks for L2 network offering services. Only 2 cases allowed: * - No services * - User Data service only, provided by ConfigDrive diff --git a/ui/l10n/en.js b/ui/l10n/en.js index e20d6093b9a..46b924450ae 100644 --- a/ui/l10n/en.js +++ b/ui/l10n/en.js @@ -511,6 +511,7 @@ var dictionary = { "label.by.type":"By Type", "label.by.type.id":"By Type ID", "label.by.zone":"By Zone", +"label.bypass.vlan.overlap.check": "Bypass VLAN id/range overlap", "label.bytes.received":"Bytes Received", "label.bytes.sent":"Bytes Sent", "label.cache.mode":"Write-cache Type", diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index 7b7cbe257f9..630877b4b50 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -347,6 +347,10 @@ var addGuestNetworkDialog = { label: 'label.vlan.id', docID: 'helpGuestNetworkZoneVLANID' }, + bypassVlanOverlapCheck: { + label: 'label.bypass.vlan.overlap.check', + isBoolean: true + }, isolatedpvlanId: { label: 'label.secondary.isolated.vlan.id' }, @@ -739,6 +743,9 @@ var addGuestNetworkDialog = { if ($form.find('.form-item[rel=vlanId]').css("display") != "none"){ cloudStack.addVlanToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.vlanId) } + if ($form.find('.form-item[rel=bypassVlanOverlapCheck]').css("display") != "none"){ + array1.push("&bypassVlanOverlapCheck=" + encodeURIComponent((args.data.bypassVlanOverlapCheck == "on"))); + } if (($form.find('.form-item[rel=isolatedpvlanId]').css("display") != "none") && (args.data.isolatedpvlanId != null && args.data.isolatedpvlanId.length > 0)){ array1.push("&isolatedpvlan=" + encodeURIComponent(args.data.isolatedpvlanId)); } @@ -929,6 +936,7 @@ var addL2GuestNetwork = { var networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering; args.$select.change(function() { var $vlan = args.$select.closest('form').find('[rel=vlan]'); + var $bypassVlanOverlapCheck = args.$select.closest('form').find('[rel=bypassVlanOverlapCheck]'); var networkOffering = $.grep( networkOfferingObjs, function(netoffer) { return netoffer.id == args.$select.val(); @@ -937,8 +945,10 @@ var addL2GuestNetwork = { if (networkOffering.specifyvlan) { $vlan.css('display', 'inline-block'); + $bypassVlanOverlapCheck.css('display', 'inline-block'); } else { $vlan.hide(); + $bypassVlanOverlapCheck.hide(); } }); @@ -962,6 +972,11 @@ var addL2GuestNetwork = { }, isHidden: true }, + bypassVlanOverlapCheck: { + label: 'label.bypass.vlan.overlap.check', + isBoolean: true, + isHidden: true + }, domain: { label: 'label.domain', @@ -1036,7 +1051,8 @@ var addL2GuestNetwork = { if (args.$form.find('.form-item[rel=vlan]').css('display') != 'none') { $.extend(dataObj, { - vlan: args.data.vlan + vlan: args.data.vlan, + bypassVlanOverlapCheck: (args.data.bypassVlanOverlapCheck == "on") }); } @@ -2884,4 +2900,4 @@ cloudStack.listDiskOfferings = function(options){ error: mergedOptions.error }); return diskOfferings; -}; \ No newline at end of file +};